An unforeseen issue arose while trying to update the data in a Chart.js chart within a Vue application

I am currently utilizing Chart.js version 3.5 along with Vue 3. After successfully creating a chart, I attempted to trigger a data change within a Vue method. However, I encountered an issue that displayed the following error message: "Uncaught TypeError: Cannot set property 'fullSize' of undefined".

Edit2: I have added a missing closing bracket. The code should now be executable.

Below is the code snippet from MyChart.vue:

<template>
    <canvas id="chartEl" width="400" height="400" ref="chartEl"></canvas>
    <button @click="addData">Update Chart</button>
</template>

<script>
import Chart from 'chart.js/auto';

export default {
    name: "Raw",
    data() {
        return {
            chart: null
            
        }
    },
    methods: {
        createChart() {             

            this.chart= new Chart(this.$refs["chartEl"], {
                type: 'doughnut',
                data: {
                    labels: ['VueJs', 'EmberJs', 'ReactJs', 'AngularJs'],
                    datasets: [
                        {
                        backgroundColor: [
                        '#41B883',
                        '#E46651',
                        '#00D8FF',
                        '#DD1B16'
                        ],
                        data: [100, 20, 80, 20]
                        }
                    ]
                },

                options: {
                    plugins: {}
                }
            })
        },


        addData() {
            const data = this.chart.data;
            if (data.datasets.length > 0) {
                data.labels.push('data #' + (data.labels.length + 1));

                for (var index = 0; index < data.datasets.length; ++index) {
                data.datasets[index].data.push(123);
                }
            this.chart.update(); // this line seems to cause the error
            }
        }
    },

    mounted () {

    this.createChart();
    }

}
</script>

Edit1: Adding the following option successfully updates the chart, but the error persists and the animation does not work as expected. The chart flickers and directly displays the final updated state. Other animations, like hiding/showing arcs, do not seem to be affected.

options: {
        
    responsive: true,

}

Edit3: Including the option "maintainAspectRatio:false" seems to prevent the chart from updating (the error mentioned above still exists).

While debugging, it seems that the following function from 'chart.esm.js' is being called successfully multiple times, but encounters an error on the final call:

  beforeUpdate(chart, _args, options) {
    const title = map.get(chart);  // this returns null, leading to an error in the subsequent call mentioned above.
    layouts.configure(chart, title, options);
    title.options = options;
  },

//////////////////////
  configure(chart, item, options) {
    item.fullSize = options.fullSize;
    item.position = options.position;
    item.weight = options.weight;
  },

Answer №1

Although this post may seem outdated, I recently encountered a similar issue after spending numerous hours grappling with it. I believe that my solution may benefit you and others facing the same problem in the future:

Before setting the Chart object as a property of your Vue component, make sure to apply Object.seal(...) on it.

For example:

const chartObj = new Chart(...);
Object.seal(chartObj);
this.chart = chartObj;

This method proved effective for me. Vue has a tendency to modify object attributes aggressively to enhance reactivity, causing Chart to not recognize these objects and retrieve their configurations from its internal mapping when necessary. By using Object.seal, you prevent new attributes from being added to the object, ensuring that Chart has all the necessary attributes initialized. I will keep an eye out for any unusual behavior resulting from this approach and update this post accordingly.

Answer №2

After a year, Alan's solution came to my rescue as well. However, I encountered a setback when trying to execute chart.destroy().

After some research, I discovered what appears to be the recommended approach in Vue.js: markRaw. Here is an example using the options API:

