diff --git a/public/assets/js/admin-stats.js b/public/assets/js/admin-stats.js index a0c0214..41060b8 100644 --- a/public/assets/js/admin-stats.js +++ b/public/assets/js/admin-stats.js @@ -55,7 +55,7 @@ if (!trendEl || !totals.length) { return; } var n = totals.length; - var VW = 900, VH = 160; + var VW = 900, VH = 480; var ml = 44, mr = 12, mt = 12, mb = 28; // marges pour axes var W = VW - ml - mr; var H = VH - mt - mb; @@ -142,7 +142,7 @@ trendEl.innerHTML = '

Trafic total — 14 derniers jours

' + '' + + ' style="width:100%;height:480px;display:block;overflow:visible">' + '' + '' + '' @@ -159,6 +159,111 @@ + ''; } + function multiLineChart(pagesByDay, rssRows) { + var el = document.getElementById('stats-multiline-container'); + if (!el) { return; } + + var COLORS = ['#0d6efd','#198754','#dc3545','#fd7e14','#6f42c1', + '#20c997','#0dcaf0','#e63946','#f4a261','#457b9d']; + var n = 14; + var VW = 900, VH = 480; + var ml = 44, mr = 12, mt = 12, mb = 28; + var W = VW - ml - mr; + var H = VH - mt - mb; + + // Top articles par total (max 10), dans l'ordre du RSS + var series = []; + rssRows.forEach(function (row) { + var pm = row.link.match(/\/post\/[^?#]*/); + var data = pm ? (pagesByDay[pm[0]] || null) : null; + if (data && series.length < 10) { + series.push({ title: row.title || row.slug, data: data }); + } + }); + if (!series.length) { return; } + + var allVals = series.reduce(function (acc, s) { return acc.concat(s.data); }, []); + var rawMax = Math.max.apply(null, allVals) || 1; + var mag = Math.pow(10, Math.floor(Math.log(rawMax) / Math.LN10)); + var maxV = Math.ceil(rawMax / mag) * mag; + var nTicks = 4; + + var now = new Date(); + var labels = series[0].data.map(function (_, i) { + var d = new Date(now); + d.setDate(d.getDate() - (n - 1 - i)); + return d.toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' }); + }); + + function smoothPath(pts) { + var d = 'M ' + pts[0].x.toFixed(1) + ' ' + pts[0].y.toFixed(1); + for (var i = 0; i < pts.length - 1; i++) { + var p0 = pts[i > 0 ? i - 1 : i]; + var p1 = pts[i], p2 = pts[i + 1]; + var p3 = pts[i + 2 < pts.length ? i + 2 : i + 1]; + var t = 0.35; + var cp1x = p1.x + t * (p2.x - p0.x) / 2, cp1y = p1.y + t * (p2.y - p0.y) / 2; + var cp2x = p2.x - t * (p3.x - p1.x) / 2, cp2y = p2.y - t * (p3.y - p1.y) / 2; + d += ' C ' + cp1x.toFixed(1) + ' ' + cp1y.toFixed(1) + + ', ' + cp2x.toFixed(1) + ' ' + cp2y.toFixed(1) + + ', ' + p2.x.toFixed(1) + ' ' + p2.y.toFixed(1); + } + return d; + } + + var grid = '', yLabels = ''; + for (var t = 0; t <= nTicks; t++) { + var val = Math.round(maxV * t / nTicks); + var gy = (mt + H - (val / maxV) * H).toFixed(1); + grid += ''; + yLabels += '' + val + ''; + } + + var xLabels = ''; + labels.forEach(function (lbl, i) { + if (i % 2 === 0 || i === n - 1) { + var x = (ml + i * W / (n - 1)).toFixed(1); + xLabels += '' + lbl + ''; + } + }); + + var lines = series.map(function (s, si) { + var color = COLORS[si % COLORS.length]; + var pts = s.data.map(function (v, i) { + return { x: ml + i * W / (n - 1), y: mt + H - (v / maxV) * H, v: v, l: labels[i] }; + }); + var dots = pts.map(function (p) { + return '' + esc(p.l) + ' — ' + esc(s.title) + ' : ' + p.v + ' vis.' + + ''; + }).join(''); + return '' + dots; + }).join(''); + + // Légende + var legend = series.map(function (s, si) { + var color = COLORS[si % COLORS.length]; + var short = s.title.length > 32 ? s.title.slice(0, 32) + '…' : s.title; + return '' + + '' + + '' + + esc(short) + ''; + }).join(''); + + el.innerHTML = + '

Par article — 14 derniers jours

' + + '' + + grid + lines + yLabels + xLabels + '' + + '
' + legend + '
'; + } + fetch('/trending?period=14d') .then(function (r) { return r.ok ? r.text() : Promise.reject(); }) .then(function (xml) { @@ -186,6 +291,7 @@ arr.forEach(function (v, i) { if (i < nDays) { totals[i] += v; } }); }); trendChart(totals); + multiLineChart(pagesByDay, rows); var html = '
'; rows.forEach(function (row, i) { diff --git a/templates/admin_stats.php b/templates/admin_stats.php index 9945d50..0383d5c 100644 --- a/templates/admin_stats.php +++ b/templates/admin_stats.php @@ -36,6 +36,7 @@ $_activeGroup = trim($_GET['group'] ?? '');

Chargement…

+