[Vuejs]-Dynamic rendering of chart with chartjs

0👍

So this was my solution:

import barChart from 'path/to/barChart'

const stats = new Vue({
    //
components:{
    "bar-chart": barChart,
},
data: function () {
    return {
        barChartOptions: {responsive: true, scales: {yAxes: [{ticks: {beginAtZero:true}}]}},
        barChartData: [],
        subscriberCountArray: null,
        readCountArray: null,
        colorArray: [],
    //
    }
},
methods: {
    initStats: function() {
        axios.post(
            //get the data and 

        ).then(response => {
            if(response.data.success) {

                this.campaignsList = response.data.campaignsList;

                this.subscriberCountArray = response.data.subscriberCountArray;
                this.readCountArray = response.data.readCountArray;

                let barDataSets = [];

                for(let i = 0; i < this.campaignIds.length; i++){

                    let currentId = parseInt(this.campaignIds[i]);

                    let color = '';
                    let rgba = [];

                    if(this.colorArray[currentId]){
                        color = this.colorArray[currentId];
                    }else{
                        //pickcolor
                    }

                    barDataSets.push({
                        label: this.campaignsList[currentId].name,
                        backgroundColor: color,
                        data: [this.subscriberCountArray[this.campaignsList[currentId].id], this.readCountArray[this.campaignsList[currentId].id]]
                    });

                this.barChartData = {labels: ['Destinataires', 'Lus'], datasets: barDataSets};

    },
    checkCampaign: function(id){
        if(this.campaignIds.length === 0 || !this.campaignIds.includes(id)){
            this.campaignIds.push(id);
        }else{
            this.campaignIds.splice(this.campaignIds.indexOf(id), 1);
        }
        this.initStats();
    },
    pickColor: function(interval = null, type = null, base = null){
        //
    },
},
mounted(){
    this.initStats();
}

With in the template:

<bar-chart :chart-data="barChartData" :options="barChartOptions"></bar-chart>

and in barChart.js:

import { Bar, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins

export default {
    extends: Bar,
    mixins: [reactiveProp],
    props: ['options'],
    mounted () {
        this.renderBarChart();
    },
    methods: {
        renderBarChart: function(){
            this.renderChart(this.chartData, this.options);
        }
    },
    watch: {
        chartData: function () {
            this.renderBarChart();
        }
    }
}

Doesn’t seem like a terribly efficient way to proceed, but that’s the only way I could make dynamics stats rendering with vue work.

0👍

It is not too clear what you want to do and why your use-case is not working, as the reactiveProp mixin should take care of updating as described in the docs.

However, you should perhaps implement your own watcher where you can run the update code. Like so:

watch: {
  chartData() {
    this.$data._chart.update();
  }
}

Basically, you can access all the methods of the chart through this.$data._chart.

Or feel free to just add this.$data._chart.update() call wherever else is more appropriate for your workflow.

Also, just be aware that there is a misspelling: charOptions instead of chartOptions

Leave a comment