useYAxisTicks

Returns the ticks of a YAxis.

This hook is useful for accessing the calculated ticks of a YAxis. The ticks are the same as the ones rendered by the YAxis component.

Available since Recharts 3.8

// #region imports and mock data
import {
  CartesianGrid,
  DefaultZIndexes,
  getRelativeCoordinate,
  InverseScaleFunction,
  Line,
  LineChart,
  MouseHandlerDataParam,
  ReferenceLine,
  RelativePointer,
  useXAxisInverseTickSnapScale,
  useYAxisInverseTickSnapScale,
  XAxis,
  YAxis,
  ZIndexLayer,
} from 'recharts';
import { MouseEvent, TouchEvent, useCallback, useState } from 'react';
import { RechartsDevtools } from '@recharts/devtools';

const data = [
  { name: 'Jan', sales: 400 },
  { name: 'Feb', sales: 3000 },
  { name: 'Mar', sales: 50000 },
  { name: 'Apr', sales: 24500 },
  { name: 'May', sales: 6000 },
  { name: 'Jun', sales: 45500 },
];
// #endregion

/**
 * This Crosshair component shows how to convert pixel coordinates to data values.
 * In effect it still follows the mouse pointer, but instead of showing pixel coordinates,
 * it shows the closest data values on both axes.
 *
 * It "snaps" to the closest data points using useXAxisInverseTickSnapScale and useYAxisInverseTickSnapScale hooks.
 *
 */
const AxisTickCrosshair = ({ pointer }: { pointer: RelativePointer | null }) => {
  // Convert pixel coordinates to the closest data values
  const xAxisInverseScale: InverseScaleFunction | undefined = useXAxisInverseTickSnapScale();
  const yAxisInverseScale: InverseScaleFunction | undefined = useYAxisInverseTickSnapScale();

  if (pointer == null || xAxisInverseScale == null || yAxisInverseScale == null) {
    return null;
  }
  const xDataLabel = String(xAxisInverseScale(pointer.relativeX));
  const yDataLabel = String(yAxisInverseScale(pointer.relativeY));
  return (
    <ZIndexLayer zIndex={DefaultZIndexes.cursorLine}>
      <ReferenceLine
        x={xDataLabel}
        /*
         * pointerEvents: none is necessary because without it, browser will detect hovering over the Cross itself
         * which makes it trigger mouseLeave on the chart which makes it erase the Cross which looks like it's blinking.
         * If we skip pointer events on the cross then we can skip the mouseLeave and the movement is smooth.
         */
        style={{ pointerEvents: 'none' }}
        stroke="green"
        strokeWidth={1}
        strokeDasharray="4"
        label={{
          value: xDataLabel,
          position: 'top',
          offset: 5,
        }}
      />
      <ReferenceLine
        y={yDataLabel}
        /*
         * pointerEvents: none is necessary because without it, browser will detect hovering over the Cross itself
         * which makes it trigger mouseLeave on the chart which makes it erase the Cross which looks like it's blinking.
         * If we skip pointer events on the cross then we can skip the mouseLeave and the movement is smooth.
         */
        style={{ pointerEvents: 'none' }}
        stroke="green"
        strokeWidth={1}
        strokeDasharray="4"
        label={{
          value: yDataLabel,
          position: 'right',
          offset: 5,
        }}
      />
    </ZIndexLayer>
  );
};

/**
 * This example demonstrates how to use getRelativeCoordinate to get pointer position in pixels,
 * and then convert those pixel coordinates to the closest axis ticks using useXAxisInverseTickSnapScale and useYAxisInverseTickSnapScale hooks.
 */
export default function AxisTickSnapExample({
  initialPointers = [],
}: {
  initialPointers?: ReadonlyArray<RelativePointer>;
}) {
  const [pointers, setPointers] = useState<ReadonlyArray<RelativePointer>>(initialPointers);

  const handleMouseMove = useCallback(
    (_data: MouseHandlerDataParam, event: MouseEvent<SVGGraphicsElement>) => {
      const chartPointer: RelativePointer = getRelativeCoordinate(event);
      setPointers([chartPointer]);
    },
    [setPointers],
  );

  const handleTouchMove = useCallback(
    (_data: unknown, event: TouchEvent<SVGGraphicsElement>) => {
      const chartPointers = getRelativeCoordinate(event);
      setPointers(chartPointers);
    },
    [setPointers],
  );

  const handleLeave = useCallback(() => {
    setPointers([]);
  }, [setPointers]);

  return (
    <LineChart
      style={{
        width: '100%',
        maxWidth: '500px',
        maxHeight: '200px',
        aspectRatio: 1,
        touchAction: 'none',
      }}
      responsive
      data={data}
      margin={{ top: 20, right: 50, left: 20, bottom: 30 }}
      onMouseMove={handleMouseMove}
      onMouseLeave={handleLeave}
      onTouchMove={handleTouchMove}
      onTouchEnd={handleLeave}
    >
      <CartesianGrid />
      <XAxis dataKey="name" />
      <YAxis width="auto" />
      <Line type="monotone" dataKey="sales" strokeWidth={2} />

      {pointers.map(pointer => (
        <AxisTickCrosshair key={`crosshair-${pointer.relativeX}-${pointer.relativeY}`} pointer={pointer} />
      ))}

      <RechartsDevtools />
    </LineChart>
  );
}

Return value

Array<TickItem> | undefined

An array of ticks, or undefined if the axis doesn't exist or hasn't been calculated yet.

  • yAxisIdnumber | stringoptional

    The yAxisId of the YAxis. Defaults to 0 if not provided.

    DEFAULT: "defaultAxisId"