2

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

1 Answers1

1

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>
LeeLenalee
  • 27,463
  • 6
  • 45
  • 69
  • This is awesome so far but I am running into a few other problems stemming from stuff I should have mentioned. I am using react-chartjs and typescript. I am trying to make my plugins section like this but am getting errors. const options = { plugins: { legend: false, tooltip: { callbacks: { label: function (context: any) { return `${context.dataset.label} - ${context.raw.r / 10} students`; }, }, }, [zeroZeroLines], <--- gives error – Adam Goodrich Aug 16 '21 at 16:18
  • Guess you have to type everything in the plugin or use the ignore type comment above it – LeeLenalee Aug 16 '21 at 17:09
  • 1
    Yeah, this is the right path and technically the correct answer to my question. I will just have to play around with it to get it to work in react-chartJS. I guess what I am struggling with is how to pass the "ctx" references in to the component. Marked as accepted answer and thanks for the help! – Adam Goodrich Aug 16 '21 at 17:18