Bar chart
Compare amounts per category as grouped or stacked bars with a zero baseline and a source table.
On this page
Daily work
Illustrative data · Monday through Friday
- Planned work
- Repairs
Code
import { BarChart } from "@bosunkit/components/bar-chart";
import { ChartLegend } from "@bosunkit/components/chart-legend";
import { ChartPanel } from "@bosunkit/components/chart-panel";
import type { ChartConfig } from "@bosunkit/components/chart-container";
import type { ReactElement } from "react";
export const description: string =
"Illustrative category amounts as vertical grouped bars; Wednesday has an unmeasured category.";
interface Amount {
readonly day: string;
readonly planned: number | null;
readonly repairs: number | null;
}
const data: readonly Amount[] = [
{ day: "Mon", planned: 4, repairs: 2 },
{ day: "Tue", planned: 5, repairs: 3 },
{ day: "Wed", planned: 6, repairs: null },
{ day: "Thu", planned: 3, repairs: 2 },
{ day: "Fri", planned: 5, repairs: 1 },
];
const values: Readonly<Record<number, string>> = {
0: "0",
1: "1",
2: "2",
3: "3",
4: "4",
5: "5",
6: "6",
7: "7",
8: "8",
9: "9",
10: "10",
};
const writeValue: (value: number) => string = (value: number): string => values[value] ?? "";
const writeDay: (value: string | number) => string = (value: string | number): string =>
typeof value === "string" ? value : "";
const config: ChartConfig<Amount> = {
planned: { label: "Planned work", formatValue: writeValue },
repairs: { label: "Repairs", formatValue: writeValue },
};
export default function DailyAmounts(): ReactElement {
return (
<ChartPanel
title="Daily work"
description="Illustrative data · Monday through Friday"
legend={<ChartLegend config={config} mark="bar" label="Work categories" />}
footer="Items per day · incomplete stacks have no drawn total"
>
<BarChart
data={data}
categoryKey="day"
config={config}
series={["planned", "repairs"]}
mode="grouped"
orientation="vertical"
valueDomain={[0, 10]}
formatCategory={writeDay}
formatAxisValue={writeValue}
label="Illustrative work amounts, Monday through Friday"
categoryLabel="Day"
dataTableLabel="View daily amounts"
missingValueText="Not counted"
/>
</ChartPanel>
);
}
A bar chart compares amounts per category. Grouped columns compare series beside one another; stacked columns show composition; horizontal bars give category names more space. The value scale always includes zero, including a caller-supplied domain.
Use
An incomplete stack has no drawn total. Its known observations remain in the source table, with caller-supplied text for missing values. Use a shared unit and comparison basis for all series. An explicit value domain clips observations outside its bounds. Filtering preserves the domain of the complete registry. Every series has a label and a patterned swatch; category colors alone do not identify a series.
categoryScale="linear" preserves numeric bin spacing for a histogram. Its categories must be finite and increasing. A numeric categoryDomain controls the viewport; source rows remain available when the drawing clips them.
Examples
Composition
Daily work
Illustrative data · Monday through Friday
- Planned work
- Repairs
Code
import { BarChart } from "@bosunkit/components/bar-chart";
import { ChartLegend } from "@bosunkit/components/chart-legend";
import { ChartPanel } from "@bosunkit/components/chart-panel";
import type { ChartConfig } from "@bosunkit/components/chart-container";
import type { ReactElement } from "react";
export const description: string =
"Illustrative category amounts as vertical grouped bars; Wednesday has an unmeasured category.";
interface Amount {
readonly day: string;
readonly planned: number | null;
readonly repairs: number | null;
}
const data: readonly Amount[] = [
{ day: "Mon", planned: 4, repairs: 2 },
{ day: "Tue", planned: 5, repairs: 3 },
{ day: "Wed", planned: 6, repairs: null },
{ day: "Thu", planned: 3, repairs: 2 },
{ day: "Fri", planned: 5, repairs: 1 },
];
const values: Readonly<Record<number, string>> = {
0: "0",
1: "1",
2: "2",
3: "3",
4: "4",
5: "5",
6: "6",
7: "7",
8: "8",
9: "9",
10: "10",
};
const writeValue: (value: number) => string = (value: number): string => values[value] ?? "";
const writeDay: (value: string | number) => string = (value: string | number): string =>
typeof value === "string" ? value : "";
const config: ChartConfig<Amount> = {
planned: { label: "Planned work", formatValue: writeValue },
repairs: { label: "Repairs", formatValue: writeValue },
};
export default function DailyAmounts(): ReactElement {
return (
<ChartPanel
title="Daily work"
description="Illustrative data · Monday through Friday"
legend={<ChartLegend config={config} mark="bar" label="Work categories" />}
footer="Items per day · incomplete stacks have no drawn total"
>
<BarChart
data={data}
categoryKey="day"
config={config}
series={["planned", "repairs"]}
mode="grouped"
orientation="vertical"
valueDomain={[0, 10]}
formatCategory={writeDay}
formatAxisValue={writeValue}
label="Illustrative work amounts, Monday through Friday"
categoryLabel="Day"
dataTableLabel="View daily amounts"
missingValueText="Not counted"
/>
</ChartPanel>
);
}
Stacked
Daily work
Illustrative data · Monday through Friday
- Planned work
- Repairs
Code
import { BarChart } from "@bosunkit/components/bar-chart";
import { ChartLegend } from "@bosunkit/components/chart-legend";
import { ChartPanel } from "@bosunkit/components/chart-panel";
import type { ChartConfig } from "@bosunkit/components/chart-container";
import type { ReactElement } from "react";
export const description: string =
"Illustrative category amounts as vertical stacked bars; Wednesday has an unmeasured category.";
interface Amount {
readonly day: string;
readonly planned: number | null;
readonly repairs: number | null;
}
const data: readonly Amount[] = [
{ day: "Mon", planned: 4, repairs: 2 },
{ day: "Tue", planned: 5, repairs: 3 },
{ day: "Wed", planned: 6, repairs: null },
{ day: "Thu", planned: 3, repairs: 2 },
{ day: "Fri", planned: 5, repairs: 1 },
];
const values: Readonly<Record<number, string>> = {
0: "0",
1: "1",
2: "2",
3: "3",
4: "4",
5: "5",
6: "6",
7: "7",
8: "8",
9: "9",
10: "10",
};
const writeValue: (value: number) => string = (value: number): string => values[value] ?? "";
const writeDay: (value: string | number) => string = (value: string | number): string =>
typeof value === "string" ? value : "";
const config: ChartConfig<Amount> = {
planned: { label: "Planned work", formatValue: writeValue },
repairs: { label: "Repairs", formatValue: writeValue },
};
export default function DailyAmounts(): ReactElement {
return (
<ChartPanel
title="Daily work"
description="Illustrative data · Monday through Friday"
legend={<ChartLegend config={config} mark="bar" label="Work categories" />}
footer="Items per day · incomplete stacks have no drawn total"
>
<BarChart
data={data}
categoryKey="day"
config={config}
series={["planned", "repairs"]}
mode="stacked"
orientation="vertical"
valueDomain={[0, 10]}
formatCategory={writeDay}
formatAxisValue={writeValue}
label="Illustrative work amounts, Monday through Friday"
categoryLabel="Day"
dataTableLabel="View daily amounts"
missingValueText="Not counted"
/>
</ChartPanel>
);
}
Horizontal
Daily work
Illustrative data · Monday through Friday
- Planned work
- Repairs
Code
import { BarChart } from "@bosunkit/components/bar-chart";
import { ChartLegend } from "@bosunkit/components/chart-legend";
import { ChartPanel } from "@bosunkit/components/chart-panel";
import type { ChartConfig } from "@bosunkit/components/chart-container";
import type { ReactElement } from "react";
export const description: string =
"Illustrative category amounts as horizontal stacked bars; Wednesday has an unmeasured category.";
interface Amount {
readonly day: string;
readonly planned: number | null;
readonly repairs: number | null;
}
const data: readonly Amount[] = [
{ day: "Mon", planned: 4, repairs: 2 },
{ day: "Tue", planned: 5, repairs: 3 },
{ day: "Wed", planned: 6, repairs: null },
{ day: "Thu", planned: 3, repairs: 2 },
{ day: "Fri", planned: 5, repairs: 1 },
];
const values: Readonly<Record<number, string>> = {
0: "0",
1: "1",
2: "2",
3: "3",
4: "4",
5: "5",
6: "6",
7: "7",
8: "8",
9: "9",
10: "10",
};
const writeValue: (value: number) => string = (value: number): string => values[value] ?? "";
const writeDay: (value: string | number) => string = (value: string | number): string =>
typeof value === "string" ? value : "";
const config: ChartConfig<Amount> = {
planned: { label: "Planned work", formatValue: writeValue },
repairs: { label: "Repairs", formatValue: writeValue },
};
export default function DailyAmounts(): ReactElement {
return (
<ChartPanel
title="Daily work"
description="Illustrative data · Monday through Friday"
legend={<ChartLegend config={config} mark="bar" label="Work categories" />}
footer="Items per day · incomplete stacks have no drawn total"
>
<BarChart
data={data}
categoryKey="day"
config={config}
series={["planned", "repairs"]}
mode="stacked"
orientation="horizontal"
valueDomain={[0, 10]}
formatCategory={writeDay}
formatAxisValue={writeValue}
label="Illustrative work amounts, Monday through Friday"
categoryLabel="Day"
dataTableLabel="View daily amounts"
missingValueText="Not counted"
/>
</ChartPanel>
);
}
Summary callout
Changes per month
Illustrative example · January–June
- Pull requests
- Change requests
Code
import type { ReactElement } from "react";
import { BarChart } from "@bosunkit/components/bar-chart";
import { ChartLegend } from "@bosunkit/components/chart-legend";
import { ChartPanel } from "@bosunkit/components/chart-panel";
// Fixed illustrative display strings; consumers supply their quantity formatter.
export const description: string =
"A persistent summary bubble names the total and reporting period; all observations are illustrative.";
const labels: Readonly<Record<number, string>> = {
"0": "0",
"100": "100",
"150": "150",
"180": "180",
"200": "200",
"250": "250",
"345": "345",
"900": "900",
"1000": "1000",
"1350": "1350",
"1620": "1620",
"1800": "1800",
"2000": "2000",
"2250": "2250",
"2700": "2700",
"3000": "3000",
"3600": "3600",
"3112": "3112",
"4000": "4000",
};
const format: (value: number) => string = (value: number): string => labels[value] ?? "";
const config = {
pull: { label: "Pull requests", formatValue: format },
changes: { label: "Change requests", formatValue: format },
};
export default function SummaryBubble(): ReactElement {
return (
<ChartPanel
title="Changes per month"
description="Illustrative example · January–June"
legend={<ChartLegend config={config} label="Change categories" mark="bar" />}
>
<BarChart
data={[
{ month: "Jan", pull: 100, changes: 900 },
{ month: "Feb", pull: 150, changes: 1350 },
{ month: "Mar", pull: 180, changes: 1620 },
{ month: "Apr", pull: 200, changes: 1800 },
{ month: "May", pull: 250, changes: 2250 },
{ month: "Jun", pull: 345, changes: 3112 },
]}
categoryKey="month"
config={config}
series={["pull", "changes"]}
mode="stacked"
formatCategory={(value: string | number): string => String(value)}
formatAxisValue={format}
label="Illustrative changes per month"
categoryLabel="Month"
dataTableLabel="View monthly changes"
missingValueText="Unavailable"
callout={{ value: "12,257", description: "changes since January", position: "top-start" }}
/>
</ChartPanel>
);
}
Latency distribution and P95
Equal-width buckets show request share. The percentile marker comes from the underlying requests; bucket centers do not establish the exact P95. Keep the bucket width and denominator visible.
Latency distribution
Share of requests by response time.
Code
import { ChartContainer } from "@bosunkit/components/chart-container";
import { ChartTooltip } from "@bosunkit/components/chart-tooltip";
import { DataTable, type Column } from "@bosunkit/components/data-table";
import { Collapsible, CollapsibleTrigger, CollapsiblePanel } from "@bosunkit/components/collapsible";
import { ChartPanel } from "@bosunkit/components/chart-panel";
import * as Recharts from "recharts";
import type { ReactElement } from "react";
export const description: string =
"Equal-width latency buckets show request share, with an independently supplied P95 at 1.9 seconds.";
const shares: readonly number[] = [2, 8, 16, 25, 20, 13, 8, 4, 1, 0.8, 0.7, 0.6, 0.5, 0.4];
const data = shares.map((share: number, index: number): { center: number; share: number } => ({
center: index * 250 + 125,
share,
}));
const shareLabels: Readonly<Record<number, string>> = {
0: "0%",
0.1: "0.1%",
0.2: "0.2%",
0.4: "0.4%",
0.5: "0.5%",
0.6: "0.6%",
0.7: "0.7%",
0.8: "0.8%",
4: "4%",
8: "8%",
13: "13%",
16: "16%",
25: "25%",
1: "1%",
2: "2%",
3: "3%",
10: "10%",
15: "15%",
20: "20%",
23: "23%",
30: "30%",
40: "40%",
50: "50%",
};
const bins: readonly string[] = [
"0 to 0.25 s",
"0.25 to 0.5 s",
"0.5 to 0.75 s",
"0.75 to 1 s",
"1 to 1.25 s",
"1.25 to 1.5 s",
"1.5 to 1.75 s",
"1.75 to 2 s",
"2 to 2.25 s",
"2.25 to 2.5 s",
"2.5 to 2.75 s",
"2.75 to 3 s",
"3 to 3.25 s",
"3.25 to 3.5 s",
];
const ticks: Readonly<Record<number, string>> = {
0: "0 s",
500: "0.5 s",
1000: "1 s",
1500: "1.5 s",
1900: "1.9 s",
2000: "2 s",
2500: "2.5 s",
3000: "3 s",
3500: "3.5 s",
};
const formatCategory: (value: string | number) => string = (value: string | number): string => {
if (typeof value !== "number") return "";
return bins[(value - 125) / 250] ?? ticks[value] ?? "";
};
const formatValue: (value: number) => string = (value: number): string => shareLabels[value] ?? "";
const columns: readonly Column[] = [
{ key: "bucket", label: "Latency bucket" },
{ key: "share", label: "Request share", align: "end" },
];
const sourceRows: readonly Record<string, unknown>[] = data.map((row, index) => ({
bucket: bins[index],
share: formatValue(row.share),
}));
export default function LatencyDistribution(): ReactElement {
return (
<div>
<ChartPanel
appearance="analytical"
title="Latency distribution"
description="Share of requests by response time."
plotMinHeight={0}
>
<ChartContainer
config={{ share: { label: "Request share", formatValue, palette: "analytical", color: "01" } }}
label="Illustrative latency distribution, Sep 27 to Oct 4, 2026"
height="var(--bk-analysis-distribution-height)"
formatCategory={formatCategory}
missingValueText="Not counted"
>
<Recharts.BarChart
data={data}
accessibilityLayer
aria-label="Request share per 250 ms latency bucket"
barCategoryGap="12%"
>
<Recharts.XAxis
type="number"
dataKey="center"
domain={[0, 3500]}
ticks={[0, 1000, 2000, 3500]}
tickFormatter={(value: number): string => (value === 3500 ? "3 s+" : (ticks[value] ?? ""))}
axisLine={false}
tickLine={false}
/>
<Recharts.YAxis hide domain={[0, 30]} />
<Recharts.Bar dataKey="share" isAnimationActive={false} radius={[3, 3, 0, 0]}>
{data.map((row, index): ReactElement => (
<Recharts.Cell
key={row.center}
fill={`var(--data-categorical-analytical-${index < 5 ? "01" : index < 8 ? "03" : "08"})`}
/>
))}
</Recharts.Bar>
<Recharts.ReferenceLine
x={1900}
stroke="var(--bk-analysis-muted)"
strokeDasharray="3 3"
label={{
value: "P95 1.9 s",
position: "insideTopRight",
fill: "var(--bk-analysis-text)",
fontSize: "var(--bk-type-caption-size)",
}}
/>
<ChartTooltip />
</Recharts.BarChart>
</ChartContainer>
</ChartPanel>
<Collapsible>
<CollapsibleTrigger>View latency distribution</CollapsibleTrigger>
<CollapsiblePanel motion={false}>
<p>Illustrative cohort · Sep 27 to Oct 4, 2026 · 250 ms buckets · 100% of requests · supplied P95 1.9 s.</p>
<DataTable columns={columns} rows={sourceRows} />
</CollapsiblePanel>
</Collapsible>
</div>
);
}
Error breakdown
A complete horizontal stack shows the composition of failures. Its denominator is failed requests, so these percentages do not describe the overall request error rate. Counts reconcile with the shares. Hovering a segment highlights that segment and shows its failure category, exact count and share. The ranked rows and source table expose the full breakdown without hover.
Error breakdown
Why requests failed this week.
- Rate limited1.9k46%
- Upstream timeout1.2k28%
- Content filtered58814%
- Provider 5xx50412%
Rate limits account for 46% of failures in this example.
Code
import { ChartContainer, type ChartRegistry } from "@bosunkit/components/chart-container";
import { ChartPanel } from "@bosunkit/components/chart-panel";
import { ChartTooltip } from "@bosunkit/components/chart-tooltip";
import { Collapsible, CollapsibleTrigger, CollapsiblePanel } from "@bosunkit/components/collapsible";
import { DataTable, type Column } from "@bosunkit/components/data-table";
import * as Recharts from "recharts";
import type { ReactElement } from "react";
export const description: string =
"A thin blue composition bar inspects each failure segment with its count and share; all 4,200 illustrative failures reconcile with the ranked rows.";
const entries = [
{ key: "limited", label: "Rate limited", count: "1,932", compact: "1.9k", share: 46, shareText: "46%", color: "01" },
{
key: "timeout",
label: "Upstream timeout",
count: "1,176",
compact: "1.2k",
share: 28,
shareText: "28%",
color: "02",
},
{
key: "filtered",
label: "Content filtered",
count: "588",
compact: "588",
share: 14,
shareText: "14%",
color: "03",
},
{ key: "provider", label: "Provider 5xx", count: "504", compact: "504", share: 12, shareText: "12%", color: "08" },
] as const;
const shares: Readonly<Record<number, string>> = { 12: "12%", 14: "14%", 28: "28%", 46: "46%" };
const formatValue: (value: number) => string = (value: number): string => shares[value] ?? "";
const config: ChartRegistry = Object.fromEntries(
entries.map((entry) => [
entry.key,
{
label: entry.label,
formatValue: (value: number): string => `${entry.count} requests (${formatValue(value)})`,
palette: "analytical",
color: entry.color,
pattern: "solid",
},
]),
);
const data = [{ cohort: "Failed requests", ...Object.fromEntries(entries.map((entry) => [entry.key, entry.share])) }];
const columns: readonly Column[] = [
{ key: "reason", label: "Failure" },
{ key: "count", label: "Requests", align: "end" },
{ key: "share", label: "Share of failures", align: "end" },
];
const rows: readonly Record<string, unknown>[] = entries.map((entry) => ({
reason: entry.label,
count: entry.count,
share: entry.shareText,
}));
export default function ErrorBreakdown(): ReactElement {
return (
<div>
<ChartPanel
appearance="analytical"
title="Error breakdown"
description="Why requests failed this week."
plotMinHeight={0}
>
<ChartContainer
config={config}
label="Illustrative failure composition, Sep 27 to Oct 4, 2026"
height="var(--bk-analysis-breakdown-height)"
formatCategory={(value: string | number): string => (typeof value === "string" ? value : "")}
missingValueText="Not counted"
>
<Recharts.BarChart
data={data}
layout="vertical"
accessibilityLayer
aria-label="Share of failed requests by reason"
margin={{ top: 0, right: 0, bottom: 0, left: 0 }}
>
<Recharts.XAxis type="number" hide domain={[0, 100]} />
<Recharts.YAxis type="category" dataKey="cohort" hide />
{entries.map((entry, index): ReactElement => (
<Recharts.Bar
key={entry.key}
dataKey={entry.key}
name={entry.label}
stackId="failures"
fill={`var(--color-${entry.key})`}
isAnimationActive={false}
activeBar={{ stroke: "var(--on-flat-active-color)", strokeWidth: "var(--bk-chart-line-width)" }}
stroke="var(--bk-analysis-panel-surface)"
strokeWidth={1}
radius={index === 0 ? [6, 0, 0, 6] : index === entries.length - 1 ? [0, 6, 6, 0] : 0}
/>
))}
<ChartTooltip shared={false} />
</Recharts.BarChart>
</ChartContainer>
<ol
aria-label="Failure categories and request counts"
style={{
listStyle: "none",
margin: "var(--space-md) 0",
padding: 0,
display: "grid",
gap: "var(--space-md)",
font: "var(--bk-type-body-reading)",
}}
>
{entries.map((entry, index): ReactElement => (
<li
key={entry.key}
style={{
display: "grid",
gridTemplateColumns: "1em 0.5em minmax(0, 1fr) auto auto",
alignItems: "center",
gap: "var(--space-sm)",
}}
>
<span aria-hidden="true" style={{ color: "var(--bk-analysis-muted)", font: "var(--bk-type-caption)" }}>
{["1", "2", "3", "4"][index]}
</span>
<span
aria-hidden="true"
style={{
width: "var(--space-sm)",
height: "var(--space-sm)",
borderRadius: "var(--radius-xs)",
background: `var(--data-categorical-analytical-${entry.color})`,
}}
/>
<span>{entry.label}</span>
<span
aria-label={`${entry.count} requests`}
style={{ color: "var(--bk-analysis-muted)", textAlign: "right", minWidth: "3em" }}
>
{entry.compact}
</span>
<strong style={{ textAlign: "right", minWidth: "3em", fontWeight: 500 }}>{entry.shareText}</strong>
</li>
))}
</ol>
<p
role="note"
style={{
margin: "var(--space-xl) 0 0",
padding: "var(--space-md)",
border: "1px solid var(--bk-analysis-panel-border)",
borderRadius: "var(--radius-sm)",
font: "var(--bk-type-body)",
color: "var(--bk-analysis-muted)",
}}
>
<span aria-hidden="true" style={{ color: "var(--data-categorical-analytical-01)" }}>
●{" "}
</span>
Rate limits account for 46% of failures in this example.
</p>
</ChartPanel>
<Collapsible>
<CollapsibleTrigger>View failure counts and shares</CollapsibleTrigger>
<CollapsiblePanel motion={false}>
<p>
Illustrative cohort · Sep 27 to Oct 4, 2026 · 4,200 failed requests · exclusive categories · 100% of
failures.
</p>
<DataTable columns={columns} rows={rows} />
</CollapsiblePanel>
</Collapsible>
</div>
);
}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| categoryScale | "category" | "linear" | undefined | "category" | Equal category spacing by default; linear preserves numeric bin or timestamp spacing. |
| mode | "grouped" | "stacked" | undefined | "grouped" | Group bars or stack them; grouped by default. An incomplete stack is a gap, with its known values preserved in the source table. |
| orientation | "vertical" | "horizontal" | undefined | – | Vertical columns or horizontal bars; vertical by default. |
| callout | ChartCallout | undefined | – | A visible summary bubble with caller-formatted value and context. |
| onCategoryDomainChange | ((range: readonly [number, number]) => void) | undefined | – | Receives a numeric viewport after drag-to-zoom or Shift-drag pan; requires categoryDomain. |
| maxGap | number | undefined | – | Maximum elapsed distance connected by a line; numeric categories only. |
| categoryDomain | readonly [number, number] | undefined | – | Controlled numeric/time viewport; emits no requests by itself. |
| syncId | string | undefined | – | Charts sharing this identifier synchronize inspection by category value or nearest time. |
| syncTolerance | number | undefined | – | Maximum distance for synchronized numeric categories; zero requires exact matches. |
| interpolation | "linear" | "stepAfter" | undefined | – | Linear segments or step changes; linear by default. Missing values remain gaps. |
| describeObservation | ((row: T) => string) | undefined | – | Caller-formatted source, processing stage or quality shown alongside every source-table row. |
| datarequired | readonly T[] | – | Rows in display order; numeric time categories must be increasing. |
| categoryKeyrequired | ChartCategoryKey<NoInfer<T>> | – | The row field naming a category or locating a sample on a numeric axis. |
| configrequired | ChartConfig<NoInfer<T>> | – | Definitions for numeric series, shared with legends and controls. |
| seriesrequired | readonly ChartValueKey<NoInfer<T>>[] | – | The visible numeric fields, in display order. Filtering preserves the complete registry's domain. |
| formatCategoryrequired | (value: string | number) => string | – | Writes category ticks, tooltip headings and the first table column. |
| formatAxisValuerequired | (value: number) => string | – | Writes value-axis ticks; separate from each series' observation formatter. |
| labelrequired | string | – | The drawing's accessible name, naming the quantity and time window. |
| categoryLabelrequired | string | – | The first table column's heading, translated by the caller. |
| dataTableLabelrequired | string | – | The disclosure button and source table's accessible name, translated by the caller. |
| missingValueTextrequired | string | – | Display text for missing values in the tooltip and source table. |
| height | string | undefined | – | The plot height as a CSS length; the chart height token by default. |
| valueDomain | readonly [number, number] | undefined | – | An explicit increasing value domain that clips outlying values; bar domains always include zero. |
| showGrid | boolean | undefined | – | Draw the grid; on by default. |
| showAxes | boolean | undefined | – | Draw axes; on by default. Values remain available in the table when off. |
| motion | MotionProp | undefined | – | Entrance and exit motion; off by default. Measurements never interpolate. |
| children | ReactNode | undefined | – | Recharts annotations appended inside the plot, such as ReferenceLine. Use ChartContainer for a custom root. |
| className | string | undefined | – | Classes added to the root. |
| testId | string | undefined | – | Becomes data-testid on the root, with --plot and --table parts. |
| ref | Ref<HTMLDivElement> | undefined | – | The chart root element. |
Daily work
Illustrative data · Monday through Friday
- Planned work
- Repairs
Keep a gap and describe the missing measurement in the source table.
Related
- Data visualization: scales, missing measurements and comparable evidence.
- Chart panel: titles, controls and source information.
- Sparkline: compact trends with operational integrity and forecast information.