Is it possible to add grid lines to MUI X charts Bar chart?

1.3k views Asked by At

I am looking to create a chart using MUI X barchart.

import { BarChart } from ‘@mui/x-charts/BarChart;

I specifically am looking only to add horizontal grid lines extending from the auto established tick marks on y axis, but thought it would be also helpful to know if vertical grid lines could also be added in case of future users searching for a similar solution for the other available charts (ex. I would think vertical grid lines would be helpful in the case of a line graph).

I haven’t been able to really try anything as I am unsure how to even go about it (I’m new to react and using MUI components so still learning how to style elements)

2

There are 2 answers

1
Houssem On

There is an issue opened on Github for this feature: https://github.com/mui/mui-x/issues/10158

In the meantime you can create a custom styled Path and use d3-scale to determine line position and draw it using path

Example :

import * as React from 'react';
import { styled } from '@mui/material/styles';
import { ScaleLinear } from 'd3-scale';
import {
  ResponsiveChartContainer,
  LinePlot,
  useDrawingArea,
  useYScale,
  useXScale,
} from '@mui/x-charts';

const x = Array.from({ length: 21 }, (_, index) => -1 + 0.2 * index);
const linear = x.map((v) => -1 + v);
const poly = x.map((v) => -1 + v ** 2 - v);

const StyledPath = styled('path')<{ color: 'primary' | 'secondary' }>(
  ({ theme, color }) => ({
    fill: 'none',
    stroke: theme.palette.text[color],
    shapeRendering: 'crispEdges',
    strokeWidth: 1,
    pointerEvents: 'none',
  }),
);

function CartesianAxis() {
  // Get the drawing area bounding box
  const { left, top, width, height } = useDrawingArea();

  // Get the two scale
  const yAxisScale = useYScale() as ScaleLinear<any, any>;
  const xAxisScale = useXScale() as ScaleLinear<any, any>;

  const yOrigin = yAxisScale(0);
  const xOrigin = xAxisScale(0);

  const xTicks = [-2, -1, 1, 2, 3];
  const yTicks = [-2, -1, 1, 2, 3, 4, 5];

  return (
    <React.Fragment>
      {yTicks.map((value) => (
        <StyledPath
          key={value}
          d={`M ${left} ${yAxisScale(value)} l ${width} 0`}
          color="secondary"
        />
      ))}
      {xTicks.map((value) => (
        <>
        <h6>hhh</h6>
        <StyledPath
          key={value}
          d={`M ${xAxisScale(value)} ${top} l 0 ${height}`}
          color="secondary"
        />
        </>
      ))}
      <StyledPath d={`M ${left} ${yOrigin} l ${width} 0`} color="primary" />
      <StyledPath d={`M ${xOrigin} ${top} l 0 ${height}`} color="primary" />
    </React.Fragment>
  );
}
export default function OriginDemo() {
  return (
    <ResponsiveChartContainer
      margin={{ top: 5, left: 5, right: 5, bottom: 5 }}
      height={300}
      series={[
        {
          type: 'line',
          data: linear,
        },

        {
          type: 'line',
          data: poly,
        },
      ]}
      xAxis={[{ data: x, scaleType: 'linear', min: -1, max: 3 }]}
      yAxis={[{ min: -2, max: 5 }]}
    >
      <CartesianAxis />
      <LinePlot />
    </ResponsiveChartContainer>
  );
}

Still you can use Your Chart Component (e.g: <BarChart/>) and put the inside it, as a children:

<BarChart>
  <CartisianAxis/>
<BarChart/>

Here is the demo : https://codesandbox.io/s/tender-napier-3htnp6?file=/src/Demo.tsx:1333-1343

0
Taylor On

MUI X v7(beta) supports grid lines