@acronis-platform/ui-react 2.0.0 → 4.0.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/dist/components/ui/accordion-container/accordion-container.js +144 -0
- package/dist/components/ui/accordion-container/accordion-container.js.map +1 -0
- package/dist/components/ui/app-shell-chat/app-shell-chat.js.map +1 -1
- package/dist/components/ui/area-chart/area-chart.js +141 -139
- package/dist/components/ui/area-chart/area-chart.js.map +1 -1
- package/dist/components/ui/avatar/avatar.js +33 -22
- package/dist/components/ui/avatar/avatar.js.map +1 -1
- package/dist/components/ui/bar-chart/bar-chart.js +295 -293
- package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
- package/dist/components/ui/card/card.js +150 -74
- package/dist/components/ui/card/card.js.map +1 -1
- package/dist/components/ui/card-section/card-section.js +111 -0
- package/dist/components/ui/card-section/card-section.js.map +1 -0
- package/dist/components/ui/category-bar/category-bar.js +109 -93
- package/dist/components/ui/category-bar/category-bar.js.map +1 -1
- package/dist/components/ui/chart/chart-palette.js +113 -0
- package/dist/components/ui/chart/chart-palette.js.map +1 -0
- package/dist/components/ui/chart/chart.js +176 -129
- package/dist/components/ui/chart/chart.js.map +1 -1
- package/dist/components/ui/chart-state/chart-state-illustrations.js +310 -0
- package/dist/components/ui/chart-state/chart-state-illustrations.js.map +1 -0
- package/dist/components/ui/chart-state/chart-state.js +48 -34
- package/dist/components/ui/chart-state/chart-state.js.map +1 -1
- package/dist/components/ui/chart-widget/chart-widget.js +87 -0
- package/dist/components/ui/chart-widget/chart-widget.js.map +1 -0
- package/dist/components/ui/composed-chart/composed-chart.js +117 -115
- package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
- package/dist/components/ui/confidence-cone/confidence-cone.js +166 -158
- package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
- package/dist/components/ui/data-table/data-table.js +4 -2
- package/dist/components/ui/data-table/data-table.js.map +1 -1
- package/dist/components/ui/empty-overlay/empty-overlay.js +49 -0
- package/dist/components/ui/empty-overlay/empty-overlay.js.map +1 -0
- package/dist/components/ui/funnel-chart/funnel-chart.js +162 -161
- package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
- package/dist/components/ui/histogram/histogram.js +94 -92
- package/dist/components/ui/histogram/histogram.js.map +1 -1
- package/dist/components/ui/input/input.js.map +1 -1
- package/dist/components/ui/label/label.js +2 -9
- package/dist/components/ui/label/label.js.map +1 -1
- package/dist/components/ui/line-chart/line-chart.js +143 -141
- package/dist/components/ui/line-chart/line-chart.js.map +1 -1
- package/dist/components/ui/metric/metric.js +74 -185
- package/dist/components/ui/metric/metric.js.map +1 -1
- package/dist/components/ui/page-content/page-content.js.map +1 -1
- package/dist/components/ui/pie-chart/pie-chart.js +201 -195
- package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
- package/dist/components/ui/radar-chart/radar-chart.js +133 -131
- package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +297 -265
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
- package/dist/components/ui/sankey-chart/sankey-chart.js +123 -101
- package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -1
- package/dist/components/ui/scatter-chart/scatter-chart.js +76 -74
- package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
- package/dist/components/ui/section/section.js +157 -31
- package/dist/components/ui/section/section.js.map +1 -1
- package/dist/components/ui/stepper/stepper.js +24 -24
- package/dist/components/ui/stepper/stepper.js.map +1 -1
- package/dist/components/ui/stepper-item/stepper-item.js +43 -24
- package/dist/components/ui/stepper-item/stepper-item.js.map +1 -1
- package/dist/components/ui/table/table.js +27 -27
- package/dist/components/ui/table/table.js.map +1 -1
- package/dist/components/ui/treemap/treemap.js +133 -124
- package/dist/components/ui/treemap/treemap.js.map +1 -1
- package/dist/components/ui/trend-indicator/trend-indicator.js +34 -69
- package/dist/components/ui/trend-indicator/trend-indicator.js.map +1 -1
- package/dist/components/ui/wizard/wizard.js +59 -0
- package/dist/components/ui/wizard/wizard.js.map +1 -0
- package/dist/hooks/use-wizard.js +75 -0
- package/dist/hooks/use-wizard.js.map +1 -0
- package/dist/index.js +540 -525
- package/dist/index.js.map +1 -1
- package/dist/llms/accordion-container.md +181 -0
- package/dist/llms/accordion.md +124 -0
- package/dist/llms/alert.md +225 -0
- package/dist/llms/app-shell-chat.md +415 -0
- package/dist/llms/area-chart.md +355 -0
- package/dist/llms/avatar.md +208 -0
- package/dist/llms/bar-chart.md +406 -0
- package/dist/llms/breadcrumb.md +326 -0
- package/dist/llms/button-group.md +298 -0
- package/dist/llms/button-icon-input.md +142 -0
- package/dist/llms/button-icon-menu.md +209 -0
- package/dist/llms/button-icon.md +128 -0
- package/dist/llms/button-menu.md +172 -0
- package/dist/llms/button.md +185 -0
- package/dist/llms/calendar-panel.md +733 -0
- package/dist/llms/calendar.md +188 -0
- package/dist/llms/card-filter.md +214 -0
- package/dist/llms/card-section.md +293 -0
- package/dist/llms/card.md +447 -0
- package/dist/llms/carousel-dialog.md +156 -0
- package/dist/llms/category-bar.md +193 -0
- package/dist/llms/chart-state.md +190 -0
- package/dist/llms/chart-widget.md +209 -0
- package/dist/llms/chart.md +182 -0
- package/dist/llms/checkbox.md +257 -0
- package/dist/llms/chip.md +195 -0
- package/dist/llms/combobox.md +164 -0
- package/dist/llms/composed-chart.md +508 -0
- package/dist/llms/confidence-cone.md +277 -0
- package/dist/llms/data-table.md +474 -0
- package/dist/llms/date-range-picker.md +272 -0
- package/dist/llms/description-list.md +131 -0
- package/dist/llms/dialog-footer-carousel.md +147 -0
- package/dist/llms/dialog-footer-default.md +142 -0
- package/dist/llms/dialog-root.md +246 -0
- package/dist/llms/dialog-welcome.md +223 -0
- package/dist/llms/dialog.md +403 -0
- package/dist/llms/dropdown-menu.md +193 -0
- package/dist/llms/empty-overlay.md +146 -0
- package/dist/llms/empty.md +156 -0
- package/dist/llms/field.md +185 -0
- package/dist/llms/filter-cards.md +157 -0
- package/dist/llms/filter-chips.md +323 -0
- package/dist/llms/filter-search.md +512 -0
- package/dist/llms/form.md +154 -0
- package/dist/llms/funnel-chart.md +333 -0
- package/dist/llms/grid.md +80 -0
- package/dist/llms/histogram.md +190 -0
- package/dist/llms/input-date-picker.md +203 -0
- package/dist/llms/input-otp.md +173 -0
- package/dist/llms/input-password.md +197 -0
- package/dist/llms/input-search.md +170 -0
- package/dist/llms/input-select.md +278 -0
- package/dist/llms/input-text-area.md +271 -0
- package/dist/llms/input-text.md +192 -0
- package/dist/llms/line-chart.md +369 -0
- package/dist/llms/link.md +209 -0
- package/dist/llms/loading.md +130 -0
- package/dist/llms/meter.md +177 -0
- package/dist/llms/metric.md +204 -0
- package/dist/llms/number-field.md +122 -0
- package/dist/llms/page-content.md +69 -0
- package/dist/llms/page-header.md +182 -0
- package/dist/llms/pagination.md +133 -0
- package/dist/llms/pie-chart.md +307 -0
- package/dist/llms/popover.md +252 -0
- package/dist/llms/progress-circle.md +126 -0
- package/dist/llms/progress.md +111 -0
- package/dist/llms/radar-chart.md +316 -0
- package/dist/llms/radial-bar-chart.md +319 -0
- package/dist/llms/radio.md +255 -0
- package/dist/llms/resizable.md +195 -0
- package/dist/llms/sankey-chart.md +208 -0
- package/dist/llms/scatter-chart.md +239 -0
- package/dist/llms/scroll-area.md +183 -0
- package/dist/llms/section.md +401 -0
- package/dist/llms/select.md +210 -0
- package/dist/llms/separator.md +87 -0
- package/dist/llms/sheet.md +202 -0
- package/dist/llms/sidebar-primary.md +360 -0
- package/dist/llms/sidebar-secondary.md +417 -0
- package/dist/llms/skeleton.md +81 -0
- package/dist/llms/slider.md +97 -0
- package/dist/llms/spinner.md +100 -0
- package/dist/llms/stack.md +80 -0
- package/dist/llms/stepper-item.md +309 -0
- package/dist/llms/stepper.md +251 -0
- package/dist/llms/switch.md +140 -0
- package/dist/llms/table.md +436 -0
- package/dist/llms/tabs.md +197 -0
- package/dist/llms/tag.md +139 -0
- package/dist/llms/timeline.md +361 -0
- package/dist/llms/timer.md +259 -0
- package/dist/llms/toast.md +241 -0
- package/dist/llms/toggle-group.md +121 -0
- package/dist/llms/toolbar.md +453 -0
- package/dist/llms/tooltip.md +164 -0
- package/dist/llms/treemap.md +254 -0
- package/dist/llms/trend-indicator.md +132 -0
- package/dist/llms/widget-placeholder.md +169 -0
- package/dist/llms/wizard.md +412 -0
- package/dist/llms.txt +142 -0
- package/dist/react.js +540 -525
- package/dist/react.js.map +1 -1
- package/dist/src/components/ui/accordion-container/accordion-container.d.ts +44 -0
- package/dist/src/components/ui/accordion-container/index.d.ts +1 -0
- package/dist/src/components/ui/area-chart/area-chart.d.ts +9 -4
- package/dist/src/components/ui/avatar/avatar.d.ts +27 -8
- package/dist/src/components/ui/bar-chart/bar-chart.d.ts +9 -4
- package/dist/src/components/ui/button/button.d.ts +1 -1
- package/dist/src/components/ui/card/card.d.ts +69 -8
- package/dist/src/components/ui/card/index.d.ts +1 -1
- package/dist/src/components/ui/card-section/card-section.d.ts +50 -0
- package/dist/src/components/ui/card-section/index.d.ts +1 -0
- package/dist/src/components/ui/category-bar/category-bar.d.ts +10 -4
- package/dist/src/components/ui/chart/__stories__/palette-control.d.ts +48 -0
- package/dist/src/components/ui/chart/__tests__/chart-palette.test.d.ts +1 -0
- package/dist/src/components/ui/chart/chart-palette.d.ts +128 -0
- package/dist/src/components/ui/chart/chart.d.ts +66 -15
- package/dist/src/components/ui/chart/index.d.ts +4 -2
- package/dist/src/components/ui/chart-state/chart-state-illustrations.d.ts +6 -0
- package/dist/src/components/ui/chart-state/chart-state.d.ts +13 -2
- package/dist/src/components/ui/chart-state/index.d.ts +1 -0
- package/dist/src/components/ui/chart-widget/chart-widget.d.ts +64 -0
- package/dist/src/components/ui/chart-widget/index.d.ts +1 -0
- package/dist/src/components/ui/composed-chart/composed-chart.d.ts +12 -7
- package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +10 -5
- package/dist/src/components/ui/dialog/dialog.d.ts +1 -1
- package/dist/src/components/ui/empty-overlay/empty-overlay.d.ts +20 -0
- package/dist/src/components/ui/empty-overlay/index.d.ts +2 -0
- package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +11 -5
- package/dist/src/components/ui/grid/grid.d.ts +1 -1
- package/dist/src/components/ui/histogram/histogram.d.ts +10 -4
- package/dist/src/components/ui/label/index.d.ts +1 -1
- package/dist/src/components/ui/label/label.d.ts +1 -5
- package/dist/src/components/ui/line-chart/line-chart.d.ts +9 -4
- package/dist/src/components/ui/metric/metric.d.ts +13 -14
- package/dist/src/components/ui/pie-chart/pie-chart.d.ts +17 -8
- package/dist/src/components/ui/radar-chart/radar-chart.d.ts +10 -5
- package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +17 -6
- package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +10 -5
- package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +10 -5
- package/dist/src/components/ui/section/index.d.ts +1 -1
- package/dist/src/components/ui/section/section.d.ts +75 -6
- package/dist/src/components/ui/sheet/sheet.d.ts +1 -1
- package/dist/src/components/ui/stack/stack.d.ts +1 -1
- package/dist/src/components/ui/stepper-item/stepper-item.d.ts +6 -5
- package/dist/src/components/ui/tag/tag.d.ts +1 -1
- package/dist/src/components/ui/treemap/treemap.d.ts +11 -5
- package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +3 -7
- package/dist/src/components/ui/wizard/index.d.ts +1 -0
- package/dist/src/components/ui/wizard/wizard.d.ts +6 -0
- package/dist/src/hooks/index.d.ts +1 -0
- package/dist/src/hooks/use-wizard.d.ts +80 -0
- package/dist/src/index.d.ts +5 -3
- package/dist/ui-react.css +1 -1
- package/package.json +12 -6
- package/dist/components/ui/app-shell/app-shell.js +0 -75
- package/dist/components/ui/app-shell/app-shell.js.map +0 -1
- package/dist/components/ui/auth-layout/auth-layout.js +0 -56
- package/dist/components/ui/auth-layout/auth-layout.js.map +0 -1
- package/dist/components/ui/collapsible/collapsible.js +0 -22
- package/dist/components/ui/collapsible/collapsible.js.map +0 -1
- package/dist/src/components/ui/app-shell/app-shell.d.ts +0 -8
- package/dist/src/components/ui/app-shell/index.d.ts +0 -1
- package/dist/src/components/ui/auth-layout/auth-layout.d.ts +0 -6
- package/dist/src/components/ui/auth-layout/index.d.ts +0 -1
- package/dist/src/components/ui/collapsible/collapsible.d.ts +0 -5
- package/dist/src/components/ui/collapsible/index.d.ts +0 -1
- package/dist/src/components/ui/label/label.docs.d.ts +0 -10
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# FunnelChart
|
|
2
|
+
|
|
3
|
+
> A typed funnel-chart composition over the shared `Chart` primitives. Plots a single series of stages (rows) as stacked, narrowing segments inside a `ChartContainer`, with a tooltip and on-chart stage labels (no legend — the inline labels name every stage). One variant axis: `lastShape` (the funnel narrows to a `triangle` point or ends `rectangle` flat). Ported from the apps/demo `FunnelChartPlayground`.
|
|
4
|
+
|
|
5
|
+
**Status:** draft · **Category:** data-display · **Since:** v0.58.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { FunnelChart } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<FunnelChart
|
|
17
|
+
config={config}
|
|
18
|
+
data={data}
|
|
19
|
+
dataKey="value"
|
|
20
|
+
nameKey="stage"
|
|
21
|
+
lastShape="triangle"
|
|
22
|
+
className="h-[380px] w-[460px]"
|
|
23
|
+
/>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
A typed funnel-chart built on the shared `Chart` primitives. Give it `data`, a
|
|
27
|
+
per-stage `config`, the value field (`dataKey`), and the label field (`nameKey`);
|
|
28
|
+
it renders a themed recharts `FunnelChart` — on-chart stage labels and a tooltip
|
|
29
|
+
included — so you don't hand-compose recharts children. (There's no legend: the
|
|
30
|
+
inline labels already name every stage.)
|
|
31
|
+
|
|
32
|
+
Stage colors come from the `palette` prop — a dataviz palette resolving to the
|
|
33
|
+
`--ui-dataviz-*` tokens — not from `config`. Stages are an ordered progression,
|
|
34
|
+
so `{ type: 'sequential', ramp }` usually reads better than the default
|
|
35
|
+
`categorical`.
|
|
36
|
+
|
|
37
|
+
> **Design-pending v1.** Ported from the apps/demo `FunnelChartPlayground`. The
|
|
38
|
+
> chrome is reconciled with Figma later; Code Connect is deferred.
|
|
39
|
+
|
|
40
|
+
## When to use
|
|
41
|
+
|
|
42
|
+
- Showing progression (and drop-off) through the ordered stages of a process —
|
|
43
|
+
a conversion funnel, a recruitment pipeline, an onboarding flow.
|
|
44
|
+
- A handful of monotonically decreasing stages read best.
|
|
45
|
+
|
|
46
|
+
## When not to use
|
|
47
|
+
|
|
48
|
+
- Unordered categories or part-to-whole of a single total — use a pie/donut or
|
|
49
|
+
bar chart.
|
|
50
|
+
- A trend over time — use a line or area chart.
|
|
51
|
+
- Values that don't decrease stage to stage — the funnel metaphor misleads.
|
|
52
|
+
|
|
53
|
+
## Variants
|
|
54
|
+
|
|
55
|
+
| Axis | Values | Effect |
|
|
56
|
+
| ----------- | ------------------------ | ---------------------------------------------- |
|
|
57
|
+
| `lastShape` | `triangle` · `rectangle` | Final segment narrows to a point vs ends flat. |
|
|
58
|
+
|
|
59
|
+
## Example
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import { FunnelChart } from '@acronis-platform/ui-react';
|
|
63
|
+
import type { ChartConfig } from '@acronis-platform/ui-react';
|
|
64
|
+
|
|
65
|
+
const data = [
|
|
66
|
+
{ stage: 'Visits', value: 5000 },
|
|
67
|
+
{ stage: 'Signups', value: 2600 },
|
|
68
|
+
{ stage: 'Trials', value: 1400 },
|
|
69
|
+
{ stage: 'Purchases', value: 620 },
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
const config = {
|
|
73
|
+
Visits: { label: 'Visits', color: 'var(--ui-background-brand-secondary)' },
|
|
74
|
+
Signups: {
|
|
75
|
+
label: 'Signups',
|
|
76
|
+
color: 'var(--ui-background-status-strong-success)',
|
|
77
|
+
},
|
|
78
|
+
Trials: {
|
|
79
|
+
label: 'Trials',
|
|
80
|
+
color: 'var(--ui-background-status-strong-warning)',
|
|
81
|
+
},
|
|
82
|
+
Purchases: {
|
|
83
|
+
label: 'Purchases',
|
|
84
|
+
color: 'var(--ui-background-status-strong-danger)',
|
|
85
|
+
},
|
|
86
|
+
} satisfies ChartConfig;
|
|
87
|
+
|
|
88
|
+
<FunnelChart
|
|
89
|
+
config={config}
|
|
90
|
+
data={data}
|
|
91
|
+
dataKey="value"
|
|
92
|
+
nameKey="stage"
|
|
93
|
+
className="h-[380px] w-[460px]"
|
|
94
|
+
/>;
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Stage colors reference existing semantic `--ui-*` tokens, keyed by each stage's
|
|
98
|
+
`nameKey` value. `--ui-background-status-strong-*` is chromatic in every brand;
|
|
99
|
+
`--ui-background-brand-secondary` is brand-dependent (blue in `default`, neutral
|
|
100
|
+
in some white-label brands), so it is not color-stable across brands until the
|
|
101
|
+
real data-viz palette lands.
|
|
102
|
+
|
|
103
|
+
## Props
|
|
104
|
+
|
|
105
|
+
| Prop | Type | Default | Required | Description |
|
|
106
|
+
|------|------|---------|----------|-------------|
|
|
107
|
+
| `lastShape` | `'triangle' | 'rectangle'` | `'triangle'` | no | How the funnel ends. `triangle` narrows the final segment to a point; `rectangle` ends it flat (a stack of trapezoids). |
|
|
108
|
+
| `data` | `ReadonlyArray<Record<string, string | number>>` | — | yes | Row-per-stage data — each row holds a `nameKey` label and a `dataKey` numeric value. |
|
|
109
|
+
| `config` | `ChartConfig` | — | yes | Stages take their colour from the container's `palette`; each entry, keyed by the stage's `nameKey` value, maps that stage to a `label` and an optional `tone`. Resolved into the `--color-<name>` custom properties the segments fill from. |
|
|
110
|
+
| `dataKey` | `string` | — | yes | The numeric field that sizes each stage. |
|
|
111
|
+
| `nameKey` | `string` | — | yes | The label field that names each stage (drives the tooltip, on-chart labels, and the `--color-<name>` lookup). Values should be unique per chart — stages sharing a name share one config/color entry. |
|
|
112
|
+
| `reversed` | `boolean` | `false` | no | Flip the funnel so it widens toward the bottom instead of narrowing. |
|
|
113
|
+
| `showLabels` | `boolean` | `true` | no | Render a label for each stage — see labelFormat and labelPosition. |
|
|
114
|
+
| `labelFormat` | `'name' | 'value' | 'percent' | 'name-value' | 'name-percent' | 'value-percent'` | `'name'` | no | What each stage's label says. A percentage is the stage's share of the widest stage — its conversion from the top of the funnel, not a share of the sum, because a funnel's stages are nested subsets rather than parts of a whole. The value is formatted by labelFormatter and the share by percentFormatter. A composite format (a pair) narrows the funnel to leave itself room, unless funnelWidth says otherwise. |
|
|
115
|
+
| `labelPosition` | `'right' | 'left' | 'inside'` | `'right'` | no | Where each stage's label sits. `right`/`left` place it beside the segment on the chart surface; `inside` centres it on the segment, which switches the label to the on-fill color so it keeps contrast over a saturated fill. `inside` only works while every stage is wide enough to hold the text — a funnel narrows, so its last stages often are not; keep the text short there (`percent`) or leave the labels beside the funnel. |
|
|
116
|
+
| `showValueLabels` | `boolean` | `false` | no | Render a second label carrying the stage's value, so the name and the number can sit on opposite sides of the funnel. |
|
|
117
|
+
| `valuePosition` | `'right' | 'left' | 'inside'` | `the side opposite labelPosition` | no | Where the value label sits. Defaults to the side opposite labelPosition, where every stage has room — so it follows the names rather than pinning itself to one edge, which would overprint them when the names move. See labelPosition before choosing inside. |
|
|
118
|
+
| `labelFill` | `string` | — | no | Color for both label lists, overriding the contrast-matched default. Pass a --ui-* token; only needed when the default doesn't work on the surface. |
|
|
119
|
+
| `labelFormatter` | `(value: number | string, index?: number) => string` | — | no | Format the numeric part of a label. |
|
|
120
|
+
| `percentFormatter` | `(value: number | string, index?: number) => string` | — | no | Format the conversion share behind the percent formats. Receives the share as a fraction (0.52); defaults to a one-decimal bare percentage ("52.0%"). Replace it for a locale that doesn't write a bare percent sign. |
|
|
121
|
+
| `showLegend` | `boolean` | `false` | no | Render the legend — one entry per visible stage. Off by default because a funnel labels its stages on the chart. |
|
|
122
|
+
| `legendPos` | `'top' | 'bottom'` | `'bottom'` | no | Which edge the legend sits on. |
|
|
123
|
+
| `colorMode` | `'palette' | 'gradient'` | `'palette'` | no | How the stages are colored. `palette` gives each stage its own config color; `gradient` ramps one hue from the widest stage down to the narrowest, mixing it toward the surface so every segment stays opaque. |
|
|
124
|
+
| `gradientColor` | `string` | — | no | The hue gradient mode ramps. Defaults to the first visible stage's own color — including a stageSettings color set on it, since that is what the stage actually paints with. Ignored when colorMode is palette. |
|
|
125
|
+
| `stageSettings` | `Record<string, { color?: string; hidden?: boolean }>` | — | no | Per-stage overrides keyed by the stage's nameKey value. `color` wins over both config and colorMode; `hidden` drops the stage from the funnel, its labels, the legend, and the conversion percentages. |
|
|
126
|
+
| `showActiveShape` | `boolean` | `false` | no | Outline the hovered segment, rather than changing its fill, so it keeps the color that ties it to its legend entry and label. |
|
|
127
|
+
| `stroke` | `string` | — | no | Segment border color — reference an existing --ui-* token. Defaults to the border token when strokeWidth is set on its own, because the renderer's own default is a hardcoded white the container neutralizes. |
|
|
128
|
+
| `strokeWidth` | `number` | — | no | Segment border width, in px. Implies a default stroke when given alone. |
|
|
129
|
+
| `funnelWidth` | `number | string` | — | no | Funnel width — px, or a percentage of the plot area ('70%'). Defaults to the full plot area, except that a composite labelFormat beside the funnel narrows it: the renderer word-wraps a label against the gap between its segment and the plot-area edge, so narrowing the funnel is what creates label room. A margin cannot — it moves that edge inward with the funnel. |
|
|
130
|
+
| `margin` | `{ top?: number; right?: number; bottom?: number; left?: number }` | — | no | Plot-area margin, in px, merged over the defaults per side so passing one side keeps the others. It reserves the side a label list sits on so unwrappable text isn't clipped at the SVG edge — see funnelWidth for the label's wrap room. |
|
|
131
|
+
| `showTooltip` | `boolean` | `true` | no | Render the hover tooltip. |
|
|
132
|
+
| `tooltipContent` | `ReactElement | ((props) => ReactNode)` | — | no | Replace the default tooltip. Pass a configured ChartTooltipContent (from this library) — e.g. with a formatter / labelFormatter — to customize the tooltip content without composing recharts. Ignored when showTooltip is false. |
|
|
133
|
+
| `animate` | `boolean` | `false` | no | Enable entrance animation. Off by default so output/baselines are unchanged. |
|
|
134
|
+
| `animationDuration` | `number` | — | no | Animation duration in ms. |
|
|
135
|
+
| `animationBegin` | `number` | — | no | Delay before the animation starts, in ms. |
|
|
136
|
+
| `animationEasing` | `'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'linear'` | — | no | Easing curve. |
|
|
137
|
+
|
|
138
|
+
## Behavior
|
|
139
|
+
|
|
140
|
+
`FunnelChart` is a typed [recharts](https://recharts.org) composition over the
|
|
141
|
+
shared `Chart` primitives. It plots a single series of stages (`data` rows) as
|
|
142
|
+
stacked, narrowing segments inside a `ChartContainer`.
|
|
143
|
+
|
|
144
|
+
```gherkin
|
|
145
|
+
Scenario: Render stages from data and config
|
|
146
|
+
Given data rows and a config mapping each stage name to a label and color
|
|
147
|
+
And dataKey "value" and nameKey "stage"
|
|
148
|
+
Then one segment renders per row, sized by its dataKey value
|
|
149
|
+
And each segment fills from its injected --color-<name> custom property
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```gherkin
|
|
153
|
+
Scenario: Triangle last shape (default)
|
|
154
|
+
Given lastShape is "triangle"
|
|
155
|
+
Then the final segment narrows to a point
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```gherkin
|
|
159
|
+
Scenario: Rectangle last shape
|
|
160
|
+
Given lastShape is "rectangle"
|
|
161
|
+
Then the final segment ends flat (a stack of trapezoids)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
```gherkin
|
|
165
|
+
Scenario: Reversed
|
|
166
|
+
Given reversed is true
|
|
167
|
+
Then the funnel widens toward the bottom instead of narrowing
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
```gherkin
|
|
171
|
+
Scenario: Stage labels
|
|
172
|
+
Given showLabels is true
|
|
173
|
+
Then each stage's name renders beside its segment
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
```gherkin
|
|
177
|
+
Scenario: Label format
|
|
178
|
+
Given showLabels is true
|
|
179
|
+
And labelFormat is "name-percent"
|
|
180
|
+
Then each label pairs the stage's name with its conversion from the widest stage
|
|
181
|
+
And the widest stage reads 100.0%, whatever order the stages arrive in
|
|
182
|
+
And the share is formatted by percentFormatter, so a locale that doesn't write a
|
|
183
|
+
bare percent sign can replace it
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```gherkin
|
|
187
|
+
Scenario: Label position drives the label color
|
|
188
|
+
Given labelPosition is "inside"
|
|
189
|
+
Then each label is centred on its segment
|
|
190
|
+
And it uses the on-fill color, which holds its contrast over a saturated fill
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```gherkin
|
|
194
|
+
Scenario: An on-segment label needs a segment wide enough to hold it
|
|
195
|
+
Given labelPosition is "inside"
|
|
196
|
+
And a stage too narrow for its label text
|
|
197
|
+
Then the text runs past that segment onto the surface, where the on-fill color
|
|
198
|
+
has nothing to sit on
|
|
199
|
+
And the readable options are a short labelFormat or a position beside the funnel
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
```gherkin
|
|
203
|
+
Scenario: Separate value labels
|
|
204
|
+
Given showValueLabels is true
|
|
205
|
+
Then each stage carries its name on one side of the funnel and its value on the
|
|
206
|
+
other — the values default to the side opposite the names
|
|
207
|
+
And both read against the surface, so the narrow tail stages stay legible
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
```gherkin
|
|
211
|
+
Scenario: The value labels follow the names to the other side
|
|
212
|
+
Given showValueLabels is true
|
|
213
|
+
And labelPosition is "left"
|
|
214
|
+
And no valuePosition is given
|
|
215
|
+
Then the values render to the right of the funnel, not on top of the names
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
```gherkin
|
|
219
|
+
Scenario: A composite label gets room by narrowing the funnel
|
|
220
|
+
Given showLabels is true
|
|
221
|
+
And labelFormat is a pair, sitting to the right of the funnel
|
|
222
|
+
And no funnelWidth is given
|
|
223
|
+
Then the funnel is narrowed within the plot area so the label has room to wrap
|
|
224
|
+
into, because a label wraps against the gap between its segment and the plot
|
|
225
|
+
area's edge — an inset moves that edge inward with the funnel and so gives it
|
|
226
|
+
less room, not more
|
|
227
|
+
And a caller-supplied funnelWidth replaces the reserve
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
```gherkin
|
|
231
|
+
Scenario: A partial margin keeps the other sides
|
|
232
|
+
Given a margin that sets only one side
|
|
233
|
+
Then the remaining sides keep their default insets rather than collapsing to zero
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```gherkin
|
|
237
|
+
Scenario: Legend is opt-in
|
|
238
|
+
Given showLegend is unset
|
|
239
|
+
Then no legend renders
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
```gherkin
|
|
243
|
+
Scenario: Legend entries come from the visible stages
|
|
244
|
+
Given showLegend is true
|
|
245
|
+
Then one entry renders per distinct visible stage name, labelled and colored
|
|
246
|
+
from config
|
|
247
|
+
And two stages sharing a name share the single entry they share a color with
|
|
248
|
+
And it sits on the edge given by legendPos (bottom by default)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
```gherkin
|
|
252
|
+
Scenario: Gradient color mode
|
|
253
|
+
Given colorMode is "gradient"
|
|
254
|
+
Then every stage fills from one hue — gradientColor, or the first visible stage's
|
|
255
|
+
own color, including a stageSettings color set on it
|
|
256
|
+
And the hue is mixed further toward the surface at each stage down the funnel
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
```gherkin
|
|
260
|
+
Scenario: Per-stage color override
|
|
261
|
+
Given a stageSettings entry keyed by a stage's nameKey value carries a color
|
|
262
|
+
Then that stage fills with it, whatever config and colorMode say
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
```gherkin
|
|
266
|
+
Scenario: Hidden stage
|
|
267
|
+
Given a stageSettings entry hides its stage
|
|
268
|
+
Then the stage has no segment, no label and no legend entry
|
|
269
|
+
And the remaining conversions are measured over the visible stages only
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
```gherkin
|
|
273
|
+
Scenario: Active segment
|
|
274
|
+
Given showActiveShape is true
|
|
275
|
+
When the user hovers a stage
|
|
276
|
+
Then that segment is outlined and keeps its fill
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
```gherkin
|
|
280
|
+
Scenario: Tooltip on hover
|
|
281
|
+
Given showTooltip is true
|
|
282
|
+
When the user hovers a stage
|
|
283
|
+
Then a card shows that stage's name and value
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
```gherkin
|
|
287
|
+
Scenario: Empty data
|
|
288
|
+
Given data is an empty array
|
|
289
|
+
Then the chart renders with no segments and does not throw
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
```gherkin
|
|
293
|
+
Scenario: Entrance animation is opt-in
|
|
294
|
+
Given animate is unset
|
|
295
|
+
Then the series render at their final geometry with no entrance animation
|
|
296
|
+
And the committed visual baselines are unaffected
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
```gherkin
|
|
300
|
+
Scenario: Reduced motion
|
|
301
|
+
Given animate is true
|
|
302
|
+
And a user with prefers-reduced-motion
|
|
303
|
+
Then the entrance animation does not play and the series render at their final geometry
|
|
304
|
+
And the same applies when rendering on the server
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Accessibility
|
|
308
|
+
|
|
309
|
+
- recharts' `accessibilityLayer` is **on by default** (recharts v3), giving the
|
|
310
|
+
chart keyboard focus and an accessible description of the plotted stages.
|
|
311
|
+
- A funnel chart is inherently visual. **Pair it with a text alternative** — a
|
|
312
|
+
caption, a summary sentence, or an adjacent data table carrying the same
|
|
313
|
+
numbers (including the drop-off between stages, which the funnel only implies) —
|
|
314
|
+
and give the chart an accessible name (`aria-label` / `aria-labelledby`
|
|
315
|
+
referencing a visible heading). The wrapper forwards native `div` attributes,
|
|
316
|
+
so `aria-*` pass through.
|
|
317
|
+
- Do **not** rely on color alone to distinguish stages. Keep `showLabels` (or the
|
|
318
|
+
tooltip) visible so each color is paired with a text label — the on-chart labels
|
|
319
|
+
are the funnel's naming channel (there is no legend).
|
|
320
|
+
- The tooltip chrome resolves to semantic `--ui-*` tokens, and on-chart labels use
|
|
321
|
+
the foreground text token — both meet contrast in light and dark.
|
|
322
|
+
**Stage colors are caller-supplied** via `config` — pick values that meet 3:1
|
|
323
|
+
against the surface and are distinguishable for color-vision deficiencies. The
|
|
324
|
+
borrowed semantic tokens are a design-pending stopgap until the `--ui-chart-*`
|
|
325
|
+
palette lands.
|
|
326
|
+
- Watch recharts issue [#4809](https://github.com/recharts/recharts/issues/4809)
|
|
327
|
+
on the a11y layer for heavily-customized charts.
|
|
328
|
+
|
|
329
|
+
## Contrast
|
|
330
|
+
|
|
331
|
+
Chart chrome and the on-chart stage labels meet contrast in both themes via the
|
|
332
|
+
semantic tokens. Segment fills come from `config` and are the caller's
|
|
333
|
+
responsibility — keep adjacent segments distinguishable from each other.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Grid
|
|
2
|
+
|
|
3
|
+
> A responsive CSS-grid layout primitive — lay children into a column count that steps down at smaller breakpoints, with a configurable gap. Ported 1:1 from the legacy shadcn-uikit `grid`.
|
|
4
|
+
|
|
5
|
+
**Status:** draft · **Category:** layout · **Since:** v0.51.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Grid } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<Grid cols={4} gap="lg">{cells}</Grid>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
A responsive CSS-grid layout primitive — lay children into a column count that
|
|
20
|
+
steps down at smaller breakpoints, with a configurable gap.
|
|
21
|
+
|
|
22
|
+
> Design-pending v1, ported 1:1 from the legacy shadcn-uikit `grid`.
|
|
23
|
+
|
|
24
|
+
## When to use
|
|
25
|
+
|
|
26
|
+
- Card galleries, dashboards, and other two-dimensional layouts.
|
|
27
|
+
|
|
28
|
+
## When not to use
|
|
29
|
+
|
|
30
|
+
- One-dimensional rows/columns — use `Stack`.
|
|
31
|
+
- Tabular data — use `Table` / `DataTable`.
|
|
32
|
+
|
|
33
|
+
## Parts
|
|
34
|
+
|
|
35
|
+
`Grid` is a single component.
|
|
36
|
+
|
|
37
|
+
## Example
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { Grid } from '@acronis-platform/ui-react';
|
|
41
|
+
|
|
42
|
+
<Grid cols={3} gap="md">
|
|
43
|
+
{items.map((i) => (
|
|
44
|
+
<Card key={i.id} {...i} />
|
|
45
|
+
))}
|
|
46
|
+
</Grid>;
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Props
|
|
50
|
+
|
|
51
|
+
| Prop | Type | Default | Required | Description |
|
|
52
|
+
|------|------|---------|----------|-------------|
|
|
53
|
+
| `cols` | `1 | 2 | 3 | 4 | 6 | 12` | `3` | no | Target column count at the largest breakpoint (steps down responsively). |
|
|
54
|
+
| `gap` | `'none' | 'sm' | 'md' | 'lg' | 'xl'` | `'md'` | no | Space between grid cells. |
|
|
55
|
+
| `container` | `boolean` | `false` | no | Size columns by the grid's own width (container queries) instead of the viewport — wraps the grid in a `@container/grid`. Use for grids inside a variable-width area (e.g. App Shell main). |
|
|
56
|
+
|
|
57
|
+
## Behavior
|
|
58
|
+
|
|
59
|
+
```gherkin
|
|
60
|
+
Scenario: Responsive columns
|
|
61
|
+
Given a Grid with cols={4}
|
|
62
|
+
Then cells lay out in up to 4 columns at large widths, stepping down to fewer
|
|
63
|
+
columns at smaller breakpoints
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```gherkin
|
|
67
|
+
Scenario: Gap
|
|
68
|
+
Given a gap value
|
|
69
|
+
Then a consistent gap is applied between rows and columns
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Accessibility
|
|
73
|
+
|
|
74
|
+
Grid is a presentational layout `<div>` with no semantics of its own; children
|
|
75
|
+
follow source order. It uses CSS grid only for visual layout — don't rely on it to
|
|
76
|
+
convey relationships that need real table/list semantics.
|
|
77
|
+
|
|
78
|
+
## Contrast
|
|
79
|
+
|
|
80
|
+
No color; nothing to evaluate.
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Histogram
|
|
2
|
+
|
|
3
|
+
> A frequency histogram — bins a set of continuous samples (`values`) into equal-width ranges and plots the count of each as contiguous bars. Distinct from `BarChart`, which plots pre-categorized rows: the binning is the component's own job (a pure helper). Built on the shared `Chart` primitives; design-pending v1 (no `--ui-chart-*` palette yet, no `apps/demo` playground).
|
|
4
|
+
|
|
5
|
+
**Status:** draft · **Category:** data-display · **Since:** v0.58.0
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Histogram } from '@acronis-platform/ui-react'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick example
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<Histogram
|
|
17
|
+
config={{ count: { label: 'Frequency', color: 'var(--ui-background-brand-secondary)' } }}
|
|
18
|
+
values={[12, 15, 18, 20, 22, 25, 30, 42]}
|
|
19
|
+
binCount={10}
|
|
20
|
+
className="h-[320px] w-[560px]"
|
|
21
|
+
/>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
A frequency histogram built on the shared `Chart` primitives. Give it raw
|
|
25
|
+
`values` and a per-series `config`; it bins the samples into equal-width ranges
|
|
26
|
+
and plots the count of each as contiguous bars — you don't pre-aggregate.
|
|
27
|
+
|
|
28
|
+
The bar color comes from the `palette` prop — a dataviz palette resolving to the
|
|
29
|
+
`--ui-dataviz-*` tokens, `categorical` by default — not from `config`.
|
|
30
|
+
|
|
31
|
+
> **Design-pending v1.** No `apps/demo` playground — built net-new. Code Connect
|
|
32
|
+
> is deferred.
|
|
33
|
+
|
|
34
|
+
## When to use
|
|
35
|
+
|
|
36
|
+
- Showing the **distribution** of a single continuous variable — how many
|
|
37
|
+
samples fall in each value range (response times, scores, sizes).
|
|
38
|
+
- Spotting shape: skew, spread, modality, outliers.
|
|
39
|
+
|
|
40
|
+
## When not to use
|
|
41
|
+
|
|
42
|
+
- Comparing named categories — that's a [`BarChart`](/components/bar-chart)
|
|
43
|
+
(pre-categorized rows), not a histogram (binned continuous data).
|
|
44
|
+
- Part-to-whole — use a pie/donut.
|
|
45
|
+
- Two-variable relationships — use a scatter chart.
|
|
46
|
+
|
|
47
|
+
## Example
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { Histogram } from '@acronis-platform/ui-react';
|
|
51
|
+
import type { ChartConfig } from '@acronis-platform/ui-react';
|
|
52
|
+
|
|
53
|
+
const values = [12, 15, 18, 20, 22, 22, 25, 28, 30, 35, 42, 48, 60];
|
|
54
|
+
|
|
55
|
+
const config = {
|
|
56
|
+
count: { label: 'Frequency', color: 'var(--ui-background-brand-secondary)' },
|
|
57
|
+
} satisfies ChartConfig;
|
|
58
|
+
|
|
59
|
+
<Histogram
|
|
60
|
+
config={config}
|
|
61
|
+
values={values}
|
|
62
|
+
binCount={10}
|
|
63
|
+
className="h-[320px] w-[560px]"
|
|
64
|
+
/>;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Tune the resolution with `binCount`, or fix the range with `domain={[0, 100]}`
|
|
68
|
+
(samples outside the domain are dropped). The bar color references an existing
|
|
69
|
+
semantic `--ui-*` token; `--ui-background-brand-secondary` is brand-dependent, so
|
|
70
|
+
it is not color-stable across brands until the real data-viz palette lands.
|
|
71
|
+
|
|
72
|
+
## Props
|
|
73
|
+
|
|
74
|
+
| Prop | Type | Default | Required | Description |
|
|
75
|
+
|------|------|---------|----------|-------------|
|
|
76
|
+
| `values` | `ReadonlyArray<number>` | — | yes | Raw continuous samples to bin. Non-finite values are ignored. |
|
|
77
|
+
| `config` | `ChartConfig` | — | yes | The single series takes its colour from the container's `palette`; the entry, keyed by `dataKey`, maps it to a `label` and an optional `tone`. Resolved into the `--color-<dataKey>` custom property the bars fill from. |
|
|
78
|
+
| `dataKey` | `string` | `'count'` | no | The `config` key that colors + labels the frequency bars. |
|
|
79
|
+
| `binCount` | `number` | `10` | no | Number of equal-width bins to split the range into. |
|
|
80
|
+
| `domain` | `[number, number]` | — | no | Fix the binning range instead of deriving it from the data's min/max; samples outside the domain are dropped. |
|
|
81
|
+
| `xAxisLabel` | `string` | — | no | Title rendered beneath the horizontal (X) axis. |
|
|
82
|
+
| `yAxisLabel` | `string` | — | no | Title rendered beside the vertical (Y) axis (rotated). |
|
|
83
|
+
| `yUnit` | `string` | — | no | Unit suffix appended to Y-axis tick values (recharts `unit`); the X axis is the bin label. |
|
|
84
|
+
| `barRadius` | `number` | `0` | no | Corner radius on the top of each bar (0 = square, the histogram default). |
|
|
85
|
+
| `showGrid` | `boolean` | `true` | no | Render the CartesianGrid. |
|
|
86
|
+
| `showTooltip` | `boolean` | `true` | no | Render the hover tooltip. |
|
|
87
|
+
| `tooltipContent` | `ReactElement | ((props) => ReactNode)` | — | no | Replace the default tooltip. Pass a configured ChartTooltipContent (from this library) — e.g. with a formatter / labelFormatter — to customize the tooltip content without composing recharts. Ignored when showTooltip is false. |
|
|
88
|
+
| `showXAxis` | `boolean` | `true` | no | Render the X axis (its ticks and title). Set false to hide it. |
|
|
89
|
+
| `showYAxis` | `boolean` | `true` | no | Render the Y axis (its ticks and title). Set false to hide it. |
|
|
90
|
+
| `xTickFormatter` | `(value: number | string, index?: number) => string` | — | no | Format each X-axis tick value. Unlike the `unit` suffix (append-only), a formatter transforms the value — abbreviate, prefix a symbol, or map to a label. Use formatCompactNumber / formatPercent / createTickFormatter from the shared Chart primitives, or any function. |
|
|
91
|
+
| `yTickFormatter` | `(value: number | string, index?: number) => string` | — | no | Format each Y-axis tick value (see xTickFormatter). |
|
|
92
|
+
| `xAxisAngle` | `number` | — | no | Rotate the X-axis tick labels by this many degrees (a negative angle tilts them up toward the right); the tick anchor + axis height adjust. |
|
|
93
|
+
| `xAxisInterval` | `number | 'preserveStart' | 'preserveEnd' | 'preserveStartEnd' | 'equidistantPreserveStart'` | — | no | X-axis tick density — a recharts placement strategy, or a fixed number of ticks to skip between two rendered ones (recharts interval: 0 shows every tick, 1 every other one, 2 every third). |
|
|
94
|
+
| `yAxisTickCount` | `number` | — | no | Desired number of ticks on the value axis (recharts tickCount; a hint, not exact). Applies to whichever axis holds the values — Y for most charts, X for BarChart with orientation="horizontal". |
|
|
95
|
+
| `yAxisDomain` | `'auto' | 'dataMin-dataMax' | 'zero'` | — | no | Value-axis domain preset — auto (fit the data at both ends; the axis need not include 0), zero (anchor the axis at 0, which is also recharts' behaviour when the prop is omitted), or dataMin-dataMax (tight to the data, no padding). Applies to whichever axis holds the values — Y for most charts, X for BarChart with orientation="horizontal". |
|
|
96
|
+
| `gridDashed` | `boolean` | — | no | Draw grid lines dashed instead of solid. |
|
|
97
|
+
| `gridHorizontal` | `boolean` | — | no | Show horizontal grid lines (defaults to the chart's own default when unset). |
|
|
98
|
+
| `gridVertical` | `boolean` | — | no | Show vertical grid lines (defaults to the chart's own default when unset). |
|
|
99
|
+
| `animate` | `boolean` | `false` | no | Enable entrance animation. Off by default so output/baselines are unchanged. |
|
|
100
|
+
| `animationDuration` | `number` | — | no | Animation duration in ms. |
|
|
101
|
+
| `animationBegin` | `number` | — | no | Delay before the animation starts, in ms. |
|
|
102
|
+
| `animationEasing` | `'ease' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'linear'` | — | no | Easing curve. |
|
|
103
|
+
|
|
104
|
+
## Behavior
|
|
105
|
+
|
|
106
|
+
`Histogram` bins a set of continuous samples (`values`) into equal-width ranges
|
|
107
|
+
and renders their frequencies as contiguous bars, built on the shared `Chart`
|
|
108
|
+
primitives.
|
|
109
|
+
|
|
110
|
+
```gherkin
|
|
111
|
+
Scenario: Bin and render a distribution
|
|
112
|
+
Given values and a binCount
|
|
113
|
+
Then the [min, max] range is split into binCount equal-width bins
|
|
114
|
+
And each bar's height is the number of samples in that bin
|
|
115
|
+
And the bars are contiguous (no category gap), reading as a distribution
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```gherkin
|
|
119
|
+
Scenario: Max value placement
|
|
120
|
+
Given a sample equal to the range maximum
|
|
121
|
+
Then it falls in the last bin (whose upper edge is inclusive), not dropped
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
```gherkin
|
|
125
|
+
Scenario: Explicit domain
|
|
126
|
+
Given a domain [lo, hi]
|
|
127
|
+
Then bins span [lo, hi] instead of the data's own min/max
|
|
128
|
+
And samples outside [lo, hi] are dropped
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```gherkin
|
|
132
|
+
Scenario: Degenerate range
|
|
133
|
+
Given all values are equal (a zero-width range)
|
|
134
|
+
Then the range is widened so a single bin still has extent and counts them
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```gherkin
|
|
138
|
+
Scenario: Non-finite samples
|
|
139
|
+
Given values containing NaN / Infinity
|
|
140
|
+
Then those are ignored and only finite samples are binned
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
```gherkin
|
|
144
|
+
Scenario: Tooltip on hover
|
|
145
|
+
Given showTooltip is true
|
|
146
|
+
When the user hovers a bar
|
|
147
|
+
Then a card shows the bin range label and its count
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```gherkin
|
|
151
|
+
Scenario: Empty data
|
|
152
|
+
Given values is empty (or has no finite samples)
|
|
153
|
+
Then no bars render and the chart does not throw
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```gherkin
|
|
157
|
+
Scenario: Entrance animation is opt-in
|
|
158
|
+
Given animate is unset
|
|
159
|
+
Then the series render at their final geometry with no entrance animation
|
|
160
|
+
And the committed visual baselines are unaffected
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```gherkin
|
|
164
|
+
Scenario: Reduced motion
|
|
165
|
+
Given animate is true
|
|
166
|
+
And a user with prefers-reduced-motion
|
|
167
|
+
Then the entrance animation does not play and the series render at their final geometry
|
|
168
|
+
And the same applies when rendering on the server
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Accessibility
|
|
172
|
+
|
|
173
|
+
- recharts' `accessibilityLayer` is **on by default** (recharts v3), giving the
|
|
174
|
+
chart keyboard focus and an accessible description of the plotted bins.
|
|
175
|
+
- A histogram is inherently visual. **Pair it with a text alternative** — a
|
|
176
|
+
caption, a summary, or an adjacent data table carrying the same counts — and
|
|
177
|
+
give the chart an accessible name (`aria-label` / `aria-labelledby` referencing
|
|
178
|
+
a visible heading). The wrapper forwards native `div` attributes, so `aria-*`
|
|
179
|
+
pass through.
|
|
180
|
+
- Do **not** rely on the bar color alone — the x-axis bin labels and the tooltip
|
|
181
|
+
(kept on via `showTooltip`) carry the range and count. Keep enough bins for the
|
|
182
|
+
distribution to be legible, but not so many that labels collide.
|
|
183
|
+
- Watch recharts issue [#4809](https://github.com/recharts/recharts/issues/4809)
|
|
184
|
+
on the a11y layer for heavily-customized charts.
|
|
185
|
+
|
|
186
|
+
## Contrast
|
|
187
|
+
|
|
188
|
+
Tooltip chrome, axis labels, and the grid meet contrast in both themes via the
|
|
189
|
+
semantic tokens. The bar fill comes from `config` and is the caller's
|
|
190
|
+
responsibility — pick a token with sufficient contrast on the surface.
|