Skip to the content
BooleanPress UI

Data

Chart

Draws data as a bar, line or area chart with the package's colours, tooltip and legend.

Import

import { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent, ChartStyle } from "@booleanpress/ui/chart"

Also install recharts: pnpm add recharts

Usage

The chart is Recharts, wrapped so its colours, tooltip and legend match the theme. ChartContainer takes a config that names each series and gives it a colour; the colour becomes a CSS variable, --color-<key>, that the Recharts parts use as fill or stroke. Install recharts in your product: it is a peer dependency.

import { Bar, BarChart, XAxis } from "recharts"
import { ChartContainer, ChartTooltip, ChartTooltipContent, type ChartConfig } from "@booleanpress/ui/chart"

const config = { sent: { label: "Emails sent", color: "var(--chart-1)" } } satisfies ChartConfig

export function Sent({ data }: { data: { day: string; sent: number }[] }) {
  return (
    <ChartContainer config={config} className="h-56 w-full">
      <BarChart data={data}>
        <XAxis dataKey="day" />
        <ChartTooltip content={<ChartTooltipContent />} />
        <Bar dataKey="sent" fill="var(--color-sent)" />
      </BarChart>
    </ChartContainer>
  )
}

Give the container a height (h-56) and a width: the chart fills it, and it has no height of its own beyond a 16:9 ratio. Colour a series with var(--chart-1) to var(--chart-5), or give theme: { light, dark } instead of color for a different value per theme. Use ChartTooltip with ChartTooltipContent and ChartLegend with ChartLegendContent; both look the series label up in config, so label is what people read. Turn off Recharts' animation (isAnimationActive={false}) when the chart must render at once, such as in a screenshot or a test.

Examples

Bar chart

Emails sent per day, with a tooltip that shows the day and the count.

Area chart

Delivered against bounced, each in its own theme colour, with a legend and a tooltip that lists both series.

Text alternative

A chart that is given a name and a table with the same numbers beneath it.

Accessibility

Semantics
The chart is an SVG. Recharts 3 turns its accessibility layer on by default: the SVG gets tabindex="0" and role="application". Nothing in it says what the numbers are.
Labels
Give every chart a name and a text alternative. Put the numbers in a table, or a sentence that states the finding, next to the chart (the Text alternative example). role="img" with an aria-label on the container names the chart as one picture and points to the table, but it makes the SVG's contents presentational, so the keyboard tooltip is no longer exposed. Pick the table: it carries the numbers.
Focus
With the accessibility layer on, the chart is a tab stop, and focus shows the tooltip at the first point. Left and Right Arrow move the tooltip between data points, and Enter shows or hides it. The focus ring is the browser's.
Known limits
  • A chart's numbers have no text alternative unless you write one. The tooltip and legend are visual; a screen-reader user cannot read the values from the SVG.
  • Colour alone separates series. Add the legend, and use the tooltip's indicator (dot, line, dashed) or different line styles, so people who cannot tell the colours apart can still tell the series apart.
  • The tooltip is a visual overlay shown on hover and from the keyboard. Anything people must read belongs in the table, not only in the tooltip.
  • The five series colours are tuned for light and dark themes, not for contrast against each other. Do not rely on them for more than three series.

Keyboard

Keyboard
KeyBehaviour
TabFocuses the chart and shows the tooltip at the first data point.
Left ArrowRight ArrowMoves the tooltip to the previous or next data point, once the chart has focus. The accessibility layer is Recharts' own.
EnterShows or hides the tooltip at the current data point.

API

ChartContainer

Renders a div and passes it every other prop.

ChartContainer props
PropTypeDefaultDescription
configrequiredChartConfigNames and colours the series by key: { sent: { label: "Emails sent", color: "var(--chart-1)" } }. Use theme: { light, dark } in place of color for per-theme values, and icon to show an icon in the legend and tooltip.
initialDimension{ width: number; height: number; }{ width: 320, height: 200 } as constThe width and height drawn before the chart is measured (default 320 by 200). Raise it where the chart renders on the server.

