diff --git a/package.json b/package.json index 8189f5a5..0cd5699f 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "vite": "^6.2.4" }, "dependencies": { - "axios": "^1.8.0" + "axios": "^1.8.0", + "chart.js": "^4.5.1" } } diff --git a/resources/js/app.js b/resources/js/app.js index 3b94f0a7..23529f79 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1,4 +1,7 @@ -import { Livewire } from '../../vendor/livewire/livewire/dist/livewire.esm'; +import { Alpine, Livewire } from '../../vendor/livewire/livewire/dist/livewire.esm'; import './bootstrap'; +import trendChart from './chart'; + +Alpine.data('trendChart', trendChart); Livewire.start(); diff --git a/resources/js/chart.js b/resources/js/chart.js new file mode 100644 index 00000000..8ad125fc --- /dev/null +++ b/resources/js/chart.js @@ -0,0 +1,66 @@ +import { + CategoryScale, + Chart, + Filler, + Legend, + LinearScale, + LineController, + LineElement, + PointElement, + Tooltip, +} from 'chart.js'; + +Chart.register( + CategoryScale, + Filler, + Legend, + LinearScale, + LineController, + LineElement, + PointElement, + Tooltip, +); + +export default function trendChart({ labels = [], series = [] } = {}) { + return { + chart: null, + + init() { + this.chart = new Chart(this.$refs.canvas, { + type: 'line', + data: this.data(labels, series), + options: { + responsive: true, + maintainAspectRatio: false, + interaction: { mode: 'index', intersect: false }, + scales: { + y: { beginAtZero: true, ticks: { precision: 0 } }, + }, + }, + }); + }, + + data(labels, series) { + return { + labels, + datasets: series.map((one, index) => ({ + label: one.name, + data: one.values, + borderColor: this.palette(index), + backgroundColor: this.palette(index), + spanGaps: false, + tension: 0.3, + })), + }; + }, + + palette(index) { + return ['#3b82f6', '#10b981'][index % 2]; + }, + + destroy() { + this.chart?.destroy(); + this.chart = null; + }, + }; +}