- CodeIgniter 4 framework setup with SQL Server database config - Models: Control, Test, Dept, Result, Daily/ Monthly entry models - Controllers: Dashboard, Control, Test, Dept, Entry, Report, API endpoints - Views: CRUD pages with modal dialogs, dashboard, reports - Database: Migrations for control test and daily/monthly result tables - Legacy v1 PHP application preserved in /v1 directory - Documentation: AGENTS.md, VIEWS_RULES.md for development guidelines
129 lines
3.7 KiB
JavaScript
129 lines
3.7 KiB
JavaScript
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();
|
|
}
|
|
});
|