Skip to content
Primitives

Chart

Recharts wired to the okibi tokens: a responsive container with a HUD-skinned tooltip and legend, driven by a config-based color system.

● LIVE
AREA // STACKED
Channel Throughput
Uplink / downlink across six cycles
Up 12.4% this window
CYCLE 0x01 TO 0x06 // TELEMETRY NOMINAL
npx shadcn@latest add https://okibi.cndr.dev/r/chart.json

Charts are not a component library: they're a thin wrapper around Recharts. You bring the chart; okibi gives it the HUD skin (sharp corners, hard offset shadows, mono telemetry labels) and a config-driven color system wired to the shared --chart-* tokens. Compose ChartContainer, ChartTooltip and ChartLegend with Recharts primitives, then copy the result into your app.

Installation

Install the theme first (it ships the --chart-1…5 palette), then add the component:

npx shadcn@latest add https://okibi.cndr.dev/r/chart.json

Your First Chart

Let's build a bar chart, then layer on a grid, an axis, a tooltip and a legend.

Add your data

Start with the data. It can be anything: an array of objects is the common shape. Here, packet counts per cycle:

const chartData = [
  { cycle: "0x01", packets: 186 },
  { cycle: "0x02", packets: 305 },
  { cycle: "0x03", packets: 237 },
  { cycle: "0x04", packets: 173 },
  { cycle: "0x05", packets: 209 },
  { cycle: "0x06", packets: 264 },
];

Add a chart config

The config holds everything that isn't data: labels, colors and (optionally) icons. Keeping it separate means you can drive content and theming without touching your data source.

import { type ChartConfig } from "@/components/ui/chart";

const chartConfig = {
  packets: {
    label: "Packets",
    color: "var(--chart-1)",
  },
} satisfies ChartConfig;

Build the chart

Wrap a Recharts chart in ChartContainer and pass the config. Each config key is exposed to the chart as a --color-<key> CSS variable, so reference your series color as var(--color-packets):

import { Bar, BarChart } from "recharts";
import { ChartContainer } from "@/components/ui/chart";

<ChartContainer config={chartConfig}>
  <BarChart data={chartData}>
    <Bar dataKey="packets" fill="var(--color-packets)" />
  </BarChart>
</ChartContainer>

Add a grid

import { CartesianGrid } from "recharts";

<CartesianGrid vertical={false} />

Add an axis

import { XAxis } from "recharts";

<XAxis dataKey="cycle" tickLine={false} axisLine={false} tickMargin={8} />

Add a tooltip

ChartTooltip is Recharts' tooltip; ChartTooltipContent is the HUD-skinned body that reads labels and colors straight from your config:

import { ChartTooltip, ChartTooltipContent } from "@/components/ui/chart";

<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />

Here is the complete chart. The Code tab contains the full source:

● LIVE
BAR // VERTICAL
Packet Volume
Per-cycle packet counts
Peak 305 at 0x02
CYCLE 0x01 TO 0x06 // 1,374 TOTAL

Add a legend

A legend earns its place once you have more than one series. Add ChartLegend with ChartLegendContent and it maps each color back to its config label:

import { ChartLegend, ChartLegendContent } from "@/components/ui/chart";

<ChartLegend content={<ChartLegendContent />} />
● LIVE
LINE // MULTIPLE
Multi-Channel Trace
Three channels overlaid
3 channels nominal
CYCLE 0x01 TO 0x06 // MUX TRACE

Chart config

ChartConfig decouples appearance from data. Each key matches a dataKey (or a nameKey) in your chart and can set a label, an icon, and either a single color or per-theme colors:

import { Cpu, MemoryStick } from "lucide-react";
import { type ChartConfig } from "@/components/ui/chart";

const chartConfig = {
  compute: {
    label: "Compute",
    icon: Cpu,
    color: "var(--chart-1)",
  },
  memory: {
    label: "Memory",
    icon: MemoryStick,
    // Per-theme colors instead of a single `color`:
    theme: { light: "var(--chart-2)", dark: "var(--chart-2)" },
  },
} satisfies ChartConfig;

Define the config once: the chart, the tooltip and the legend all read from it.

Theming

Charts pull their colors from the shared tokens. okibi ships a five-step chart palette, --chart-1 through --chart-5 (scarlet → warning → success → cyan → special), with values already defined for both light and dark.

CSS variables

Reference a token in your config and ChartContainer exposes it to the chart as --color-<key>:

const chartConfig = {
  uplink: { label: "Uplink", color: "var(--chart-1)" },
  downlink: { label: "Downlink", color: "var(--chart-2)" },
} satisfies ChartConfig;

Using colors

Once the config is set, reference the generated variable anywhere Recharts takes a color:

<Bar dataKey="uplink" fill="var(--color-uplink)" />
<Line dataKey="uplink" stroke="var(--color-uplink)" />

The tooltip and legend read the same config, so they stay in sync automatically. To recolor a chart, point the config at different --chart-* steps (or any token): nothing in the chart body changes. Because every value flows from the shared tokens, the chart renders identically here and in your app after install.

Tooltip

A tooltip has a label, a per-series indicator, a name and a value. ChartTooltipContent accepts:

PropDescription
indicatorIndicator style: "dot" (default), "line" or "dashed".
hideLabelHide the top label row.
hideIndicatorHide the per-series color swatch.
nameKeyConfig key to use for each series' name.
labelKeyConfig key to use for the label.
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />

Legend

ChartLegend is Recharts' legend; ChartLegendContent renders the HUD swatches and labels. It accepts:

PropDescription
nameKeyConfig key to use for each item's label.
verticalAlign"bottom" (default) or "top".
hideIconHide the color swatch / config icon.
<ChartLegend content={<ChartLegendContent />} />

Accessibility

Recharts can add keyboard navigation and screen-reader support via the accessibilityLayer prop on the chart:

<BarChart accessibilityLayer data={chartData}>

The gallery demos opt out (accessibilityLayer={false}) because they're display-only HUD readouts that reveal nothing on interaction. This removes the stray focus ring and tab stop. Turn it on for charts users actually explore.

More charts

This page teaches the API. For the full catalog, with every family rendered in the okibi skin and paired with copy-paste source, see the Charts gallery:

  • Area: stacked, gradient and stepped
  • Bar: vertical, horizontal and stacked
  • Line: linear, multi-series and dotted
  • Pie: donut and labeled
  • Radar: multi-axis profile
  • Radial: single-metric gauge

On this page