Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update event not firing on data change #118

Closed
Lenndev opened this issue Jun 2, 2017 · 6 comments
Closed

update event not firing on data change #118

Lenndev opened this issue Jun 2, 2017 · 6 comments

Comments

@Lenndev
Copy link

Lenndev commented Jun 2, 2017

After updating to latest version it seems the update event is not being fired on datachange.
Anyone else having this same issue? Even better, a solution?

Expected Behavior

the width of the chart is adjusted by the length of the data.
the parent div is also resized, making it scrollable.

<statsgraph chart-id="statsgraph" class="graphAreaWrapper" :chart-data="graphdata"
                                :options="graphoptions" ref="statsgraph"
                                v-on:resizedGraphWidth="resizeGridHolder"></statsgraph>

import {Bar,Line, mixins} from 'vue-chartjs';
import $ from 'jquery';
const {reactiveProp} = mixins;

export default Bar.extend({
    name: 'statsgraph',
    props: ['options','height'],
    mixins: [reactiveProp],
    mounted(){
        this.renderChart(this.chartData, this.options);
        
    },
    updated(){
        this.resizeWidth();
    },
    methods: {
        getLegend(){
            return this._chart.generateLegend();
        },
        getScales(){
            return this._chart.scales;
        },
        getCtx(){
            return this._chart.chart.ctx;
        },
        getCanvas(){
            return this._chart.chart.canvas;
        },
        getParent(){
            return this._chart.chart.canvas.parentElement;
        },
        getDataSets(){
            
            return this.chartData.datasets || [];
        },
        resizeWidth(){
            let datasets = this.getDataSets();
            let newWidth = 0;
            
            if (datasets.length > 0) {
                let datasets = this.getDataSets();
                
                if(datasets.length > 0){
                    datasets = datasets[0];
                    
                    if (datasets.data && datasets.data.length) {
                        newWidth = datasets.data.length * 60;
                    }
                }
            }
            let parentsParentWidth = $(this.getParent()).parent().width();
            if (newWidth < parentsParentWidth) {
                newWidth = parentsParentWidth;
            }
            
            $(this.getParent()).width(newWidth);
            
            this._chart.resize();
            this.$emit('resizedGraphWidth',{width:newWidth});
            
        }
    }
})

example : jsfiddle https://jsfiddle.net/Lenndev/p8dwaaf3/

This code does work with vue-chart.js version 2.5.6

Actual Behavior

this.resizeWidth() is not fired because updated() is not fired. therefore the width of the parent div and therefore the canvas is not resized, causing the chart to be very squeezed

Environment

  • vue.js version: <^2.2.1>
  • vue-chart.js version: <^2.5.6>
@apertureless
Copy link
Owner

Hi @Lenndev ,

thanks for the issue.

So, with vue 2.2.1 and vue-chartjs 2.5.6 updated() does fire, right?
And with vue 2.3.3 and vue-chartjs 2.6.3 it does not fire ?

I will try to reproduce it tomorrow. However, your jsfiddle, it not vue / vue-chartjs related 😕

@apertureless
Copy link
Owner

Hey @Lenndev

could you provide two fiddles with a working and a non-working example?
I could not really reproduce this. Well I see that the updated() hook is not called. But I tried it with vue-chartjs@2.5.6 and it is also not working.

And to be honest, I don't see that this will be working. And I kind of doubt, that this worked before. 🤔

If you take a look in the vue.js docs for the updated hook

Called after a data change causes the virtual DOM to be re-rendered and patched.

But as Chart.js works in a canvas, there is never a change in virtual dom and never a vue.js re-render or patch. So in my mind, the updated() hook will never be called, only because you change your chart data.

@Lenndev
Copy link
Author

Lenndev commented Jun 6, 2017

Hi @apertureless sorry for the delayed response,
sorry for the misguiding jsfiddle, it is indeed not using vue-chartjs, but just chartjs, but it shows the expected behavior. And the actual behaviour when i use it in my app with the versions mentioned before.

You have to believe me that it does work with the mentioned versions, much more than the code i gave you i cannot give.

