perelin
perelin

Reputation: 1448

Chart.js chart in vue.js component does not update

I´m developing a visualization module for some crypto portfolios with vue.js and chart.js but am currently stuck with this:

Empty chart is displayed but non of the values are rendered.

Since the values are dynamically loaded after the chart is initialized I believe that the chart is not updating itself properly (even though I call .update()), but no errors are displayed whatsoever.

I wrapped the chart.js rendering in a vue component:

Vue.component('portfolioValues', {
    template: '<canvas width="400" height="200"></canvas>',
    data: function() {
        return {
            portfolio_value: [],
            portfolio_labels: [],
            chart: null,
        }
    },
    methods: {
        load_portfolio_value_local: function() {
            values = [];
            labels = []
            local_data.forEach(element => {
                values.push(element.total_usd);
                labels.push(moment(element.timestamp, 'X'));
            });
            this.portfolio_value = values;
            this.portfolio_labels = labels;
            this.chart.update();
        },

        render_chart: function() {
            this.chart = new Chart(this.$el, {
                type: 'line',
                data: {
                    labels: this.portfolio_labels,
                    datasets: [{
                        label: "Portfolio Value",
                        data: this.portfolio_value,
                    }]
                },
                options: {
                    scales: {
                        xAxes: [{
                            type: 'time',
                            distribution: 'linear',
                        }]
                    }
                }
            });
        }
    },
    mounted: function() {
        this.render_chart();
        this.load_portfolio_value_local();
    }
});

For demonstration purposes I just added some data locally, looks like this:

local_data = [{
        "timestamp": 1515102737,
        "total_btc": 0.102627448096786,
        "total_usd": 1539.41274772627
    }, {
        "timestamp": 1515102871,
        "total_btc": 0.102636926127186,
        "total_usd": 1538.52649627725
    }, {
        "timestamp": 1515103588,
        "total_btc": 0.102627448096786,
        "total_usd": 1532.33042753311
    }
]

Here is the full demo code: https://codepen.io/perelin/pen/mppbxV

Any ideas why no data gets rendered? thx!

Upvotes: 0

Views: 491

Answers (1)

Christian
Christian

Reputation: 22353

The problem you have here is how vuejs handles its data.

If you use it like that:

local_data.forEach(element => {
    this.portfolio_value.push(element.total_usd);
    this.portfolio_labels.push(moment(element.timestamp, 'X'));
});

this.chart.update();

The chart will update. But by re-initializing the arrays you work against vuejs.

TL;DR

If you want to re-initialize an object, you could assign the array to the object:

Object.assign(this.portfolio_value, values);
Object.assign(this.portfolio_labels, labels);

That way, the linking stays working.

Upvotes: 1

Related Questions