(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); })();