vue-chartjs icon indicating copy to clipboard operation
vue-chartjs copied to clipboard

[Bug]: Vue-ChartJS keeps throwing [Vue warn]: Error in mounted hook: "RangeError: Maximum call stack size exceeded" keeps showing

Open AlexLightning opened this issue 3 years ago • 10 comments

Would you like to work on a fix?

  • [ ] Check this if you would like to implement a PR, we are more than happy to help you go through the process.

Current and expected behavior

Every time I include a chart in a page I keep getting this in the console: [Vue warn]: Error in mounted hook: "RangeError: Maximum call stack size exceeded".

The chart loads and acts as expected but I keep getting this warning.

I am using vue-chartjs v4.0.7 with chart.js v3.7.1 in Vue 2.6.14.

The usage of the component is basic. I include it in another component like this:

<StatisticsGraph :statisticsGraph="statisticsGraph" style="max-height:490px; width:100%;"/>

statisticsGraph is just a data() field that gets updated after an axios call. I have checked and it only gets called twice.

And then the component looks like this:

<template>
    <LineChart :chart-data="chartData" :chart-options="chartOptions"/>
</template>
<script>
    import 'chart.js/auto';
    import { Line } from 'vue-chartjs/legacy';

    export default{
        components: {LineChart: Line},
        props: {
            statisticsGraph: Object
        },
        data: function(){
            var labels = [
                        'Monday','Monday-end','Friday','Friday-end'];
             return {
                chartData: {
                    labels: labels,
                    datasets: [
                        {   
                            type: 'line',
                            steppedLine: true,
                            data: this.statisticsGraph.last_week,
                            borderColor: '#d0d7e1',
                            pointRadius: 0,
                            borderWidth: 2,
                            fill: false,
                        },
                        {
                            type:'line',
                            steppedLine: true,
                            data: this.statisticsGraph.this_week,
                            borderColor: '#77c0b4',
                            backgroundColor: '#77c0b4',
                            pointRadius: 0,
                            borderWidth: 2,
                            fill: false,
                        },
                    ]
                },
                chartOptions: {
                    plugins: {
                        legend: {
                            display: false,
                            labels: {
                                boxWidth: 20,
                            }
                        },
                    },
                    scales: {
                        x: {
                            grid: {
                                display: false,
                            },
                            ticks: {
                                padding: 10,
                                fontColor: '#95AAC9',
                                fontSize: 13,
                                autoSkip: false,
                                maxRotation: 0,
                                callback: (value) => {return (labels[value] === 'Monday' ||  labels[value] === 'Friday') ? labels[value] : ' '}
                            },
                        },
                        y: {
                            grid: {
                                drawBorder: false,
                            },
                            ticks: {
                                fontColor: '#95AAC9',
                                fontSize: 13,
                            }
                        }
                    },
                    responsive: true,
                    maintainAspectRatio: false
                }
            }
        }
    }
</script>

Any idea what might cause this? I searched a lot for it and I couldn't find any answer or resolution.

Reproduction

