Search code examples
typescriptvuejs3vue-chartjs

vue.js 3 typescript vue-chartjs Radar data not reactive


I have a problem with vue 3 vue-chartjs not updating the data when I add a new dataset. Basically the data is not reactive. If I add a new hardcoded object with datasets it works, but not when its added using array push. I tried anything I could think of including recreating the object using a labels array and a dataset array that I add in a new var object.

Thank you for your time, ukw

<template>
     <Radar id="my-chart-id-1" :options="BarChartOptions" :data="BarData" />

     <button type="button" @click="addNewData">Add</button>
</template>

<script lang="ts">
import { mapActions } from "pinia";
import { defineComponent } from 'vue'
import { Radar } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale, RadialLinearScale, PointElement, LineElement, Filler } from 'chart.js'

ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale, RadialLinearScale, PointElement, LineElement, Filler)

export default defineComponent({
    setup() {

    },
    components: {
        Radar,
    },
    data() {
        return {
            BarChartOptions: {
                scale: {
                    min: 0,
                    max: 100,
                },
                responsive: true,
                elements: {
                    line: {
                        borderWidth: 1
                    }
                },
                scales: {
                    r: {
                        grid: {
                            color: '#CCCCCC'
                        },
                    }
                }
            },
            BarData: {
                labels: [
                    '1. Title',
                    '2. Title',
                    '3. Title',
                    '4. Title',
                    '5. Title',
                ],
                datasets: [{
                    label: 'First',
                    data: [10, 30, 30, 30, 30],
                    fill: true,
                    backgroundColor: 'rgba(255, 99, 132, 0.2)',
                    borderColor: 'rgb(255, 99, 132)',
                    pointBackgroundColor: 'rgb(255, 99, 132)',
                    pointBorderColor: '#fff',
                    pointHoverBackgroundColor: '#fff',
                    pointHoverBorderColor: 'rgb(255, 99, 132)'
                }
                ]
            },
},
methods: {
        addNewData() {
               let obj = {
                    label: 'test',
                    data: [50, 50, 50, 50, 50],
                    fill: true,
                    backgroundColor: 'rgba(155, 99, 132, 0.5)',
                    borderColor: 'rgb(155, 99, 132)',
                    pointBackgroundColor: 'rgb(155, 99, 132)',
                    pointBorderColor: '#fff',
                    pointHoverBackgroundColor: '#fff',
                    pointHoverBorderColor: 'rgb(255, 99, 132)'
                }
                this.BarData.datasets.push(obj);
        }
});
</script>

Solution

  • vue-charts don't seem to be deeply reactive. Changes to nested properties such as datasets won't trigger updates like you'd expect. Reassigning the entire data object is a possible workaround.

    addNewData() {
      const obj = {
        label: 'test',
        data: [50, 50, 50, 50, 50],
        fill: true,
        backgroundColor: 'rgba(155, 99, 132, 0.5)',
        borderColor: 'rgb(155, 99, 132)',
        pointBackgroundColor: 'rgb(155, 99, 132)',
        pointBorderColor: '#fff',
        pointHoverBackgroundColor: '#fff',
        pointHoverBorderColor: 'rgb(255, 99, 132)'
      }
      // re-assign entire object to trigger reactivity
      this.BarData = {
        ...this.BarData,
        datasets: [...this.BarData.datasets, obj]
      }
    }