tinyqc/public/js/charts.js

129 lines
3.7 KiB
JavaScript
Raw Normal View History

window.ChartManager = {
charts: {},
init(containerId, chartData, options = {}) {
const container = document.getElementById(containerId);
if (!container) return;
const ctx = container.getContext('2d');
if (this.charts[containerId]) {
this.charts[containerId].destroy();
}
const defaultOptions = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'top',
}
}
};
this.charts[containerId] = new Chart(ctx, {
type: options.type || 'line',
data: chartData,
options: { ...defaultOptions, ...options }
});
return this.charts[containerId];
},
createTrendChart(containerId, labels, datasets) {
return this.init(containerId, {
labels,
datasets: datasets.map((ds, i) => ({
label: ds.label || `Control ${i + 1}`,
data: ds.data,
borderColor: ds.color || this.getColor(i),
backgroundColor: this.getColor(i, 0.1),
tension: 0.3,
fill: true,
pointRadius: 4,
pointHoverRadius: 6
}))
}, {
type: 'line',
plugins: {
title: {
display: true,
text: 'Monthly QC Trend'
}
}
});
},
createComparisonChart(containerId, labels, datasets) {
return this.init(containerId, {
labels,
datasets: datasets.map((ds, i) => ({
label: ds.label || `Control ${i + 1}`,
data: ds.data,
backgroundColor: this.getColor(i, 0.6),
borderColor: this.getColor(i),
borderWidth: 1
}))
}, {
type: 'bar',
plugins: {
title: {
display: true,
text: 'Control Comparison'
}
}
});
},
createViolationChart(containerId, labels, datasets) {
return this.init(containerId, {
labels,
datasets: datasets.map((ds, i) => ({
label: ds.label || `Control ${i + 1}`,
data: ds.data,
backgroundColor: ds.data.map(v => v > 100 ? 'rgba(239, 68, 68, 0.6)' : 'rgba(34, 197, 94, 0.6)'),
borderColor: ds.data.map(v => v > 100 ? 'rgb(239, 68, 68)' : 'rgb(34, 197, 94)'),
borderWidth: 1
}))
}, {
type: 'bar',
plugins: {
title: {
display: true,
text: 'QC Violations (Values > 100)'
}
}
});
},
getColor(index, alpha = 1) {
const colors = [
`rgba(59, 130, 246, ${alpha})`,
`rgba(16, 185, 129, ${alpha})`,
`rgba(245, 158, 11, ${alpha})`,
`rgba(239, 68, 68, ${alpha})`,
`rgba(139, 92, 246, ${alpha})`,
`rgba(236, 72, 153, ${alpha})`
];
return colors[index % colors.length];
},
destroy(containerId) {
if (this.charts[containerId]) {
this.charts[containerId].destroy();
delete this.charts[containerId];
}
},
destroyAll() {
Object.keys(this.charts).forEach(id => this.destroy(id));
}
};
document.addEventListener('DOMContentLoaded', () => {
const chartsContainer = document.getElementById('charts-container');
if (chartsContainer && typeof initReportCharts === 'function') {
initReportCharts();
}
});