Data Format
MetricUI charts accept a simple, flat data format. Pass an array of rows with an index column and categories — the same data works across every chart type.
Overview
Most charting libraries require you to reshape your data for each chart type — series arrays for line charts, keyed objects for bar charts, id/value pairs for donuts. MetricUI lets you pass the same flat rows to any chart. Just tell it which column is the index (x-axis) and which columns are the categories (series).
Basic Usage
Pass flat row data with index and categories:
const data = [
{ month: "Jan", revenue: 4200, costs: 2100 },
{ month: "Feb", revenue: 5100, costs: 2400 },
{ month: "Mar", revenue: 4800, costs: 2200 },
{ month: "Apr", revenue: 6200, costs: 2800 },
];
// Same data, any chart
<AreaChart data={data} index="month" categories={["revenue", "costs"]} />
<BarChart data={data} index="month" categories={["revenue", "costs"]} />
<LineChart data={data} index="month" categories={["revenue", "costs"]} />index is the column used for the x-axis (or slice labels in a donut). categories are the numeric columns to plot as series.
Zero-Config Mode
Omit both index and categories entirely. MetricUI auto-infers the schema from your data: the first string column becomes the index, all number columns become categories.
const data = [
{ month: "Jan", revenue: 4200, costs: 2100 },
{ month: "Feb", revenue: 5100, costs: 2400 },
];
// Zero config — "month" is auto-detected as index,
// "revenue" and "costs" as categories
<BarChart data={data} title="Monthly Breakdown" format="currency" />CategoryConfig
Categories can be plain strings or rich config objects. Mix and match:
import type { Category } from "metricui";
// Plain strings
categories={["revenue", "costs"]}
// Rich config — per-category labels, formats, colors, axis
categories={[
{ key: "revenue", label: "Revenue", format: "currency", color: "#6366F1" },
{ key: "margin", label: "Margin %", format: "percent", axis: "right" },
]}
// Mixed
categories={[
"revenue",
{ key: "margin", format: "percent", axis: "right" },
]}| Field | Type | Description |
|---|---|---|
key | string | Column key in the data row (required) |
label | string | Display label — defaults to key |
format | FormatOption | Format for this category's values |
color | string | Override color for this series |
axis | "left" | "right" | Assign to right Y-axis (BarLineChart, dual-axis) |
Swap Chart Types
The unified format means you can change visualization without changing data. This is the whole point — one data shape, any chart:
const data = [
{ browser: "Chrome", share: 65 },
{ browser: "Safari", share: 19 },
{ browser: "Firefox", share: 10 },
{ browser: "Edge", share: 6 },
];
// Bar chart
<BarChart data={data} index="browser" categories={["share"]} />
// Donut chart — same data, same props
<DonutChart data={data} index="browser" categories={["share"]} />
// HeatMap — same shape works here too
<HeatMap data={data} index="browser" categories={["share"]} />BarLineChart Unified
BarLineChart uses axis: "right" in CategoryConfig to split categories into bars (left axis) and lines (right axis). No separate barData/lineData needed:
const data = [
{ month: "Jan", revenue: 42000, margin: 0.32 },
{ month: "Feb", revenue: 51000, margin: 0.35 },
{ month: "Mar", revenue: 48000, margin: 0.31 },
];
<BarLineChart
data={data}
index="month"
categories={[
{ key: "revenue", format: "currency" },
{ key: "margin", label: "Margin %", format: "percent", axis: "right" },
]}
title="Revenue & Margin"
/>Categories without axis: "right" become bars on the left axis. Categories with axis: "right" become line series on the right axis.
Supported Charts
The unified format works with charts that plot tabular, multi-series data:
| Component | Unified Format | Notes |
|---|---|---|
AreaChart | Yes | index → x-axis, categories → series |
LineChart | Yes | Same as AreaChart (wrapper with fill disabled) |
BarChart | Yes | index → category axis, categories → bar groups |
BarLineChart | Yes | axis: "right" splits bars vs lines |
DonutChart | Yes | index → slice labels, first category → values |
HeatMap | Yes | index → row labels, categories → columns |
Gauge | No | Single value — not tabular data |
Funnel | No | Sequential stages — its own shape (id/label/value) |
Waterfall | No | Sequential deltas — its own shape (label/value/type) |
Sparkline | No | Flat number array — already minimal |
BulletChart | No | Actual vs target vs ranges — specialized shape |
Charts that don't support the unified format have fundamentally different data shapes — they're not plotting rows of comparable series. Each has its own purpose-built data interface documented on its component page.
Legacy Format
The legacy format (series arrays, keys/indexBy, barData/lineData) still works and is fully backward compatible. When both are provided, the legacy format takes priority.
// Legacy format — still works
<AreaChart
data={[
{ id: "revenue", data: [{ x: "Jan", y: 4200 }, { x: "Feb", y: 5100 }] },
]}
/>
// Unified format — same result, simpler
<AreaChart
data={[{ month: "Jan", revenue: 4200 }, { month: "Feb", revenue: 5100 }]}
index="month"
categories={["revenue"]}
/>We recommend the unified format for new code. It's simpler, portable across chart types, and supports per-category configuration via CategoryConfig.