Data

Chart

Wrapper Vue 3 per Chart.js che supporta grafici bar, line, pie, doughnut, radar, polarArea, bubble e scatter con aggiornamento reattivo.

Dipendenze

Il componente richiede chart.js come peer dependency:

npm install chart.js

Import

import { Chart } from '@pzeta/vue-components'

Esempio Base

Props

PropTipoDefaultDescrizione
typeChartType'bar'Tipo di grafico da visualizzare
dataChartDataDati del grafico in formato Chart.js
optionsChartOptionsOpzioni di configurazione Chart.js
pluginsPlugin[]Plugin Chart.js personalizzati
widthnumber300Larghezza del canvas in px (modalita' non responsive)
heightnumber150Altezza del canvas in px (modalita' non responsive)
classstringClasse CSS aggiuntiva per il container

ChartType

Valori accettati per la prop type:

ValoreDescrizione
'bar'Grafico a barre
'line'Grafico a linee
'pie'Grafico a torta
'doughnut'Grafico a ciambella
'radar'Grafico radar
'polarArea'Grafico ad area polare
'bubble'Grafico a bolle
'scatter'Grafico a dispersione

Emits

EventoPayloadDescrizione
chartCreateChartInstanceEmesso quando l'istanza Chart.js viene creata
chartUpdateChartInstanceEmesso quando il grafico viene aggiornato con nuovi dati
chartDestroyEmesso quando l'istanza Chart.js viene distrutta

Metodi Esposti (defineExpose)

Il componente espone i seguenti metodi tramite ref:

Metodo/Proprieta'TipoDescrizione
chartChartInstance | nullRiferimento reattivo all'istanza Chart.js corrente
refresh()() => voidAggiorna il grafico con i dati correnti (senza ricreare l'istanza)
reinit()() => voidReinizializza completamente il grafico (utile al cambio di type)
getChart()() => ChartInstance | nullRestituisce l'istanza Chart.js corrente

Esempi

Grafico a Linee

<script setup lang="ts">
import type { ChartData, ChartOptions } from 'chart.js'

const lineData: ChartData = {
  labels: ['Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab', 'Dom'],
  datasets: [
    {
      label: 'Visitatori',
      data: [120, 190, 300, 250, 220, 310, 180],
      fill: true,
      backgroundColor: 'rgba(34, 197, 94, 0.2)',
      borderColor: 'rgb(34, 197, 94)',
      tension: 0.4,
    },
  ],
}

const lineOptions: ChartOptions = {
  responsive: true,
  plugins: {
    legend: { position: 'top' },
    title: { display: true, text: 'Visitatori della settimana' },
  },
}
</script>

<template>
  <Chart type="line" :data="lineData" :options="lineOptions" />
</template>

Grafico a Torta

<script setup lang="ts">
import type { ChartData } from 'chart.js'

const pieData: ChartData = {
  labels: ['Rosso', 'Blu', 'Verde', 'Giallo'],
  datasets: [
    {
      data: [300, 50, 100, 80],
      backgroundColor: [
        'rgb(239, 68, 68)',
        'rgb(59, 130, 246)',
        'rgb(34, 197, 94)',
        'rgb(245, 158, 11)',
      ],
    },
  ],
}
</script>

<template>
  <Chart type="pie" :data="pieData" />
</template>

Grafico Radar

<script setup lang="ts">
import type { ChartData } from 'chart.js'

const radarData: ChartData = {
  labels: ['Velocita', 'Affidabilita', 'Comfort', 'Sicurezza', 'Efficienza'],
  datasets: [
    {
      label: 'Prodotto A',
      data: [65, 75, 70, 80, 60],
      backgroundColor: 'rgba(59, 130, 246, 0.2)',
      borderColor: 'rgb(59, 130, 246)',
    },
    {
      label: 'Prodotto B',
      data: [55, 85, 65, 90, 75],
      backgroundColor: 'rgba(34, 197, 94, 0.2)',
      borderColor: 'rgb(34, 197, 94)',
    },
  ],
}
</script>

<template>
  <Chart type="radar" :data="radarData" />
</template>

Aggiornamento Programmatico

<script setup lang="ts">
import { ref } from 'vue'
import type { ChartData } from 'chart.js'

const chartRef = ref()
const chartData = ref<ChartData>({
  labels: ['A', 'B', 'C'],
  datasets: [{ label: 'Dati', data: [10, 20, 30], backgroundColor: 'rgba(59, 130, 246, 0.5)' }],
})

function aggiornaGrafico() {
  chartData.value.datasets[0].data = [Math.random() * 100, Math.random() * 100, Math.random() * 100]
  chartRef.value?.refresh()
}
</script>

<template>
  <Chart ref="chartRef" type="bar" :data="chartData" />
  <button @click="aggiornaGrafico">Aggiorna dati</button>
</template>

Note Comportamento

  • Il componente registra automaticamente tutti i controller e gli elementi Chart.js necessari
  • I colori del testo e della griglia vengono letti dalle variabili CSS --chart-text-color e --chart-grid-color per integrazione con il tema
  • Le opzioni passate via options vengono unite con le opzioni di default (deep merge); le opzioni fornite hanno precedenza
  • Il watch su data e options e' debounced a 100ms per evitare aggiornamenti eccessivi
  • Al cambio di type, il grafico viene completamente reinizializzato
  • Usa shallowRef internamente per evitare che Chart.js diventi reattivo in profondita', prevenendo problemi di performance

Costanti di Utilita'

Il modulo esporta costanti per colori predefiniti:

import { CHART_COLORS, CHART_PALETTE } from '@pzeta/vue-components'

// Colori singoli
CHART_COLORS.primary       // 'rgb(59, 130, 246)'
CHART_COLORS.success       // 'rgb(34, 197, 94)'
CHART_COLORS.danger        // 'rgb(239, 68, 68)'

// Palette per dataset multipli (8 colori)
CHART_PALETTE              // string[]

TypeScript

import type { ChartProps, ChartEmits, ChartExpose, ChartType } from '@pzeta/vue-components'
import type { ChartData, ChartOptions } from 'chart.js'

const chartData: ChartData = {
  labels: ['A', 'B', 'C'],
  datasets: [
    {
      label: 'Dataset',
      data: [10, 20, 30],
      backgroundColor: 'rgba(59, 130, 246, 0.5)',
    },
  ],
}