Change Chartjs label color on click without losing hover

I’m using vue-chart-js with the labels plugin for a donut chart.

When I click on a donut section, the section background color changes correctly. I want to trigger a label font color change for the specific donut chart section I clicked as well.

This is how I trigger a label color change for the donut chart options:

   return {
    options: {
      events: ['click'],
      plugins: {
        labels: {
          render: 'label',
          fontColor: ['black', 'black', 'black'],
        },
      },
      onClick: (evt, item) => {
        // change font color for the section to red, changes the fontColor item in array above and trigger 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 use the recommended destroy() and re-render methods by the Vue-Chartjs docs to update the chart component

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);
  },
};

If I click on a chart section, the label is correctly turned red. But the chart re-renders and loses the red section background that the click toggled. If I use the update() method for the chart, instead of destroying or re-rendering, nothing happens.

Is there a way to achieve clicking on the chart and change the section background and its label without having to re-render the chart OR not losing the section background color change on click=

Answer

You can use update method. See Updating Options. And actually vue-chartjs also use that for chartData.

On data mutation, it will call update() if the data inside the datasets has changed, or renderChart() if new datasets were added. [source]

Example 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