Files
Claper/assets/js/admin-charts.js
2025-11-20 10:44:06 +01:00

207 lines
4.6 KiB
JavaScript

import {
Chart,
LineElement,
PointElement,
CategoryScale,
LinearScale,
Title,
Tooltip,
Legend,
LineController,
Filler
} from 'chart.js';
import 'chartjs-adapter-moment';
// Register Chart.js components
Chart.register(
LineElement,
PointElement,
CategoryScale,
LinearScale,
Title,
Tooltip,
Legend,
LineController,
Filler
);
export class AdminCharts {
constructor() {
this.charts = {};
this.defaultOptions = {
responsive: true,
maintainAspectRatio: false,
interaction: {
intersect: false,
mode: 'index'
},
plugins: {
legend: {
display: true,
position: 'top',
labels: {
usePointStyle: true,
padding: 20,
font: {
size: 12,
family: 'Inter, system-ui, sans-serif'
},
color: 'rgba(255, 255, 255, 0.9)'
}
},
tooltip: {
enabled: true,
backgroundColor: 'rgba(0, 0, 0, 0.8)',
titleColor: 'rgba(255, 255, 255, 0.9)',
bodyColor: 'rgba(255, 255, 255, 0.9)',
borderColor: 'rgba(255, 255, 255, 0.1)',
borderWidth: 1,
cornerRadius: 8,
displayColors: false,
padding: 12,
titleFont: {
size: 14,
weight: 'bold'
},
bodyFont: {
size: 13
}
}
},
scales: {
x: {
display: true,
grid: {
display: false
},
ticks: {
color: 'rgba(255, 255, 255, 0.7)',
font: {
size: 11
}
}
},
y: {
display: true,
grid: {
color: 'rgba(255, 255, 255, 0.1)',
drawBorder: false
},
ticks: {
color: 'rgba(255, 255, 255, 0.7)',
font: {
size: 11
},
callback: function(value) {
return Number.isInteger(value) ? value : '';
}
}
}
},
elements: {
line: {
tension: 0.4,
borderWidth: 3,
fill: true
},
point: {
radius: 0,
hoverRadius: 6,
hoverBorderWidth: 2,
hoverBorderColor: 'rgba(255, 255, 255, 0.9)'
}
},
animation: {
duration: 800,
easing: 'easeInOutQuart'
}
};
}
createUsersChart(canvasId, data) {
const ctx = document.getElementById(canvasId);
if (!ctx) return null;
const chartData = {
labels: data.labels,
datasets: [{
label: 'Users',
data: data.values,
borderColor: 'rgba(102, 126, 234, 1)',
backgroundColor: 'rgba(102, 126, 234, 0.1)',
pointBackgroundColor: 'rgba(102, 126, 234, 1)',
pointBorderColor: 'rgba(255, 255, 255, 0.9)',
pointHoverBackgroundColor: 'rgba(102, 126, 234, 1)',
pointHoverBorderColor: 'rgba(255, 255, 255, 0.9)',
}]
};
if (this.charts[canvasId]) {
this.charts[canvasId].destroy();
}
this.charts[canvasId] = new Chart(ctx, {
type: 'line',
data: chartData,
options: this.defaultOptions
});
return this.charts[canvasId];
}
createEventsChart(canvasId, data) {
const ctx = document.getElementById(canvasId);
if (!ctx) return null;
const chartData = {
labels: data.labels,
datasets: [{
label: 'Events',
data: data.values,
borderColor: 'rgba(16, 185, 129, 1)',
backgroundColor: 'rgba(16, 185, 129, 0.1)',
pointBackgroundColor: 'rgba(16, 185, 129, 1)',
pointBorderColor: 'rgba(255, 255, 255, 0.9)',
pointHoverBackgroundColor: 'rgba(16, 185, 129, 1)',
pointHoverBorderColor: 'rgba(255, 255, 255, 0.9)',
}]
};
if (this.charts[canvasId]) {
this.charts[canvasId].destroy();
}
this.charts[canvasId] = new Chart(ctx, {
type: 'line',
data: chartData,
options: this.defaultOptions
});
return this.charts[canvasId];
}
updateChart(canvasId, data) {
const chart = this.charts[canvasId];
if (!chart) return;
chart.data.labels = data.labels;
chart.data.datasets[0].data = data.values;
chart.update('active');
}
destroyChart(canvasId) {
if (this.charts[canvasId]) {
this.charts[canvasId].destroy();
delete this.charts[canvasId];
}
}
destroyAllCharts() {
Object.keys(this.charts).forEach(canvasId => {
this.destroyChart(canvasId);
});
}
}
// Create global instance
window.AdminCharts = new AdminCharts();