import { markRaw } from 'vue'
// ...
export default {
  // ...
  beforeUnmount () {
    if (this.chart) {
      this.chart.destroy()
    }
  },
  methods: {
    createChart() {  
      const chart = new Chart(this.$refs["chartEl"], {
        // ... your chart data and options
      })
      this.chart = markRaw(chart)
    },
    addData() {
      // ... your update
      this.chart.update()
    },
  },
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Looking to trigger the closing of a q-popup-proxy by clicking a button from a separate component

I am currently working with a q-popup-proxy component in my project. <q-btn label="Add Fault" class="addFaultButton" dense @click="openPopUp()"> <q-popup-proxy position="center" v-if="openFaults" ...

Creating a switch statement that evaluates the id of $(this) element as a case

I have a menu bar with blocks inside a div. I am looking to create a jQuery script that changes the class of surrounding blocks in the menu when hovering over a specific one. My idea is to use a switch statement that checks the ID of $(this) and then modif ...

Retrieve data from the api

Can someone provide the JavaScript code to loop through an API, extract the coordinates/address, and map it? Here is a simple demonstration of fetching the API data: const fetch = require("node-fetch"); fetch('url').then(function (resp ...

Creating interfaces for applications that are driven by events in JavaScript

When it comes to designing an application, traditional UML Class diagrams may not always be useful, especially for programs that do not heavily rely on classes. For instance, in a JavaScript application that is mainly event-driven, where you listen for eve ...

Is there a way to adjust this validation logic so that it permits the entry of both regular characters and certain special characters?

Currently, the input field only accepts characters. If any other type of character is entered, an error will be thrown as shown in the code below. How can I update this logic to allow not only letters but also special characters like hyphens and apostrop ...

Problem with custom anchor component in React that needs to perform an action before being clicked

React Component (Custom Anchor) import React from 'react'; class Anchor extends React.Component { onClick = (event) => { // ----------------------------- // send Google Analytics request ...

Definition of a class in Typescript when used as a property of an object

Currently working on a brief .d.ts for this library, but encountered an issue with the following: class Issuer { constructor(metadata) { // ... const self = this; Object.defineProperty(this, 'Client', { va ...

What is the best way to merge two approaches for tallying items within each category?

I have an Angular 8 application that includes two methods for displaying the number of items in each category. These items are retrieved from the back-end and are categorized as follows: <mat-tab> <ng-template mat-tab-label> ...

Creating a dynamic image display feature using VueJS

Explore the connections between the elements How can I transmit a value from one child component to another in VueJS? The code snippet below is not generating any errors and the image is not being displayed <img v-bind:src="image_url" /> Code: & ...

Issue with ng-true-value in AngularJS version 1.6.1 - not functioning as expected

Recently, I delved into AngularJS and followed an online tutorial that showcased how to utilize ng-true-value and ng-false-value. Here's the snippet: <!DOCTYPE html> <html lang="en"> <head> <script src="https://ajax.googleapis ...

How can I add a black-colored name and a red-colored star to the Placeholder Star as a required field?

I'm looking to customize the placeholder text in an input field. I want the main placeholder text to be in black and have a red star indicating it's a required field. However, my attempt to set the color of the star specifically to red using `::- ...

What is the best way to use Javascript in order to automatically open a designated tab within SharePoint 2013?

Currently, I am in the process of developing a website project which incorporates Bootstrap tabs utilizing jQuery. While these tabs are functioning excellently on various pages, I am faced with the challenge of linking specific icons to corresponding tabs ...

In JavaScript, the gallery feature with Lightbox effect creates a unique touch as only half of the screen fades to black in

Hello everyone, I'm a complete beginner when it comes to programming so please be gentle with me on my first question :) I'm trying to put together a simple website with a lightbox gallery, and you can check out what I have so far here. The prob ...

Is it possible to create a translucent glass floating box over HTML elements, similar to the frosted glass effect seen in iOS7?

Creating an overlapping div with a frosted glass effect typically requires using an image background (like ). I am interested in having a floating div (position:fixed) that can apply a frosted glass effect over any content below it, whether it be an image ...

Exploring Enum properties within an angular js select drop down

I am working with an enum in Java that looks like this: public enum myEnum{ enum1("enumDisplayVal1"), enum2("enumDisplayVal2") myEnum(String displayValue) { this.displayValue = displayValue;} private String displayValue; public String getDisp ...

Unsuccessful attempt at aborting an Ajax request

Currently, I have developed a basic live search feature using jQuery ajax to search through a JSON file on the server and display a list of events. The script is programmed to show a list of events that were previously displayed on the page if the search ...

What methods can be used to create a universal JS function for popup windows?

How can I create a more flexible code structure? I have successfully implemented the functionality using the following approach: let popup1 = document.getElementById("popup-1"); function openPopup1() { popup1.classList.add("open-popup& ...

Sharing Data via JSON for a Pop-Up Display

section of a website, there is a button that, when clicked, triggers a small pop-up. The data being posted appears to be in JSON format as seen in HttpFox. Personally, I have little knowledge of javascript and AJAX. When the specific button is clicked, i ...

Navigate to the top of the page prior to updating the Link route in NextJS

Whenever I click on a link to navigate to a new page, the page loads and immediately scrolls to the top. I want to change this behavior so that the scroll resets to the top before the new page is rendered. You can observe this issue on . If you scroll do ...

Troubleshooting problems with hosting create-react-app on IIS and Internet Explorer

Having some trouble setting up my React application that was built using the React Create App template. When trying to host it with IIS, I encountered some issues. The index.html main page seems to be loading fine, but the compiled JS file is not loading ...