114 lines
3.6 KiB
JavaScript
114 lines
3.6 KiB
JavaScript
|
|
(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);
|
||
|
|
})();
|