Phase 110 complete: - add Statistics -> Podsumowanie page - add monthly order count and value charts per integration plus total - use Chart.js with table fallback and 04-2026 default history start - update PAUL and DOCS technical documentation
120 lines
3.0 KiB
JavaScript
120 lines
3.0 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
var palette = ['#2563eb', '#0f766e', '#c2410c', '#7c3aed', '#be123c', '#0369a1', '#4d7c0f', '#9333ea'];
|
|
var totalColor = '#111827';
|
|
|
|
function parseData() {
|
|
var node = document.getElementById('js-statistics-summary-data');
|
|
if (!node) return null;
|
|
|
|
try {
|
|
return JSON.parse(node.textContent || '{}');
|
|
} catch (error) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function colorForSeries(item, index) {
|
|
return item.key === 'total' ? totalColor : palette[index % palette.length];
|
|
}
|
|
|
|
function moneyLabel(value) {
|
|
return Number(value || 0).toLocaleString('pl-PL', {
|
|
minimumFractionDigits: 2,
|
|
maximumFractionDigits: 2
|
|
});
|
|
}
|
|
|
|
function datasetForSeries(item, index) {
|
|
var color = colorForSeries(item, index);
|
|
var isTotal = item.key === 'total';
|
|
|
|
return {
|
|
label: item.label || item.key || '',
|
|
data: item.values || [],
|
|
borderColor: color,
|
|
backgroundColor: color,
|
|
borderWidth: isTotal ? 3 : 2,
|
|
pointRadius: isTotal ? 4 : 3,
|
|
pointHoverRadius: isTotal ? 6 : 5,
|
|
tension: 0.25
|
|
};
|
|
}
|
|
|
|
function renderChart(container, chart) {
|
|
if (!window.Chart || !container || !chart || !Array.isArray(chart.labels) || !Array.isArray(chart.series)) return;
|
|
|
|
var canvas = container.querySelector('canvas');
|
|
if (!canvas) return;
|
|
|
|
var isMoney = chart.valueType === 'money';
|
|
var context = canvas.getContext('2d');
|
|
|
|
new window.Chart(context, {
|
|
type: 'line',
|
|
data: {
|
|
labels: chart.labels,
|
|
datasets: chart.series.map(datasetForSeries)
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
interaction: {
|
|
mode: 'index',
|
|
intersect: false
|
|
},
|
|
plugins: {
|
|
legend: {
|
|
position: 'bottom',
|
|
labels: {
|
|
boxWidth: 18,
|
|
boxHeight: 3,
|
|
usePointStyle: false
|
|
}
|
|
},
|
|
tooltip: {
|
|
callbacks: {
|
|
label: function (item) {
|
|
var label = item.dataset.label ? item.dataset.label + ': ' : '';
|
|
return label + (isMoney ? moneyLabel(item.parsed.y) : Math.round(item.parsed.y));
|
|
}
|
|
}
|
|
}
|
|
},
|
|
scales: {
|
|
x: {
|
|
grid: {
|
|
display: false
|
|
}
|
|
},
|
|
y: {
|
|
beginAtZero: true,
|
|
ticks: {
|
|
callback: function (value) {
|
|
return isMoney ? moneyLabel(value) : value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function init() {
|
|
var data = parseData();
|
|
if (!data) return;
|
|
|
|
document.querySelectorAll('[data-statistics-chart]').forEach(function (container) {
|
|
var key = container.getAttribute('data-statistics-chart');
|
|
renderChart(container, data[key]);
|
|
});
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', init);
|
|
} else {
|
|
init();
|
|
}
|
|
})();
|