Modify Chartjs label color onClick while retaining hover functionality

Currently, I have implemented vue-chart-js along with the labels plugin for a donut chart. Everything is working well so far - when I click on a section of the donut chart, the background color changes as expected. However, I now want to also change the font color of the label specific to the donut section I clicked on.

The following code snippet demonstrates how I am currently changing the label color for the donut chart options:

   return {
    options: {
      events: ['click'],
      plugins: {
        labels: {
          render: 'label',
          fontColor: ['black', 'black', 'black'],
        },
      },
      onClick: (evt, item) => {
        // Changing the font color for the section to red, which updates the fontColor item in the array above and triggers reactivity for the options prop in the donut chart component
        this.$set(this.doughnutChart.options.plugins.labels.fontColor, 0, 'red');
      },
    },
    chartData: {
      labels: ['A', 'B', 'C'],
      datasets: [
        {
          hoverBackgroundColor: 'red',
          data: this.chartData,
        },
      ],
    },

I make use of the recommended destroy() and re-render methods provided by the Vue-Chartjs documentation to update the chart component accordingly.

export default {
  extends: Doughnut,
  mixins: [mixins.reactiveProp],
  props: {
    chartData: {
      type: Object,
      default: null,
    },
    options: {
      type: Object,
      default: null,
    },
  },
  watch: {
    options: {
      handler() {
        this._data._chart.destroy();
        this.renderChart(this.chartData, this.options);
      },
      deep: true,
    },
  },
  mounted() {
    this.renderChart(this.chartData, this.options);
  },
};

Although clicking on a chart section successfully turns the label text red, the issue arises when the chart re-renders and the red section background color that was toggled on click resets. When attempting to use the update() method instead of destroying or re-rendering the chart, no changes occur.

Is there a way to achieve both clicking on the chart to change the section background color and its label text without needing to re-render the entire chart or losing the section's background color change upon clicking?

Answer №1

If you need to make updates, the update method can be utilized. Take a look at Updating Options. Additionally, vue-chartjs also employs this for the chartData.

Upon data mutation, the update() function will be invoked if there are changes within the datasets, or renderChart() will be called when new datasets are added. [source]

Sample code:

import { Doughnut, mixins } from "vue-chartjs";
import "chartjs-plugin-labels";

export default {
  extends: Doughnut,
  mixins: [mixins.reactiveProp],
  props: ["options"],
  watch: {
    options: {
      handler() {
        let chart = this.$data._chart;
        chart.options = this.options;
        chart.update();
      },
      deep: true
    }
  },
  mounted() {
    this.renderChart(this.chartData, this.options);
  }
};

CodeSandbox

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

The use of "app.use("*") appears to be triggering the function repeatedly

app.use("*", topUsers) is being invoked multiple times. The function topUsers is called repeatedly. function topUsers(req, res, next){ console.log("req.url", req.url) findMostUsefullReviewsAggregate(6) .then(function(aggregationResult){ ...

When the user hits the enter key, automatically submit a form without the need for

Is it possible to submit a form on enter using type="button"? Here are my input fields: <input type="text" id = "login-user" class="form-control log-input" placeholder="Username" required="required"> <input type="password" id="login-password" clas ...

Customize your Wordpress site with a JQuery load more button specifically designed for custom post types

I'm currently working on adding a "load more" button to my WordPress website in order to load my custom post types. I've managed to successfully make it load the posts, but I'm facing an issue where each time I load more posts, it replaces t ...

Troubleshooting directive not functioning properly with AngularJS ng-click

My HTML img tag is not responding to ng-click when clicked. I'm puzzled by this issue occurring in masonryPictureView.html Main page - home.html <ng-masonry> <ng-picture ng-items="projectdescription.pictures"></ng-picture> </n ...

A guide on accessing the first element in an array when performing multiplication within the Interval component in React.js

I am having trouble initiating an if statement from number 0 once the window is loaded, as it seems to be skipping over 0 and starting from 1 instead. Can someone please assist me in understanding how this works? showAnime = () => { let counter ...

Having trouble creating an axios instance in Vue

I recently came across a helpful tip in an article about using axios for AJAX requests in Vue. The author mentioned that by setting Vue.prototype.$http = axios, we can then use this.$http within the Vue instance, which worked perfectly for me. However, wh ...

How can you initiate the wizard sequence again in TelegrafJS?

I've created a handler function for "/start" that leads to the wizard scene. Now, I have a message with an inline_keyboard containing a button labeled "redo". When I click on the "redo" button, I want it to restart the entire scene, basically initiat ...

The challenge with the Optional Chaining operator in Typescript 3.7@beta

When attempting to utilize the Typescript optional chaining operator, I encountered the following exception: index.ts:6:1 - error TS2779: The left-hand side of an assignment expression may not be an optional property access. Here is my sample code: const ...

Interactive v-card featuring a designated region that is not part of the v-menu

Currently utilizing Vuetify's v-card, I am looking to add click functionality by using the "to" property. Although it works well, there is an issue when incorporating a menu on the top-right side of the card. Clicking on the menu counts as clicking on ...

Dragging objects on a map is done using jQuery and it causes them to bounce

Currently, I am working on implementing the JQuery Draggable feature. My idea is to create a map where I can attach image Divs to it dynamically using Jquery. So far, I have been successful in adding the Divs and making them draggable around the map effici ...

Display current weather conditions with the Open Weather API (featuring weather icons)

Hello everyone, I need some help from the community. I am currently working on a weather app using the openweather API. However, I'm facing an issue with displaying the weather conditions icon for each city. I have stored every icon id in a new array ...

Revitalize website when submitting in React.js

I need assistance with reloading my React.js page after clicking the submit button. The purpose of this is to update the displayed data by fetching new entries from the database. import React, {useEffect, useState} from 'react'; import axios from ...

Begin Leaflet with JQuery UI Slider set to a predefined value

I have integrated the LeafletSlider library into my project to slide through multiple layers with different timestamps in Leaflet. My goal is to initialize the slider at the timestamp closest to the current time. In SliderControl.js, I made the following ...

How can I stretch a background image using jquery to cover the entire document instead of just the window

I have implemented a plugin called https://github.com/srobbin/jquery-backstretch to effectively stretch the background image. The problem arises when the content of the page is long enough to create a scrollbar. In this case, while scrolling, the backgrou ...

Creating a customized image modal in ReactJS that incorporates a dynamic slideshow feature using the

I am attempting to incorporate an image lightbox into my React application: https://www.w3schools.com/howto/howto_js_lightbox.asp Here is the link to the CodeSandbox where I have tried implementing it: https://codesandbox.io/s/reactjs-practice-vbxwt ...

Tips for creating a mobile-responsive React + MUI component

A React component utilizing Material-UI (MUI) has been created and I am working on making it mobile responsive. The current appearance is as follows: https://i.stack.imgur.com/8z0T8.png My goal is to have it look like this: https://i.stack.imgur.com/L8g ...

Prevent Typing in Vuetify's Combobox - A Guide to Disabling Input in the Vuetify Combobox

Is there a way to prevent users from typing inside the vuetify combobox? Below is my current implementation of the combobox: <v-combobox :loading="isSurveyBeingPopulated" class="static--inputs" color="red" box :items="folders" :rules="[rules.required] ...

The deletion was not successfully carried out in the ajax request

Can anyone help with an issue I'm having while trying to remove a row from a table using the closest function? The function works fine outside of the $.post request, but it doesn't work properly when used within the post request. Here is my code: ...

Following an AJAX request, jQuery.each() does not have access to the newly loaded CSS selectors

Note: While I value the opinions of others, I don't believe this issue is a duplicate based on the provided link. I have searched for a solution but have not found one that addresses my specific problem. Objective: Load HTML content to an element u ...

Anticipate that the typescript tsc will generate an error, yet no error was encountered

While working in the IDE to edit the TypeScript code, an issue was noticed in checkApp.ts with the following warning: Argument type { someWrongParams: any } is not assignable to parameter type AddAppToListParams. Surprisingly, when running tsc, no error ...