ChartTooltipContent

Renders a div and passes it every other prop.

ChartTooltipContent props
PropTypeDefaultDescription
activebooleanIf true, then Tooltip is always displayed, once an activeIndex is set by mouse over, or programmatically. If false, then Tooltip is never displayed. If undefined, Recharts will control when the Tooltip displays. This includes mouse and keyboard controls.
allowEscapeViewBoxAllowInDimensionThis option allows the tooltip to extend beyond the viewBox of the chart itself.
animationDurationnumberSpecifies the duration of animation, the unit of this option is ms.
animationEasingEasingInputThe type of easing function.
axisIdAxisIdTooltip always attaches itself to the "Tooltip" axis. Which axis is it? Depends on the layout: - horizontal layout -> X axis - vertical layout -> Y axis - radial layout -> radial axis - centric layout -> angle axis Tooltip will use the default axis for the layout, unless you specify an axisId.
content(ContentType<ValueType, NameType> & string)Renders the content of the tooltip. This should return HTML elements, not SVG elements. - If not set, the {@link DefaultTooltipContent } component is used. - If set to a React element, this element will be cloned and extra props will be passed in. - If set to a function, the function will be called and should return HTML elements.
contentStyleCSSPropertiesCSS styles to be applied to the wrapper div element.
cursorCursorDefinitionIf set false, no cursor will be drawn when tooltip is active. If set a object, the option is the configuration of cursor. If set a React element, the option is the custom react element of drawing cursor.
defaultIndexnumber | TooltipIndex
filterNullbooleanWhen an item of the payload has value null or undefined, this item won't be displayed.
formatterFormatter<ValueType, NameType> | ((value: ValueType, name: NameType, item: TooltipPayloadEntry, index: number, payload: TooltipPayload) => ReactNode | [...])Function to customize the value in the tooltip. If you return an array, the first entry will be the formatted "value", and the second entry will be the formatted "name"
hideIndicatorbooleanfalseHides the marker beside each value.
hideLabelbooleanfalseHides the heading line (the category, such as the day).
includeHiddenbooleanIf true, the tooltip will display information about hidden series. Defaults to false. Interacting with the hide property of Area, Bar, Line, Scatter.
indicator"line" | "dot" | "dashed"dotThe marker beside each value: dot (default), line or dashed.
isAnimationActiveboolean | "auto"If set false, animation of tooltip will be disabled. If set "auto", the animation will be disabled in SSR and will respect the user's prefers-reduced-motion system preference for accessibility.
itemSorter"name" | "value" | "dataKey" | ((item: Payload<ValueType, NameType>) => string | number)Sorts tooltip items. Defaults to 'name' which means it sorts alphabetically by graphical item name property.
itemStyleCSSPropertiesStyle of individual items inside the tooltip, a <li> element. These show the data label (name, or dataKey) and value. If a chart has multiple graphical items then the Tooltip renders multiple item and each of them gets this itemStyle applied.
labelReactNode
labelClassNamestring
labelFormatter((label: ReactNode, payload: readonly Payload<ValueType, NameType>[]) => ReactNode) | ((label: ReactNode, payload: TooltipPayload) => ReactNode)The formatter function of label in tooltip.
labelKeystringThe data key that gives the heading, when it is not the axis key.
labelStyleCSSProperties"Label" is the tooltip title. Renders once on the top of tooltip and shows categorical axis value. Even if there are multiple graphical items in the chart, only one label gets rendered. Note that "Label" in tooltip is the header, which is different from {@link Legend } where "labelStyle" are the individual items.
nameKeystringThe data key that names each row, when it is not the series key.
offsetnumber | CoordinateThe offset size between the position of tooltip and the mouse cursor position. When a number is provided, the same offset is applied to both x and y axes. When a Coordinate object is provided, you can specify different offsets for each axis (x and y as numbers)
payloadreadonly Payload<ValueType, TooltipNameType>[]
payloadUniqByUniqueOption<TooltipPayloadEntry>
portalHTMLElement | nullIf portal is defined, then Tooltip will use this element as a target for rendering using React Portal: https://react.dev/reference/react-dom/createPortal If this is undefined then Tooltip renders inside the recharts-wrapper element.
positionPartial<Coordinate>If this field is set, the tooltip will be displayed at the specified position regardless of the mouse position. You can set a single field (x or y) and let the other field be calculated automatically based on the mouse position.
reverseDirectionAllowInDimension@defaultValue {"x":false,"y":false}
separatorstringThe separator between name and value.
sharedbooleanDefines whether the tooltip is reacting to the current data point, or to all data points at the current axis coordinate. - true: tooltip will appear on top of all bars on an axis tick. - false: tooltip will appear on individual bars. Different chart types allow different modes, and have different defaults.
trigger"hover" | "click"If hover then the Tooltip shows on mouse enter and hides on mouse leave. If click then the Tooltip shows after clicking and stays active.
useTranslate3dboolean@defaultValue false
wrapperClassNamestring
wrapperStyleCSSPropertiesCSS styles to be applied to the wrapper div element.