` /** method to load the graph by setting the view property graphdata, it should fire updated() event of the <statsgraph :chart-data="graphdata"/>
             * @param {Object} data {stats,meta}
             */
loadGraph(data){
                if (!data) {
                    if(this.parkdata == null){
                        return false;
                    } else {
                        data = this.parkdata;
                    }
                }


                this.generateGridData(data);

                let datasets = this.generateDataSets(data);

                this.graphdata = {
                    type: 'bar',//overall type, must be bar to be able to put in line and bar chart.
                    labels: this.xLabels,
                    datasets: datasets
                };
            },

//vue data 
data(){
            let self = this;
            return {
                parkdata: null,
                xLabels:[],
                graphdata: {},
                graphoptions: {
                    animation: {
                        duration: 1,
                        onComplete: function () {
                            let chartInstance = this.chart,
                                ctx = chartInstance.ctx;
                            ctx.font = Chart.helpers.fontString(15, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
                            ctx.textAlign = 'center';
                            ctx.textBaseline = 'bottom';

                            this.data.datasets.forEach(function (dataset, i) {
                                let meta = chartInstance.controller.getDatasetMeta(i);
                                meta.data.forEach(function (bar, index) {
                                    if (dataset.data[index] != '') {
                                        let data = dataset.data[index] + '\u00B0';
                                        ctx.fillStyle = '#234464';
                                        ctx.fillText(data, bar._model.x, bar._model.y - 5);
                                    }
                                });
                            });
                        }
                    },
                    responsive: false,
                    maintainAspectRatio: false,
                    legend: {//no legend displayed (has features like hiding/showing line/bar graph
                        display: false,

                    },
                    layout: {
                        padding: 0
                    },
                    elements: {
                        line: {
                            fill: true,
                            borderColor: '#234464',
                            borderWidth: 2,
                            lineTension: 0,
                        },
                        point: {
                            display: false,
                            backgroundColor: '#234464',
                            radius: 0,
                            hitRadius: 0,
                            borderColor: '#234464',

                        }
                    },
                    tooltips: {
                        enabled:false
                    },
                    scales: {
                        yAxes: [
                            {
                                id: 'lineY',
                                type: 'linear',
                                position: 'left',
                                display: false,
                                ticks: {
                                    display: false,
                                    beginAtZero: true,
                                    fontColor: '#234464',
                                    fontSize: 10,
                                    min: 0,
                                    max: 30,
                                    mirror: false,
                                    maxRotation: 0,
                                    minRotation: 0,
                                },
                                gridLines: {
                                    display:false,
                                }
                            }
                        ],
                        xAxes: [
                            {
                                id: 'xAxe',
                                barThickness: 60,
                                type: 'category',
                                gridLines:{
                                  display:false
                                },
                                ticks: {
                                    display: false,
                                    fontColor: '#234464',
                                    fontSize: 10,
                                    maxRotation: 90,
                                    minRotation: 90
                                },
                                zeroLineColor:'transparent'
                            }
                        ]
                    }
                }
            }
        }

@apertureless
Copy link
Owner

Have you also updated Vue.js to the current version?

@apertureless
Copy link
Owner

Hey @Lenndev

well, I could not reproduce this. I mean, I could not reproduce a working example.
I would need a minimal working example from you. I don't need all your code and all the special methods, just the critical stuff.

I setup here a pen with vue-chartjs 2.5.6

https://codepen.io/apertureless/pen/BZKBdX

However the updated() hook never gets called. And thats your problem, right? But like I said, I don't think that the Vuejs updated() hook will ever get called only because you pass in new chart-data. Because the DOM simply does not change at all. It all in chart.js canvas.

Furthermore I don't think that it is related to vue-chartjs. As nothing that critical has changed form 2.5.6 up to the current version. Some changes in the build setup mostly and smaller bug fixes.

However, instead of using the Vue.js updated() hook you could simply listen on an update event that you fire by your own. Over an event bus or smth.

Or you add your own watcher to chart-data and if something changes, you can call your resizeWidth method.

✌️

@apertureless
Copy link
Owner

🔐 Closed due to inactivity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants