How to dynamically update Chartjs legend label colors?

973 Views Asked by At

I am using vue-chartjs and chartjs-plugin-colorschemes to style a doughnut graph. I'm trying to allow the user to choose from a select which theme they prefer. I have it 90% working; the user can select a theme, hit update, and the doughnut plus its label correctly change color. What doesn't work though, is on initial page load, the doughnut has a color scheme but the legend does not.

I am currently passing a default theme down as props, and I am using a watch method to watch for changes to the theme. The error occurs inside of this watch method.

How can I dynamically update the legend label colors? Here is a minimal example of my component:

<script>
  /* eslint-disable no-new */
  import convert from 'convert-units';
  import { Doughnut } from 'vue-chartjs';
  import Chart from 'chart.js';
  import { calculateCategoryWeight } from '~/helpers/functions';
  import 'chartjs-plugin-colorschemes';

  export default {
    extends: Doughnut,

    props: {
      selected: {
        type: Object,
        default: () => {}
      },
      theme: {
        type: String,
        default: ''
      }
    },

    data () {
      const vm = this;
      return {
        chartData: {
          labels: this.selected.categories.map(category => {
            return this.$options.filters.truncate(category.name, 20);
          }),
          datasets: [
            {
              label: 'Selected Graph',
              data: this.selected.categories.map(category => {
                return parseFloat(convert(category).from('g').to('oz')).toFixed(2);
              })
            }
          ]
        },
        options: {
          cutoutPercentage: 75,
          legend: {
            display: true,
            position: 'right'
          },
          plugins: {
            colorschemes: {
              scheme: this.theme
            }
          },
          responsive: true,
          maintainAspectRatio: false,
          tooltips: {
            enabled: false
          },
        }
      };
    },

    mounted () {
      this.renderChart(this.chartData, this.options);
    },

    watch: {
      theme (newVal, oldVal) {
        const { chart } = this.$data._chart;
        chart.options.plugins.colorschemes.scheme = newVal; //<--- updates chart only
        chart.update();
      }
    }
  };
</script>
1

There are 1 best solutions below

0
On BEST ANSWER

Well I discovered the fix finally.

Essentially in the watch method, I was digging in too deep into the chart instance. By moving up a level in the chart object, both the legend and chart colors are both updated correctly.

watch: {
  theme (newVal, oldVal) {
    const chart = this.$data._chart;  //<-- changed here
    chart.options.plugins.colorschemes.scheme = newVal;
    chart.update();
  }
}