Compare commits
No commits in common. "e9b9a04a70b5dd2deadd5051c7392f5721e7c881" and "c6f0058d62a667680ddae577c99ce29c26a4ba97" have entirely different histories.
e9b9a04a70
...
c6f0058d62
|
@ -74,9 +74,7 @@ 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);
|
||||||
$coordinates = Link_interaction::getCoordinates($id);
|
return view('details', ['shortlink' => $shortlink, 'countrylist' => $countrylist]);
|
||||||
$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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,21 +78,16 @@ class Link_interaction extends Model
|
||||||
return $link_interaction;
|
return $link_interaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getTimes(string $link) {
|
public 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 static function getCoordinates(string $link) {
|
public function getCoordinates(string $link) {
|
||||||
$coordinates = [];
|
$link_interaction = [];
|
||||||
$link_interaction = Link_interaction::where('link', $link)->select('latitude', 'longitude')->get()->toArray();
|
$link_interaction = Link_interaction::where('link', $link)->select('latitude', 'longitude')->get()->toArray();
|
||||||
foreach ($link_interaction as $interaction) {
|
return $link_interaction;
|
||||||
if ($interaction['latitude'] != null && $interaction['longitude'] != null) {
|
|
||||||
array_push($coordinates, $interaction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $coordinates;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
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;
|
||||||
|
@ -353,7 +352,7 @@ header nav a {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background-color: #888;
|
background-color: #888;
|
||||||
width: calc(500% + 20px);
|
width: 500%;
|
||||||
transform: translateY(5px);
|
transform: translateY(5px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,20 +363,4 @@ 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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,10 +4,6 @@
|
||||||
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>
|
||||||
|
@ -68,14 +64,7 @@
|
||||||
</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>
|
||||||
|
@ -98,91 +87,4 @@
|
||||||
|
|
||||||
@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: 'Total Clicks',
|
|
||||||
data: data,
|
|
||||||
borderColor: 'rgba(255, 0, 80, 1)',
|
|
||||||
backgroundColor: 'rgba(255, 0, 80, 0.2)',
|
|
||||||
borderWidth: 1,
|
|
||||||
fill: true
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
type: 'time',
|
|
||||||
time: {
|
|
||||||
unit: 'day'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
beginAtZero: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@endsection
|
@endsection
|
Loading…
Reference in New Issue