Chart & Data Visualizations
@nofinite/charts is a standalone package featuring high-performance visualization primitives including AreaChart, BarChart, LineChart, PieChart, DonutChart, ScatterChart, and export utilities. Visit the dedicated Charts Documentation Hub for comprehensive guides.
A comprehensive, universal SVG data visualization library built with modular D3 and designed to integrate seamlessly with @nofinite/nuicss design tokens. Supports Area, Bar, Line, Donut, Pie, and Scatter charts with multi-series datasets, interactive crosshair scrubbing, and floating glassmorphic tooltips.
import {
AreaChart,
BarChart,
LineChart,
DonutChart,
PieChart,
ScatterChart,
ChartLegend
} from '@nofinite/charts/react';Interactive Preview
Unified vs Direct Component API
You can render charts using either the polymorphic <Chart variant="..." /> wrapper or direct component imports:
// 1. Polymorphic wrapper
<Chart variant="bar" data={data} xAccessor={(d) => d.name} yAccessor={(d) => d.val} />
// 2. Direct component
<BarChart data={data} xAccessor={(d) => d.name} yAccessor={(d) => d.val} />Chart Variants
1. Bar Chart
Ideal for discrete categorical comparisons across metrics:
import { BarChart } from '@nofinite/charts/react';
const quarterlyData = [
{ quarter: 'Q1', revenue: 45000 },
{ quarter: 'Q2', revenue: 58000 },
{ quarter: 'Q3', revenue: 72000 },
{ quarter: 'Q4', revenue: 91000 },
];
export function RevenueBarChart() {
return (
<div className="w-full h-64 p-4 border border-default rounded-lg bg-surface">
<BarChart
data={quarterlyData}
xAccessor={(d) => d.quarter}
yAccessor={(d) => d.revenue}
/>
</div>
);
}2. Area Chart
Displays cumulative volume, bandwidth, or growth trends over time with a subtle gradient fill:
import { AreaChart } from '@nofinite/charts/react';
const latencyData = [
{ time: new Date('2026-03-01'), latency: 42 },
{ time: new Date('2026-03-02'), latency: 38 },
{ time: new Date('2026-03-03'), latency: 45 },
{ time: new Date('2026-03-04'), latency: 31 },
];
export function LatencyAreaChart() {
return (
<div className="w-full h-64 p-4 border border-default rounded-lg bg-surface">
<AreaChart
data={latencyData}
xAccessor={(d) => d.time}
yAccessor={(d) => d.latency}
/>
</div>
);
}3. Line Chart
Optimized for continuous multi-point rate-of-change metrics:
import { LineChart } from '@nofinite/charts/react';
const serverLoad = [
{ time: new Date('2026-03-01T00:00:00Z'), cpu: 22 },
{ time: new Date('2026-03-01T04:00:00Z'), cpu: 35 },
{ time: new Date('2026-03-01T08:00:00Z'), cpu: 68 },
{ time: new Date('2026-03-01T12:00:00Z'), cpu: 84 },
{ time: new Date('2026-03-01T16:00:00Z'), cpu: 52 },
];
export function ServerLoadLineChart() {
return (
<div className="w-full h-64 p-4 border border-default rounded-lg bg-surface">
<LineChart
data={serverLoad}
xAccessor={(d) => d.time}
yAccessor={(d) => d.cpu}
/>
</div>
);
}4. Donut & Pie Charts
Perfect for proportional breakdowns, traffic distribution, and segment composition:
import { DonutChart } from '@nofinite/charts/react';
const trafficSources = [
{ source: 'Direct', visitors: 4500 },
{ source: 'Organic Search', visitors: 3200 },
{ source: 'Referral', visitors: 1800 },
{ source: 'Social', visitors: 950 },
];
export function TrafficDonutChart() {
return (
<div className="w-full h-64 p-4 border border-default rounded-lg bg-surface">
<DonutChart
data={trafficSources}
labelAccessor={(d) => d.source}
valueAccessor={(d) => d.visitors}
/>
</div>
);
}Semantic Tokens & Theming
All charts in @nofinite/nui strictly eliminate hardcoded sRGB or hex values. Strokes, fills, and axes automatically synchronize with @nofinite/nuicss design tokens:
| Element | NUICSS Token | Purpose |
|---|---|---|
| Primary Series | var(--chart-1, var(--color-primary)) | Default stroke and gradient accent |
| Axis & Grid | var(--border-default) | Subtle ticks and horizontal guide grids |
| Tooltip Container | var(--bg-surface), var(--border-default) | Elevated card surface for hovered points |
| Tooltip Shadow | var(--shadow-md) | Depth and layer elevation |
| Tooltip Typography | var(--fg-default) | Crisp legible metric values |
When your application toggles between light and dark modes, chart elements immediately inherit the updated CSS variables without triggering React re-renders.
Best Practices
Do
- Always wrap the chart inside a container element with an explicit height (e.g.
className="w-full h-64"). The charts use responsive sizing (ParentSize) and require height bounds from their parent. - Provide clean
Dateornumbervalues for time-series accessors to ensure correct axis tick scaling. - Keep tooltips informative by formatting numbers (e.g. currency, percentages) in your data accessors or labels.
Don't
- Do not pass fixed pixel
widthandheightprops unless building a non-responsive print export. - Never pass hardcoded hex values (like
#3b82f6) when styling custom overlays; always rely on semantic tokens likevar(--color-primary). - Avoid rendering hundreds of data points on compact mobile screens without pre-aggregating or bucketing intervals.
API Reference
Unified Chart Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | T[] | — | — |
series | ChartSeries<T>[] | — | — |
barLayout | any | grouped | — |
referenceLines | ReferenceLine[] | — | — |
showLegend | boolean | — | — |
legendPosition | enum | bottom | — |
animate | boolean | true | — |
xAccessor | ((d: T) => string | number | Date) | — | — |
yAccessor | ((d: T) => number) | — | — |
width | number | — | — |
height | number | 300 | — |
margin | { top: number; right: number; bottom: number; left: number; } | — | — |
color | string | var(--chart-1, var(--color-primary)) | — |
className | string | — | — |
ariaLabel | string | — | — |
showGrid | boolean | true | — |
showAxes | boolean | true | — |
showTooltip | boolean | true | — |
xTickFormat | ((val: string | number | Date) => string) | — | — |
yTickFormat | ((val: number) => string) | — | — |
tooltipFormatter | any | — | — |
onToggleSeries | ((seriesName: string) => void) | — | — |
AreaChart Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | T[] | — | — |
series | ChartSeries<T>[] | — | — |
areaMode | any | overlapping | — |
referenceLines | ReferenceLine[] | — | — |
showLegend | boolean | — | — |
legendPosition | enum | bottom | — |
xAccessor | ((d: T) => string | number | Date) | — | — |
yAccessor | ((d: T) => number) | — | — |
width | number | — | — |
height | number | 300 | — |
margin | { top: number; right: number; bottom: number; left: number; } | — | — |
color | string | var(--chart-1, var(--color-primary)) | — |
className | string | — | — |
ariaLabel | string | — | — |
showGrid | boolean | true | — |
showAxes | boolean | true | — |
showTooltip | boolean | true | — |
showCrosshair | boolean | true | — |
animate | boolean | true | — |
downsampleThreshold | number | — | — |
xTickFormat | ((val: string | number | Date) => string) | — | — |
yTickFormat | ((val: number) => string) | — | — |
tooltipFormatter | any | — | — |
onToggleSeries | ((seriesName: string) => void) | — | — |
BarChart Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | T[] | — | — |
series | ChartSeries<T>[] | — | — |
barLayout | any | grouped | — |
referenceLines | ReferenceLine[] | — | — |
showLegend | boolean | — | — |
legendPosition | enum | bottom | — |
animate | boolean | true | — |
xAccessor | ((d: T) => string | number | Date) | — | — |
yAccessor | ((d: T) => number) | — | — |
width | number | — | — |
height | number | 300 | — |
margin | { top: number; right: number; bottom: number; left: number; } | — | — |
color | string | var(--chart-1, var(--color-primary)) | — |
className | string | — | — |
ariaLabel | string | — | — |
showGrid | boolean | true | — |
showAxes | boolean | true | — |
showTooltip | boolean | true | — |
xTickFormat | ((val: string | number | Date) => string) | — | — |
yTickFormat | ((val: number) => string) | — | — |
tooltipFormatter | any | — | — |
onToggleSeries | ((seriesName: string) => void) | — | — |