1

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 Answer 1

1

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).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.