0
votes

I have created a doughnut chart using vue-chart.js, Chart.js and using some values which are within my vuex state. The chart works apart from when the vuex state is updated the chart doesn't updated too.

I have tried to use computed properties to try keep the chart up to date. But then I get the following errors:

Error in callback for watcher "chartData": "TypeError: Cannot set property 'data' of undefined"
TypeError: Cannot set property 'data' of undefined

DoughnutChart.vue:

<script>
    import { Doughnut, mixins } from 'vue-chartjs';
    const { reactiveProp } = mixins;

    export default {
        extends: Doughnut,
        mixins: [reactiveProp],
        props: ['chartData', 'options'],
        mounted () {
            this.renderChart(this.chartdata, this.options)
        }
    }
</script>

AppCharts.vue:

<template>
    <div id="chart_section">
        <h2 class="section_heading">Charts</h2>

        <div id="charts">
            <DoughnutChart :chart-data="datacollection" :options="chartOptions" class="chart"></DoughnutChart>

        </div>
    </div>
</template>


<script>
import DoughnutChart from './DoughnutChart';
import { mapGetters } from 'vuex';

export default {
    components: {
        DoughnutChart
    },
    computed: {
        ...mapGetters(['boardColumnData']),
        datacollection() {
            return {
                datasets: [{
                    data: [this.boardColumnData[0].total.$numberDecimal, this.boardColumnData[1].total.$numberDecimal, this.boardColumnData[2].total.$numberDecimal, this.boardColumnData[3].total.$numberDecimal],
                    backgroundColor: [
                        '#83dd1a', 
                        '#d5d814',
                        '#fdab2f',
                        '#1ad4dd'
                    ],
                    borderColor: [
                        '#83dd1a', 
                        '#d5d814',
                        '#fdab2f',
                        '#1ad4dd'
                    ],
                }]
            }
        },
    },
    data() {
        return {
            chartOptions: null
        }
    },
    mounted () {
        this.fillData();
    },
    methods: {
        fillData() {
            this.chartOptions = {
                responsive: true,
                maintainAspectRatio: false
            }
        }
    }
}
</script>

this is what boardColumnData looks like after getting the state:

[
    {
        "name":"Opportunities",
        "percentage":{
            "$numberDecimal":"0"
        },
        "total":{
            "$numberDecimal":70269
        }
    },
    {
        "name":"Prospects",
        "percentage":{
            "$numberDecimal":"0.25"
        },
        "total":{
            "$numberDecimal":0
        }
    },
    {
        "name":"Proposals",
        "percentage":{
            "$numberDecimal":"0.5"
        },
        "total":{
            "$numberDecimal":5376
        }
    },
    {
        "name":"Presentations",
        "percentage":{
            "$numberDecimal":"0.75"
        },
        "total":{
            "$numberDecimal":21480
        }
    },
]

The $numberDecimal value is what is updated inside vuex when an event on another component happens. When these values are changed I want the chart to update with the new values.

1

1 Answers

0
votes

You must pass the data in the prop. I.e. fastest solution for you would be to have fillData() return the datacollection in the correct format.

E.g.

fillData(){
    return {
      datasets: [
        {
          data: [
            this.boardColumnData[0].total.$numberDecimal,
            this.boardColumnData[1].total.$numberDecimal,
            this.boardColumnData[2].total.$numberDecimal,
            this.boardColumnData[3].total.$numberDecimal,
          ],
          backgroundColor: ["#83dd1a", "#d5d814", "#fdab2f", "#1ad4dd"],
          borderColor: ["#83dd1a", "#d5d814", "#fdab2f", "#1ad4dd"],
        },
      ];
    }
}

You need to do the same for the options, but pass them in a new options=yourOptions() prop.

This drove me absolutely bonkers. I hope this still helps you (or someone else).