chartjs4vue
v1.0.12
Published
Plugin Vue 3 untuk menampilkan chart berbasis Chart.js 4 dengan dukungan datalabel, tooltip kustom, legend, stacked chart, chart campuran, serta format angka otomatis.
Readme
chartjs4vue
Plugin Vue 3 untuk menampilkan chart berbasis Chart.js 4 dengan dukungan datalabel, tooltip kustom, legend, stacked chart, chart campuran, serta format angka otomatis.
Komponen ini dibuat berdasarkan file komponen utama src/components/chart.vue dan dapat digunakan langsung pada aplikasi Vue 3.
Fitur utama
- Mendukung chart jenis line, bar, pie, doughnut, dan tipe Chart.js lainnya
- Dapat menampilkan datalabel pada setiap titik data
- Tooltip kustom yang lebih fleksibel
- Legend yang dapat diaktifkan/ditiadakan
- Dukungan format persen, angka, dan postfix seperti rb/jt
- Mendukung chart stacked, mixed, dan multiple y-axis
- Integrasi dengan plugin Chart.js dan chartjs-plugin-datalabels
Instalasi
Install dependency yang dibutuhkan:
npm install chart.js chartjs-plugin-datalabels vueJika Anda ingin menggunakan plugin secara global:
// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import ChartPlugin from 'chartjs4vue'
const app = createApp(App)
app.use(ChartPlugin)
app.mount('#app')Jika Anda ingin mendaftarkan komponen secara lokal:
import { Chart } from 'chartjs4vue'
export default {
components: {
Chart
}
}Penggunaan dasar
<template>
<Chart
id="sales-chart"
:width="700"
:height="320"
:labels="labels"
:datasets="datasets"
/>
</template>
<script setup lang="ts">
const labels = ['Jan', 'Feb', 'Mar', 'Apr']
const datasets = [
{
label: 'Penjualan',
data: [120, 180, 150, 220],
borderColor: '#3b82f6',
backgroundColor: 'rgba(59, 130, 246, 0.3)'
}
]
</script>Struktur data dataset
Dataset yang diterima adalah array objek dengan format seperti berikut:
const datasets = [
{
label: 'Target',
data: [10, 20, 30],
borderColor: '#f59e0b',
backgroundColor: 'rgba(245, 158, 11, 0.4)',
type: 'bar',
postfix: 'rb',
showPercent: false,
format: 'percent'
}
]Properti penting pada dataset:
- label: nama dataset
- data: array nilai yang akan ditampilkan
- borderColor: warna garis batas
- backgroundColor: warna fill area/bar
- type: override tipe chart per dataset (misalnya bar atau line)
- postfix: suffix tambahan seperti rb, jt, %
- showPercent: bila true, nilai akan diformat sebagai persen
- format: bisa bernilai percent atau decimal
- rawData: data asli yang ingin ditampilkan di tooltip
- formatData: data hasil format yang ingin ditampilkan
- displayRaw: bila true, tooltip akan menampilkan raw data
- disableTooltips: array index data yang ingin disembunyikan dari tooltip
- yAxisID: untuk chart multi axis
- position: untuk mengatur posisi datalabel
Props yang tersedia
Berikut props utama yang didukung oleh komponen ini:
| Prop | Tipe | Default | Keterangan | |---|---|---:|---| | id | String | wajib | ID unik untuk canvas dan elemen terkait | | width | Number | wajib | Lebar canvas | | height | Number | wajib | Tinggi canvas | | fill | Boolean | true | Mengaktifkan fill area chart | | types | String | line | Tipe chart default | | color | String | white | Warna default untuk sumbu, label, dan tick | | labels | Array | wajib | Label sumbu X | | datasets | Array | wajib | Data dataset chart | | yScales | Array | [] | Nama skala Y untuk chart multi-axis | | yTitles | Array | [] | Judul sumbu Y | | maxTick | Number | 7 | Batas maksimal tick sumbu X | | showStack | Boolean | false | Aktifkan stacked chart | | showLabel | Boolean | false | Menampilkan label tambahan | | showRealtime | Boolean | false | Mode chart realtime | | showMix | Boolean | false | Aktifkan chart campuran | | showPercent | Boolean | true | Format nilai sebagai persen | | getDynamicColor | Function | - | Fungsi untuk memberi warna dinamis berdasarkan nama dataset | | dsNames | Array | [] | Nama dataset untuk warna dinamis | | enableDefaultLegend | Boolean | false | Gunakan legend bawaan Chart.js | | enableDefaultTooltip | Boolean | false | Gunakan tooltip bawaan Chart.js | | yFormats | Array | [] | Format per skala Y | | yFormat | String | percent | Format default skala Y | | dataLabelAlign | String | top | Posisi datalabel | | dataLabelAnchor | String | start | Anchor datalabel | | dataLabelColor | String | - | Warna datalabel custom | | dataLabelOffsets | Array | [] | Offset datalabel per dataset | | useDataLabelStatisColor | Boolean | true | Pakai warna statis untuk datalabel | | useDataLabelBgColor | Boolean | false | Tambahkan background pada datalabel | | dataLabelPadding | Object | null | Padding datalabel | | dataLabelUseFunc | Boolean | false | Gunakan fungsi visual position untuk penentuan posisi | | postfix | String | - | Postfix global untuk tooltip/legend | | showTicks | Boolean | true | Tampilkan ticks sumbu Y | | showTicksX | Boolean | true | Tampilkan ticks sumbu X | | showTooltip | Boolean | true | Aktifkan tooltip kustom | | showLegend | Boolean | true | Tampilkan legend custom | | decimal | Number | 0 | Jumlah desimal | | rotateX | Number | 0 | Rotasi label sumbu X |
Contoh penggunaan lanjutan
1. Chart garis sederhana
<template>
<Chart
id="line-chart"
:width="700"
:height="300"
types="line"
:labels="labels"
:datasets="datasets"
:showPercent="false"
/>
</template>
<script setup lang="ts">
const labels = ['Jan', 'Feb', 'Mar', 'Apr']
const datasets = [
{
label: 'Pengunjung',
data: [100, 180, 140, 220],
borderColor: '#10b981',
backgroundColor: 'rgba(16, 185, 129, 0.2)'
}
]
</script>2. Chart batang stacked
<template>
<Chart
id="stacked-chart"
:width="700"
:height="300"
types="bar"
:showStack="true"
:labels="labels"
:datasets="datasets"
/>
</template>
<script setup lang="ts">
const labels = ['Q1', 'Q2', 'Q3', 'Q4']
const datasets = [
{
label: 'Produk A',
data: [20, 30, 25, 35],
backgroundColor: '#3b82f6'
},
{
label: 'Produk B',
data: [15, 20, 18, 22],
backgroundColor: '#f59e0b'
}
]
</script>3. Chart campuran (mixed)
<template>
<Chart
id="mixed-chart"
:width="700"
:height="320"
:showMix="true"
:showPercent="false"
:labels="labels"
:datasets="datasets"
/>
</template>
<script setup lang="ts">
const labels = ['Jan', 'Feb', 'Mar', 'Apr']
const datasets = [
{
label: 'Revenue',
data: [100, 220, 180, 260],
type: 'bar',
backgroundColor: '#8b5cf6'
},
{
label: 'Target',
data: [80, 150, 170, 240],
type: 'line',
borderColor: '#ef4444'
}
]
</script>Format nilai dan postfix
Komponen ini menggunakan formatter internal untuk menampilkan angka yang lebih rapi. Secara default, nilai akan diformat ke format singkat seperti:
- 1000 -> 1.000
- 1500 -> 1,5rb
- 1200000 -> 1,2jt
Anda bisa mengontrol format dengan properti berikut:
- showPercent: true akan menambahkan simbol %
- postfix: menambahkan suffix global, misalnya rb/jt
- dataset.postfix: postfix per dataset
- dataset.format: "percent" atau "decimal"
Contoh:
<Chart
id="fmt-chart"
:width="700"
:height="300"
:labels="labels"
:datasets="datasets"
:showPercent="false"
postfix="rb"
/>Tooltip dan legend custom
Komponen ini memiliki tooltip dan legend custom yang dapat diaktifkan dengan prop:
<Chart
id="custom-chart"
:width="700"
:height="300"
:labels="labels"
:datasets="datasets"
:enableDefaultLegend="false"
:enableDefaultTooltip="false"
:showTooltip="true"
:showLegend="true"
/>Event
Komponen ini mengirim event:
- chart-onupdate: saat chart diperbarui
- chart-onclick: saat pengguna mengklik chart
Contoh:
<Chart
id="event-chart"
:width="700"
:height="300"
:labels="labels"
:datasets="datasets"
@chart-onclick="handleClick"
/>const handleClick = (event: any) => {
console.log('Klik chart', event)
}Catatan penting
- Prop width dan height wajib diisi.
- Prop labels dan datasets wajib diisi.
- Untuk chart dengan data yang ingin ditampilkan berbeda dari data asli, gunakan rawData dan formatData.
- Untuk chart campuran, gunakan prop showMix dan tentukan type per dataset.
Contoh lengkap
<template>
<div class="p-4">
<Chart
id="complete-chart"
:width="900"
:height="360"
types="line"
:labels="labels"
:datasets="datasets"
:showStack="false"
:showPercent="false"
:showLegend="true"
:showTooltip="true"
color="#111827"
postfix="rb"
:dataLabelOffsets="[8, -8]"
:rotateX="0"
/>
</div>
</template>
<script setup lang="ts">
const labels = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei']
const datasets = [
{
label: 'Penjualan',
data: [120, 180, 150, 220, 260],
borderColor: '#2563eb',
backgroundColor: 'rgba(37, 99, 235, 0.3)',
type: 'line'
},
{
label: 'Target',
data: [100, 160, 170, 200, 240],
borderColor: '#f59e0b',
backgroundColor: 'rgba(245, 158, 11, 0.3)',
type: 'bar'
}
]
</script>Kesimpulan
Komponen chartjs4vue ini cocok digunakan jika Anda ingin membuat chart modern di Vue 3 dengan fitur formatting, tooltip, legend, datalabel, dan chart campuran tanpa perlu menulis konfigurasi Chart.js secara manual dari nol.
Debugging & tracing
Jika Anda menemui error runtime seperti TypeError: chart.value?.setColorConfig is not a function atau RangeError: Maximum call stack size exceeded, langkah-langkah berikut membantu melacak dan mencegah masalah:
Gunakan tag komponen PascalCase: pastikan dalam template Anda memanggil komponen sebagai
<Chart>(bukan<chart>). Jika Anda menggunakan import lokal, daftarkan komponen dicomponents.Tunggu child ready sebelum memanggil method: beberapa properti/dll baru tersedia setelah child ter-mount. Contoh aman:
import { nextTick, onMounted } from 'vue';
onMounted(async () => {
await nextTick();
if (typeof chart.value?.setColorConfig === 'function') {
// panggil dengan aman
chart.value.setColorConfig(['Sales'], data.value, 0);
} else {
console.warn('chart ref not ready', chart.value);
}
});- Pasang global error handlers untuk menangkap stack traces dan unhandled promise rejections saat debugging di environment pengguna:
window.addEventListener('error', (ev) => {
console.error('Global error', ev.error ?? ev.message, ev.error?.stack);
});
window.addEventListener('unhandledrejection', (ev) => {
console.error('Unhandled rejection', ev.reason);
});Log nilai
chart.valuebila method tidak ada — ini membantu melihat apakahrefmengarah ke DOM element atau component instance.Call stack overflow (Max call stack size) sering disebabkan oleh rekursi atau loop reaktif. Untuk men-debug:
- Periksa watcher/prop yang memicu update berkali-kali (mis. memodifikasi
datasetsdari dalam hook yang memicu update lagi). - Tambahkan
console.trace()atauconsole.error()sebelum memanggil fungsi yang diduga menimbulkan loop.
- Periksa watcher/prop yang memicu update berkali-kali (mis. memodifikasi
Contoh melindungi perubahan dataset untuk menghindari loop reaktif:
// jangan ubah langsung datasets yang dipasang ke prop tanpa debounce/guard
if (!updating) {
updating = true;
// lakukan perubahan
setTimeout(() => { updating = false; }, 0);
}Jika Anda mau, saya bisa:
- tambahkan contoh kecil yang runnable (App + main) di folder
examples/untuk mereplikasi masalah; atau - patch komponen supaya mencetak peringatan developer (console.warn) lebih kaya ketika ref salah tipe.
Beritahu saya pilihan Anda dan saya lanjutkan.
