| svelte | |
| <script> | |
| import { onMount } from 'svelte'; | |
| import { Chart } from 'chart.js/auto'; | |
| let chart; | |
| let canvas; | |
| onMount(() => { | |
| if (canvas) { | |
| chart = new Chart(canvas, { | |
| type: 'doughnut', | |
| data: { | |
| labels: ['Screen Repair', 'Battery', 'Software', 'Accessories', 'Other'], | |
| datasets: [{ | |
| data: [35, 25, 20, 15, 5], | |
| backgroundColor: [ | |
| '#FF6384', | |
| '#36A2EB', | |
| '#FFCE56', | |
| '#4BC0C0', | |
| '#9966FF' | |
| ], | |
| borderWidth: 0 | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| plugins: { | |
| legend: { | |
| position: 'right' | |
| }, | |
| tooltip: { | |
| callbacks: { | |
| label: function(context) { | |
| const label = context.label || ''; | |
| const value = context.raw || 0; | |
| const total = context.dataset.data.reduce((a, b) => a + b, 0); | |
| const percentage = Math.round((value / total) * 100); | |
| return `${label}: ${percentage}% (Rp ${value.toLocaleString()})`; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }); | |
| } | |
| return () => { | |
| if (chart) { | |
| chart.destroy(); | |
| } | |
| }; | |
| }); | |
| </script> | |
| <div class="card h-full"> | |
| <h2 class="text-lg font-semibold text-slate-900 mb-4">Expense Categories</h2> | |
| <canvas bind:this={canvas}></canvas> | |
| </div> | |
| </html> |