I was not able to replicate this :( maybe you have an idea what might cause it

chart.js version

v4.0.7

vue-chartjs version

v3.7.1

Possible solution

No response

AlexLightning avatar May 13 '22 09:05 AlexLightning

You may need to make sure, that your axios data is there, before passing it to the chart.

apertureless avatar May 13 '22 11:05 apertureless

I have tried adding checks everywhere, even on the LineChart component... But it is still showing. Any idea if there might be something else that's causing this?

AlexLightning avatar May 30 '22 11:05 AlexLightning

I do not really understand what is happening. I went the extra mile on another page and:

  • removed all other charts in the parent component
  • made the chart component as basic as possible

And it is still happening. I am now on latest versions of vue-charjs and chartjs. Here is how I use the basic chart now:

This is in the parent component. It's just in a div, no v-if, no v-for in there, just plain html:

<TestChart />

This is the simplified component:

<template>
    <Doughnut :chart-data="{datasets:[{data:[2]}]}" />
</template>
<script>
    import 'chart.js/auto';
    import { Doughnut } from 'vue-chartjs/legacy';

    export default {
        components: { Doughnut },
    }
</script>

And I still get the same error:

vue-app.js:311796 [Vue warn]: Error in mounted hook: "RangeError: Maximum call stack size exceeded"

found in

---> <Doughnut>
vue-app.js:313072 RangeError: Maximum call stack size exceeded
    at Reflect.ownKeys (<anonymous>)
    at Object.ownKeys (vue-app.js:108225:22)
    at Function.keys (<anonymous>)
    at Observer.walk (vue-app.js:312107:21)
    at new Observer (vue-app.js:312097:10)
    at observe (vue-app.js:312165:10)
    at defineReactive$$1 (vue-app.js:312197:29)
    at Observer.walk (vue-app.js:312109:5)
    at new Observer (vue-app.js:312097:10)
    at observe (vue-app.js:312165:10)

Also, before removing it for test, on this page I also had a Bar chart and that one did not throw any error/warning...

Any idea what might be happening? I did a lot of work to migrate everything from the old version where there were no problems just to get stuck at the end in this...

AlexLightning avatar Jun 02 '22 10:06 AlexLightning

Can you please provide a reproduction codepen / codesandbox.io ?

apertureless avatar Jun 02 '22 11:06 apertureless

I finally realized what was causing this, somewhere random in the code in another component I had this:

import { Chart as ChartJS } from "chart.js";
import chartAnnotation from 'chartjs-plugin-annotation';
ChartJS.register(chartAnnotation);

After removing it the errors disappear, but I can't use the annotation plugin in the component that I need. Looking over the docs I saw this:

When using [chartjs-plugin-annotation](https://www.chartjs.org/chartjs-plugin-annotation/latest/) and Vue 2 simultaneously, you will not be able to place multiple reactive charts on one page.

So I suppose somehow it sees all the charts on the same page?

Is there any way to work around this, or should I just live to the fact that I won't be able to use the annotation plugin...?

AlexLightning avatar Jun 02 '22 12:06 AlexLightning

Hi @AlexLightning. I'm sorry, but this bug is not the vue-chartjs library. You can see this example which does not use vue-chartjs. Joint use of Vue2, Chart.js, and chartjs-plugin-annotationn create Maximum call stack size error. We can't fix it.

thabarbados avatar Jun 07 '22 10:06 thabarbados

Thanks for the answer. I eventually discovered something in my case that made the error go away:

  1. For every chart that I needed annotation on, I just used it like described in the docs (those were not throwing any errors)
  2. I noticed I was getting error for the other graphs that had no annotation. So I tried adding this to the chartOptions:
plugins: {
  annotation: {
    annotations: [

    ]
},

And the errors are no longer showing. Maybe it will help somebody else that will be in my situation :)

AlexLightning avatar Jun 08 '22 07:06 AlexLightning

Wow, great! It looks like a hack :) I will explore this option and maybe add your solution to the docs!

thabarbados avatar Jun 08 '22 08:06 thabarbados

If you remove the chart: null from the reactive data definition then the warning / stack size exceeded goes away.

It seems that in chart.js 3 the chart object itself uses some kind of observable pattern and that collides with vue's observable pattern. Keeping it out of data or using a shallow copy seems to work.

https://github.com/chartjs/chartjs-plugin-annotation/discussions/478#discussioncomment-1627423 https://stackoverflow.com/a/68609820

markkimsal avatar Aug 01 '22 22:08 markkimsal

I did not have "chart: null", so this wouldn't have helped in my case. But it might help someone that actually mentioned it

AlexLightning avatar Aug 08 '22 14:08 AlexLightning

I don't understand. This same crash is the only outcome I get when I'm trying to change the data. Am I the only one who is changing the data on the chart dynamically or is it working for everyone else?

Can anyone point me to a working example that shows dynamic data update?

I've already spent a couple of hours trying to migrate from vue-chartjs v3.5.1/chart.js v2.9.4 to vue-chartjs v5.2.0/chart.js v4.4.0, but this crash is already driving me crazy.

If you remove the chart: null from the reactive data definition then the warning / stack size exceeded goes away.

It seems that in chart.js 3 the chart object itself uses some kind of observable pattern and that collides with vue's observable pattern. Keeping it out of data or using a shallow copy seems to work.

chartjs/chartjs-plugin-annotation#478 (comment) https://stackoverflow.com/a/68609820

Isn't the answer from stackoverflow from above is the fix and that it should be applied on the vue-chartjs side?

I mean, making Chart a shallowRef should fix it, but those charts are created inside the vue-chartjs so the shallowRef should be applied there. Or if I create the chart directly, what is the point of vue-chartjs in the first place? Is it only suitable to display a static data now?

There is either something terribly wrong with this bug or I'm approaching it from a completely wrong angle.

arthabus avatar Oct 21 '23 22:10 arthabus

If you remove the chart: null from the reactive data definition then the warning / stack size exceeded goes away.

It seems that in chart.js 3 the chart object itself uses some kind of observable pattern and that collides with vue's observable pattern. Keeping it out of data or using a shallow copy seems to work.

chartjs/chartjs-plugin-annotation#478 (comment) https://stackoverflow.com/a/68609820

This has fixed my issue. Thanks alot

benkab2 avatar Jan 29 '24 10:01 benkab2

I don't understand. This same crash is the only outcome I get when I'm trying to change the data. Am I the only one who is changing the data on the chart dynamically or is it working for everyone else?

Can anyone point me to a working example that shows dynamic data update?

https://stackblitz.com/github/apertureless/vue-chartjs/tree/main/sandboxes/reactive

apertureless avatar Jan 29 '24 12:01 apertureless