[BUG] Cannot read property ‘skip’ of undefined when hover the chart

Expected Behavior

Here is a live example: https://codepen.io/anon/pen/mRbrze
It shouldn’t show error in the console when I hover the chart.

Current Behavior

There are many error message in the console when I hover the chart: Cannot read property ‘skip’ of undefined

Possible Solution

I can follow the source of the error to:

if (!element._view.skip) {

Steps to Reproduce (for bugs)

  1. open the live example: https://codepen.io/anon/pen/mRbrze
  2. hover mouse on the chart, the error message should be in the console

Context

For performance reason, when a chart is not in viewport, I update the data, but don’t call chart1.update().

Environment

Author: Fantashit

12 thoughts on “[BUG] Cannot read property ‘skip’ of undefined when hover the chart

  1. We need to synchronize the data with the metadata to get proper animations: if you replace the whole dataset.data object (and so avoid metadata implicit synchronization), there should be no errors because synchronisation will be fully done when calling chart.update().

    But I don’t think it’s a good approach to have the chart data / labels not synced with elements while interacting with the chart (i.e. modifying data without calling update() immediately). I would rather buffer data/labels in another location and when the chart become visible (or you need it to be updated), load data and call chart.update() right after.

  2. This was not resolved. I’m experiencing the same issue. It should not have been closed, in my opinion, as the solution was a workaround instead of a fix for the bug. In my case, either it’s impractical to eliminate user interaction before calling update, or I’m misunderstanding the solution. I call chart update once per second, and I have an asynchronous data timer that gets data every 10 seconds. The data timer performs one fetch that gets data used for about 10 charts, which is why I’m not sure I can tie the chart updates to the completion of the data timer. If I had something like the .onevent functionality of NodeJS, this would probably be a moot discussion. 🙂

  3. In my case I got this error when the dataset(s) were continuously updated over an interval, and it was resolved by setting option events: ['click'] to completely remove the hover event.

  4. I fixed this error by changing Ids for yAxisIDs
    with error:

    var altitudeSpeedGlideChartData = {
            labels: ['a','b'],
            datasets: [{
                label: 'Altitude',
                borderColor: "rgb(255, 99, 132)",
                backgroundColor: "rgb(255, 99, 132)",
                fill: false,
                data: [-1,2],
                yAxisID: 'y-axis-1',
            }, {
                label: 'Vertical Speed',
                borderColor: "rgb(54, 162, 235)",
                backgroundColor: "rgb(54, 162, 235)",
                fill: false,
                data: [4,6],
                yAxisID: 'y-axis-2',
            }]
        };
    
    var altitudeSpeedGlideChart = document.getElementById('altitudeSpeedGlide').getContext('2d');
    
            window.altitudeSpeedGlide = new Chart(altitudeSpeedGlideChart, {
                type: 'line',
                data: altitudeSpeedGlideChartData,
                options: {
                    responsive: true,
                    hoverMode: 'index',
                    stacked: false,
                    scales: {
                        yAxes: [{
                            type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
                            display: true,
                            position: 'left',
                            yAxisID: 'y-axis-1',
                        }, {
                            type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
                            display: true,
                            position: 'right',
                            yAxisID: 'y-axis-2',
                            // grid line settings
                            gridLines: {
                                drawOnChartArea: false, // only want the grid lines for one axis to show up
                            },
                        }],
                    }
                }
            });
    

    without error:

    var altitudeSpeedGlideChartData = {
            labels: ['a','b'],
            datasets: [{
                label: 'Altitude',
                borderColor: "rgb(255, 99, 132)",
                backgroundColor: "rgb(255, 99, 132)",
                fill: false,
                data: [-1,2],
                yAxisID: 'y-1',
            }, {
                label: 'Vertical Speed',
                borderColor: "rgb(54, 162, 235)",
                backgroundColor: "rgb(54, 162, 235)",
                fill: false,
                data: [4,6],
                yAxisID: 'y-2',
            }]
        };
    
    var altitudeSpeedGlideChart = document.getElementById('altitudeSpeedGlide').getContext('2d');
    
            window.altitudeSpeedGlide = new Chart(altitudeSpeedGlideChart, {
                type: 'line',
                data: altitudeSpeedGlideChartData,
                options: {
                    responsive: true,
                    hoverMode: 'index',
                    stacked: false,
                    scales: {
                        yAxes: [{
                            type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
                            display: true,
                            position: 'left',
                            yAxisID: 'y-1',
                        }, {
                            type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
                            display: true,
                            position: 'right',
                            yAxisID: 'y-2',
                            // grid line settings
                            gridLines: {
                                drawOnChartArea: false, // only want the grid lines for one axis to show up
                            },
                        }],
                    }
                }
            });
    
    

    I guess those Ids were reserved

  5. This error still exists in 2.7.2 using the sample for the mixed chart example. Resolution is to revert to 2.5.
    Stack Trace is:
    core.interaction.js:39 Uncaught TypeError: Cannot read property ‘skip’ of undefined
    at parseVisibleItems (core.interaction.js:39)
    at getIntersectItems (core.interaction.js:55)
    at indexMode (core.interaction.js:117)
    at Chart.getElementsAtEventForMode (core.controller.js:678)
    at Chart.handleEvent (core.controller.js:906)
    at Chart.eventHandler (core.controller.js:856)
    at listener (core.controller.js:793)
    at HTMLCanvasElement.proxies.(anonymous function)

  6. Downgrading to 2.5 didn’t solve it either. I’m still seeing that error when i try to hover the graph while new data points are added in a definite interval.

  7. Hey everyone, I’ve been working through this bug trying to incorporate Chart.js into a single file Vue component. I just discovered that it was an async data issue: I was trying to use data from an API call to populate my x-axis and my datasets but the chart was rendering before it had a chance to get all of the data from the call, which was provoking all kinds of errors. Just a v-if boolean evaluation in the Vue template solved this issue for me.

  8. Hey guys, I just got the same issue.
    I fixed it. so I share with this post.
    When data change let call method destroy(), after call new Chart(...)

  9. Just ran into this same issue while using this library: https://github.com/apertureless/vue-chartjs

    Maybe too naive of a thought, but why not just check to make sure element._view is not undefined before accessing its skip property?

    Current:

    // core.interaction.js:39
    if (!element._view.skip) {
        handler(element);
    }

    Proposed:

    // core.interaction.js:39
    if (element._view && !element._view.skip) {
        handler(element);
    }
  10. Like many others I also ran into this error when hovering (or clicking) a chart while I was still feeding data to it. The above suggestion by jrtitus was close but didn’t work, it turned out that the actual view is undefined and not just the skip property. So altering the function in core.interaction.js fixed it for me. This is what I added (full function further below):

    if (!element.hasOwnProperty('_view')) {
        continue;
    }
    

    Entire function with the addition:

    function parseVisibleItems(chart, handler) {
    	var datasets = chart.data.datasets;
    	var meta, i, j, ilen, jlen;
    
    	for (i = 0, ilen = datasets.length; i < ilen; ++i) {
    		if (!chart.isDatasetVisible(i)) {
    			continue;
    		}
    
    		meta = chart.getDatasetMeta(i);
    		for (j = 0, jlen = meta.data.length; j < jlen; ++j) {
    			var element = meta.data[j];
    			if (!element.hasOwnProperty('_view')) {
    				continue;
    			}
    			if (!element._view.skip) {
    				handler(element);
    			}
    		}
    	}
    }
    
    

    That worked for me, I hope it works for you too. Maybe the chart.js pros could have a look and see if it should be added permanently. I don’t think this issue should have been closed anyway.

Comments are closed.