0

I'm looking for a way to fill everything below 0 on my graph as a nice shade of red. After scouring SO and the documentation, I haven't been able to find a way to do this. I tried creating a dataset filled with decimal.MinValue and setting everything below 0 as filled, but it shifted the entire graph down to the min regardless of whether the dataset was set to be hidden or not. Any advise would be greatly appreciated. Thank you.enter image description here

Joshua Stevens
  • 200
  • 1
  • 9
  • Is this what you want to achieve: https://stackoverflow.com/questions/36916867/chart-js-line-different-fill-color-for-negative-point ? – Raptor Jun 30 '21 at 04:49

1 Answers1

0

You can use a custom inline plugin for this:

var options = {
  type: 'line',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [100, 19, 3, 5, -10, 3],
        borderColor: 'red',
        backgroundColor: 'red'
      },
      {
        label: '# of Votes2',
        data: [20, 10, 4, 3, -30, 32],
        borderColor: 'blue',
        backgroundColor: 'blue'
      }
    ]
  },
  options: {
    plugins: {
      backgrounds: {
        hbars: [{
          from: 0,
          to: 'MIN',
          color: "rgb(230, 195, 195)"
        }]
      }
    }
  },
  plugins: [{
    id: 'backgrounds',
    beforeDraw: (chart, args, options) => {
      const {
        canvas,
        ctx,
        chartArea,
        scales: {
          y
        }
      } = chart;
      let from = 0;
      let to = 0;

      options.hbars.forEach((hBar) => {
        from = hBar.from;
        to = hBar.to;

        from = from === 'MIN' ? y.min : from;
        from = from === 'MAX' ? y.max : from;

        to = to === 'MIN' ? y.min : to;
        to = to === 'MAX' ? y.max : to;

        ctx.save(canvas.width, canvas.height);
        ctx.fillStyle = hBar.color;
        ctx.fillRect(chartArea.left, y.getPixelForValue(from), chartArea.right - chartArea.left, y.getPixelForValue(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.4.0/chart.js"></script>
</body>
LeeLenalee
  • 27,463
  • 6
  • 45
  • 69
  • @LeeLanalee that's great! Is there a way to get it to not fill behind the labels? Thank you very much for your help! – Joshua Stevens Jul 01 '21 at 14:05
  • It doesnt fill behind the labels? It stops on the bottom of the y Scale – LeeLenalee Jul 01 '21 at 15:08
  • https://ibb.co/hdDmL1c Also, I'm still searching through myself, but would you happen to know which event I would use to have it update when I change datasets? – Joshua Stevens Jul 01 '21 at 15:18
  • Actually, I think that the past the labels shading is on me. Before my page loads in, I had a dataset with a point at -1000. When my page finished loading and the chart dataset was populated with actual data, the background did not update so it appears as if the shading went past the labels. Once I figure out the updating shading after dataset update that should fix the issue. – Joshua Stevens Jul 01 '21 at 15:24
  • I think I might know where the issue is comming from, trying to fix it – LeeLenalee Jul 01 '21 at 15:31
  • I greatly appreciate it. – Joshua Stevens Jul 01 '21 at 15:32
  • (*Chef's kiss*) You are the man! Thank you so much! – Joshua Stevens Jul 01 '21 at 15:38
  • Actually I've got one more issue. When 0 is not on the graph. Everything under the last row (the labels) are shaded. – Joshua Stevens Jul 01 '21 at 16:40
  • Dont see that issue if I have a chart with all values above 0, but otherwise you might want to build in an extra check in the plugin if the to and from are not above and below the scale min and max, if they are just set them to the min/max – LeeLenalee Jul 01 '21 at 16:52
  • Added a `if (to < 0)` check around the `ctx` lines. Did the trick. – Joshua Stevens Jul 01 '21 at 19:29