diff --git a/public/analytics.js b/public/analytics.js
index 27eb823d..57f01ee6 100644
--- a/public/analytics.js
+++ b/public/analytics.js
@@ -840,29 +840,44 @@
}
}
+ var CHANNEL_TIMELINE_MAX_SERIES = 8;
+
function renderChannelTimeline(data) {
if (!data.length) return '
No data
';
var hours = []; var hourSet = {};
var channelList = []; var channelSet = {};
var lookup = {};
- var maxCount = 1;
+ var channelVolume = {};
for (var i = 0; i < data.length; i++) {
var d = data[i];
if (!hourSet[d.hour]) { hourSet[d.hour] = 1; hours.push(d.hour); }
if (!channelSet[d.channel]) { channelSet[d.channel] = 1; channelList.push(d.channel); }
lookup[d.hour + '|' + d.channel] = d.count;
- if (d.count > maxCount) maxCount = d.count;
+ channelVolume[d.channel] = (channelVolume[d.channel] || 0) + d.count;
}
hours.sort();
+ // Sort channels by total volume descending, cap to top N
+ channelList.sort(function(a, b) { return channelVolume[b] - channelVolume[a]; });
+ var hiddenCount = Math.max(0, channelList.length - CHANNEL_TIMELINE_MAX_SERIES);
+ var visibleChannels = channelList.slice(0, CHANNEL_TIMELINE_MAX_SERIES);
+
+ var maxCount = 1;
+ for (var vi = 0; vi < visibleChannels.length; vi++) {
+ for (var hi2 = 0; hi2 < hours.length; hi2++) {
+ var c = lookup[hours[hi2] + '|' + visibleChannels[vi]] || 0;
+ if (c > maxCount) maxCount = c;
+ }
+ }
+
var colors = ['#ef4444','#22c55e','#3b82f6','#f59e0b','#8b5cf6','#ec4899','#14b8a6','#64748b'];
var w = 600, h = 180, pad = 35;
var xScale = (w - pad * 2) / Math.max(hours.length - 1, 1);
var yScale = (h - pad * 2) / maxCount;
var svg = '';
var legendParts = [];
- for (var lci = 0; lci < channelList.length; lci++) {
- legendParts.push('' + esc(channelList[lci]) + '');
+ for (var lci = 0; lci < visibleChannels.length; lci++) {
+ legendParts.push('' + esc(visibleChannels[lci]) + '');
+ }
+ if (hiddenCount > 0) {
+ legendParts.push('+' + hiddenCount + ' more');
}
svg += '' + legendParts.join('') + '
';
return svg;