AI
NUI logov3.1.0

Chart & Data Visualizations

Note

@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.

tsx
import { 
  AreaChart, 
  BarChart, 
  LineChart, 
  DonutChart, 
  PieChart, 
  ScatterChart,
  ChartLegend 
} from '@nofinite/charts/react';

Interactive Preview

Loading preview...

Unified vs Direct Component API

You can render charts using either the polymorphic <Chart variant="..." /> wrapper or direct component imports:

tsx
// 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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

ElementNUICSS TokenPurpose
Primary Seriesvar(--chart-1, var(--color-primary))Default stroke and gradient accent
Axis & Gridvar(--border-default)Subtle ticks and horizontal guide grids
Tooltip Containervar(--bg-surface), var(--border-default)Elevated card surface for hovered points
Tooltip Shadowvar(--shadow-md)Depth and layer elevation
Tooltip Typographyvar(--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 Date or number values 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 width and height props unless building a non-responsive print export.
  • Never pass hardcoded hex values (like #3b82f6) when styling custom overlays; always rely on semantic tokens like var(--color-primary).
  • Avoid rendering hundreds of data points on compact mobile screens without pre-aggregating or bucketing intervals.

API Reference

Unified Chart Props

PropTypeDefaultDescription
dataT[]——
seriesChartSeries<T>[]——
barLayoutanygrouped—
referenceLinesReferenceLine[]——
showLegendboolean——
legendPositionenumbottom—
animatebooleantrue—
xAccessor((d: T) => string | number | Date)——
yAccessor((d: T) => number)——
widthnumber——
heightnumber300—
margin{ top: number; right: number; bottom: number; left: number; }——
colorstringvar(--chart-1, var(--color-primary))—
classNamestring——
ariaLabelstring——
showGridbooleantrue—
showAxesbooleantrue—
showTooltipbooleantrue—
xTickFormat((val: string | number | Date) => string)——
yTickFormat((val: number) => string)——
tooltipFormatterany——
onToggleSeries((seriesName: string) => void)——

AreaChart Props

PropTypeDefaultDescription
dataT[]——
seriesChartSeries<T>[]——
areaModeanyoverlapping—
referenceLinesReferenceLine[]——
showLegendboolean——
legendPositionenumbottom—
xAccessor((d: T) => string | number | Date)——
yAccessor((d: T) => number)——
widthnumber——
heightnumber300—
margin{ top: number; right: number; bottom: number; left: number; }——
colorstringvar(--chart-1, var(--color-primary))—
classNamestring——
ariaLabelstring——
showGridbooleantrue—
showAxesbooleantrue—
showTooltipbooleantrue—
showCrosshairbooleantrue—
animatebooleantrue—
downsampleThresholdnumber——
xTickFormat((val: string | number | Date) => string)——
yTickFormat((val: number) => string)——
tooltipFormatterany——
onToggleSeries((seriesName: string) => void)——

BarChart Props

PropTypeDefaultDescription
dataT[]——
seriesChartSeries<T>[]——
barLayoutanygrouped—
referenceLinesReferenceLine[]——
showLegendboolean——
legendPositionenumbottom—
animatebooleantrue—
xAccessor((d: T) => string | number | Date)——
yAccessor((d: T) => number)——
widthnumber——
heightnumber300—
margin{ top: number; right: number; bottom: number; left: number; }——
colorstringvar(--chart-1, var(--color-primary))—
classNamestring——
ariaLabelstring——
showGridbooleantrue—
showAxesbooleantrue—
showTooltipbooleantrue—
xTickFormat((val: string | number | Date) => string)——
yTickFormat((val: number) => string)——
tooltipFormatterany——
onToggleSeries((seriesName: string) => void)——