Home > other >  Background color of the graph affects the other graphs too
Background color of the graph affects the other graphs too

Time:10-12

The graph under App.js has a background color. The problem is, the background color also takes effect in the other graph from another component. How can I fix this where only the graph from App.js has the background color. I have recreated this in codesandbox: https://codesandbox.io/s/color-the-canvas-fec5y?file=/src/App.js

This is what I've used to color the background of the graph:

  useEffect(() => {
    Chart.register({
      id: "custom_canvas_background_color",
      beforeDraw: (chart) => {
        const ctx = chart.canvas.getContext("2d");
        ctx.save();
        ctx.globalCompositeOperation = "destination-over";
        ctx.fillStyle = "lightblue";
        ctx.fillRect(0, 0, chart.width, chart.height);
        ctx.restore();
      }
    });
  }, []);

CodePudding user response:

According to the chart.js plugins documentation, using Chart.register registers the plugin globally and applies it to all charts. Instead, store the plugin in a variable

const plugin = {
    id: "custom_canvas_background_color",
    beforeDraw: (chart) => {
      const ctx = chart.canvas.getContext("2d");
      ctx.save();
      ctx.globalCompositeOperation = "destination-over";
      ctx.fillStyle = "lightBlue";
      ctx.fillRect(0, 0, chart.width, chart.height);
      ctx.restore();
    }
  };

And pass it as a props to the Line component like this:

<Line
  plugins={[plugin]}
/>

CodePudding user response:

As Alexandre pointed out with Chart.register your plugin gets registered globally to all your charts and since you hardcode a backgroundColor it will apply to all the charts. You can either only register it locally to the single chart instance as Alexandre suggested.

The other better approach is to make the backgroundColor a variable that you can set in your options. First you can check if it is set, if not you dont draw anything and if its set you can have a different color on different charts:

Chart.register({
  id: "custom_canvas_background_color",
  beforeDraw: (chart, args, opts) => {
    if (!opts.color) {
      return
    }

    const ctx = chart.canvas.getContext("2d");
    ctx.save();
    ctx.globalCompositeOperation = "destination-over";
    ctx.fillStyle = opts.color;
    ctx.fillRect(0, 0, chart.width, chart.height);
    ctx.restore();
  }
});

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'
    }]
  },
  options: {
    plugins: {
      custom_canvas_background_color: {
        color: 'lightblue'
      }
    }
  }
}

const options2 = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      borderColor: 'orange'
    }]
  },
  options: {
    plugins: {
      custom_canvas_background_color: {
        color: 'pink'
      }
    }
  }
}

const options3 = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      borderColor: 'lightblue'
    }]
  },
  options: {}
}

const ctx = document.getElementById('chartJSContainer').getContext('2d');
const ctx2 = document.getElementById('chartJSContainer2').getContext('2d');
const ctx3 = document.getElementById('chartJSContainer3').getContext('2d');

new Chart(ctx, options);
new Chart(ctx2, options2);
new Chart(ctx3, options3);
<body>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <canvas id="chartJSContainer2" width="600" height="400"></canvas>
  <canvas id="chartJSContainer3" width="600" height="400"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.js"></script>
</body>

CodeSandbox

  • Related