M
MetricUI
Guide

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" },
]}
FieldTypeDescription
keystringColumn key in the data row (required)
labelstringDisplay label — defaults to key
formatFormatOptionFormat for this category's values
colorstringOverride 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:

ComponentUnified FormatNotes
AreaChartYesindex → x-axis, categories → series
LineChartYesSame as AreaChart (wrapper with fill disabled)
BarChartYesindex → category axis, categories → bar groups
BarLineChartYesaxis: "right" splits bars vs lines
DonutChartYesindex → slice labels, first category → values
HeatMapYesindex → row labels, categories → columns
GaugeNoSingle value — not tabular data
FunnelNoSequential stages — its own shape (id/label/value)
WaterfallNoSequential deltas — its own shape (label/value/type)
SparklineNoFlat number array — already minimal
BulletChartNoActual 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.