@zuilib/charts 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -0
- package/dist/authoring.d.ts +47 -0
- package/dist/authoring.js +11 -0
- package/dist/chart-defaults.d.ts +60 -0
- package/dist/chart-defaults.js +24 -0
- package/dist/chart-frame-B9fxUxGG.d.ts +90 -0
- package/dist/chart-frame.d.ts +4 -0
- package/dist/chart-frame.js +14 -0
- package/dist/chart-legend.d.ts +25 -0
- package/dist/chart-legend.js +13 -0
- package/dist/chart-spec-CH0tAkLG.d.ts +226 -0
- package/dist/chart-tooltip.d.ts +44 -0
- package/dist/chart-tooltip.js +11 -0
- package/dist/chart.d.ts +78 -0
- package/dist/chart.js +24 -0
- package/dist/chunk-3VGLTPGL.js +19 -0
- package/dist/chunk-6QTIAMA3.js +169 -0
- package/dist/chunk-7WABBHMT.js +88 -0
- package/dist/chunk-7WJ26NHR.js +48 -0
- package/dist/chunk-BFTWWI46.js +148 -0
- package/dist/chunk-D7K23UFP.js +43 -0
- package/dist/chunk-G4FXJJ66.js +169 -0
- package/dist/chunk-HNJKYOPE.js +45 -0
- package/dist/chunk-IPOBQIYU.js +13 -0
- package/dist/chunk-MJDIQVJX.js +148 -0
- package/dist/chunk-PV27RZSV.js +61 -0
- package/dist/chunk-SHQZRND7.js +83 -0
- package/dist/chunk-UN3XPBZ5.js +17 -0
- package/dist/chunk-WVWGHGZE.js +90 -0
- package/dist/chunk-YMPZODMC.js +1084 -0
- package/dist/cross-filter.d.ts +62 -0
- package/dist/cross-filter.js +13 -0
- package/dist/format.d.ts +17 -0
- package/dist/format.js +7 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +93 -0
- package/dist/interop.d.ts +46 -0
- package/dist/interop.js +12 -0
- package/dist/registry.d.ts +111 -0
- package/dist/registry.js +25 -0
- package/package.json +98 -0
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# @zuilib/charts
|
|
2
|
+
|
|
3
|
+
Enterprise analytics charts on Recharts, styled only through ZUI tokens: a
|
|
4
|
+
serializable chart spec for runtime chart builders, styled primitives for
|
|
5
|
+
hand-written composition, and cross-filtering that links charts to each
|
|
6
|
+
other and to `@zuilib/data-grid` — without a hard dependency on it.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pnpm add @zuilib/charts @zuilib/components @zuilib/tokens recharts
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`recharts` (v3), `react` and `@zuilib/tokens` are peer dependencies. The
|
|
15
|
+
package imports the `@zuilib/components` primitives, so the components'
|
|
16
|
+
Tailwind source (or the prebuilt `zui.css`) must be loaded once in your
|
|
17
|
+
app; with the Tailwind source, add `@source "…/@zuilib/charts/dist"` so the
|
|
18
|
+
chart utilities are generated.
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import Chart from '@zuilib/charts'
|
|
24
|
+
|
|
25
|
+
// Plain JSON: store it, send it from a server, let users build it.
|
|
26
|
+
const spec = {
|
|
27
|
+
version: 1,
|
|
28
|
+
type: 'bar',
|
|
29
|
+
title: 'Revenue by region',
|
|
30
|
+
xKey: 'region',
|
|
31
|
+
series: [{field: 'revenue', label: 'Revenue', format: 'currency:USD'}],
|
|
32
|
+
yAxis: {format: 'compact'},
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
<Chart spec={spec} rows={rows} />
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Component API
|
|
39
|
+
|
|
40
|
+
### Chart — `@zuilib/charts`
|
|
41
|
+
|
|
42
|
+
| Prop | Type | Default |
|
|
43
|
+
|------|------|---------|
|
|
44
|
+
| `spec` | `ChartSpec` | required — the serializable chart description |
|
|
45
|
+
| `rows` | `ChartRow[]` | required — the rows behind the chart |
|
|
46
|
+
| `registry` | `ChartRegistry` | built-ins — `createChartRegistry(defaultChartTypes, yourDefs)` adds or overrides types without forking the component |
|
|
47
|
+
| `formats` | `Record<string, FormatterFn \| FormatterFactory>` | — custom formatter tokens the spec may name (functions stay out of the spec) |
|
|
48
|
+
| `locale` | `string` | user's locale — BCP 47 tag for formatted values |
|
|
49
|
+
| `width` / `height` | `number` | responsive — fixed pixel size for tests and SSR |
|
|
50
|
+
| `aspect` | `number` | `16/9` — responsive width/height ratio when `height` is left out |
|
|
51
|
+
| `loading` | `boolean` | `false` — renders a skeleton instead of the chart |
|
|
52
|
+
| `error` | `ReactNode` | — renders an error state instead of the chart |
|
|
53
|
+
| `emptyState` | `ReactNode` | the `noData` label — renders when `rows` is empty |
|
|
54
|
+
| `hiddenSeries` / `defaultHiddenSeries` / `onHiddenSeriesChange` | `string[]`, `string[]`, `(fields: string[]) => void` | — series fields hidden by the legend; controlled when `hiddenSeries` is passed, otherwise kept internally from `defaultHiddenSeries` |
|
|
55
|
+
| `onMarkClick` | `(event: ChartMarkEvent) => void` | — every mark click, whether or not a `CrossFilterProvider` is present |
|
|
56
|
+
| `labels` | `Partial<ChartLabels>` | English — every built-in string |
|
|
57
|
+
| `animate` | `boolean` | `true` unless the user prefers reduced motion |
|
|
58
|
+
| `ariaLabel` | `string` | the spec's title — accessible name of the figure |
|
|
59
|
+
| `className` | `string` | merged onto the container |
|
|
60
|
+
|
|
61
|
+
## Entry points
|
|
62
|
+
|
|
63
|
+
`@zuilib/charts` (or `./chart`) is the config-driven renderer: ten chart
|
|
64
|
+
types (line, area, bar, pie/donut, scatter, composed, radar, radial-bar,
|
|
65
|
+
funnel, treemap) from one discriminated `ChartSpec`, with loading, error
|
|
66
|
+
and empty states, a controlled `hiddenSeries` legend, and `onMarkClick`.
|
|
67
|
+
Formats are named tokens (`'currency:USD'`, `'compact'`, `'percent'`,
|
|
68
|
+
`'date:short'`) resolved through `./format`; custom formatter functions
|
|
69
|
+
arrive via the `formats` prop so the spec stays JSON.
|
|
70
|
+
|
|
71
|
+
`./registry` is the open chart-type registry `<Chart>` dispatches through.
|
|
72
|
+
Every type is a `ChartTypeDef` — renderer, cross-filter fields, and a
|
|
73
|
+
complete JSON Schema of its spec variant — and
|
|
74
|
+
`createChartRegistry(defaultChartTypes, yourDefs)` merges defs last-wins
|
|
75
|
+
by `type`, so an app adds or overrides a chart type without forking the
|
|
76
|
+
package:
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import { createChartRegistry, defaultChartTypes, defineChartType, chartTypeSchema } from '@zuilib/charts/registry'
|
|
80
|
+
|
|
81
|
+
const registry = createChartRegistry(defaultChartTypes, [
|
|
82
|
+
defineChartType<GaugeChartSpec>({
|
|
83
|
+
type: 'gauge',
|
|
84
|
+
family: 'named',
|
|
85
|
+
render: GaugeRenderer, // receives RendererProps<GaugeChartSpec> from @zuilib/charts/authoring
|
|
86
|
+
crossFilterField: (spec) => spec.nameKey,
|
|
87
|
+
schema: chartTypeSchema('gauge', {
|
|
88
|
+
nameKey: { type: 'string' },
|
|
89
|
+
valueKey: { type: 'string' },
|
|
90
|
+
}, ['nameKey', 'valueKey']),
|
|
91
|
+
}),
|
|
92
|
+
])
|
|
93
|
+
|
|
94
|
+
<Chart spec={gaugeSpec} rows={rows} registry={registry} />
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Custom specs type as `CustomChartSpec` (`type` plus the shared options and
|
|
98
|
+
whatever the def's schema declares); built-in specs stay the closed
|
|
99
|
+
`ChartSpec` union, so the escape hatch never loosens their checking.
|
|
100
|
+
`chartSpecJsonSchema(registry?)` emits the whole ChartSpec JSON Schema
|
|
101
|
+
(draft 2020-12, per-type `if`/`then` conditionals from the defs' complete
|
|
102
|
+
fragments) for validation and structured generation — one source, so the
|
|
103
|
+
schema can't drift from what renders.
|
|
104
|
+
|
|
105
|
+
`./authoring` is the custom-chart authoring surface: `RendererProps` (what
|
|
106
|
+
a registered renderer receives) and the mark-interaction helpers
|
|
107
|
+
(`reportMarkClick`, `activeCategoryValues`, `markDimOpacity`,
|
|
108
|
+
`MarkInteraction`) that keep an app-registered chart type's clicks and
|
|
109
|
+
dimming consistent with the built-ins.
|
|
110
|
+
|
|
111
|
+
`./chart-frame`, `./chart-tooltip`, `./chart-legend` and
|
|
112
|
+
`./chart-defaults` are the primitives for hand-written Recharts
|
|
113
|
+
composition: `ChartFrame` owns the series-color CSS variables
|
|
114
|
+
(`fill={seriesColorVar('revenue')}`) and the states; `ChartTooltipPanel`
|
|
115
|
+
and `ChartLegendList` render on popover tokens via Recharts'
|
|
116
|
+
`Tooltip`/`Legend` `content` prop, the legend as real buttons (click
|
|
117
|
+
isolates, shift-click toggles, `aria-pressed`).
|
|
118
|
+
|
|
119
|
+
`./cross-filter` is the shared filter/highlight state
|
|
120
|
+
(`CrossFilterProvider`, `useCrossFilter`) with the same
|
|
121
|
+
controlled/uncontrolled whole-state contract as the data grid; `./interop`
|
|
122
|
+
is four pure converters (`toColumnFilters`, `fromColumnFilters`,
|
|
123
|
+
`toHighlight`, `applyFilters`) that wire it to a data grid's
|
|
124
|
+
`columnFilters` and row selection structurally, with zero imports.
|
|
125
|
+
|
|
126
|
+
## Theming
|
|
127
|
+
|
|
128
|
+
Series colors are the `--chart-1` … `--chart-8` tokens — a categorical
|
|
129
|
+
palette validated for color-vision-deficiency separation in both modes.
|
|
130
|
+
Slots are assigned in fixed declaration order and never cycled. A brand may
|
|
131
|
+
override `--chart-1` with its primary hue; overriding more slots requires
|
|
132
|
+
re-validating the order. Grid lines, ticks, tooltips and states read the
|
|
133
|
+
same semantic tokens as every other ZUI package.
|
|
134
|
+
|
|
135
|
+
## Localisation
|
|
136
|
+
|
|
137
|
+
Every built-in string is overridable through the `labels` prop
|
|
138
|
+
(`ChartLabels`), and every formatted value honors the `locale` prop.
|
|
139
|
+
Mark entrance animation follows `prefers-reduced-motion` (or the `animate`
|
|
140
|
+
prop).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { UseCrossFilterResult } from './cross-filter.js';
|
|
2
|
+
import { Formatters } from './format.js';
|
|
3
|
+
import { d as ChartRow, c as ChartMarkEvent } from './chart-spec-CH0tAkLG.js';
|
|
4
|
+
import 'react/jsx-runtime';
|
|
5
|
+
import 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Renderer plumbing shared by every chart type: the normalized mark-click
|
|
9
|
+
* pipeline (one `ChartMarkEvent` shape regardless of Recharts' per-chart
|
|
10
|
+
* payloads) and the dim/keep logic for cross-filtered marks. Public through
|
|
11
|
+
* `@zuilib/charts/authoring` for app-registered chart types; internal
|
|
12
|
+
* renderers import this module directly.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
interface MarkInteraction {
|
|
16
|
+
/** The category field of this chart (its `xKey` / `nameKey` / `groupKey`). */
|
|
17
|
+
field: string;
|
|
18
|
+
crossFilter: UseCrossFilterResult | null;
|
|
19
|
+
interaction: 'filter' | 'highlight' | 'none';
|
|
20
|
+
onMarkClick?: (event: ChartMarkEvent) => void;
|
|
21
|
+
}
|
|
22
|
+
/** What every renderer receives from the `<Chart>` dispatcher. */
|
|
23
|
+
interface RendererProps<S> {
|
|
24
|
+
spec: S;
|
|
25
|
+
rows: ChartRow[];
|
|
26
|
+
formats: Formatters;
|
|
27
|
+
hiddenSeries: string[];
|
|
28
|
+
markInteraction: MarkInteraction;
|
|
29
|
+
/** Injected by `ChartFrame` at fixed size; forwarded to the chart root. */
|
|
30
|
+
width?: number;
|
|
31
|
+
/** Injected by `ChartFrame` at fixed size; forwarded to the chart root. */
|
|
32
|
+
height?: number;
|
|
33
|
+
/** Mark entrance animation; off under `prefers-reduced-motion`. */
|
|
34
|
+
animate: boolean;
|
|
35
|
+
}
|
|
36
|
+
/** Reports a mark click and applies the spec's cross-filter interaction. */
|
|
37
|
+
declare function reportMarkClick(interaction: MarkInteraction, value: string | number, seriesField: string | undefined, row: ChartRow, additive: boolean): void;
|
|
38
|
+
/**
|
|
39
|
+
* The category values whose marks render full-strength, or null when
|
|
40
|
+
* nothing dims. A highlight on this chart's field wins over its filter
|
|
41
|
+
* entry.
|
|
42
|
+
*/
|
|
43
|
+
declare function activeCategoryValues(interaction: MarkInteraction): (string | number)[] | null;
|
|
44
|
+
/** Opacity for the mark of `value`: dimmed outside the active set. */
|
|
45
|
+
declare function markDimOpacity(active: (string | number)[] | null, value: unknown): number | undefined;
|
|
46
|
+
|
|
47
|
+
export { type MarkInteraction, type RendererProps, activeCategoryValues, markDimOpacity, reportMarkClick };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Themed default prop bags for Recharts elements, plus the palette helpers.
|
|
3
|
+
* Pure module — spread these into hand-written charts:
|
|
4
|
+
*
|
|
5
|
+
* ```tsx
|
|
6
|
+
* <XAxis dataKey="month" {...xAxisDefaults} />
|
|
7
|
+
* <CartesianGrid {...cartesianGridDefaults} />
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
10
|
+
/** Number of `--chart-N` palette slots the token contract defines. */
|
|
11
|
+
declare const CHART_COLOR_COUNT = 8;
|
|
12
|
+
/** The CSS variable of palette slot `slot` (1-based, clamped to the palette). */
|
|
13
|
+
declare function chartColorVar(slot: number): string;
|
|
14
|
+
/**
|
|
15
|
+
* The CSS variable `ChartFrame` defines for a series field
|
|
16
|
+
* (`var(--color-revenue)`); non-word characters are folded to `-`.
|
|
17
|
+
*/
|
|
18
|
+
declare function seriesColorVar(field: string): string;
|
|
19
|
+
/** The custom-property name behind `seriesColorVar` (for inline styles). */
|
|
20
|
+
declare function seriesColorProperty(field: string): string;
|
|
21
|
+
/** Recessive category axis: no axis or tick lines, muted tick labels. */
|
|
22
|
+
declare const xAxisDefaults: {
|
|
23
|
+
readonly tickLine: false;
|
|
24
|
+
readonly axisLine: false;
|
|
25
|
+
readonly tickMargin: 8;
|
|
26
|
+
readonly tick: {
|
|
27
|
+
readonly fill: "var(--muted-foreground)";
|
|
28
|
+
readonly fontSize: 12;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
/** Recessive value axis: no axis or tick lines, muted tick labels. */
|
|
32
|
+
declare const yAxisDefaults: {
|
|
33
|
+
readonly tickLine: false;
|
|
34
|
+
readonly axisLine: false;
|
|
35
|
+
readonly tickMargin: 8;
|
|
36
|
+
readonly tick: {
|
|
37
|
+
readonly fill: "var(--muted-foreground)";
|
|
38
|
+
readonly fontSize: 12;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
/** Horizontal-only grid on the border token. */
|
|
42
|
+
declare const cartesianGridDefaults: {
|
|
43
|
+
readonly stroke: "var(--border)";
|
|
44
|
+
readonly strokeDasharray: "3 3";
|
|
45
|
+
readonly vertical: false;
|
|
46
|
+
};
|
|
47
|
+
/** Hover cursor for bar/area charts: a soft wash of the accent surface. */
|
|
48
|
+
declare const tooltipCursorDefaults: {
|
|
49
|
+
readonly fill: "var(--accent)";
|
|
50
|
+
readonly opacity: 0.5;
|
|
51
|
+
};
|
|
52
|
+
/** Hover cursor for line/scatter charts: a hairline crosshair. */
|
|
53
|
+
declare const tooltipCrosshairDefaults: {
|
|
54
|
+
readonly stroke: "var(--border)";
|
|
55
|
+
readonly strokeWidth: 1;
|
|
56
|
+
};
|
|
57
|
+
/** Opacity of marks outside the active cross-filter or highlight. */
|
|
58
|
+
declare const DIMMED_OPACITY = 0.35;
|
|
59
|
+
|
|
60
|
+
export { CHART_COLOR_COUNT, DIMMED_OPACITY, cartesianGridDefaults, chartColorVar, seriesColorProperty, seriesColorVar, tooltipCrosshairDefaults, tooltipCursorDefaults, xAxisDefaults, yAxisDefaults };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CHART_COLOR_COUNT,
|
|
3
|
+
DIMMED_OPACITY,
|
|
4
|
+
cartesianGridDefaults,
|
|
5
|
+
chartColorVar,
|
|
6
|
+
seriesColorProperty,
|
|
7
|
+
seriesColorVar,
|
|
8
|
+
tooltipCrosshairDefaults,
|
|
9
|
+
tooltipCursorDefaults,
|
|
10
|
+
xAxisDefaults,
|
|
11
|
+
yAxisDefaults
|
|
12
|
+
} from "./chunk-7WJ26NHR.js";
|
|
13
|
+
export {
|
|
14
|
+
CHART_COLOR_COUNT,
|
|
15
|
+
DIMMED_OPACITY,
|
|
16
|
+
cartesianGridDefaults,
|
|
17
|
+
chartColorVar,
|
|
18
|
+
seriesColorProperty,
|
|
19
|
+
seriesColorVar,
|
|
20
|
+
tooltipCrosshairDefaults,
|
|
21
|
+
tooltipCursorDefaults,
|
|
22
|
+
xAxisDefaults,
|
|
23
|
+
yAxisDefaults
|
|
24
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
3
|
+
import { createFormatters } from './format.js';
|
|
4
|
+
import { F as FormatToken } from './chart-spec-CH0tAkLG.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Every string a chart renders or announces, overridable for another
|
|
8
|
+
* language. A `{name}` placeholder is replaced with the value named.
|
|
9
|
+
*/
|
|
10
|
+
interface ChartLabels {
|
|
11
|
+
/** The default empty state. @default 'No data' */
|
|
12
|
+
noData: string;
|
|
13
|
+
/** Announced while `loading`. @default 'Loading chart…' */
|
|
14
|
+
loading: string;
|
|
15
|
+
/** The default error state title. @default 'Chart failed to load' */
|
|
16
|
+
chartError: string;
|
|
17
|
+
/** A legend button. `{series}` is replaced. @default 'Toggle {series}' */
|
|
18
|
+
toggleSeries: string;
|
|
19
|
+
/** The legend list's accessible name. @default 'Chart legend' */
|
|
20
|
+
legend: string;
|
|
21
|
+
/** Announced on a cross-filtering mark. `{value}` is replaced. @default 'Filter by {value}' */
|
|
22
|
+
filterBy: string;
|
|
23
|
+
}
|
|
24
|
+
declare const defaultChartLabels: ChartLabels;
|
|
25
|
+
/** Replaces each `{name}` in a label with `values[name]`. */
|
|
26
|
+
declare function fillLabel(template: string, values: Record<string, string | number>): string;
|
|
27
|
+
|
|
28
|
+
/** How one series is labeled and colored. */
|
|
29
|
+
interface ChartSeriesConfig {
|
|
30
|
+
/** Legend / tooltip name. */
|
|
31
|
+
label: string;
|
|
32
|
+
/** Any CSS color; `var(--chart-N)` normally. Wins over `theme`. */
|
|
33
|
+
color?: string;
|
|
34
|
+
/** Per-mode colors, emitted scoped to this chart for light and `.dark`. */
|
|
35
|
+
theme?: {
|
|
36
|
+
light: string;
|
|
37
|
+
dark: string;
|
|
38
|
+
};
|
|
39
|
+
/** Value format for tooltip rows of this series. */
|
|
40
|
+
format?: FormatToken;
|
|
41
|
+
}
|
|
42
|
+
/** Series field → its config. Key order assigns the default palette slots. */
|
|
43
|
+
type ChartConfig = Record<string, ChartSeriesConfig>;
|
|
44
|
+
interface ChartFrameProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {
|
|
45
|
+
/** The series behind the chart; drives colors, the legend and the tooltip. */
|
|
46
|
+
config: ChartConfig;
|
|
47
|
+
/** Recharts elements (one chart root, e.g. `<BarChart>`). */
|
|
48
|
+
children: ReactNode;
|
|
49
|
+
/**
|
|
50
|
+
* Fixed pixel size. Both set, the chart renders at exactly this size with
|
|
51
|
+
* no `ResizeObserver` (tests, SSR); otherwise it fills its parent's width.
|
|
52
|
+
*/
|
|
53
|
+
width?: number;
|
|
54
|
+
/** Fixed pixel height (with `width`), or the responsive height. @default aspect-driven */
|
|
55
|
+
height?: number;
|
|
56
|
+
/** Responsive width/height ratio when `height` is left out. @default 16/9 */
|
|
57
|
+
aspect?: number;
|
|
58
|
+
/** Renders a skeleton instead of the chart. @default false */
|
|
59
|
+
loading?: boolean;
|
|
60
|
+
/** Renders an error state instead of the chart. */
|
|
61
|
+
error?: ReactNode;
|
|
62
|
+
/** Renders instead of the chart when `empty`. @default the `noData` label */
|
|
63
|
+
emptyState?: ReactNode;
|
|
64
|
+
/** Marks the data empty. @default false */
|
|
65
|
+
empty?: boolean;
|
|
66
|
+
/** Accessible name of the figure. */
|
|
67
|
+
ariaLabel?: string;
|
|
68
|
+
/** String overrides for another language. */
|
|
69
|
+
labels?: Partial<ChartLabels>;
|
|
70
|
+
/** Custom format tokens the series configs may name. */
|
|
71
|
+
formats?: Parameters<typeof createFormatters>[1];
|
|
72
|
+
/** BCP 47 tag for formatted values. @default the user's locale */
|
|
73
|
+
locale?: string;
|
|
74
|
+
/** Series fields hidden by the legend (controlled; kept internally when left out). */
|
|
75
|
+
hiddenSeries?: string[];
|
|
76
|
+
/** Series fields hidden initially when uncontrolled. @default [] */
|
|
77
|
+
defaultHiddenSeries?: string[];
|
|
78
|
+
/** Reports the next hidden set on a legend interaction. */
|
|
79
|
+
onHiddenSeriesChange?: (fields: string[]) => void;
|
|
80
|
+
/** Category charts: the field legend entries cross-filter on. */
|
|
81
|
+
categoryField?: string;
|
|
82
|
+
/** Category charts: the legend entries, in palette order. */
|
|
83
|
+
categories?: {
|
|
84
|
+
value: string | number;
|
|
85
|
+
color: string;
|
|
86
|
+
}[];
|
|
87
|
+
}
|
|
88
|
+
declare const ChartFrame: react.ForwardRefExoticComponent<ChartFrameProps & react.RefAttributes<HTMLDivElement>>;
|
|
89
|
+
|
|
90
|
+
export { type ChartConfig as C, ChartFrame as a, type ChartFrameProps as b, type ChartLabels as c, type ChartSeriesConfig as d, defaultChartLabels as e, fillLabel as f };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
ChartFrame,
|
|
4
|
+
chart_frame_default
|
|
5
|
+
} from "./chunk-G4FXJJ66.js";
|
|
6
|
+
import "./chunk-7WABBHMT.js";
|
|
7
|
+
import "./chunk-3VGLTPGL.js";
|
|
8
|
+
import "./chunk-UN3XPBZ5.js";
|
|
9
|
+
import "./chunk-IPOBQIYU.js";
|
|
10
|
+
import "./chunk-7WJ26NHR.js";
|
|
11
|
+
export {
|
|
12
|
+
ChartFrame,
|
|
13
|
+
chart_frame_default as default
|
|
14
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Interactive themed legend list. Recharts' `Legend` wires it into the
|
|
5
|
+
* chart; pass `content={<ChartLegendList />}` to get real buttons: a plain
|
|
6
|
+
* click isolates the series (and restores all when it is already alone),
|
|
7
|
+
* shift-click toggles just it. On category charts (pie family) the buttons
|
|
8
|
+
* cross-filter the category value instead.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
interface LegendEntry {
|
|
12
|
+
dataKey?: unknown;
|
|
13
|
+
value?: unknown;
|
|
14
|
+
color?: string;
|
|
15
|
+
}
|
|
16
|
+
interface ChartLegendListProps {
|
|
17
|
+
/** Injected by Recharts. */
|
|
18
|
+
payload?: readonly LegendEntry[];
|
|
19
|
+
/** Extra classes on the list. */
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
/** One legend button per entry; hidden entries dim but never disappear. */
|
|
23
|
+
declare function ChartLegendList({ payload, className }: ChartLegendListProps): ReactNode;
|
|
24
|
+
|
|
25
|
+
export { ChartLegendList, type ChartLegendListProps, ChartLegendList as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
ChartLegendList,
|
|
4
|
+
chart_legend_default
|
|
5
|
+
} from "./chunk-SHQZRND7.js";
|
|
6
|
+
import "./chunk-WVWGHGZE.js";
|
|
7
|
+
import "./chunk-UN3XPBZ5.js";
|
|
8
|
+
import "./chunk-IPOBQIYU.js";
|
|
9
|
+
import "./chunk-7WJ26NHR.js";
|
|
10
|
+
export {
|
|
11
|
+
ChartLegendList,
|
|
12
|
+
chart_legend_default as default
|
|
13
|
+
};
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The serializable chart contract. Everything in a `ChartSpec` is JSON-safe —
|
|
3
|
+
* no functions, no dates, no JSX — so a spec can be stored in a database,
|
|
4
|
+
* sent by a server, or produced by a runtime chart builder. Formatting is
|
|
5
|
+
* named by token (see `format.ts`); custom formatter functions travel as
|
|
6
|
+
* React props on `<Chart>`, never inside the spec.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Names a formatter: a built-in (`'number'`, `'compact'`, `'percent'`,
|
|
10
|
+
* `'currency:USD'`, `'date:short'`, `'datetime:medium'`, `'none'`) or a
|
|
11
|
+
* custom token registered through `<Chart formats={...}>`. The part after
|
|
12
|
+
* `:` is the factory argument.
|
|
13
|
+
*/
|
|
14
|
+
type FormatToken = string;
|
|
15
|
+
/** One plotted series: a row field, and how it is drawn and labeled. */
|
|
16
|
+
interface SeriesSpec {
|
|
17
|
+
/** Row field holding this series' value. */
|
|
18
|
+
field: string;
|
|
19
|
+
/** Legend / tooltip name. @default the field */
|
|
20
|
+
label?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Palette slot 1–8 (`--chart-N`). Left out, slots are assigned in series
|
|
23
|
+
* declaration order — fixed order, never cycled.
|
|
24
|
+
*/
|
|
25
|
+
paletteSlot?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Value axis. `'secondary'` enables the secondary axis; prefer small
|
|
28
|
+
* multiples over dual axes. @default 'primary'
|
|
29
|
+
*/
|
|
30
|
+
axis?: 'primary' | 'secondary';
|
|
31
|
+
/** Series sharing a `stackId` stack; `stacked` on the spec is shorthand for one shared stack. */
|
|
32
|
+
stackId?: string;
|
|
33
|
+
/** Composed charts only: how this series is drawn. @default 'bar' */
|
|
34
|
+
mark?: 'line' | 'area' | 'bar';
|
|
35
|
+
/** Value format for tooltips and labels. @default the spec's y-axis format */
|
|
36
|
+
format?: FormatToken;
|
|
37
|
+
}
|
|
38
|
+
/** Axis options. All optional; defaults come from the themed axis prop bags. */
|
|
39
|
+
interface AxisSpec {
|
|
40
|
+
/** Axis title. */
|
|
41
|
+
label?: string;
|
|
42
|
+
/** Tick format. */
|
|
43
|
+
format?: FormatToken;
|
|
44
|
+
/** Value-axis domain. @default ['auto', 'auto'] */
|
|
45
|
+
domain?: [number | 'auto' | 'dataMin', number | 'auto' | 'dataMax'];
|
|
46
|
+
/** Suggested tick count. */
|
|
47
|
+
tickCount?: number;
|
|
48
|
+
/** Hides the axis entirely. @default false */
|
|
49
|
+
hidden?: boolean;
|
|
50
|
+
/** X axis only: the scale the x values live on. @default 'band' */
|
|
51
|
+
scale?: 'band' | 'number' | 'time' | 'log';
|
|
52
|
+
}
|
|
53
|
+
/** A horizontal or vertical reference line. */
|
|
54
|
+
interface ReferenceLineSpec {
|
|
55
|
+
/**
|
|
56
|
+
* Which axis the value belongs to: `'y'`/`'y2'` draw horizontal lines
|
|
57
|
+
* (`'y2'` positions on the secondary value axis), `'x'` vertical.
|
|
58
|
+
*/
|
|
59
|
+
axis: 'x' | 'y' | 'y2';
|
|
60
|
+
/** Position on that axis. */
|
|
61
|
+
value: number | string;
|
|
62
|
+
/** Text beside the line. */
|
|
63
|
+
label?: string;
|
|
64
|
+
/** Palette slot 1–8. @default the muted foreground */
|
|
65
|
+
paletteSlot?: number;
|
|
66
|
+
/** Dashed stroke. @default true */
|
|
67
|
+
dashed?: boolean;
|
|
68
|
+
}
|
|
69
|
+
/** Options shared by every chart type. */
|
|
70
|
+
interface ChartSpecCommon {
|
|
71
|
+
/** Contract version of this spec. */
|
|
72
|
+
version: 1;
|
|
73
|
+
/** Figure title, also the default accessible name. */
|
|
74
|
+
title?: string;
|
|
75
|
+
/** Longer description for assistive tech. */
|
|
76
|
+
description?: string;
|
|
77
|
+
/** Legend visibility/placement. @default true for two or more series, false for one */
|
|
78
|
+
legend?: boolean | {
|
|
79
|
+
placement: 'top' | 'bottom';
|
|
80
|
+
};
|
|
81
|
+
/** @default true */
|
|
82
|
+
tooltip?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* What a mark click does inside a `CrossFilterProvider`: update the shared
|
|
85
|
+
* filters, only the shared highlight, or nothing. @default 'filter'
|
|
86
|
+
*/
|
|
87
|
+
interaction?: 'filter' | 'highlight' | 'none';
|
|
88
|
+
}
|
|
89
|
+
/** The cartesian frame: axes, grid, reference lines, brush. */
|
|
90
|
+
interface CartesianFrameSpec extends ChartSpecCommon {
|
|
91
|
+
xAxis?: AxisSpec;
|
|
92
|
+
yAxis?: AxisSpec;
|
|
93
|
+
/** Secondary value axis; used by series with `axis: 'secondary'`. */
|
|
94
|
+
secondaryAxis?: AxisSpec;
|
|
95
|
+
/** Grid lines. @default horizontal only */
|
|
96
|
+
grid?: boolean | {
|
|
97
|
+
horizontal?: boolean;
|
|
98
|
+
vertical?: boolean;
|
|
99
|
+
};
|
|
100
|
+
referenceLines?: ReferenceLineSpec[];
|
|
101
|
+
/** Renders a range brush under the plot. @default false */
|
|
102
|
+
brush?: boolean;
|
|
103
|
+
}
|
|
104
|
+
/** Options shared by the series-based cartesian chart types. */
|
|
105
|
+
interface CartesianSpecCommon extends CartesianFrameSpec {
|
|
106
|
+
/** Category / x field. Also the field mark clicks cross-filter on. */
|
|
107
|
+
xKey: string;
|
|
108
|
+
/** The plotted series, in palette-slot order. */
|
|
109
|
+
series: SeriesSpec[];
|
|
110
|
+
}
|
|
111
|
+
interface LineChartSpec extends CartesianSpecCommon {
|
|
112
|
+
type: 'line';
|
|
113
|
+
/** @default 'monotone' */
|
|
114
|
+
curve?: 'linear' | 'monotone' | 'step';
|
|
115
|
+
/** Dots on every point (dots always show on hover). @default false */
|
|
116
|
+
dots?: boolean;
|
|
117
|
+
}
|
|
118
|
+
interface AreaChartSpec extends CartesianSpecCommon {
|
|
119
|
+
type: 'area';
|
|
120
|
+
/** @default 'monotone' */
|
|
121
|
+
curve?: 'linear' | 'monotone' | 'step';
|
|
122
|
+
/** `true` stacks the series; `'percent'` normalizes each stack to 100%. @default false */
|
|
123
|
+
stacked?: boolean | 'percent';
|
|
124
|
+
}
|
|
125
|
+
interface BarChartSpec extends CartesianSpecCommon {
|
|
126
|
+
type: 'bar';
|
|
127
|
+
/** Bar direction: `'horizontal'` lays categories on the y axis. @default 'vertical' */
|
|
128
|
+
orientation?: 'vertical' | 'horizontal';
|
|
129
|
+
/** `true` stacks the series; `'percent'` normalizes each stack to 100%. @default false */
|
|
130
|
+
stacked?: boolean | 'percent';
|
|
131
|
+
}
|
|
132
|
+
interface ScatterChartSpec extends CartesianFrameSpec {
|
|
133
|
+
type: 'scatter';
|
|
134
|
+
/** Row field of the x value (numeric). */
|
|
135
|
+
xKey: string;
|
|
136
|
+
/** Row field of the y value. */
|
|
137
|
+
yKey: string;
|
|
138
|
+
/**
|
|
139
|
+
* Row field that splits points into colored groups; at most 3 concurrent
|
|
140
|
+
* groups (the all-pairs-validated palette subset). Also the field mark
|
|
141
|
+
* clicks cross-filter on. Left out, all points form one series.
|
|
142
|
+
*/
|
|
143
|
+
groupKey?: string;
|
|
144
|
+
/** Row field sized into bubble area. */
|
|
145
|
+
sizeKey?: string;
|
|
146
|
+
/** Bubble size range in px². @default [64, 400] */
|
|
147
|
+
sizeRange?: [number, number];
|
|
148
|
+
}
|
|
149
|
+
interface ComposedChartSpec extends CartesianSpecCommon {
|
|
150
|
+
type: 'composed';
|
|
151
|
+
/** Stacks the bar series. @default false */
|
|
152
|
+
stacked?: boolean;
|
|
153
|
+
}
|
|
154
|
+
interface PieChartSpec extends ChartSpecCommon {
|
|
155
|
+
/** `'donut'` is a pie with an inner radius. */
|
|
156
|
+
type: 'pie' | 'donut';
|
|
157
|
+
/** Row field of the slice name; also the cross-filter field. */
|
|
158
|
+
nameKey: string;
|
|
159
|
+
/** Row field of the slice value. */
|
|
160
|
+
valueKey: string;
|
|
161
|
+
/** Value format for tooltip and labels. @default 'number' */
|
|
162
|
+
format?: FormatToken;
|
|
163
|
+
/** Direct labels beside the slices. @default false */
|
|
164
|
+
labels?: boolean;
|
|
165
|
+
}
|
|
166
|
+
interface RadarChartSpec extends ChartSpecCommon {
|
|
167
|
+
type: 'radar';
|
|
168
|
+
/** Row field of the spoke name. */
|
|
169
|
+
xKey: string;
|
|
170
|
+
/** The plotted series. */
|
|
171
|
+
series: SeriesSpec[];
|
|
172
|
+
/** Translucent fill under each outline. @default true */
|
|
173
|
+
filled?: boolean;
|
|
174
|
+
}
|
|
175
|
+
interface RadialBarChartSpec extends ChartSpecCommon {
|
|
176
|
+
type: 'radial-bar';
|
|
177
|
+
/** Row field of the ring name; also the cross-filter field. */
|
|
178
|
+
nameKey: string;
|
|
179
|
+
/** Row field of the ring value. */
|
|
180
|
+
valueKey: string;
|
|
181
|
+
/** Domain start. @default 0 */
|
|
182
|
+
min?: number;
|
|
183
|
+
/** Domain end. @default the data max */
|
|
184
|
+
max?: number;
|
|
185
|
+
/** @default 'number' */
|
|
186
|
+
format?: FormatToken;
|
|
187
|
+
}
|
|
188
|
+
interface FunnelChartSpec extends ChartSpecCommon {
|
|
189
|
+
type: 'funnel';
|
|
190
|
+
/** Row field of the stage name; also the cross-filter field. */
|
|
191
|
+
nameKey: string;
|
|
192
|
+
/** Row field of the stage value. */
|
|
193
|
+
valueKey: string;
|
|
194
|
+
/** @default 'number' */
|
|
195
|
+
format?: FormatToken;
|
|
196
|
+
}
|
|
197
|
+
interface TreemapChartSpec extends ChartSpecCommon {
|
|
198
|
+
type: 'treemap';
|
|
199
|
+
/** Row field of the tile name; also the cross-filter field. */
|
|
200
|
+
nameKey: string;
|
|
201
|
+
/** Row field sized into tile area. */
|
|
202
|
+
sizeKey: string;
|
|
203
|
+
/** Row field that groups tiles into colored clusters. */
|
|
204
|
+
groupKey?: string;
|
|
205
|
+
/** @default 'number' */
|
|
206
|
+
format?: FormatToken;
|
|
207
|
+
}
|
|
208
|
+
/** The serializable chart description `<Chart>` renders. Discriminated on `type`. */
|
|
209
|
+
type ChartSpec = LineChartSpec | AreaChartSpec | BarChartSpec | ScatterChartSpec | ComposedChartSpec | PieChartSpec | RadarChartSpec | RadialBarChartSpec | FunnelChartSpec | TreemapChartSpec;
|
|
210
|
+
/** A row of chart data. Values are read through the spec's row fields. */
|
|
211
|
+
type ChartRow = Record<string, unknown>;
|
|
212
|
+
/** What a mark click reports, whether or not a `CrossFilterProvider` is present. */
|
|
213
|
+
interface ChartMarkEvent {
|
|
214
|
+
/** The field the clicked mark belongs to (the spec's `xKey` / `nameKey`). */
|
|
215
|
+
field: string;
|
|
216
|
+
/** The clicked mark's category value. */
|
|
217
|
+
value: string | number;
|
|
218
|
+
/** The clicked series' field, when the mark belongs to one. */
|
|
219
|
+
seriesField?: string;
|
|
220
|
+
/** The full row behind the mark. */
|
|
221
|
+
row: ChartRow;
|
|
222
|
+
/** Whether the click asked for additive (shift-click) filtering. */
|
|
223
|
+
additive: boolean;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export type { AreaChartSpec as A, BarChartSpec as B, CartesianFrameSpec as C, FormatToken as F, LineChartSpec as L, PieChartSpec as P, RadarChartSpec as R, ScatterChartSpec as S, TreemapChartSpec as T, AxisSpec as a, CartesianSpecCommon as b, ChartMarkEvent as c, ChartRow as d, ChartSpec as e, ChartSpecCommon as f, ComposedChartSpec as g, FunnelChartSpec as h, RadialBarChartSpec as i, ReferenceLineSpec as j, SeriesSpec as k };
|