Chart Tooltip

Shared tooltip card and positioning helpers used by the visx chart components.

14:00
Measured1.7
Projected1.7

Usage

import {
  ChartTooltipCard,
  clampTooltipPosition,
  useMeasuredSize,
  type ChartTooltipRow,
} from '@epilot/spark-ui/chart'
function HoverTip({
  anchorX,
  anchorY,
  width,
  height,
  rows,
}: {
  anchorX: number
  anchorY: number
  width: number
  height: number
  rows: ChartTooltipRow[]
}) {
  const [tipRef, tipSize] = useMeasuredSize<HTMLDivElement>()
  const pos = clampTooltipPosition({
    anchorX,
    anchorY,
    width,
    height,
    tipWidth: tipSize.width,
    tipHeight: tipSize.height,
    placement: 'beside',
  })

  return (
    <div
      ref={tipRef}
      className="pointer-events-none absolute"
      style={{ left: pos.left, top: pos.top }}
    >
      <ChartTooltipCard label="14:00" rows={rows} />
    </div>
  )
}

These helpers keep every Spark chart tooltip looking and behaving the same. Line Chart, Bar Chart, and the HEMS history charts already use them via @visx/tooltip. Reach for the primitives when building a custom visx surface that should match.

API Reference

ChartTooltipCard

PropTypeDefaultDescription
labelReactNodeOptional header (usually the hovered time or category).
rowsChartTooltipRow[]One coloured-dot row per series. Empty array renders nothing.
classNamestringMerges onto the card.

ChartTooltipRow

FieldTypeDefaultDescription
keystringReact key.
labelReactNodeSeries name.
colorstringCSS color for the swatch (for example var(--orange-a9)).
valueReactNodeFormatted value on the right.
marker"dot" | "dashed-line""dot"dashed-line for dashed series so same-color rows stay distinguishable.

useMeasuredSize

Returns [ref, { width, height }]. Attach ref to an element that stays mounted (the tooltip wrapper can be opacity-hidden) so ResizeObserver can measure it before the first paint of an open tip.

clampTooltipPosition

ArgTypeDefaultDescription
anchorXnumberChart-local x the tip should sit near.
anchorYnumberChart-local y.
widthnumberChart bounds width.
heightnumberChart bounds height.
tipWidthnumberMeasured tooltip width.
tipHeightnumberMeasured tooltip height.
gapnumber12Space between the anchor and the tip.
padnumber8Minimum inset from every chart edge.
placement"above" | "beside""above"above flips below if needed (bars). beside prefers the right side (lines).

Returns { left, top } in chart-local coordinates. The tip stays fully inside the chart bounds.

Accessibility

  • ChartTooltipCard is presentational. Announce values elsewhere if they are required reading; do not make a hover tip the only path to a number.
  • Keep the measured wrapper in the DOM while closed so size stays accurate when the tip opens.

On this page