ChartLegendContent

Renders a div and passes it every other prop.

ChartLegendContent props
PropTypeDefaultDescription
align"center" | "left" | "right"@deprecated use position instead which has more options, is more flexible and has more intuitive default styles.
formatterFormatterFunction to customize how content is serialized before rendering. This should return HTML elements, or strings.
hideIconbooleanfalseShows the coloured square, not the series icon.
iconSizenumberThe size of icon in each legend item.
iconType"circle" | "line" | "rect" | "none" | "cross" | "diamond" | "plainline" | "square" | "star" | "triangle" | "wye"The type of icon in each legend item.
inactiveColorstringThe color of the icon when the item is inactive.
labelStyleCSSPropertiesStyle of individual items inside the Legend, a <span> element. These show the data label (name, or dataKey) and value. If a chart has multiple graphical items then the Legend renders multiple item and each of them gets this itemStyle applied. Pie charts render multiple labels from a single data series. Note that this is different from {@link Tooltip }: - in Tooltip: "labelStyle" styles the title / header - in Tooltip: "itemStyle" styles the individual data points - in Legend: "labelStyle" styles the individual data points Beware of the naming inconsistency!
layout"horizontal" | "vertical"The layout of legend items inside the legend container.
nameKeystringThe data key that names each entry, when it is not the series key.
onPointerEnterCaptureAdaptChildPointerEventHandler<LegendPayload, ReactElement<unknown, string | JSXElementConstructor<any>>>
onPointerLeaveCaptureAdaptChildPointerEventHandler<LegendPayload, ReactElement<unknown, string | JSXElementConstructor<any>>>
payloadreadonly LegendPayload[]DefaultLegendContent.payload is omitted from Legend props. A custom payload can be passed here if desired, or it can be passed from the Legend "content" callback.
verticalAlign"top" | "bottom" | "middle"bottom@deprecated use position instead which has more options, is more flexible and has more intuitive default styles.

ChartStyle

ChartStyle props
PropTypeDefaultDescription
configrequiredChartConfig
idrequiredstring

Also exported: ChartTooltip, Tooltip from Recharts, re-exported; ChartLegend, Legend from Recharts, re-exported.

Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.

Data attributes: data-slot="chart" (ChartContainer), and data-chart.

Theming

Series colours come from the --chart-1 to --chart-5 tokens of theme.css, set per theme. The container also styles Recharts' grid lines, axis text, tooltip cursor and dots with theme tokens, so a chart needs no colour of its own.

The tokens its classes read. Change their values in your theme, and it follows.

Theme tokens
TokenUsed for
--backgroundbackground
--borderstroke, border
--foregroundtext
--mutedfill
--muted-foregroundfill, text