@misoto22/design 0.3.1 → 0.6.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 +124 -0
- package/bin/misoto22-design.mjs +205 -0
- package/dist/agent/Accordion.md +41 -0
- package/dist/agent/Alert.md +42 -0
- package/dist/agent/AppShell.md +40 -0
- package/dist/agent/AreaChart.md +68 -0
- package/dist/agent/Article.md +41 -0
- package/dist/agent/Avatar.md +32 -0
- package/dist/agent/Badge.md +40 -0
- package/dist/agent/BarChart.md +65 -0
- package/dist/agent/BarList.md +40 -0
- package/dist/agent/BigNumber.md +45 -0
- package/dist/agent/BoxPlot.md +58 -0
- package/dist/agent/Breadcrumb.md +32 -0
- package/dist/agent/BulletChart.md +48 -0
- package/dist/agent/Button.md +56 -0
- package/dist/agent/Calendar.md +42 -0
- package/dist/agent/Card.md +49 -0
- package/dist/agent/Checkbox.md +35 -0
- package/dist/agent/Collapsible.md +46 -0
- package/dist/agent/Combobox.md +50 -0
- package/dist/agent/Command.md +93 -0
- package/dist/agent/ComposedChart.md +57 -0
- package/dist/agent/ContextMenu.md +59 -0
- package/dist/agent/DatePicker.md +75 -0
- package/dist/agent/Diagram.md +46 -0
- package/dist/agent/Dialog.md +52 -0
- package/dist/agent/DropdownMenu.md +70 -0
- package/dist/agent/EmptyState.md +37 -0
- package/dist/agent/ErrorState.md +41 -0
- package/dist/agent/Facet.md +82 -0
- package/dist/agent/Field.md +37 -0
- package/dist/agent/FigureBand.md +37 -0
- package/dist/agent/FloatingIconButton.md +38 -0
- package/dist/agent/FunnelChart.md +52 -0
- package/dist/agent/Heatmap.md +53 -0
- package/dist/agent/Histogram.md +63 -0
- package/dist/agent/Input.md +30 -0
- package/dist/agent/Kbd.md +29 -0
- package/dist/agent/LineChart.md +60 -0
- package/dist/agent/LinkArrow.md +29 -0
- package/dist/agent/NativeSelect.md +40 -0
- package/dist/agent/NavItem.md +35 -0
- package/dist/agent/Pagination.md +43 -0
- package/dist/agent/PieChart.md +55 -0
- package/dist/agent/Popover.md +57 -0
- package/dist/agent/Progress.md +33 -0
- package/dist/agent/RadarChart.md +54 -0
- package/dist/agent/RadialChart.md +57 -0
- package/dist/agent/RadioGroup.md +44 -0
- package/dist/agent/SankeyChart.md +61 -0
- package/dist/agent/ScatterChart.md +54 -0
- package/dist/agent/ScrollArea.md +40 -0
- package/dist/agent/SearchableMenu.md +46 -0
- package/dist/agent/Select.md +75 -0
- package/dist/agent/Separator.md +35 -0
- package/dist/agent/Sheet.md +57 -0
- package/dist/agent/Skeleton.md +73 -0
- package/dist/agent/Slider.md +39 -0
- package/dist/agent/Sparkline.md +45 -0
- package/dist/agent/Spinner.md +39 -0
- package/dist/agent/StatusDot.md +36 -0
- package/dist/agent/StatusPill.md +28 -0
- package/dist/agent/Steps.md +44 -0
- package/dist/agent/Switch.md +29 -0
- package/dist/agent/Table.md +85 -0
- package/dist/agent/Tabs.md +48 -0
- package/dist/agent/Tag.md +35 -0
- package/dist/agent/Textarea.md +26 -0
- package/dist/agent/Toast.md +26 -0
- package/dist/agent/ToggleGroup.md +44 -0
- package/dist/agent/Tooltip.md +51 -0
- package/dist/agent/TreemapChart.md +52 -0
- package/dist/agent/WaterfallChart.md +62 -0
- package/dist/agent/catalog.json +1791 -0
- package/dist/agent/index.md +131 -0
- package/dist/article.css +393 -0
- package/dist/charts/AreaChart/AreaChart.d.ts +191 -0
- package/dist/charts/AreaChart/AreaChart.js +480 -0
- package/dist/charts/AreaChart/AreaChart.js.map +1 -0
- package/dist/charts/BarChart/BarChart.d.ts +179 -0
- package/dist/charts/BarChart/BarChart.js +591 -0
- package/dist/charts/BarChart/BarChart.js.map +1 -0
- package/dist/charts/BarList/BarList.d.ts +57 -0
- package/dist/charts/BarList/BarList.js +71 -0
- package/dist/charts/BarList/BarList.js.map +1 -0
- package/dist/charts/BigNumber/BigNumber.d.ts +56 -0
- package/dist/charts/BigNumber/BigNumber.js +31 -0
- package/dist/charts/BigNumber/BigNumber.js.map +1 -0
- package/dist/charts/BoxPlot/BoxPlot.d.ts +177 -0
- package/dist/charts/BoxPlot/BoxPlot.js +495 -0
- package/dist/charts/BoxPlot/BoxPlot.js.map +1 -0
- package/dist/charts/BulletChart/BulletChart.d.ts +100 -0
- package/dist/charts/BulletChart/BulletChart.js +162 -0
- package/dist/charts/BulletChart/BulletChart.js.map +1 -0
- package/dist/charts/ComposedChart/ComposedChart.d.ts +171 -0
- package/dist/charts/ComposedChart/ComposedChart.js +667 -0
- package/dist/charts/ComposedChart/ComposedChart.js.map +1 -0
- package/dist/charts/Facet/Facet.d.ts +240 -0
- package/dist/charts/Facet/Facet.js +133 -0
- package/dist/charts/Facet/Facet.js.map +1 -0
- package/dist/charts/Facet/panels.d.ts +187 -0
- package/dist/charts/Facet/panels.js +203 -0
- package/dist/charts/Facet/panels.js.map +1 -0
- package/dist/charts/FunnelChart/FunnelChart.d.ts +101 -0
- package/dist/charts/FunnelChart/FunnelChart.js +147 -0
- package/dist/charts/FunnelChart/FunnelChart.js.map +1 -0
- package/dist/charts/Heatmap/Heatmap.d.ts +78 -0
- package/dist/charts/Heatmap/Heatmap.js +108 -0
- package/dist/charts/Heatmap/Heatmap.js.map +1 -0
- package/dist/charts/Histogram/Histogram.d.ts +165 -0
- package/dist/charts/Histogram/Histogram.js +350 -0
- package/dist/charts/Histogram/Histogram.js.map +1 -0
- package/dist/charts/LineChart/LineChart.d.ts +167 -0
- package/dist/charts/LineChart/LineChart.js +486 -0
- package/dist/charts/LineChart/LineChart.js.map +1 -0
- package/dist/charts/PieChart/PieChart.d.ts +128 -0
- package/dist/charts/PieChart/PieChart.js +309 -0
- package/dist/charts/PieChart/PieChart.js.map +1 -0
- package/dist/charts/RadarChart/RadarChart.d.ts +123 -0
- package/dist/charts/RadarChart/RadarChart.js +299 -0
- package/dist/charts/RadarChart/RadarChart.js.map +1 -0
- package/dist/charts/RadialChart/RadialChart.d.ts +124 -0
- package/dist/charts/RadialChart/RadialChart.js +257 -0
- package/dist/charts/RadialChart/RadialChart.js.map +1 -0
- package/dist/charts/SankeyChart/SankeyChart.d.ts +137 -0
- package/dist/charts/SankeyChart/SankeyChart.js +501 -0
- package/dist/charts/SankeyChart/SankeyChart.js.map +1 -0
- package/dist/charts/ScatterChart/ScatterChart.d.ts +128 -0
- package/dist/charts/ScatterChart/ScatterChart.js +269 -0
- package/dist/charts/ScatterChart/ScatterChart.js.map +1 -0
- package/dist/charts/Sparkline/Sparkline.d.ts +53 -0
- package/dist/charts/Sparkline/Sparkline.js +93 -0
- package/dist/charts/Sparkline/Sparkline.js.map +1 -0
- package/dist/charts/TreemapChart/TreemapChart.d.ts +93 -0
- package/dist/charts/TreemapChart/TreemapChart.js +118 -0
- package/dist/charts/TreemapChart/TreemapChart.js.map +1 -0
- package/dist/charts/WaterfallChart/WaterfallChart.d.ts +164 -0
- package/dist/charts/WaterfallChart/WaterfallChart.js +319 -0
- package/dist/charts/WaterfallChart/WaterfallChart.js.map +1 -0
- package/dist/charts/index.d.ts +41 -0
- package/dist/charts/index.js +128 -0
- package/dist/charts/index.js.map +1 -0
- package/dist/charts/lib/annotations.d.ts +103 -0
- package/dist/charts/lib/annotations.js +99 -0
- package/dist/charts/lib/annotations.js.map +1 -0
- package/dist/charts/lib/axis.d.ts +18 -0
- package/dist/charts/lib/axis.js +21 -0
- package/dist/charts/lib/axis.js.map +1 -0
- package/dist/charts/lib/background.d.ts +33 -0
- package/dist/charts/lib/background.js +173 -0
- package/dist/charts/lib/background.js.map +1 -0
- package/dist/charts/lib/brush.d.ts +94 -0
- package/dist/charts/lib/brush.js +535 -0
- package/dist/charts/lib/brush.js.map +1 -0
- package/dist/charts/lib/chart.d.ts +94 -0
- package/dist/charts/lib/chart.js +134 -0
- package/dist/charts/lib/chart.js.map +1 -0
- package/dist/charts/lib/dot.d.ts +29 -0
- package/dist/charts/lib/dot.js +78 -0
- package/dist/charts/lib/dot.js.map +1 -0
- package/dist/charts/lib/empty.d.ts +31 -0
- package/dist/charts/lib/empty.js +13 -0
- package/dist/charts/lib/empty.js.map +1 -0
- package/dist/charts/lib/export.d.ts +103 -0
- package/dist/charts/lib/export.js +204 -0
- package/dist/charts/lib/export.js.map +1 -0
- package/dist/charts/lib/figure.d.ts +61 -0
- package/dist/charts/lib/figure.js +59 -0
- package/dist/charts/lib/figure.js.map +1 -0
- package/dist/charts/lib/format.d.ts +46 -0
- package/dist/charts/lib/format.js +56 -0
- package/dist/charts/lib/format.js.map +1 -0
- package/dist/charts/lib/legend.d.ts +45 -0
- package/dist/charts/lib/legend.js +117 -0
- package/dist/charts/lib/legend.js.map +1 -0
- package/dist/charts/lib/loading.d.ts +48 -0
- package/dist/charts/lib/loading.js +105 -0
- package/dist/charts/lib/loading.js.map +1 -0
- package/dist/charts/lib/paint.d.ts +154 -0
- package/dist/charts/lib/paint.js +551 -0
- package/dist/charts/lib/paint.js.map +1 -0
- package/dist/charts/lib/sonify-control.d.ts +163 -0
- package/dist/charts/lib/sonify-control.js +172 -0
- package/dist/charts/lib/sonify-control.js.map +1 -0
- package/dist/charts/lib/sonify.d.ts +248 -0
- package/dist/charts/lib/sonify.js +262 -0
- package/dist/charts/lib/sonify.js.map +1 -0
- package/dist/charts/lib/toolbar.d.ts +143 -0
- package/dist/charts/lib/toolbar.js +156 -0
- package/dist/charts/lib/toolbar.js.map +1 -0
- package/dist/charts/lib/tooltip.d.ts +59 -0
- package/dist/charts/lib/tooltip.js +135 -0
- package/dist/charts/lib/tooltip.js.map +1 -0
- package/dist/charts/lib/values.d.ts +56 -0
- package/dist/charts/lib/values.js +71 -0
- package/dist/charts/lib/values.js.map +1 -0
- package/dist/charts/lib/zoom.d.ts +139 -0
- package/dist/charts/lib/zoom.js +314 -0
- package/dist/charts/lib/zoom.js.map +1 -0
- package/dist/components/AppShell/AppShell.d.ts +15 -1
- package/dist/components/AppShell/AppShell.js +8 -4
- package/dist/components/AppShell/AppShell.js.map +1 -1
- package/dist/components/Article/Article.d.ts +51 -0
- package/dist/components/Article/Article.js +21 -0
- package/dist/components/Article/Article.js.map +1 -0
- package/dist/components/Button/Button.js +2 -2
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Calendar/Calendar.d.ts +1 -1
- package/dist/components/Calendar/Calendar.js +259 -24
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.js +1 -1
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/Collapsible/Collapsible.d.ts +15 -1
- package/dist/components/Collapsible/Collapsible.js +18 -0
- package/dist/components/Collapsible/Collapsible.js.map +1 -1
- package/dist/components/Combobox/Combobox.js +1 -1
- package/dist/components/Combobox/Combobox.js.map +1 -1
- package/dist/components/Command/Command.js +7 -7
- package/dist/components/Command/Command.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.js +2 -2
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
- package/dist/components/Diagram/Diagram.d.ts +81 -0
- package/dist/components/Diagram/Diagram.js +139 -0
- package/dist/components/Diagram/Diagram.js.map +1 -0
- package/dist/components/Dialog/Dialog.js +1 -1
- package/dist/components/Dialog/Dialog.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js +2 -2
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/FigureBand/FigureBand.js +41 -30
- package/dist/components/FigureBand/FigureBand.js.map +1 -1
- package/dist/components/Popover/Popover.js +1 -1
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Select/Select.js +2 -2
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Sheet/Sheet.js +1 -1
- package/dist/components/Sheet/Sheet.js.map +1 -1
- package/dist/components/Slider/Slider.js +1 -1
- package/dist/components/Slider/Slider.js.map +1 -1
- package/dist/components/Steps/Steps.d.ts +65 -0
- package/dist/components/Steps/Steps.js +55 -0
- package/dist/components/Steps/Steps.js.map +1 -0
- package/dist/components/Switch/Switch.js +1 -1
- package/dist/components/Switch/Switch.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.js +1 -1
- package/dist/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/useSelectionIndicator.js +14 -10
- package/dist/lib/useSelectionIndicator.js.map +1 -1
- package/dist/semantic.css +19 -0
- package/dist/styles.css +1 -1
- package/dist/themes.css +103 -7
- package/dist/tokens.css +193 -10
- package/dist/tokens.d.ts +25 -0
- package/dist/tokens.js +154 -8
- package/dist/tokens.json +154 -8
- package/package.json +45 -20
- package/skills/misoto22-design/SKILL.md +171 -0
- package/skills/misoto22-design/evals/claims.json +95 -0
- package/skills/misoto22-design/rules/a11y.md +115 -0
- package/skills/misoto22-design/rules/composition.md +108 -0
- package/skills/misoto22-design/rules/forms.md +128 -0
- package/skills/misoto22-design/rules/naming.md +155 -0
- package/skills/misoto22-design/rules/tokens.md +131 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ChartFigure } from "../lib/figure.js";
|
|
3
|
+
import { ChartEmpty } from "../lib/empty.js";
|
|
4
|
+
import { defaultTick } from "../lib/format.js";
|
|
5
|
+
const BAND_WEIGHT = { heaviest: 1, lightest: 0.3 };
|
|
6
|
+
const BAR_SHARE = 0.34;
|
|
7
|
+
function position(value, [low, high]) {
|
|
8
|
+
const span = high - low;
|
|
9
|
+
if (span === 0) return 0;
|
|
10
|
+
return Math.min(1, Math.max(0, (value - low) / span));
|
|
11
|
+
}
|
|
12
|
+
function pct(share) {
|
|
13
|
+
return `${Number((share * 100).toFixed(4))}%`;
|
|
14
|
+
}
|
|
15
|
+
function bands(ranges, [low, high], formatValue) {
|
|
16
|
+
const bounds = [...new Set(ranges.filter(Number.isFinite))].sort((a, b) => a - b).filter((bound) => bound > low && bound < high);
|
|
17
|
+
const edges = [low, ...bounds, high];
|
|
18
|
+
const count = edges.length - 1;
|
|
19
|
+
const { heaviest, lightest } = BAND_WEIGHT;
|
|
20
|
+
const list = Array.from({ length: count }, (_, index) => ({
|
|
21
|
+
from: edges[index],
|
|
22
|
+
to: edges[index + 1],
|
|
23
|
+
// Heaviest at the low end, lightening as the scale rises — so the measure
|
|
24
|
+
// bar, which is solid, stands out most where performance is best.
|
|
25
|
+
weight: count === 1 ? lightest : heaviest - index / (count - 1) * (heaviest - lightest)
|
|
26
|
+
}));
|
|
27
|
+
return { list, label: bounds.map(formatValue).join(", ") };
|
|
28
|
+
}
|
|
29
|
+
function resolve(data, domain, ranges, formatValue) {
|
|
30
|
+
return data.map((measure) => {
|
|
31
|
+
const own = measure.ranges ?? ranges ?? [];
|
|
32
|
+
const high = Math.max(measure.value, measure.target ?? Number.NEGATIVE_INFINITY, ...own);
|
|
33
|
+
const scale = measure.domain ?? domain ?? [Math.min(0, measure.value), high || 1];
|
|
34
|
+
const built = bands(own, scale, formatValue);
|
|
35
|
+
return { ...measure, domain: scale, bands: built.list, rangeLabel: built.label };
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function BulletChart({
|
|
39
|
+
title,
|
|
40
|
+
showTitle,
|
|
41
|
+
description,
|
|
42
|
+
data,
|
|
43
|
+
ranges,
|
|
44
|
+
domain,
|
|
45
|
+
formatValue = defaultTick,
|
|
46
|
+
showScale = false,
|
|
47
|
+
className,
|
|
48
|
+
hideDataTable = false,
|
|
49
|
+
empty
|
|
50
|
+
}) {
|
|
51
|
+
const measures = resolve(data, domain, ranges, formatValue);
|
|
52
|
+
return /* @__PURE__ */ jsx(
|
|
53
|
+
ChartFigure,
|
|
54
|
+
{
|
|
55
|
+
title,
|
|
56
|
+
showTitle,
|
|
57
|
+
description,
|
|
58
|
+
className,
|
|
59
|
+
table: hideDataTable ? false : {
|
|
60
|
+
rows: measures,
|
|
61
|
+
rowKey: "name",
|
|
62
|
+
columns: [
|
|
63
|
+
{ key: "value", label: "Value" },
|
|
64
|
+
{ key: "target", label: "Target" },
|
|
65
|
+
{ key: "rangeLabel", label: "Range bounds" }
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
children: measures.length === 0 ? /* @__PURE__ */ jsx(ChartEmpty, { ...empty || {} }) : /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col gap-4", children: measures.map((measure) => /* @__PURE__ */ jsx(
|
|
69
|
+
BulletRow,
|
|
70
|
+
{
|
|
71
|
+
measure,
|
|
72
|
+
formatValue,
|
|
73
|
+
showScale
|
|
74
|
+
},
|
|
75
|
+
measure.name
|
|
76
|
+
)) })
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
function BulletRow({
|
|
81
|
+
measure,
|
|
82
|
+
formatValue,
|
|
83
|
+
showScale
|
|
84
|
+
}) {
|
|
85
|
+
const scale = measure.domain;
|
|
86
|
+
const barShare = position(measure.value, scale);
|
|
87
|
+
const targetShare = measure.target === void 0 ? null : position(measure.target, scale);
|
|
88
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-1.5", children: [
|
|
89
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-3", children: [
|
|
90
|
+
/* @__PURE__ */ jsxs("span", { className: "truncate text-sm text-(--ink)", children: [
|
|
91
|
+
measure.name,
|
|
92
|
+
measure.detail && /* @__PURE__ */ jsx("span", { className: "ms-2 mono-meta text-(--ink-3-aa)", children: measure.detail })
|
|
93
|
+
] }),
|
|
94
|
+
/* @__PURE__ */ jsxs("span", { className: "shrink-0 font-mono text-xs tabular-nums text-(--ink)", children: [
|
|
95
|
+
formatValue(measure.value),
|
|
96
|
+
measure.target !== void 0 && /* @__PURE__ */ jsxs("span", { className: "text-(--ink-3-aa)", children: [
|
|
97
|
+
" / ",
|
|
98
|
+
formatValue(measure.target)
|
|
99
|
+
] })
|
|
100
|
+
] })
|
|
101
|
+
] }),
|
|
102
|
+
/* @__PURE__ */ jsxs(
|
|
103
|
+
"div",
|
|
104
|
+
{
|
|
105
|
+
"aria-hidden": true,
|
|
106
|
+
"data-slot": "bullet-track",
|
|
107
|
+
className: "relative h-6 w-full overflow-hidden rounded-(--radius-sm)",
|
|
108
|
+
children: [
|
|
109
|
+
measure.bands.map((band) => /* @__PURE__ */ jsx(
|
|
110
|
+
"span",
|
|
111
|
+
{
|
|
112
|
+
"data-slot": "bullet-band",
|
|
113
|
+
className: "absolute inset-y-0 block",
|
|
114
|
+
style: {
|
|
115
|
+
insetInlineStart: pct(position(band.from, scale)),
|
|
116
|
+
inlineSize: pct(position(band.to, scale) - position(band.from, scale)),
|
|
117
|
+
// The one translucent-mark pair in the token layer, because it is
|
|
118
|
+
// the only one that holds a different number on each ground.
|
|
119
|
+
backgroundColor: `color-mix(in srgb, var(--series-1) calc(var(--chart-fill) * ${band.weight} * 100%), transparent)`
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
`${band.from}-${band.to}`
|
|
123
|
+
)),
|
|
124
|
+
/* @__PURE__ */ jsx(
|
|
125
|
+
"span",
|
|
126
|
+
{
|
|
127
|
+
"data-slot": "bullet-bar",
|
|
128
|
+
className: "absolute block bg-(--series-1)",
|
|
129
|
+
style: {
|
|
130
|
+
insetInlineStart: 0,
|
|
131
|
+
insetBlockStart: pct((1 - BAR_SHARE) / 2),
|
|
132
|
+
blockSize: pct(BAR_SHARE),
|
|
133
|
+
inlineSize: pct(barShare)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
),
|
|
137
|
+
targetShare !== null && // A rule ACROSS the bar rather than a second bar beside it: the two
|
|
138
|
+
// are different kinds of number, and the reader has to be able to
|
|
139
|
+
// tell at a glance which one was achieved and which was asked for.
|
|
140
|
+
/* @__PURE__ */ jsx(
|
|
141
|
+
"span",
|
|
142
|
+
{
|
|
143
|
+
"data-slot": "bullet-target",
|
|
144
|
+
className: "absolute inset-y-1 block w-0.5 bg-(--ink)",
|
|
145
|
+
style: { insetInlineStart: pct(targetShare), marginInlineStart: "-1px" }
|
|
146
|
+
}
|
|
147
|
+
)
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
),
|
|
151
|
+
showScale && /* @__PURE__ */ jsxs("div", { className: "flex justify-between mono-meta text-(--chart-axis)", children: [
|
|
152
|
+
/* @__PURE__ */ jsx("span", { children: formatValue(scale[0]) }),
|
|
153
|
+
/* @__PURE__ */ jsx("span", { children: formatValue(scale[1]) })
|
|
154
|
+
] })
|
|
155
|
+
] });
|
|
156
|
+
}
|
|
157
|
+
var BulletChart_default = BulletChart;
|
|
158
|
+
export {
|
|
159
|
+
BulletChart,
|
|
160
|
+
BulletChart_default as default
|
|
161
|
+
};
|
|
162
|
+
//# sourceMappingURL=BulletChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/charts/BulletChart/BulletChart.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport { ChartFigure } from '../lib/figure'\nimport { ChartEmpty, type ChartEmptyProps } from '../lib/empty'\nimport { defaultTick } from '../lib/format'\n\n/**\n * The heaviest and lightest a qualitative band may be, as multiples of\n * `--chart-fill`.\n *\n * Few's rule is no more than five bands in one hue, arranged so the low end of\n * the scale is the heaviest. The measure bar is solid ink on top of them, so\n * the ceiling has to stay well under it: bands that compete with the bar stop\n * being the ground it is read against.\n */\nconst BAND_WEIGHT = { heaviest: 1, lightest: 0.3 } as const\n\n/** How tall the measure bar is, as a share of the track. Few's is a third. */\nconst BAR_SHARE = 0.34\n\n/** One measure, its target, and the bands it is read against. */\nexport interface BulletMeasure {\n /** What is being measured. Doubles as the row's key, so it must be unique. */\n name: string\n /** The number the row is about. */\n value: number\n /**\n * The number the measure is being judged against — last year, the budget,\n * the SLO. Drawn as a rule across the bar, not as a second bar.\n */\n target?: number\n /**\n * The qualitative bands, as ascending UPPER bounds. `[60, 80]` on a 0–100\n * scale draws three bands: 0–60, 60–80, 80–100.\n *\n * Few's limit is five, and it is a real one: past that the shades stop being\n * separable and the bands become a gradient nobody can read a boundary off.\n */\n ranges?: number[]\n /** The scale, as `[min, max]`. Falls back to the chart's, then to the data. */\n domain?: [number, number]\n /** A second line under the name — the unit, the window, the owner. */\n detail?: ReactNode\n}\n\n/** A measure with its scale and bands resolved. */\ninterface ResolvedMeasure extends BulletMeasure {\n domain: [number, number]\n bands: { from: number; to: number; weight: number }[]\n /** Written out for the hidden table, which cannot print an array. */\n rangeLabel: string\n}\n\n/** Where a value sits on the scale, 0 to 1, clamped to it. */\nfunction position(value: number, [low, high]: [number, number]): number {\n const span = high - low\n if (span === 0) return 0\n return Math.min(1, Math.max(0, (value - low) / span))\n}\n\n/**\n * A share of the track, as a CSS percentage.\n *\n * Rounded, because binary floating point turns `0.8 - 0.5` into\n * `30.000000000000004%` — a number no layout engine cares about and every\n * reader of the DOM does. Four places is finer than a subpixel on any track\n * this chart will be given.\n */\nfunction pct(share: number): string {\n return `${Number((share * 100).toFixed(4))}%`\n}\n\n/** The bands, from the ascending upper bounds, each with its own weight. */\nfunction bands(\n ranges: number[],\n [low, high]: [number, number],\n formatValue: (value: number) => string,\n): { list: ResolvedMeasure['bands']; label: string } {\n const bounds = [...new Set(ranges.filter(Number.isFinite))]\n .sort((a, b) => a - b)\n .filter((bound) => bound > low && bound < high)\n\n const edges = [low, ...bounds, high]\n const count = edges.length - 1\n const { heaviest, lightest } = BAND_WEIGHT\n\n const list = Array.from({ length: count }, (_, index) => ({\n from: edges[index]!,\n to: edges[index + 1]!,\n // Heaviest at the low end, lightening as the scale rises — so the measure\n // bar, which is solid, stands out most where performance is best.\n weight: count === 1 ? lightest : heaviest - (index / (count - 1)) * (heaviest - lightest),\n }))\n\n // The label names the bounds the caller SET, not the band tops: the last\n // band's top is the end of the scale, which is not a threshold anybody chose.\n return { list, label: bounds.map(formatValue).join(', ') }\n}\n\n/** Every measure, with its scale and bands worked out. */\nfunction resolve(\n data: BulletMeasure[],\n domain: [number, number] | undefined,\n ranges: number[] | undefined,\n formatValue: (value: number) => string,\n): ResolvedMeasure[] {\n return data.map((measure) => {\n const own = measure.ranges ?? ranges ?? []\n const high = Math.max(measure.value, measure.target ?? Number.NEGATIVE_INFINITY, ...own)\n // Anchored at zero unless told otherwise: the measure is drawn as a BAR,\n // and a bar read off a scale that does not start at zero overstates every\n // difference on it.\n const scale: [number, number] = measure.domain ?? domain ?? [Math.min(0, measure.value), high || 1]\n const built = bands(own, scale, formatValue)\n\n return { ...measure, domain: scale, bands: built.list, rangeLabel: built.label }\n })\n}\n\nexport interface BulletChartProps {\n /**\n * What the chart shows, in a sentence a reader could act on. Required, and\n * announced to a screen reader even when it is not printed.\n */\n title: string\n /** Prints the title above the rows instead of hiding it from sight. */\n showTitle?: boolean\n /** A line under the title — the unit, the window, the caveat. */\n description?: ReactNode\n /** One entry per measure. Order is the reading order; it is not sorted. */\n data: BulletMeasure[]\n /**\n * The bands every measure falls back to, as ascending upper bounds.\n *\n * Shared bands only mean something when the measures share a scale. Where\n * they do not — a latency beside a conversion rate — put `ranges` and\n * `domain` on each measure instead.\n */\n ranges?: number[]\n /** The scale every measure falls back to, as `[min, max]`. */\n domain?: [number, number]\n /** Formats every number the chart prints. */\n formatValue?: (value: number) => string\n /** Prints the scale's two ends under each track. */\n showScale?: boolean\n /** Merged onto the figure, last, so a call site can size or space it. */\n className?: string\n /** Drops the hidden table view. Only correct when the page prints the data itself. */\n hideDataTable?: boolean\n /** What the chart shows when it has nothing to draw. */\n empty?: ChartEmptyProps\n}\n\n/**\n * A measure, its target, and the bands that say whether the number is any good\n * — one dense row per thing being tracked.\n *\n * Stephen Few designed this to replace the dashboard gauge, and the argument\n * has held: a speedometer spends a whole card saying one number badly, where a\n * bullet graph says the same number, its target, and the qualitative context\n * around it in the height of a line of text. Ten of them stack into a status\n * page a reader can scan in one pass.\n *\n * What it will not do is show change over time. A bullet graph is one instant,\n * and `target` is the only comparison it carries; when the question is\n * \"how did we get here\" it wants a `<LineChart>`, and when several measures\n * have to be compared against each OTHER rather than each against its own\n * target, a `<BarList>` ranks them and this does not.\n *\n * **The bands are the part to be careful with.** They are a judgement — someone\n * decided that 80 is \"good\" — drawn in the same ink as the measurement, and a\n * reader has no way to tell an agreed threshold from a number somebody typed.\n * They also compress: a value near the top of the scale sits in the same band\n * whether it cleared the boundary by a point or by thirty. The band answers\n * \"is this acceptable\", never \"by how much\".\n *\n * No rendering engine, deliberately — this is the one chart in the set with\n * nothing to compute. Each row is a single linear scale with no axis, no ticks\n * and no shared plot area, so it is laid out as HTML: the bands and the bar are\n * inline-axis offsets, which means the whole chart mirrors correctly in a\n * right-to-left document, where an SVG drawn in user space would not.\n *\n * @example\n * <BulletChart\n * title=\"Service levels against target\"\n * data={[{ name: 'Uptime', value: 99.4, target: 99.9, ranges: [98, 99.5] }]}\n * domain={[95, 100]}\n * />\n */\nexport function BulletChart({\n title,\n showTitle,\n description,\n data,\n ranges,\n domain,\n formatValue = defaultTick,\n showScale = false,\n className,\n hideDataTable = false,\n empty,\n}: BulletChartProps) {\n const measures = resolve(data, domain, ranges, formatValue)\n\n return (\n <ChartFigure\n title={title}\n showTitle={showTitle}\n description={description}\n className={className}\n table={\n hideDataTable\n ? false\n : {\n rows: measures as unknown as Record<string, unknown>[],\n rowKey: 'name',\n columns: [\n { key: 'value', label: 'Value' },\n { key: 'target', label: 'Target' },\n { key: 'rangeLabel', label: 'Range bounds' },\n ],\n }\n }\n >\n {measures.length === 0 ? (\n <ChartEmpty {...(empty || {})} />\n ) : (\n <div className=\"flex w-full flex-col gap-4\">\n {measures.map((measure) => (\n <BulletRow\n key={measure.name}\n measure={measure}\n formatValue={formatValue}\n showScale={showScale}\n />\n ))}\n </div>\n )}\n </ChartFigure>\n )\n}\n\nfunction BulletRow({\n measure,\n formatValue,\n showScale,\n}: {\n measure: ResolvedMeasure\n formatValue: (value: number) => string\n showScale: boolean\n}) {\n const scale = measure.domain\n const barShare = position(measure.value, scale)\n const targetShare = measure.target === undefined ? null : position(measure.target, scale)\n\n return (\n <div className=\"flex w-full flex-col gap-1.5\">\n <div className=\"flex items-baseline justify-between gap-3\">\n <span className=\"truncate text-sm text-(--ink)\">\n {measure.name}\n {measure.detail && (\n <span className=\"ms-2 mono-meta text-(--ink-3-aa)\">{measure.detail}</span>\n )}\n </span>\n <span className=\"shrink-0 font-mono text-xs tabular-nums text-(--ink)\">\n {formatValue(measure.value)}\n {measure.target !== undefined && (\n <span className=\"text-(--ink-3-aa)\"> / {formatValue(measure.target)}</span>\n )}\n </span>\n </div>\n\n {/* The graphic repeats what the line above and the hidden table already\n say, so it is out of the accessibility tree entirely rather than\n announced a third time as a stack of empty boxes. */}\n <div\n aria-hidden\n data-slot=\"bullet-track\"\n className=\"relative h-6 w-full overflow-hidden rounded-(--radius-sm)\"\n >\n {measure.bands.map((band) => (\n <span\n key={`${band.from}-${band.to}`}\n data-slot=\"bullet-band\"\n className=\"absolute inset-y-0 block\"\n style={{\n insetInlineStart: pct(position(band.from, scale)),\n inlineSize: pct(position(band.to, scale) - position(band.from, scale)),\n // The one translucent-mark pair in the token layer, because it is\n // the only one that holds a different number on each ground.\n backgroundColor: `color-mix(in srgb, var(--series-1) calc(var(--chart-fill) * ${band.weight} * 100%), transparent)`,\n }}\n />\n ))}\n\n {/* Solid, and a third of the track's height. The measure is the one\n thing here that is a measurement rather than a judgement, so it is\n the only mark drawn at full weight. */}\n <span\n data-slot=\"bullet-bar\"\n className=\"absolute block bg-(--series-1)\"\n style={{\n insetInlineStart: 0,\n insetBlockStart: pct((1 - BAR_SHARE) / 2),\n blockSize: pct(BAR_SHARE),\n inlineSize: pct(barShare),\n }}\n />\n\n {targetShare !== null && (\n // A rule ACROSS the bar rather than a second bar beside it: the two\n // are different kinds of number, and the reader has to be able to\n // tell at a glance which one was achieved and which was asked for.\n <span\n data-slot=\"bullet-target\"\n className=\"absolute inset-y-1 block w-0.5 bg-(--ink)\"\n style={{ insetInlineStart: pct(targetShare), marginInlineStart: '-1px' }}\n />\n )}\n </div>\n\n {showScale && (\n <div className=\"flex justify-between mono-meta text-(--chart-axis)\">\n <span>{formatValue(scale[0])}</span>\n <span>{formatValue(scale[1])}</span>\n </div>\n )}\n </div>\n )\n}\n\nexport default BulletChart\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { ChartCurveType, AreaStrokeVariant, ChartTooltipSlotProps, ChartLegendSlotProps } from '../AreaChart/AreaChart.js';
|
|
2
|
+
import { BarVariant } from '../BarChart/BarChart.js';
|
|
3
|
+
import * as react from 'react';
|
|
4
|
+
import { ComponentProps, ReactNode, FC } from 'react';
|
|
5
|
+
import { XAxis, YAxis, Bar, ComposedChart as ComposedChart$1, Line, CartesianGrid } from 'recharts';
|
|
6
|
+
import { ChartConfig } from '../lib/chart.js';
|
|
7
|
+
import { ChartEmptyProps } from '../lib/empty.js';
|
|
8
|
+
import { ValuesProps } from '../lib/values.js';
|
|
9
|
+
import { ChartBackgroundVariant } from '../lib/background.js';
|
|
10
|
+
import { ChartDotVariant } from '../lib/dot.js';
|
|
11
|
+
import { BrushProps } from '../lib/brush.js';
|
|
12
|
+
import { ToolbarProps } from '../lib/toolbar.js';
|
|
13
|
+
import { ChartRevealType } from '../lib/paint.js';
|
|
14
|
+
import { ReferenceLine, ReferenceBand, Annotation } from '../lib/annotations.js';
|
|
15
|
+
import '../lib/sonify-control.js';
|
|
16
|
+
import '../lib/sonify.js';
|
|
17
|
+
import '../lib/legend.js';
|
|
18
|
+
import '../lib/tooltip.js';
|
|
19
|
+
import 'recharts/types/component/DefaultTooltipContent';
|
|
20
|
+
import '../lib/zoom.js';
|
|
21
|
+
import '../lib/figure.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The axis props, with `label` narrowed to a string.
|
|
25
|
+
*
|
|
26
|
+
* Recharts' own `label` accepts a render function and a config object, neither
|
|
27
|
+
* of which a call site should be reaching for to name an axis — and both of
|
|
28
|
+
* which would let a consumer opt out of the system's own axis type styling
|
|
29
|
+
* without noticing.
|
|
30
|
+
*/
|
|
31
|
+
type ChartXAxisProps = Omit<ComponentProps<typeof XAxis>, 'label'> & {
|
|
32
|
+
/** What this axis measures. Say the unit here or in the series label, once. */
|
|
33
|
+
label?: string;
|
|
34
|
+
};
|
|
35
|
+
type ChartYAxisProps = Omit<ComponentProps<typeof YAxis>, 'label'> & {
|
|
36
|
+
/** What this axis measures. Say the unit here or in the series label, once. */
|
|
37
|
+
label?: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
type ValidateKeys<TData, TConfig> = {
|
|
41
|
+
[K in keyof TConfig]: K extends keyof TData ? ChartConfig[string] : never;
|
|
42
|
+
};
|
|
43
|
+
interface ComposedChartProps<TData extends Record<string, unknown>, TConfig extends Record<string, ChartConfig[string]>> {
|
|
44
|
+
config: TConfig & ValidateKeys<TData, TConfig>;
|
|
45
|
+
/** The rows the chart draws. One entry per point, bar or category. */
|
|
46
|
+
data: TData[];
|
|
47
|
+
/**
|
|
48
|
+
* What the chart shows, in a sentence a reader could act on. Required, and
|
|
49
|
+
* announced to a screen reader even when it is not printed.
|
|
50
|
+
*/
|
|
51
|
+
title: string;
|
|
52
|
+
/** Prints the title above the plot instead of hiding it from sight. */
|
|
53
|
+
showTitle?: boolean;
|
|
54
|
+
/** A line under the title — the unit, the window, the caveat. */
|
|
55
|
+
description?: ReactNode;
|
|
56
|
+
/**
|
|
57
|
+
* The composed parts — axes, grid, tooltip, legend, and the marks
|
|
58
|
+
* themselves.
|
|
59
|
+
*/
|
|
60
|
+
children: ReactNode;
|
|
61
|
+
/** Merged onto the figure, last, so a call site can size or space it. */
|
|
62
|
+
className?: string;
|
|
63
|
+
/** Escape hatch onto the raw Recharts chart element. */
|
|
64
|
+
chartProps?: ComponentProps<typeof ComposedChart$1>;
|
|
65
|
+
/**
|
|
66
|
+
* How the line between two points is interpolated. Every mark inherits it
|
|
67
|
+
* unless it says otherwise.
|
|
68
|
+
*/
|
|
69
|
+
curveType?: ChartCurveType;
|
|
70
|
+
animationType?: ChartRevealType;
|
|
71
|
+
barGap?: number;
|
|
72
|
+
barCategoryGap?: number;
|
|
73
|
+
/** The series lit on first render. Selection dims every other series. */
|
|
74
|
+
defaultSelectedDataKey?: string | null;
|
|
75
|
+
/** Fires when the selection changes, and with null when it is cleared. */
|
|
76
|
+
onSelectionChange?: (selectedDataKey: string | null) => void;
|
|
77
|
+
/**
|
|
78
|
+
* Swaps the marks for an animated skeleton, keeping the measured height so
|
|
79
|
+
* the page does not jump when the data lands.
|
|
80
|
+
*/
|
|
81
|
+
isLoading?: boolean;
|
|
82
|
+
/** How many bars the skeleton draws. */
|
|
83
|
+
loadingBars?: number;
|
|
84
|
+
/**
|
|
85
|
+
* The row field on the category axis. Needed by the brush and by the table
|
|
86
|
+
* view.
|
|
87
|
+
*/
|
|
88
|
+
xDataKey?: keyof TData & string;
|
|
89
|
+
/**
|
|
90
|
+
* Drops the hidden table view. Only correct when the page prints the data
|
|
91
|
+
* itself.
|
|
92
|
+
*/
|
|
93
|
+
hideDataTable?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* What the chart shows when it has nothing to draw.
|
|
96
|
+
*
|
|
97
|
+
* Rendered instead of the plot whenever `data` is empty and the chart is not
|
|
98
|
+
* loading — the state a real dashboard reaches within a week, and the one an
|
|
99
|
+
* empty pair of axes is indistinguishable from a failed load. `false` keeps
|
|
100
|
+
* the axes, for a chart whose emptiness is itself the reading.
|
|
101
|
+
*/
|
|
102
|
+
empty?: ChartEmptyProps | false;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Bars and lines over one axis — the shape for "the volume, and the rate it
|
|
106
|
+
* moved at".
|
|
107
|
+
*
|
|
108
|
+
* One axis, always. Two measures at different scales belong in two charts or
|
|
109
|
+
* indexed to a common base; a second y-scale lets the author choose where the
|
|
110
|
+
* lines cross, which is the single most misleading thing a chart can do.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* <ComposedChart title="Revenue and profit" config={config} data={data}>
|
|
114
|
+
* <ComposedChart.Grid />
|
|
115
|
+
* <ComposedChart.XAxis dataKey="month" />
|
|
116
|
+
* <ComposedChart.Tooltip />
|
|
117
|
+
* <ComposedChart.Bar dataKey="revenue" variant="duotone" />
|
|
118
|
+
* <ComposedChart.Line dataKey="profit" />
|
|
119
|
+
* </ComposedChart>
|
|
120
|
+
*/
|
|
121
|
+
declare function ComposedChart<TData extends Record<string, unknown>, TConfig extends Record<string, ChartConfig[string]>>({ config, data, title, showTitle, description, children, className, chartProps, curveType, animationType, barGap, barCategoryGap, defaultSelectedDataKey, onSelectionChange, isLoading, loadingBars, xDataKey, hideDataTable, empty, }: ComposedChartProps<TData, TConfig>): react.JSX.Element;
|
|
122
|
+
declare namespace ComposedChart {
|
|
123
|
+
var Bar: ({ dataKey, variant, radius, glowing, animationType, isClickable, enableHoverHighlight, children, barProps, }: ComposedBarProps) => react.JSX.Element | null;
|
|
124
|
+
var Line: ({ dataKey, strokeVariant, curveType, animationType, connectNulls, glowing, isClickable, children, lineProps, }: ComposedLineProps) => react.JSX.Element | null;
|
|
125
|
+
var Dot: FC<DotProps>;
|
|
126
|
+
var ActiveDot: FC<DotProps>;
|
|
127
|
+
var XAxis: ({ tickLine, axisLine, tickMargin, minTickGap, label, ...rest }: ChartXAxisProps) => react.JSX.Element | null;
|
|
128
|
+
var YAxis: ({ tickLine, axisLine, tickMargin, minTickGap, width, tickFormatter, label, ...rest }: ChartYAxisProps) => react.JSX.Element | null;
|
|
129
|
+
var Grid: ({ vertical, strokeDasharray, ...rest }: ComponentProps<typeof CartesianGrid>) => react.JSX.Element;
|
|
130
|
+
var Tooltip: ({ variant, roundness, defaultIndex, cursor }: ChartTooltipSlotProps) => react.JSX.Element | null;
|
|
131
|
+
var Legend: ({ variant, align, verticalAlign, isClickable, }: ChartLegendSlotProps) => react.JSX.Element;
|
|
132
|
+
var Background: ({ variant }: {
|
|
133
|
+
variant: ChartBackgroundVariant;
|
|
134
|
+
}) => react.JSX.Element | null;
|
|
135
|
+
var ReferenceLine: typeof ReferenceLine;
|
|
136
|
+
var ReferenceBand: typeof ReferenceBand;
|
|
137
|
+
var Annotation: typeof Annotation;
|
|
138
|
+
var Values: FC<ValuesProps>;
|
|
139
|
+
var Brush: FC<BrushProps>;
|
|
140
|
+
var Toolbar: FC<ToolbarProps>;
|
|
141
|
+
}
|
|
142
|
+
interface ComposedBarProps {
|
|
143
|
+
dataKey: string;
|
|
144
|
+
variant?: BarVariant;
|
|
145
|
+
radius?: number;
|
|
146
|
+
/** A halo behind the bars. */
|
|
147
|
+
glowing?: boolean;
|
|
148
|
+
animationType?: ChartRevealType;
|
|
149
|
+
isClickable?: boolean;
|
|
150
|
+
/** Dims this series while another COLUMN is hovered. */
|
|
151
|
+
enableHoverHighlight?: boolean;
|
|
152
|
+
/** `<ComposedChart.Values>`. */
|
|
153
|
+
children?: ReactNode;
|
|
154
|
+
barProps?: ComponentProps<typeof Bar>;
|
|
155
|
+
}
|
|
156
|
+
interface ComposedLineProps {
|
|
157
|
+
dataKey: string;
|
|
158
|
+
strokeVariant?: AreaStrokeVariant;
|
|
159
|
+
curveType?: ChartCurveType;
|
|
160
|
+
animationType?: ChartRevealType;
|
|
161
|
+
connectNulls?: boolean;
|
|
162
|
+
glowing?: boolean;
|
|
163
|
+
isClickable?: boolean;
|
|
164
|
+
children?: ReactNode;
|
|
165
|
+
lineProps?: ComponentProps<typeof Line>;
|
|
166
|
+
}
|
|
167
|
+
interface DotProps {
|
|
168
|
+
variant?: ChartDotVariant;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export { type ChartXAxisProps, type ChartYAxisProps, type ComposedBarProps, ComposedChart, type ComposedChartProps, type ComposedLineProps, type DotProps, ComposedChart as default };
|