'How to apply to different bground color for each area in Chart.js

In react-chartjs-2

In Line chart every grid should have different background colors.

Is this achievable with this library?

This is how LineChart should looks: enter image description here

This is my Code/configuration:

const options = {
        responsive: true,
        scales: {
            y: {
                grid: {
                    backgroundColor: [
                        'rgba(36, 206, 0, 0.8)',
                        'rgba(255, 255, 0, .8)',
                        'rgba(255, 162, 0, 0.8)',
                        'rgba(36, 206, 0, 0.8)',
                    ],
                },
    };

Thanks for reading.



Solution 1:[1]

You can use an inline plugin to achieve it:

var GradientBgPlugin = {
  beforeDraw: function(chart, args, options) {
    const ctx = chart.ctx;
    const canvas = chart.canvas;
    const chartArea = chart.chartArea;

    // Chart background
    var gradientBack = canvas.getContext("2d").createLinearGradient(0, 250, 0, 0);
    gradientBack.addColorStop(0, "rgba(213,235,248,1)");
    gradientBack.addColorStop(0.16, "rgba(213,235,248,1)");
    gradientBack.addColorStop(0.17, "rgba(226,245,234,1)");
    gradientBack.addColorStop(0.25, "rgba(226,245,234,1)");
    gradientBack.addColorStop(0.26, "rgba(252,244,219,1)");
    gradientBack.addColorStop(0.5, "rgba(252,244,219,1)");
    gradientBack.addColorStop(0.51, "rgba(251,221,221,1)");
    gradientBack.addColorStop(1, "rgba(251,221,221,1)");

    ctx.fillStyle = gradientBack;
    ctx.fillRect(chartArea.left, chartArea.bottom,
      chartArea.right - chartArea.left, chartArea.top - chartArea.bottom);
  }
};

Than just include it in your Chart options:

plugins: [GradientBgPlugin]

The result should be similar to this JSFiddle.

EDIT

For Reach Charts JS 2, you need small changes in setup. You define plugin this way:

const plugins = [{
  beforeDraw: function(chart) {
    const ctx = chart.ctx;
    const canvas = chart.canvas;
    const chartArea = chart.chartArea;

    // Chart background
    var gradientBack = canvas.getContext("2d").createLinearGradient(0, 250, 0, 0);
    gradientBack.addColorStop(0, "rgba(213,235,248,1)");
    gradientBack.addColorStop(0.16, "rgba(213,235,248,1)");
    gradientBack.addColorStop(0.17, "rgba(226,245,234,1)");
    gradientBack.addColorStop(0.25, "rgba(226,245,234,1)");
    gradientBack.addColorStop(0.26, "rgba(252,244,219,1)");
    gradientBack.addColorStop(0.5, "rgba(252,244,219,1)");
    gradientBack.addColorStop(0.51, "rgba(251,221,221,1)");
    gradientBack.addColorStop(1, "rgba(251,221,221,1)");

    ctx.fillStyle = gradientBack;
    ctx.fillRect(chartArea.left, chartArea.bottom,
      chartArea.right - chartArea.left, chartArea.top - chartArea.bottom);
  }
}];

Than you plug it this way:

<Line data={data} plugins={plugins} />

You can see it working fine on CodeSandbox here.

Solution 2:[2]

You can write a custom inline plugin, that draws the colors on the chart Area. In the options section you can put an object with all the sections you want, from where to where and which color they need to be

Example:

var options = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [100, 19, 3, 5, 2, 3],
        borderWidth: 1
      },
      {
        label: '# of Points',
        data: [7, 11, 5, 8, 3, 7],
        borderWidth: 1
      }
    ]
  },
  options: {
    plugins: {
      backgrounds: {
        hbars: [{
            from: 28,
            to: 100,
            color: "rgb(195, 230, 195)"
          },
          {
            from: 20,
            to: 28,
            color: "rgb(230, 220, 195)"
          },
          {
            from: 0,
            to: 20,
            color: "rgb(230, 195, 195)"
          }
        ]
      }
    }
  },
  plugins: [{
    id: 'backgrounds',
    beforeDraw: (chart, args, options) => {
      const {
        ctx,
        chartArea,
        scales: {
          y
        }
      } = chart;

      options.hbars.forEach((hBar) => {
        ctx.save();
        ctx.fillStyle = hBar.color;
        ctx.fillRect(chartArea.left, y.getPixelForValue(hBar.from), chartArea.right - chartArea.left, y.getPixelForValue(hBar.to) - y.getPixelForValue(hBar.from));
        ctx.restore();
      })
    }
  }]
}

var 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.2.0/chart.js"></script>
</body>

Solution 3:[3]

Detailed explanation can be found here: https://medium.com/@omi10859/alternative-background-lines-in-chartjs-a626ce4d3bcb

We can use annotaion plugin with chartjs to create custom elements. we can use annotation plugin to do this

import annotationPlugin from "chartjs-plugin-annotation";
import {Chart} from 'chart.js';
Chart.register(annotationPlugin);

this code will add a box to our chart

{
  type: 'box', #type of draw
  drawTime: 'beforeDraw', #this will decide background or foreground
  yMin: 5, #value min on y axis
  yMax: 10, #value max on y axis
  borderColor: 'rgb(242, 244, 248, 0.9)', #border color of the box
  borderWidth: 1, #boarder width for box
  backgroundColor: '#F2F4F8', #colour of the box
}
# add option while rendering
const options = {
  plugins: {annotation: {annotations: background_annotation}
}

this code render this enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 LeeLenalee
Solution 3 omkar yadav