Composed Chart

A mixed-mark time-series chart — areas, time-aligned bars, and lines on one shared time axis with optional dual y-axes, an animated entrance, and a loading state.

VisitorsOrdersSessions

Installation

pnpm add @blakeui/pro-react
npm install @blakeui/pro-react
yarn add @blakeui/pro-react
bun add @blakeui/pro-react

Usage

ComposedChart is built on visx and the motion library — it does not use Recharts, and its Recharts compound surface (ComposedChart.Area / .Bar / .Line / …) is retired. It is a single component: pass data (one row per time point; the xDataKey field holds a Date, ISO string, or epoch ms) and describe the marks with the series array — a discriminated union on type: "bar" | "line" | "area", drawn in array order on one shared time x-scale. Bars are time-aligned (centered on each row's time, not a band scale), a series can read a right y-axis for a second unit, and lines and areas reveal left-to-right while bars grow in staggered from the baseline. Series colors come from the categorical --chart-1 … --chart-5 tokens (override per-series with color); chrome maps onto BlakeUI's neutral tokens automatically. The hover layer renders the shared ChartTooltipContent panel — for bar-heavy compositions, showCrosshair={false} reads better.

import {ComposedChart} from "@blakeui/pro-react";

const traffic = [
  {date: "2025-01-01", visitors: 5200, conversions: 340, revenue: 18200},
  {date: "2025-02-01", visitors: 7000, conversions: 460, revenue: 24800},
  // …
];

function App() {
  return (
    <ComposedChart
      data={traffic}
      series={[
        {type: "area", dataKey: "visitors", name: "Visitors", color: "var(--chart-4)"},
        {type: "bar", dataKey: "conversions", name: "Conversions", color: "var(--chart-3)", yAxis: "right"},
        {type: "line", dataKey: "revenue", name: "Revenue", color: "var(--chart-1)"},
      ]}
      showCrosshair={false}
    />
  );
}

Keyboard & motion

The chart is keyboard-accessible: focus it and use the left/right arrow keys (or Home / End) to move across data points; Escape clears. The active point is announced to screen readers through a live region. The entrance reveal, bar stagger, and tooltip springs all respect prefers-reduced-motion — when it is set, the chart renders without animation.

Loading state

Set status="loading" to show a stroke-only skeleton wave while data resolves; flip it to "ready" and the load→ready choreography plays — the pulse flows out, the caption exits, the line/area reveal wipes left-to-right while the bars grow in staggered.

Loading traffic…
VisitorsOrdersSessions

API Reference

ComposedChart

The single chart component. Measures its container, builds the shared time scale and left/right value scales, and renders the marks plus the hover layer.

PropTypeDefaultDescription
dataRecord<string, unknown>[]One row per time point; each row has the x key plus one numeric field per series.
seriesComposedChartSeries[]The marks to draw, in paint order — a discriminated union on type: "bar" | "line" | "area" (see the series tables below).
xDataKeystring"date"Key in each row holding the x (time) value: Date, ISO string, or epoch ms.
tickMode"data" | "domain""data"X ticks snap to data rows, or spread evenly across the time span.
numTicksnumber5Approximate x tick count (always includes the first and last).
xTickFormat(date: Date, index: number) => stringCustom x tick formatter (default: short month, plus day for spans under ~6 months).
yTickFormat(value: number) => stringCustom y tick formatter (both axes).
barSizenumberTarget bar width in px. Default derives from the data spacing (slot × 0.88, capped by maxBarSize).
maxBarSizenumberMaximum bar width in px.
barGapnumber4Gap between grouped bar series in px.
stackedbooleanfalseStack all bar series in series order at each x (lines/areas are never stacked).
stackGapnumber0Gap in px between stacked segments.
marginPartial<Margin>{top: 40, right: 40, bottom: 40, left: 40}Plot margins.
aspectRatiostring"2 / 1"CSS aspect ratio of the chart box (3/2 suits narrow cards; ignored when height is set).
heightnumberFixed pixel height. Overrides aspectRatio.
showGridbooleantrueRender horizontal grid rows.
showXAxisbooleantrueRender the x axis.
showYAxisbooleantrueRender the y axis (the right axis appears when any series uses it).
showTooltipbooleantrueShow the hover tooltip layer (the shared ChartTooltipContent panel).
showCrosshairbooleantrueShow the vertical crosshair. Off reads better for bar-heavy compositions.
showDotsbooleantrueShow per-series dots at the active point (line/area series only).
showPillbooleantrueShow the animated time pill under the crosshair.
valuePrefixstringStatic text rendered before each tooltip value (e.g. "$").
animationDurationnumber1100Entrance duration in ms — the line/area reveal and each bar's grow (bars stagger over 40% of it).
status"loading" | "ready""ready"While loading, shows the skeleton wave and disables interaction. Flipping to ready plays the entrance.
loadingLabelstring""Centered caption shown while loading. Empty string hides it.

Also supports all native div HTML attributes.

Series union

Every entry shares dataKey, name, color, and yAxis ("left" default, "right" for a second unit); the type discriminant adds the mark-specific options.

OptionTypeDefaultDescription
bar · radiusnumbermin(w, h) / 2Corner radius override, clamped to the capsule cap — bars render as full capsules by default; pass 0 for square. Stacked stacks round only the top segment.
line · strokeWidthnumber2.5Stroke width.
line · curve"natural" | "monotone" | "linear""natural"Curve interpolation.
line · showMarkersbooleanfalseRing markers on every data point (r5 dot with a surface ring).
line · dashFromIndexnumberRender the path dashed from this row index onward (e.g. a projection tail).
line · dashArraystring"6,4"Dash pattern for the tail.
area · strokeWidthnumber2Top-edge stroke width.
area · curve"natural" | "monotone" | "linear""monotone"Curve interpolation.
area · fadeEdgesbooleantrueDissolve the fill at the left/right plot edges (~10% per side); the stroke stays crisp.

On this page