807
Sponsor

Dither Area Chart

Composable dithered area charts with layered fills, dots, axes, stacking, bloom, and keyboard interaction

Terminal

Installation

$ pnpm dlx shadcn@latest add @termcn/ink/dither-area-chart

Usage

import {
  Area,
  AreaChart,
  Grid,
  Legend,
  Tooltip,
  XAxis,
  YAxis,
} from "@/components/ui/dither-area-chart";
import type { ChartConfig } from "@/components/ui/dither-area-chart";
const data = [
  { month: "Jan", desktop: 38, mobile: 22 },
  { month: "Feb", desktop: 52, mobile: 31 },
  { month: "Mar", desktop: 47, mobile: 35 },
];
 
const config = {
  desktop: { color: "blue", label: "Desktop" },
  mobile: { color: "pink", label: "Mobile" },
} satisfies ChartConfig;
 
<AreaChart config={config} data={data} height={12} width={56}>
  <Grid horizontal />
  <XAxis dataKey="month" />
  <YAxis tickCount={4} />
  <Area dataKey="desktop" variant="gradient" />
  <Area dataKey="mobile" variant="dotted" />
  <Legend align="left" />
  <Tooltip labelKey="month" />
</AreaChart>;

Examples

Fill variants

Set variant on each Area to choose a gradient, dotted, hatched, or solid fill.

Terminal
import { Box } from "ink";

import { Area, AreaChart } from "@/components/ui/dither-area-chart";
import type { ChartConfig } from "@/components/ui/dither-area-chart";

const data = [
  { value: 18 },
  { value: 28 },
  { value: 24 },
  { value: 39 },
  { value: 34 },
  { value: 48 },
];

const config = {
  value: { color: "blue", label: "Sessions" },
} satisfies ChartConfig;

const variants = ["gradient", "dotted", "hatched", "solid"] as const;

export function DitherAreaChartVariants() {
  return (
    <Box flexDirection="column" gap={1}>
      {[variants.slice(0, 2), variants.slice(2)].map((row, rowIndex) => (
        <Box gap={2} key={rowIndex}>
          {row.map((variant) => (
            <AreaChart
              animate={false}
              config={config}
              data={data}
              height={6}
              interactive={false}
              key={variant}
              title={variant}
              width={27}
            >
              <Area dataKey="value" variant={variant} />
            </AreaChart>
          ))}
        </Box>
      ))}
    </Box>
  );
}

Stacking modes

Use stackType="stacked" for cumulative values or stackType="percent" for normalized proportions.

Terminal
import { Box } from "ink";

import { Area, AreaChart } from "@/components/ui/dither-area-chart";
import type { ChartConfig } from "@/components/ui/dither-area-chart";

const data = [
  { direct: 24, search: 18 },
  { direct: 35, search: 22 },
  { direct: 31, search: 28 },
  { direct: 46, search: 25 },
  { direct: 41, search: 34 },
];

const config = {
  direct: { color: "blue", label: "Direct" },
  search: { color: "green", label: "Search" },
} satisfies ChartConfig;

export function DitherAreaChartStacking() {
  return (
    <Box gap={2}>
      {(["stacked", "percent"] as const).map((stackType) => (
        <AreaChart
          animate={false}
          config={config}
          data={data}
          height={7}
          interactive={false}
          key={stackType}
          stackType={stackType}
          title={stackType}
          width={29}
        >
          <Area dataKey="direct" variant="gradient" />
          <Area dataKey="search" variant="dotted" />
        </AreaChart>
      ))}
    </Box>
  );
}

API Reference

PropTypeDefault
dataTData[]required
configChartConfigrequired
widthnumber56
heightnumber12
stackType"default" | "stacked" | "percent""default"
bloom"off" | "low" | "high" | "aura" | BloomConfig"off"
markerIndexnumber | nullnull
interactivebooleantrue
noColorbooleanfalse
screenReaderModebooleanfalse

Use left/right to inspect points, up/down to focus a series, Enter to select, Escape to clear, and R to replay animation. H/J/K/L are supported too.