From 31b374763445e6abd189b79c0b7fe0daa8368da4 Mon Sep 17 00:00:00 2001 From: aphandersen Date: Wed, 15 Apr 2026 19:54:04 +0000 Subject: [PATCH] Upload files to "ansico-stat-plugin/assets/js" --- .../assets/js/ansico-stat-chart.js | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 ansico-stat-plugin/assets/js/ansico-stat-chart.js diff --git a/ansico-stat-plugin/assets/js/ansico-stat-chart.js b/ansico-stat-plugin/assets/js/ansico-stat-chart.js new file mode 100644 index 0000000..a91dd07 --- /dev/null +++ b/ansico-stat-plugin/assets/js/ansico-stat-chart.js @@ -0,0 +1,113 @@ +(function () { + function drawChart(canvas) { + if (!canvas || !canvas.getContext) { + return; + } + + var labels = []; + var values = []; + + try { + labels = JSON.parse(canvas.dataset.labels || '[]'); + values = JSON.parse(canvas.dataset.values || '[]'); + } catch (e) { + return; + } + + var ctx = canvas.getContext('2d'); + var dpr = window.devicePixelRatio || 1; + var cssWidth = canvas.clientWidth || canvas.parentNode.clientWidth || 600; + var cssHeight = canvas.height || 160; + + canvas.width = cssWidth * dpr; + canvas.height = cssHeight * dpr; + ctx.scale(dpr, dpr); + ctx.clearRect(0, 0, cssWidth, cssHeight); + + if (!values.length) { + ctx.font = '13px sans-serif'; + ctx.fillStyle = '#666'; + ctx.fillText('No data yet.', 10, 20); + return; + } + + var padding = { top: 16, right: 14, bottom: 30, left: 44 }; + var chartWidth = cssWidth - padding.left - padding.right; + var chartHeight = cssHeight - padding.top - padding.bottom; + var maxValue = Math.max.apply(null, values.concat([1])); + var minValue = 0; + var steps = 4; + + ctx.strokeStyle = '#d9d9d9'; + ctx.lineWidth = 1; + ctx.fillStyle = '#555'; + ctx.font = '11px sans-serif'; + + for (var i = 0; i <= steps; i++) { + var y = padding.top + (chartHeight / steps) * i; + var value = Math.round(maxValue - ((maxValue - minValue) / steps) * i); + ctx.beginPath(); + ctx.moveTo(padding.left, y); + ctx.lineTo(padding.left + chartWidth, y); + ctx.stroke(); + ctx.fillText(String(value), 6, y + 4); + } + + ctx.strokeStyle = '#2271b1'; + ctx.lineWidth = 2; + ctx.beginPath(); + + values.forEach(function (value, index) { + var x = padding.left + (chartWidth * index) / Math.max(values.length - 1, 1); + var y = padding.top + chartHeight - ((value - minValue) / Math.max(maxValue - minValue, 1)) * chartHeight; + if (index === 0) { + ctx.moveTo(x, y); + } else { + ctx.lineTo(x, y); + } + }); + ctx.stroke(); + + ctx.fillStyle = 'rgba(34, 113, 177, 0.10)'; + ctx.beginPath(); + values.forEach(function (value, index) { + var x = padding.left + (chartWidth * index) / Math.max(values.length - 1, 1); + var y = padding.top + chartHeight - ((value - minValue) / Math.max(maxValue - minValue, 1)) * chartHeight; + if (index === 0) { + ctx.moveTo(x, y); + } else { + ctx.lineTo(x, y); + } + }); + ctx.lineTo(padding.left + chartWidth, padding.top + chartHeight); + ctx.lineTo(padding.left, padding.top + chartHeight); + ctx.closePath(); + ctx.fill(); + + ctx.fillStyle = '#2271b1'; + values.forEach(function (value, index) { + var x = padding.left + (chartWidth * index) / Math.max(values.length - 1, 1); + var y = padding.top + chartHeight - ((value - minValue) / Math.max(maxValue - minValue, 1)) * chartHeight; + ctx.beginPath(); + ctx.arc(x, y, 2.5, 0, Math.PI * 2); + ctx.fill(); + }); + + ctx.fillStyle = '#555'; + ctx.font = '10px sans-serif'; + var labelIndexes = [0, Math.floor(labels.length / 2), labels.length - 1].filter(function (v, i, a) { return a.indexOf(v) === i; }); + labelIndexes.forEach(function (idx) { + var x = padding.left + (chartWidth * idx) / Math.max(labels.length - 1, 1); + var text = labels[idx] || ''; + ctx.fillText(text, Math.max(0, x - 18), cssHeight - 8); + }); + } + + function initCharts() { + var canvases = document.querySelectorAll('.ansico-stat-chart'); + canvases.forEach(drawChart); + } + + document.addEventListener('DOMContentLoaded', initCharts); + window.addEventListener('resize', initCharts); +})();