MIF_HomsinNIME31231582/resources/js/charts.js

232 lines
7.8 KiB
JavaScript

// resources/js/charts.js
export class ChartManager {
constructor() {
this.charts = {};
}
init(data) {
console.log('ChartManager initialized with data:', data);
this.destroyAll();
this.createBarChart(data);
this.createPieChart(data);
this.createScoreChart(data);
this.createMetricsChart(data);
}
destroyAll() {
Object.values(this.charts).forEach(chart => {
if (chart) chart.destroy();
});
this.charts = {};
}
createBarChart(data) {
const canvas = document.getElementById('barChart');
if (!canvas) {
console.warn('Canvas barChart tidak ditemukan');
return;
}
const ctx = canvas.getContext('2d');
const total = data.positif + data.negatif;
const positifPercent = total > 0 ? ((data.positif / total) * 100).toFixed(1) : 0;
const negatifPercent = total > 0 ? ((data.negatif / total) * 100).toFixed(1) : 0;
this.charts.barChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Positif', 'Negatif'],
datasets: [{
label: 'Jumlah Sentimen',
data: [data.positif, data.negatif],
backgroundColor: ['#10b981', '#ef4444'],
borderColor: ['#059669', '#dc2626'],
borderWidth: 2,
borderRadius: 8,
barPercentage: 0.7
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
label: (context) => {
const value = context.raw;
const percentage = context.dataIndex === 0 ? positifPercent : negatifPercent;
return `Jumlah: ${value} (${percentage}%)`;
}
}
}
},
scales: {
y: {
beginAtZero: true,
grid: { color: 'rgba(255, 255, 255, 0.1)' },
ticks: { color: '#ffffff' }
},
x: {
grid: { display: false },
ticks: { color: '#ffffff' }
}
}
}
});
console.log('Bar chart created');
}
createPieChart(data) {
const canvas = document.getElementById('pieChart');
if (!canvas) {
console.warn('Canvas pieChart tidak ditemukan');
return;
}
const ctx = canvas.getContext('2d');
const total = data.positif + data.negatif;
const positifPercent = total > 0 ? ((data.positif / total) * 100).toFixed(1) : 0;
const negatifPercent = total > 0 ? ((data.negatif / total) * 100).toFixed(1) : 0;
this.charts.pieChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: [`Positif (${positifPercent}%)`, `Negatif (${negatifPercent}%)`],
datasets: [{
data: [data.positif, data.negatif],
backgroundColor: ['#10b981', '#ef4444'],
borderColor: 'rgba(255, 255, 255, 0.2)',
borderWidth: 2,
hoverOffset: 8
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: { color: '#ffffff', font: { size: 12 }, padding: 20 }
}
},
cutout: '60%'
}
});
console.log('Pie chart created');
}
createScoreChart(data) {
const canvas = document.getElementById('scoreChart');
if (!canvas) {
console.warn('Canvas scoreChart tidak ditemukan');
return;
}
const ctx = canvas.getContext('2d');
this.charts.scoreChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['0-20', '21-40', '41-60', '61-80', '81-100'],
datasets: [{
label: 'Distribusi Score',
data: data.scoreDistribution,
borderColor: '#3b82f6',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
borderWidth: 3,
pointBackgroundColor: '#3b82f6',
pointBorderColor: '#ffffff',
pointBorderWidth: 2,
pointRadius: 6,
pointHoverRadius: 8,
tension: 0.3,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
label: (context) => `Jumlah: ${context.raw} data`
}
}
},
scales: {
y: {
beginAtZero: true,
grid: { color: 'rgba(255, 255, 255, 0.1)' },
ticks: { color: '#ffffff' }
},
x: {
grid: { display: false },
ticks: { color: '#ffffff' }
}
}
}
});
console.log('Score chart created');
}
createMetricsChart(data) {
const canvas = document.getElementById('groupedMetricsChart');
if (!canvas) {
console.warn('Canvas groupedMetricsChart tidak ditemukan');
return;
}
const ctx = canvas.getContext('2d');
this.charts.metricsChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Precision', 'Recall', 'F1-Score'],
datasets: [
{
label: 'Negatif',
data: data.metrics.negatif,
backgroundColor: '#ef4444',
borderRadius: 6
},
{
label: 'Positif',
data: data.metrics.positif,
backgroundColor: '#10b981',
borderRadius: 6
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
labels: { color: '#ffffff' }
},
tooltip: {
callbacks: {
label: (context) => `${context.dataset.label}: ${(context.raw * 100).toFixed(1)}%`
}
}
},
scales: {
y: {
beginAtZero: true,
max: 1,
grid: { color: 'rgba(255, 255, 255, 0.1)' },
ticks: {
color: '#ffffff',
callback: (value) => (value * 100) + '%'
}
},
x: {
grid: { display: false },
ticks: { color: '#ffffff' }
}
}
}
});
console.log('Metrics chart created');
}
}