add hourly bar diagram

This commit is contained in:
lelo 2025-03-30 19:21:52 +00:00
parent 2101669567
commit 2ee5cf3a26
2 changed files with 82 additions and 25 deletions

View File

@ -123,16 +123,44 @@ def dashboard():
''', (start.isoformat(),))
daily_access_data = [dict(date=row[0], count=row[1]) for row in cursor.fetchall()]
# Top files for bar chart
cursor.execute('''
SELECT rel_path, COUNT(*) as access_count
FROM file_access_log
WHERE timestamp >= ?
GROUP BY rel_path
ORDER BY access_count DESC
LIMIT 10
''', (start.isoformat(),))
top_files_data = [dict(rel_path=row[0], access_count=row[1]) for row in cursor.fetchall()]
# Aggregate download counts by time bucket according to the timeframe.
if timeframe == 'today':
# Group by hour (0-23)
cursor.execute('''
SELECT strftime('%H', timestamp) as bucket, COUNT(*) as count
FROM file_access_log
WHERE timestamp >= ?
GROUP BY bucket
ORDER BY bucket
''', (start.isoformat(),))
elif timeframe in ('7days', '30days'):
# Group by day (YYYY-MM-DD)
cursor.execute('''
SELECT date(timestamp) as bucket, COUNT(*) as count
FROM file_access_log
WHERE timestamp >= ?
GROUP BY bucket
ORDER BY bucket
''', (start.isoformat(),))
elif timeframe == '365days':
# Group by month (YYYY-MM)
cursor.execute('''
SELECT strftime('%Y-%m', timestamp) as bucket, COUNT(*) as count
FROM file_access_log
WHERE timestamp >= ?
GROUP BY bucket
ORDER BY bucket
''', (start.isoformat(),))
else:
# Fallback: group by day
cursor.execute('''
SELECT date(timestamp) as bucket, COUNT(*) as count
FROM file_access_log
WHERE timestamp >= ?
GROUP BY bucket
ORDER BY bucket
''', (start.isoformat(),))
timeframe_data = [dict(bucket=row[0], count=row[1]) for row in cursor.fetchall()]
# User agent distribution (aggregate by device type)
cursor.execute('''
@ -224,10 +252,10 @@ def dashboard():
timeframe=timeframe,
rows=rows,
daily_access_data=daily_access_data,
top_files_data=top_files_data,
user_agent_data=user_agent_data,
folder_data=folder_data,
location_data=location_data,
total_accesses=total_accesses,
unique_files=unique_files,
unique_user=unique_user)
unique_user=unique_user,
timeframe_data=timeframe_data)

View File

@ -75,12 +75,12 @@
</div>
</div>
</div>
<!-- Top Files Accessed Chart -->
<!-- Timeframe Breakdown Chart (Bar Chart) -->
<div class="col-md-6 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Häufig geladene Dateien</h5>
<canvas id="topFilesChart"></canvas>
<h5 class="card-title">Downloads nach Zeit</h5>
<canvas id="timeframeChart"></canvas>
</div>
</div>
</div>
@ -171,11 +171,41 @@
<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'
// Replace topFilesData usage with timeframeData for this chart
const timeframeData = {{ timeframe_data|tojson }};
const userAgentData = {{ user_agent_data|tojson }};
const folderData = {{ folder_data|tojson }};
// shift the labels to local time zone
const timeframe = "{{ timeframe }}"; // e.g., 'today', '7days', '30days', or '365days'
const shiftedLabels = timeframeData.map(item => {
if (timeframe === 'today') {
// For "today", the bucket is an hour in UTC (e.g., "14")
const utcHour = parseInt(item.bucket, 10);
const now = new Date();
// Create Date objects for the start and end of the hour in UTC
const utcStart = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), utcHour));
const utcEnd = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), utcHour + 1));
// Convert to local time strings, e.g., "16:00"
const localStart = utcStart.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
const localEnd = utcEnd.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
return `${localStart} - ${localEnd}`;
} else if (timeframe === '7days' || timeframe === '30days') {
// For these timeframes, the bucket is a date in the format "YYYY-MM-DD"
const utcDate = new Date(item.bucket + 'T00:00:00Z');
return utcDate.toLocaleDateString(); // Adjust formatting as needed
} else if (timeframe === '365days') {
// For this timeframe, the bucket is a month in the format "YYYY-MM"
const [year, month] = item.bucket.split('-');
const dateObj = new Date(year, month - 1, 1);
// Format to something like "Mar 2025"
return dateObj.toLocaleString([], { month: 'short', year: 'numeric' });
} else {
// Fallback: use the bucket value as-is
return item.bucket;
}
});
// Access Trend Chart - Line Chart
const ctxTrend = document.getElementById('accessTrendChart').getContext('2d');
new Chart(ctxTrend, {
@ -199,25 +229,24 @@
}
});
// Top Files Chart - Horizontal Bar Chart
const ctxTopFiles = document.getElementById('topFilesChart').getContext('2d');
new Chart(ctxTopFiles, {
// Timeframe Breakdown Chart - Bar Chart (for "today" timeframe)
const ctxTimeframe = document.getElementById('timeframeChart').getContext('2d');
new Chart(ctxTimeframe, {
type: 'bar',
data: {
labels: topFilesData.map(item => item.full_path),
labels: shiftedLabels,
datasets: [{
label: 'Download Count',
data: topFilesData.map(item => item.access_count),
data: timeframeData.map(item => item.count),
borderWidth: 1
}]
},
options: {
indexAxis: 'y',
responsive: true,
plugins: { legend: { display: false } },
scales: {
x: { title: { display: true, text: 'Download Count' } },
y: { title: { display: true, text: '' } }
x: { title: { display: true, text: 'Local Time Range' } },
y: { title: { display: true, text: 'Download Count' } }
}
}
});