Search code examples
javascriptchart.jsreact-chartjs

How to style specific gridlines differently in chartJs?


I am using chartJS to draw a bubble chart with an x axis running from -5 to +5 and a y axis running from -5 to +5. I was able to change the grid line styling using

x: {
    grid: {
      borderDash: [2, 10],
      lineWidth: 1,
      color: `#000`,
    },

to get this result.

my chart output so far

I need to have the X and Y axis at 0 on both to be solid bold. Is there a way to style gridline at specific tick points?

desired result is this...

desired chart styling


Solution

  • The borderDash option is non scriptable so to achieve this behaviour you will need to use a custom plugin to draw over the default grid lines:

    const zeroZeroLines = {
      id: 'zeroZeroLines',
      beforeDatasetsDraw: (chart, args, opts) => {
        const {
          ctx,
          chartArea: {
            top,
            bottom,
            left,
            right
          },
          scales: {
            x,
            y
          }
        } = chart;
    
        const color = opts.color || 'black';
        const width = opts.width || 1;
    
        ctx.beginPath();
    
        ctx.lineWidth = width;
        ctx.strokeStyle = color;
    
        ctx.moveTo(x.getPixelForValue(0), bottom);
        ctx.lineTo(x.getPixelForValue(0), top);
    
        ctx.moveTo(left, y.getPixelForValue(0));
        ctx.lineTo(right, y.getPixelForValue(0));
    
        ctx.stroke();
      }
    }
    
    const options = {
      type: 'bubble',
      data: {
        datasets: [{
          label: '# of Votes',
          data: [{
            x: -4,
            y: 0,
            r: 4
          }, {
            x: 1,
            y: -3,
            r: 10
          }, {
            x: 3,
            y: 3,
            r: 20
          }, {
            x: 0,
            y: 0,
            r: 20
          }],
          backgroundColor: 'pink'
        }]
      },
      options: {
        scales: {
          x: {
            min: -5,
            max: 5,
            grid: {
              borderDash: [2, 2]
            }
          },
          y: {
            min: -5,
            max: 5,
            grid: {
              borderDash: [2, 2]
            }
          }
        },
        plugins: {
          zeroZeroLines: {
            color: 'black',
            width: 1
          }
        }
      },
      plugins: [zeroZeroLines]
    }
    
    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.5.0/chart.js"></script>
    </body>