Chartjs-Chart.js: Change lengend colors to array

1👍

Edit: Another answer below has running snippet that is simpler to implement which also answers OP’s request. My original answer below is more focused on building the legend completely by oneself.


Live Demo. I’ve found this is fun…

Some points to note:

  1. You need to build the legend yourself, as your colors are not "relevant" to the data you use (that’s why by default it is using the colors from dataset "a") (edited as another answer shows such possibility)
  2. As you are using Svelte, in the Demo I used the <style> which binds with the <div> for the legend for styling of the legend.
  3. For people who ain’t using Svelte, or are seeking solutions within Chart.js, they should follow the advice from the StackOverflow answer OP linked — they need to build the legend using the plugins field of 2nd argument when creating a new Chart()

No matter which route to take, to keep the functionality of the legend as OP mentioned, I added a tweaked version of default behaviour of OnClick.

P.S. For (3) we have to further override generateLabels() (here, but may cause meta.controllers._resolveAnimation having problems, which we may still need to override onClick).

P.P.S. When a legend item is clicked, the label is crossed out (strikethrough) as a default behaviour. That is left as a further exercise or another answer. (For Svelte, use Boolean flags to change styles. Alternatively, hack with CSS checked checkbox labels).

0👍

You can achieve this in 2 ways, using a custom generateLabels function or by specifying a backgroundcolor in the dataset.

Custom generateLabels:

let legendColors = ['#dddddd', '#aaaaaa'];

const options = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderColor: 'pink'
      },
      {
        label: '# of Points',
        data: [7, 11, 5, 8, 3, 7],
        borderColor: 'orange'
      }
    ]
  },
  options: {
    plugins: {
      legend: {
        labels: {
          generateLabels: function(chart) {
            const datasets = chart.data.datasets;
            const {
              labels: {
                usePointStyle,
                pointStyle,
                textAlign,
                color
              }
            } = chart.legend.options;

            return chart._getSortedDatasetMetas().map((meta, i) => {
              const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
              const borderWidth = Chart.helpers.toPadding(style.borderWidth);

              return {
                text: datasets[meta.index].label,
                fillStyle: legendColors[i],
                fontColor: color,
                hidden: !meta.visible,
                lineCap: style.borderCapStyle,
                lineDash: style.borderDash,
                lineDashOffset: style.borderDashOffset,
                lineJoin: style.borderJoinStyle,
                lineWidth: (borderWidth.width + borderWidth.height) / 4,
                strokeStyle: style.borderColor,
                pointStyle: pointStyle || style.pointStyle,
                rotation: style.rotation,
                textAlign: textAlign || style.textAlign,
                borderRadius: 0, // TODO: v4, default to style.borderRadius

                // Below is extra data used for toggling the datasets
                datasetIndex: meta.index
              };
            }, this);
          }
        }
      }
    }
  },
}

const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>

Adding background color prop in datasets:

const options = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderColor: 'pink',
        pointBackgroundColor: 'pink',
        backgroundColor: '#dddddd'
      },
      {
        label: '# of Points',
        data: [7, 11, 5, 8, 3, 7],
        borderColor: 'orange',
        pointBackgroundColor: 'orange',
        backgroundColor: '#aaaaaa'
      }
    ]
  },
  options: {},
}

const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>

Leave a comment