Added graphing and heatmap

This commit is contained in:
Notoric 2024-06-11 01:17:06 +01:00
parent c6f0058d62
commit 1bc6b50727
4 changed files with 129 additions and 7 deletions

View File

@ -74,7 +74,9 @@ class ShortlinkController extends Controller
return response()->json(['error' => 'Unauthorized'], 401); return response()->json(['error' => 'Unauthorized'], 401);
} }
$countrylist = (new Link_interactionController)->getCountryArray($id); $countrylist = (new Link_interactionController)->getCountryArray($id);
return view('details', ['shortlink' => $shortlink, 'countrylist' => $countrylist]); $coordinates = Link_interaction::getCoordinates($id);
$timestamps = Link_interaction::getTimes($id);
return view('details', ['shortlink' => $shortlink, 'countrylist' => $countrylist, 'coordinates' => $coordinates, 'timestamps' => $timestamps]);
} catch (\Exception $e) { } catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 404); return response()->json(['error' => $e->getMessage()], 404);
} }

View File

@ -78,16 +78,21 @@ class Link_interaction extends Model
return $link_interaction; return $link_interaction;
} }
public function getTimes(string $link) { public static function getTimes(string $link) {
$link_interaction = []; $link_interaction = [];
$link_interaction = Link_interaction::where('link', $link)->select('created_at')->get()->toArray(); $link_interaction = Link_interaction::where('link', $link)->select('created_at')->get()->toArray();
return $link_interaction; return $link_interaction;
} }
public function getCoordinates(string $link) { public static function getCoordinates(string $link) {
$link_interaction = []; $coordinates = [];
$link_interaction = Link_interaction::where('link', $link)->select('latitude', 'longitude')->get()->toArray(); $link_interaction = Link_interaction::where('link', $link)->select('latitude', 'longitude')->get()->toArray();
return $link_interaction; foreach ($link_interaction as $interaction) {
if ($interaction['latitude'] != null && $interaction['longitude'] != null) {
array_push($coordinates, $interaction);
}
}
return $coordinates;
} }
} }

View File

@ -10,6 +10,7 @@
body { body {
margin: 0; margin: 0;
overflow: hidden; overflow: hidden;
overflow-y: scroll;
font-family: 'Roboto', sans-serif; font-family: 'Roboto', sans-serif;
background-color: var(--background); background-color: var(--background);
color: white; color: white;
@ -363,4 +364,20 @@ a button {
align-self: center; align-self: center;
font-size: 0.8em; font-size: 0.8em;
cursor: pointer; cursor: pointer;
} }
#graphs {
display: flex;
flex-direction: row;
justify-content: space-between;
}
#graphs h2 {
margin-bottom: 20px;
}
#map {
width: 540px;
height: 400px;
}

View File

@ -4,6 +4,10 @@
Details & Logs Details & Logs
@endsection @endsection
@section('head')
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
@endsection
@section('content') @section('content')
<div id="banner-container" class="container"> <div id="banner-container" class="container">
<h1>Details & Logs</h1> <h1>Details & Logs</h1>
@ -64,7 +68,14 @@
</form> </form>
</div> </div>
<div id="graphs" class="container"> <div id="graphs" class="container">
<div id="map-wrapper">
<h2>Heatmap</h2>
<div id="map"></div>
</div>
<div id="timeline-wrapper">
<h2>Timeline</h2>
<canvas id="cumulativeGraph" width="540" height="400"></canvas>
</div>
</div> </div>
<div id="stats" class="container"> <div id="stats" class="container">
<h2>Link Clicks</h2> <h2>Link Clicks</h2>
@ -87,4 +98,91 @@
@section('scripts') @section('scripts')
<script src="{{ asset('js/details.js') }}"></script> <script src="{{ asset('js/details.js') }}"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet.heat/dist/leaflet-heat.js"></script>
<script>
var map = L.map('map').setView([50, 0], 3);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 10,
}).addTo(map);
var heat = L.heatLayer([], {
radius: 50,
blur: 20,
maxZoom: 3,
max: 5,
}).addTo(map);
async function loadHeatmapData() {
var data = [
@foreach ($coordinates as $coordinate)
{lat:{{ $coordinate['latitude'] }}, lng:{{ $coordinate['longitude'] }}},
@endforeach
];
heat.setLatLngs(data);
}
loadHeatmapData();
</script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns"></script>
<script>
const timestamps = [
@foreach ($timestamps as $timestamp)
'{{ $timestamp['created_at'] }}',
@endforeach
];
// Function to count occurrences cumulatively
function getCumulativeCounts(timestamps) {
const counts = [];
const dateCounts = {};
timestamps.forEach((timestamp) => {
const date = new Date(timestamp).toISOString(); // Get date part only
if (dateCounts[date]) {
dateCounts[date]++;
} else {
dateCounts[date] = 1;
}
counts.push({ date: date, count: Object.values(dateCounts).reduce((a, b) => a + b, 0) });
});
return counts;
}
// Get the cumulative data
const cumulativeData = getCumulativeCounts(timestamps);
// Extract dates and counts for the chart
const labels = cumulativeData.map(data => data.date);
const data = cumulativeData.map(data => data.count);
// Create the chart
const ctx = document.getElementById('cumulativeGraph').getContext('2d');
const cumulativeGraph = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Cumulative Count',
data: data,
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderWidth: 1,
fill: true
}]
},
options: {
scales: {
x: {
type: 'time',
time: {
unit: 'day'
}
},
y: {
beginAtZero: true
}
}
}
});
</script>
@endsection @endsection