272 lines
8.2 KiB
HTML
272 lines
8.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Dashboard - Verbindungsanalyse</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<style>
|
|
body { margin: 20px; }
|
|
.card { margin-bottom: 20px; }
|
|
canvas { max-width: 100%; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1 class="mb-4">Dashboard - Verbindungsanalyse({{ timeframe }})</h1>
|
|
<!-- Timeframe selection buttons -->
|
|
<div class="mb-3">
|
|
<a href="{{ url_for('index') }}" class="btn btn-primary">Home</a>
|
|
<a href="{{ url_for('network') }}" class="btn btn-primary">Netzwerk</a>
|
|
<a href="{{ url_for('dashboard', timeframe='today') }}" class="btn btn-primary">Today</a>
|
|
<a href="{{ url_for('dashboard', timeframe='7days') }}" class="btn btn-primary">Last 7 Days</a>
|
|
<a href="{{ url_for('dashboard', timeframe='30days') }}" class="btn btn-primary">Last 30 Days</a>
|
|
<a href="{{ url_for('dashboard', timeframe='365days') }}" class="btn btn-primary">Last 365 Days</a>
|
|
</div>
|
|
|
|
<!-- Summary Cards -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-4">
|
|
<div class="card text-white bg-info">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Total Accesses</h5>
|
|
<p class="card-text">{{ total_accesses }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card text-white bg-success">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Unique Files</h5>
|
|
<p class="card-text">{{ unique_files }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card text-white bg-warning">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Unique IPs</h5>
|
|
<p class="card-text">{{ unique_ips }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Charts Section -->
|
|
<div class="row">
|
|
<!-- Access Trend Chart -->
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Access Trend</h5>
|
|
<canvas id="accessTrendChart"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Top Files Accessed Chart -->
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Top Files Accessed</h5>
|
|
<canvas id="topFilesChart"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- User Agent Distribution Chart -->
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">User Agent Distribution</h5>
|
|
<canvas id="userAgentChart"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Referrer Distribution Chart -->
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Referrer Distribution</h5>
|
|
<canvas id="referrerChart"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- New Section: IP Address Access Data -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
IP Address Access Distribution
|
|
</div>
|
|
<div class="card-body">
|
|
<table class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>IP Address</th>
|
|
<th>Access Count</th>
|
|
<th>City</th>
|
|
<th>Country</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for ip in ip_data %}
|
|
<tr>
|
|
<td>{{ ip.ip }}</td>
|
|
<td>{{ ip.count }}</td>
|
|
<td>{{ ip.city }}</td>
|
|
<td>{{ ip.country }}</td>
|
|
</tr>
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="4">No IP access data available for the selected timeframe.</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- New Section: Aggregated City Access Data -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
City Access Distribution
|
|
</div>
|
|
<div class="card-body">
|
|
<table class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>City</th>
|
|
<th>Access Count</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for city in city_data %}
|
|
<tr>
|
|
<td>{{ city.city }}</td>
|
|
<td>{{ city.count }}</td>
|
|
</tr>
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="2">No city access data available for the selected timeframe.</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Detailed Table of Top File Accesses -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
Detailed File Access Data
|
|
</div>
|
|
<div class="card-body">
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>File Path</th>
|
|
<th>Access Count</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for row in rows %}
|
|
<tr>
|
|
<td>{{ row[0] }}</td>
|
|
<td>{{ row[1] }}</td>
|
|
</tr>
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="2">No data available for the selected timeframe.</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Load Chart.js from CDN -->
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<script>
|
|
// Data passed from the backend as JSON
|
|
const dailyAccessData = {{ daily_access_data|tojson }};
|
|
const topFilesData = {{ top_files_data|tojson }};
|
|
// Note: user_agent_data now contains 'device' and 'count'
|
|
const userAgentData = {{ user_agent_data|tojson }};
|
|
const referrerData = {{ referrer_data|tojson }};
|
|
|
|
// Access Trend Chart - Line Chart
|
|
const ctxTrend = document.getElementById('accessTrendChart').getContext('2d');
|
|
new Chart(ctxTrend, {
|
|
type: 'line',
|
|
data: {
|
|
labels: dailyAccessData.map(item => item.date),
|
|
datasets: [{
|
|
label: 'Access Count',
|
|
data: dailyAccessData.map(item => item.count),
|
|
borderWidth: 2,
|
|
fill: true
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
plugins: { legend: { position: 'top' } },
|
|
scales: {
|
|
x: { title: { display: true, text: 'Date' } },
|
|
y: { title: { display: true, text: 'Access Count' } }
|
|
}
|
|
}
|
|
});
|
|
|
|
// Top Files Chart - Horizontal Bar Chart
|
|
const ctxTopFiles = document.getElementById('topFilesChart').getContext('2d');
|
|
new Chart(ctxTopFiles, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: topFilesData.map(item => item.full_path),
|
|
datasets: [{
|
|
label: 'Access Count',
|
|
data: topFilesData.map(item => item.access_count),
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
indexAxis: 'y',
|
|
responsive: true,
|
|
plugins: { legend: { display: false } },
|
|
scales: {
|
|
x: { title: { display: true, text: 'Access Count' } },
|
|
y: { title: { display: true, text: 'File Path' } }
|
|
}
|
|
}
|
|
});
|
|
|
|
// User Agent Distribution - Pie Chart (using aggregated device data)
|
|
const ctxUserAgent = document.getElementById('userAgentChart').getContext('2d');
|
|
new Chart(ctxUserAgent, {
|
|
type: 'pie',
|
|
data: {
|
|
labels: userAgentData.map(item => item.device),
|
|
datasets: [{
|
|
data: userAgentData.map(item => item.count)
|
|
}]
|
|
},
|
|
options: { responsive: true }
|
|
});
|
|
|
|
// Referrer Distribution - Pie Chart (with shortened referrers)
|
|
const ctxReferrer = document.getElementById('referrerChart').getContext('2d');
|
|
new Chart(ctxReferrer, {
|
|
type: 'pie',
|
|
data: {
|
|
labels: referrerData.map(item => item.referrer),
|
|
datasets: [{
|
|
data: referrerData.map(item => item.count)
|
|
}]
|
|
},
|
|
options: { responsive: true }
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|