@sckyzo/cosmos-charts 0.1.1 → 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/CHANGELOG.md +103 -0
- package/README.md +107 -16
- package/THIRD_PARTY_NOTICES.md +81 -0
- package/dist/BarChart.cjs +137 -0
- package/dist/BarChart.cjs.map +1 -0
- package/dist/BarChart.js +135 -0
- package/dist/BarChart.js.map +1 -0
- package/dist/BoxPlotChart.cjs +214 -0
- package/dist/BoxPlotChart.cjs.map +1 -0
- package/dist/BoxPlotChart.js +212 -0
- package/dist/BoxPlotChart.js.map +1 -0
- package/dist/BumpChart.cjs +328 -0
- package/dist/BumpChart.cjs.map +1 -0
- package/dist/BumpChart.js +326 -0
- package/dist/BumpChart.js.map +1 -0
- package/dist/CalendarChart.cjs +216 -0
- package/dist/CalendarChart.cjs.map +1 -0
- package/dist/CalendarChart.js +214 -0
- package/dist/CalendarChart.js.map +1 -0
- package/dist/DonutChart.cjs +122 -0
- package/dist/DonutChart.cjs.map +1 -0
- package/dist/DonutChart.js +120 -0
- package/dist/DonutChart.js.map +1 -0
- package/dist/FunnelChart.cjs +422 -0
- package/dist/FunnelChart.cjs.map +1 -0
- package/dist/FunnelChart.js +420 -0
- package/dist/FunnelChart.js.map +1 -0
- package/dist/GradientRadial.cjs +51 -0
- package/dist/GradientRadial.cjs.map +1 -0
- package/dist/GradientRadial.js +49 -0
- package/dist/GradientRadial.js.map +1 -0
- package/dist/HeatmapChart.cjs +146 -0
- package/dist/HeatmapChart.cjs.map +1 -0
- package/dist/HeatmapChart.js +144 -0
- package/dist/HeatmapChart.js.map +1 -0
- package/dist/LineAreaChart.cjs +98 -0
- package/dist/LineAreaChart.cjs.map +1 -0
- package/dist/LineAreaChart.js +96 -0
- package/dist/LineAreaChart.js.map +1 -0
- package/dist/MixedChart.cjs +195 -0
- package/dist/MixedChart.cjs.map +1 -0
- package/dist/MixedChart.js +193 -0
- package/dist/MixedChart.js.map +1 -0
- package/dist/RadarChart.cjs +109 -0
- package/dist/RadarChart.cjs.map +1 -0
- package/dist/RadarChart.js +107 -0
- package/dist/RadarChart.js.map +1 -0
- package/dist/RadialBarChart.cjs +99 -0
- package/dist/RadialBarChart.cjs.map +1 -0
- package/dist/RadialBarChart.js +97 -0
- package/dist/RadialBarChart.js.map +1 -0
- package/dist/RangeBarChart.cjs +218 -0
- package/dist/RangeBarChart.cjs.map +1 -0
- package/dist/RangeBarChart.js +216 -0
- package/dist/RangeBarChart.js.map +1 -0
- package/dist/RealtimeChart.cjs +173 -0
- package/dist/RealtimeChart.cjs.map +1 -0
- package/dist/RealtimeChart.js +171 -0
- package/dist/RealtimeChart.js.map +1 -0
- package/dist/ScatterChart.cjs +134 -0
- package/dist/ScatterChart.cjs.map +1 -0
- package/dist/ScatterChart.js +131 -0
- package/dist/ScatterChart.js.map +1 -0
- package/dist/SemiCircleGauge.cjs +142 -0
- package/dist/SemiCircleGauge.cjs.map +1 -0
- package/dist/SemiCircleGauge.js +140 -0
- package/dist/SemiCircleGauge.js.map +1 -0
- package/dist/Sparkline.cjs +117 -0
- package/dist/Sparkline.cjs.map +1 -0
- package/dist/Sparkline.js +115 -0
- package/dist/Sparkline.js.map +1 -0
- package/dist/StrokedGauge.cjs +94 -0
- package/dist/StrokedGauge.cjs.map +1 -0
- package/dist/StrokedGauge.js +92 -0
- package/dist/StrokedGauge.js.map +1 -0
- package/dist/TreemapChart.cjs +263 -0
- package/dist/TreemapChart.cjs.map +1 -0
- package/dist/TreemapChart.js +261 -0
- package/dist/TreemapChart.js.map +1 -0
- package/dist/WaterfallChart.cjs +235 -0
- package/dist/WaterfallChart.cjs.map +1 -0
- package/dist/WaterfallChart.js +233 -0
- package/dist/WaterfallChart.js.map +1 -0
- package/dist/WorldMap.cjs +2088 -0
- package/dist/WorldMap.cjs.map +1 -0
- package/dist/WorldMap.js +603 -0
- package/dist/WorldMap.js.map +1 -0
- package/dist/chunk-3N43QT36.js +60 -0
- package/dist/chunk-3N43QT36.js.map +1 -0
- package/dist/chunk-5C2RLJYZ.js +11 -0
- package/dist/chunk-5C2RLJYZ.js.map +1 -0
- package/dist/chunk-6ALKZLN2.js +127 -0
- package/dist/chunk-6ALKZLN2.js.map +1 -0
- package/dist/chunk-6BKLL7LZ.cjs +30 -0
- package/dist/chunk-6BKLL7LZ.cjs.map +1 -0
- package/dist/chunk-6NRRABPF.cjs +64 -0
- package/dist/chunk-6NRRABPF.cjs.map +1 -0
- package/dist/chunk-AAYHG7YK.cjs +30 -0
- package/dist/chunk-AAYHG7YK.cjs.map +1 -0
- package/dist/chunk-AOSO5QHL.js +19 -0
- package/dist/chunk-AOSO5QHL.js.map +1 -0
- package/dist/chunk-BFEDLXVW.js +12 -0
- package/dist/chunk-BFEDLXVW.js.map +1 -0
- package/dist/chunk-DBZQI4HM.cjs +14 -0
- package/dist/chunk-DBZQI4HM.cjs.map +1 -0
- package/dist/chunk-F2PMFYJ5.cjs +40 -0
- package/dist/chunk-F2PMFYJ5.cjs.map +1 -0
- package/dist/chunk-FUZW3H5X.js +38 -0
- package/dist/chunk-FUZW3H5X.js.map +1 -0
- package/dist/chunk-GDZLYYL2.js +27 -0
- package/dist/chunk-GDZLYYL2.js.map +1 -0
- package/dist/chunk-GVTMZYOM.cjs +30 -0
- package/dist/chunk-GVTMZYOM.cjs.map +1 -0
- package/dist/chunk-GZRMVE4X.cjs +131 -0
- package/dist/chunk-GZRMVE4X.cjs.map +1 -0
- package/dist/chunk-HMH6DI7U.js +27 -0
- package/dist/chunk-HMH6DI7U.js.map +1 -0
- package/dist/chunk-ICL5K2CW.js +280 -0
- package/dist/chunk-ICL5K2CW.js.map +1 -0
- package/dist/chunk-IW6EWB26.cjs +21 -0
- package/dist/chunk-IW6EWB26.cjs.map +1 -0
- package/dist/chunk-K3R7JGOW.cjs +18 -0
- package/dist/chunk-K3R7JGOW.cjs.map +1 -0
- package/dist/chunk-LT3UC65O.cjs +68 -0
- package/dist/chunk-LT3UC65O.cjs.map +1 -0
- package/dist/chunk-MN4CDVOS.cjs +63 -0
- package/dist/chunk-MN4CDVOS.cjs.map +1 -0
- package/dist/chunk-OCD6JIIX.js +23 -0
- package/dist/chunk-OCD6JIIX.js.map +1 -0
- package/dist/chunk-RILUG7JB.js +44 -0
- package/dist/chunk-RILUG7JB.js.map +1 -0
- package/dist/chunk-RLHGPHC7.cjs +51 -0
- package/dist/chunk-RLHGPHC7.cjs.map +1 -0
- package/dist/chunk-SGG7XKOY.js +58 -0
- package/dist/chunk-SGG7XKOY.js.map +1 -0
- package/dist/chunk-T3K6Q34U.cjs +82 -0
- package/dist/chunk-T3K6Q34U.cjs.map +1 -0
- package/dist/chunk-TPH5T3DA.cjs +282 -0
- package/dist/chunk-TPH5T3DA.cjs.map +1 -0
- package/dist/chunk-TYQWZR3S.cjs +13 -0
- package/dist/chunk-TYQWZR3S.cjs.map +1 -0
- package/dist/chunk-UATB2IRY.js +51 -0
- package/dist/chunk-UATB2IRY.js.map +1 -0
- package/dist/chunk-UJIV5PVI.js +13 -0
- package/dist/chunk-UJIV5PVI.js.map +1 -0
- package/dist/chunk-URNXLVSK.js +44 -0
- package/dist/chunk-URNXLVSK.js.map +1 -0
- package/dist/chunk-VIOSQN4Z.js +79 -0
- package/dist/chunk-VIOSQN4Z.js.map +1 -0
- package/dist/chunk-X3YZP5WF.cjs +46 -0
- package/dist/chunk-X3YZP5WF.cjs.map +1 -0
- package/dist/chunk-YWYF5CCJ.js +61 -0
- package/dist/chunk-YWYF5CCJ.js.map +1 -0
- package/dist/chunk-Z4LZFMDH.cjs +60 -0
- package/dist/chunk-Z4LZFMDH.cjs.map +1 -0
- package/dist/index.cjs +155 -522
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +621 -58
- package/dist/index.d.ts +621 -58
- package/dist/index.js +23 -506
- package/dist/index.js.map +1 -1
- package/dist/theme.cjs +88 -0
- package/dist/theme.cjs.map +1 -0
- package/dist/theme.js +84 -0
- package/dist/theme.js.map +1 -0
- package/package.json +25 -14
package/dist/BarChart.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { roundedBarShape, isOuterInStack } from './chunk-GDZLYYL2.js';
|
|
3
|
+
import { useCategoryKeys } from './chunk-FUZW3H5X.js';
|
|
4
|
+
import { referenceMarks } from './chunk-SGG7XKOY.js';
|
|
5
|
+
import { trimLabel, categoryAxis } from './chunk-HMH6DI7U.js';
|
|
6
|
+
import { useHiddenSeries, legendProps } from './chunk-6ALKZLN2.js';
|
|
7
|
+
import { ANIMATION } from './chunk-5C2RLJYZ.js';
|
|
8
|
+
import { useAxis, GRID_PROPS, xAxisTitle, yAxisTitle } from './chunk-RILUG7JB.js';
|
|
9
|
+
import { ChartTooltip } from './chunk-VIOSQN4Z.js';
|
|
10
|
+
import { hasNoData, seriesKey, toRows } from './chunk-UJIV5PVI.js';
|
|
11
|
+
import { ChartEmpty, frameProps } from './chunk-3N43QT36.js';
|
|
12
|
+
import { BORDER, seriesColor } from './chunk-UATB2IRY.js';
|
|
13
|
+
import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Legend, Tooltip, Bar } from 'recharts';
|
|
14
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
15
|
+
|
|
16
|
+
var BarChart = ({
|
|
17
|
+
series,
|
|
18
|
+
categories,
|
|
19
|
+
orientation = "vertical",
|
|
20
|
+
stacked = false,
|
|
21
|
+
colors,
|
|
22
|
+
formatValue,
|
|
23
|
+
xTitle,
|
|
24
|
+
yTitle,
|
|
25
|
+
referenceLines,
|
|
26
|
+
referenceBands,
|
|
27
|
+
showLegend,
|
|
28
|
+
legendPosition = "top",
|
|
29
|
+
borderRadius = 4,
|
|
30
|
+
colorByValue,
|
|
31
|
+
distributed = false,
|
|
32
|
+
negativeColor,
|
|
33
|
+
emptyMessage = "No data",
|
|
34
|
+
ariaLabel,
|
|
35
|
+
children,
|
|
36
|
+
height = 320,
|
|
37
|
+
width
|
|
38
|
+
}) => {
|
|
39
|
+
const hidden = useHiddenSeries();
|
|
40
|
+
const axis = useAxis();
|
|
41
|
+
const categoryKeys = useCategoryKeys(orientation === "horizontal" ? "vertical" : "horizontal");
|
|
42
|
+
const name = ariaLabel ?? `Bar chart: ${series.map((s) => s.name).join(", ")}`;
|
|
43
|
+
if (hasNoData(series)) {
|
|
44
|
+
return /* @__PURE__ */ jsx(ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
45
|
+
}
|
|
46
|
+
const horizontal = orientation === "horizontal";
|
|
47
|
+
const layout = horizontal ? "vertical" : "horizontal";
|
|
48
|
+
const fillFor = colorByValue || negativeColor !== void 0 || distributed ? (value, index) => colorByValue?.(value, index) ?? (negativeColor !== void 0 && value < 0 ? negativeColor : distributed ? seriesColor(index, colors) : void 0) : void 0;
|
|
49
|
+
const shown = series.map((_, i) => seriesKey(i)).filter((key) => !hidden.hidden.has(key));
|
|
50
|
+
return /* @__PURE__ */ jsxs(
|
|
51
|
+
BarChart$1,
|
|
52
|
+
{
|
|
53
|
+
ref: categoryKeys,
|
|
54
|
+
...frameProps({ height, width, ariaLabel: name }),
|
|
55
|
+
data: toRows(categories, series),
|
|
56
|
+
layout,
|
|
57
|
+
stackOffset: "sign",
|
|
58
|
+
margin: { top: 4, right: 8, bottom: 0, left: 0 },
|
|
59
|
+
barGap: 4,
|
|
60
|
+
barCategoryGap: "22%",
|
|
61
|
+
children: [
|
|
62
|
+
/* @__PURE__ */ jsx(
|
|
63
|
+
CartesianGrid,
|
|
64
|
+
{
|
|
65
|
+
...GRID_PROPS,
|
|
66
|
+
...horizontal ? { horizontal: false, vertical: true } : {}
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
horizontal ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
70
|
+
/* @__PURE__ */ jsx(XAxis, { type: "number", tickFormatter: formatValue, ...axis, ...xAxisTitle(xTitle) }),
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
YAxis,
|
|
73
|
+
{
|
|
74
|
+
type: "category",
|
|
75
|
+
dataKey: "category",
|
|
76
|
+
width: "auto",
|
|
77
|
+
tickFormatter: trimLabel,
|
|
78
|
+
...axis,
|
|
79
|
+
...yAxisTitle(yTitle)
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
XAxis,
|
|
85
|
+
{
|
|
86
|
+
dataKey: "category",
|
|
87
|
+
...axis,
|
|
88
|
+
...xAxisTitle(xTitle),
|
|
89
|
+
...categoryAxis(categories, xTitle)
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ jsx(YAxis, { width: "auto", tickFormatter: formatValue, ...axis, ...yAxisTitle(yTitle) })
|
|
93
|
+
] }),
|
|
94
|
+
(showLegend ?? series.length > 1) && /* @__PURE__ */ jsx(Legend, { ...legendProps(legendPosition, hidden) }),
|
|
95
|
+
/* @__PURE__ */ jsx(
|
|
96
|
+
Tooltip,
|
|
97
|
+
{
|
|
98
|
+
content: /* @__PURE__ */ jsx(ChartTooltip, { format: formatValue, colorOf: fillFor }),
|
|
99
|
+
cursor: { fill: BORDER, fillOpacity: 0.35, radius: 8 },
|
|
100
|
+
animationDuration: 150
|
|
101
|
+
}
|
|
102
|
+
),
|
|
103
|
+
series.map((s, i) => {
|
|
104
|
+
const key = seriesKey(i);
|
|
105
|
+
return /* @__PURE__ */ jsx(
|
|
106
|
+
Bar,
|
|
107
|
+
{
|
|
108
|
+
name: s.name,
|
|
109
|
+
dataKey: key,
|
|
110
|
+
fill: seriesColor(i, colors),
|
|
111
|
+
stackId: stacked ? "stack" : void 0,
|
|
112
|
+
maxBarSize: 44,
|
|
113
|
+
shape: roundedBarShape({
|
|
114
|
+
layout,
|
|
115
|
+
radius: borderRadius,
|
|
116
|
+
dataKey: key,
|
|
117
|
+
isOuter: stacked ? isOuterInStack(shown, key) : void 0,
|
|
118
|
+
fillFor
|
|
119
|
+
}),
|
|
120
|
+
hide: hidden.hidden.has(key),
|
|
121
|
+
...ANIMATION
|
|
122
|
+
},
|
|
123
|
+
key
|
|
124
|
+
);
|
|
125
|
+
}),
|
|
126
|
+
referenceMarks({ referenceLines, referenceBands, axis: horizontal ? "x" : "y" }),
|
|
127
|
+
children
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export { BarChart };
|
|
134
|
+
//# sourceMappingURL=BarChart.js.map
|
|
135
|
+
//# sourceMappingURL=BarChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/BarChart.tsx"],"names":["RechartsBarChart"],"mappings":"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","file":"BarChart.js","sourcesContent":["import {\n Bar,\n BarChart as RechartsBarChart,\n CartesianGrid,\n Legend,\n Tooltip,\n XAxis,\n YAxis,\n} from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { GRID_PROPS, useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { categoryAxis, trimLabel } from './core/categoryAxis';\nimport { useCategoryKeys } from './core/categoryKeys';\nimport { ChartTooltip } from './core/ChartTooltip';\nimport { legendProps, useHiddenSeries } from './core/ChartLegend';\nimport { BORDER, seriesColor } from './core/colors';\nimport { hasNoData, seriesKey, toRows } from './core/data';\nimport { ChartEmpty, frameProps } from './core/frame';\nimport { referenceMarks } from './core/reference';\nimport { isOuterInStack, roundedBarShape } from './core/roundedBar';\nimport type {\n ChartAxisTitleProps,\n ChartEmptyProps,\n ChartLegendProps,\n ChartProps,\n ChartReferenceProps,\n} from './types';\n\nexport type BarChartOrientation = 'vertical' | 'horizontal';\n\nexport type BarChartProps = ChartProps &\n ChartEmptyProps &\n ChartLegendProps &\n ChartAxisTitleProps &\n ChartReferenceProps & {\n series: { name: string; data: number[] }[];\n categories: (string | number)[];\n /** `vertical` (default) draws bars upward; `horizontal` draws them rightward. */\n orientation?: BarChartOrientation;\n /** Stack multi-series bars instead of grouping them side-by-side. */\n stacked?: boolean;\n /** Override the default Cosmos palette. */\n colors?: string[];\n /** Format the numeric axis labels and the tooltip values. */\n formatValue?: (value: number) => string;\n /** Show the legend (auto-true when 2+ series). */\n showLegend?: boolean;\n /** Radius, in px, of the end of a bar away from the axis; only the outer end of a stack is rounded. Default 4. */\n borderRadius?: number;\n /**\n * The color of a bar from its value and the index of its category, for a threshold or a\n * ranking. Return `undefined` to keep the color the other rules give. Applies to every\n * series; the tooltip chip of a bar follows it, the legend keeps the series color.\n */\n colorByValue?: (value: number, index: number) => string | undefined;\n /** One palette color per category (`colors` cycles), instead of one per series. For a single series. */\n distributed?: boolean;\n /** The color of the bars below zero, for diverging bars. `colorByValue` wins over it. */\n negativeColor?: string;\n };\n\nexport const BarChart = ({\n series,\n categories,\n orientation = 'vertical',\n stacked = false,\n colors,\n formatValue,\n xTitle,\n yTitle,\n referenceLines,\n referenceBands,\n showLegend,\n legendPosition = 'top',\n borderRadius = 4,\n colorByValue,\n distributed = false,\n negativeColor,\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 320,\n width,\n}: BarChartProps) => {\n const hidden = useHiddenSeries();\n const axis = useAxis();\n // Recharts names the layout after the axis the categories sit on.\n const categoryKeys = useCategoryKeys(orientation === 'horizontal' ? 'vertical' : 'horizontal');\n const name = ariaLabel ?? `Bar chart: ${series.map((s) => s.name).join(', ')}`;\n if (hasNoData(series)) {\n return <ChartEmpty message={emptyMessage} ariaLabel={name} height={height} width={width} />;\n }\n const horizontal = orientation === 'horizontal';\n // Recharts names the layout after the axis the categories sit on.\n const layout = horizontal ? 'vertical' : 'horizontal';\n // A bar's own color, in order of precedence: colorByValue, negativeColor, distributed.\n const fillFor =\n colorByValue || negativeColor !== undefined || distributed\n ? (value: number, index: number) =>\n colorByValue?.(value, index) ??\n (negativeColor !== undefined && value < 0\n ? negativeColor\n : distributed\n ? seriesColor(index, colors)\n : undefined)\n : undefined;\n const shown = series.map((_, i) => seriesKey(i)).filter((key) => !hidden.hidden.has(key));\n return (\n <RechartsBarChart\n ref={categoryKeys}\n {...frameProps({ height, width, ariaLabel: name })}\n data={toRows(categories, series)}\n layout={layout}\n // Stacks of both signs: the negative values stack down from zero, apart from the positive ones.\n stackOffset=\"sign\"\n margin={{ top: 4, right: 8, bottom: 0, left: 0 }}\n barGap={4}\n barCategoryGap=\"22%\"\n >\n <CartesianGrid\n {...GRID_PROPS}\n {...(horizontal ? { horizontal: false, vertical: true } : {})}\n />\n {horizontal ? (\n <>\n <XAxis type=\"number\" tickFormatter={formatValue} {...axis} {...xAxisTitle(xTitle)} />\n <YAxis\n type=\"category\"\n dataKey=\"category\"\n width=\"auto\"\n tickFormatter={trimLabel}\n {...axis}\n {...yAxisTitle(yTitle)}\n />\n </>\n ) : (\n <>\n <XAxis\n dataKey=\"category\"\n {...axis}\n {...xAxisTitle(xTitle)}\n {...categoryAxis(categories, xTitle)}\n />\n <YAxis width=\"auto\" tickFormatter={formatValue} {...axis} {...yAxisTitle(yTitle)} />\n </>\n )}\n {(showLegend ?? series.length > 1) && <Legend {...legendProps(legendPosition, hidden)} />}\n <Tooltip\n content={<ChartTooltip format={formatValue} colorOf={fillFor} />}\n cursor={{ fill: BORDER, fillOpacity: 0.35, radius: 8 }}\n animationDuration={150}\n />\n {series.map((s, i) => {\n const key = seriesKey(i);\n return (\n <Bar\n key={key}\n name={s.name}\n dataKey={key}\n fill={seriesColor(i, colors)}\n stackId={stacked ? 'stack' : undefined}\n maxBarSize={44}\n shape={roundedBarShape({\n layout,\n radius: borderRadius,\n dataKey: key,\n isOuter: stacked ? isOuterInStack(shown, key) : undefined,\n fillFor,\n })}\n hide={hidden.hidden.has(key)}\n {...ANIMATION}\n />\n );\n })}\n {referenceMarks({ referenceLines, referenceBands, axis: horizontal ? 'x' : 'y' })}\n {children}\n </RechartsBarChart>\n );\n};\n"]}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkF2PMFYJ5_cjs = require('./chunk-F2PMFYJ5.cjs');
|
|
5
|
+
var chunkZ4LZFMDH_cjs = require('./chunk-Z4LZFMDH.cjs');
|
|
6
|
+
var chunk6BKLL7LZ_cjs = require('./chunk-6BKLL7LZ.cjs');
|
|
7
|
+
var chunkGZRMVE4X_cjs = require('./chunk-GZRMVE4X.cjs');
|
|
8
|
+
var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
|
|
9
|
+
var chunkRLHGPHC7_cjs = require('./chunk-RLHGPHC7.cjs');
|
|
10
|
+
var chunkT3K6Q34U_cjs = require('./chunk-T3K6Q34U.cjs');
|
|
11
|
+
var chunkK3R7JGOW_cjs = require('./chunk-K3R7JGOW.cjs');
|
|
12
|
+
var chunk6NRRABPF_cjs = require('./chunk-6NRRABPF.cjs');
|
|
13
|
+
var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
|
|
14
|
+
var recharts = require('recharts');
|
|
15
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
16
|
+
|
|
17
|
+
var ROWS = [
|
|
18
|
+
["Max", 4],
|
|
19
|
+
["Q3", 3],
|
|
20
|
+
["Median", 2],
|
|
21
|
+
["Q1", 1],
|
|
22
|
+
["Min", 0]
|
|
23
|
+
];
|
|
24
|
+
var summaryKey = (index) => `box${index}`;
|
|
25
|
+
var boxShape = (index, color, horizontal) => (props) => {
|
|
26
|
+
const { x, y, width, height } = props;
|
|
27
|
+
const row = props.payload;
|
|
28
|
+
const summary = row[summaryKey(index)];
|
|
29
|
+
if (!summary) return null;
|
|
30
|
+
const [min, q1, median, q3, max] = summary;
|
|
31
|
+
const span = max - min || 1;
|
|
32
|
+
const left = Math.min(x, x + width);
|
|
33
|
+
const top = Math.min(y, y + height);
|
|
34
|
+
const w = Math.abs(width);
|
|
35
|
+
const h = Math.abs(height);
|
|
36
|
+
const at = (v) => horizontal ? left + (v - min) / span * w : top + (max - v) / span * h;
|
|
37
|
+
const mid = horizontal ? top + h / 2 : left + w / 2;
|
|
38
|
+
const size = horizontal ? h : w;
|
|
39
|
+
const cap = size * 0.25;
|
|
40
|
+
const point = (value, across) => horizontal ? { x: at(value), y: across } : { x: across, y: at(value) };
|
|
41
|
+
const line = (from, to, key, wide = 1.5) => /* @__PURE__ */ jsxRuntime.jsx("line", { x1: from.x, y1: from.y, x2: to.x, y2: to.y, stroke: color, strokeWidth: wide }, key);
|
|
42
|
+
const [boxStart, boxEnd] = [at(q1), at(q3)];
|
|
43
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
|
|
44
|
+
line(point(min, mid), point(q1, mid), "lower"),
|
|
45
|
+
line(point(q3, mid), point(max, mid), "upper"),
|
|
46
|
+
line(point(min, mid - cap), point(min, mid + cap), "min"),
|
|
47
|
+
line(point(max, mid - cap), point(max, mid + cap), "max"),
|
|
48
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
49
|
+
"rect",
|
|
50
|
+
{
|
|
51
|
+
x: horizontal ? Math.min(boxStart, boxEnd) : mid - size / 2,
|
|
52
|
+
y: horizontal ? mid - size / 2 : Math.min(boxStart, boxEnd),
|
|
53
|
+
width: horizontal ? Math.abs(boxEnd - boxStart) : size,
|
|
54
|
+
height: horizontal ? size : Math.abs(boxEnd - boxStart),
|
|
55
|
+
rx: 2,
|
|
56
|
+
fill: color,
|
|
57
|
+
fillOpacity: 0.35,
|
|
58
|
+
stroke: color,
|
|
59
|
+
strokeWidth: 1.5
|
|
60
|
+
}
|
|
61
|
+
),
|
|
62
|
+
line(point(median, mid - size / 2), point(median, mid + size / 2), "median", 2.5)
|
|
63
|
+
] });
|
|
64
|
+
};
|
|
65
|
+
var BoxPlotChart = ({
|
|
66
|
+
series,
|
|
67
|
+
categories,
|
|
68
|
+
orientation = "vertical",
|
|
69
|
+
colors,
|
|
70
|
+
formatValue = String,
|
|
71
|
+
xTitle,
|
|
72
|
+
yTitle,
|
|
73
|
+
referenceLines,
|
|
74
|
+
referenceBands,
|
|
75
|
+
showLegend,
|
|
76
|
+
legendPosition = "top",
|
|
77
|
+
emptyMessage = "No data",
|
|
78
|
+
ariaLabel,
|
|
79
|
+
children,
|
|
80
|
+
height = 320,
|
|
81
|
+
width
|
|
82
|
+
}) => {
|
|
83
|
+
const hidden = chunkGZRMVE4X_cjs.useHiddenSeries();
|
|
84
|
+
const axis = chunkRLHGPHC7_cjs.useAxis();
|
|
85
|
+
const categoryKeys = chunkF2PMFYJ5_cjs.useCategoryKeys(orientation === "horizontal" ? "vertical" : "horizontal");
|
|
86
|
+
const name = ariaLabel ?? `Box plot: ${series.map((s) => s.name).join(", ")}`;
|
|
87
|
+
if (chunkK3R7JGOW_cjs.hasNoData(series)) {
|
|
88
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunk6NRRABPF_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
89
|
+
}
|
|
90
|
+
const horizontal = orientation === "horizontal";
|
|
91
|
+
const rows = categories.map((category, i) => ({
|
|
92
|
+
category,
|
|
93
|
+
...Object.fromEntries(
|
|
94
|
+
series.flatMap((s, index) => {
|
|
95
|
+
const summary = s.data[i];
|
|
96
|
+
return summary ? [
|
|
97
|
+
[summaryKey(index), summary],
|
|
98
|
+
[chunkK3R7JGOW_cjs.seriesKey(index), [summary[0], summary[4]]]
|
|
99
|
+
] : [];
|
|
100
|
+
})
|
|
101
|
+
)
|
|
102
|
+
}));
|
|
103
|
+
const tooltip = ({ active, payload, label }) => {
|
|
104
|
+
const row = payload?.[0]?.payload;
|
|
105
|
+
if (!active || !row) return null;
|
|
106
|
+
const lines = series.flatMap((s, index) => {
|
|
107
|
+
const summary = row[summaryKey(index)];
|
|
108
|
+
if (!summary || hidden.hidden.has(chunkK3R7JGOW_cjs.seriesKey(index))) return [];
|
|
109
|
+
const color = chunkLT3UC65O_cjs.seriesColor(index, colors);
|
|
110
|
+
return [
|
|
111
|
+
...series.length > 1 ? [{ name: s.name, value: "", color }] : [],
|
|
112
|
+
...ROWS.map(([title, at]) => ({
|
|
113
|
+
name: title,
|
|
114
|
+
value: formatValue(summary[at]),
|
|
115
|
+
color: series.length > 1 ? "transparent" : color
|
|
116
|
+
}))
|
|
117
|
+
];
|
|
118
|
+
});
|
|
119
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkT3K6Q34U_cjs.TooltipCard, { title: label, rows: lines });
|
|
120
|
+
};
|
|
121
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
122
|
+
recharts.BarChart,
|
|
123
|
+
{
|
|
124
|
+
ref: categoryKeys,
|
|
125
|
+
...chunk6NRRABPF_cjs.frameProps({ height, width, ariaLabel: name }),
|
|
126
|
+
data: rows,
|
|
127
|
+
layout: horizontal ? "vertical" : "horizontal",
|
|
128
|
+
margin: { top: 4, right: 12, bottom: 0, left: 0 },
|
|
129
|
+
barGap: 4,
|
|
130
|
+
barCategoryGap: "22%",
|
|
131
|
+
children: [
|
|
132
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
133
|
+
recharts.CartesianGrid,
|
|
134
|
+
{
|
|
135
|
+
...chunkRLHGPHC7_cjs.GRID_PROPS,
|
|
136
|
+
...horizontal ? { horizontal: false, vertical: true } : {}
|
|
137
|
+
}
|
|
138
|
+
),
|
|
139
|
+
horizontal ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
140
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
141
|
+
recharts.XAxis,
|
|
142
|
+
{
|
|
143
|
+
type: "number",
|
|
144
|
+
domain: ["auto", "auto"],
|
|
145
|
+
tickFormatter: formatValue,
|
|
146
|
+
...axis,
|
|
147
|
+
...chunkRLHGPHC7_cjs.xAxisTitle(xTitle)
|
|
148
|
+
}
|
|
149
|
+
),
|
|
150
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
151
|
+
recharts.YAxis,
|
|
152
|
+
{
|
|
153
|
+
type: "category",
|
|
154
|
+
dataKey: "category",
|
|
155
|
+
width: "auto",
|
|
156
|
+
tickFormatter: chunk6BKLL7LZ_cjs.trimLabel,
|
|
157
|
+
...axis,
|
|
158
|
+
...chunkRLHGPHC7_cjs.yAxisTitle(yTitle)
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
162
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
163
|
+
recharts.XAxis,
|
|
164
|
+
{
|
|
165
|
+
dataKey: "category",
|
|
166
|
+
...axis,
|
|
167
|
+
...chunkRLHGPHC7_cjs.xAxisTitle(xTitle),
|
|
168
|
+
...chunk6BKLL7LZ_cjs.categoryAxis(categories, xTitle)
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
172
|
+
recharts.YAxis,
|
|
173
|
+
{
|
|
174
|
+
type: "number",
|
|
175
|
+
domain: ["auto", "auto"],
|
|
176
|
+
width: "auto",
|
|
177
|
+
tickFormatter: formatValue,
|
|
178
|
+
...axis,
|
|
179
|
+
...chunkRLHGPHC7_cjs.yAxisTitle(yTitle)
|
|
180
|
+
}
|
|
181
|
+
)
|
|
182
|
+
] }),
|
|
183
|
+
(showLegend ?? series.length > 1) && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { ...chunkGZRMVE4X_cjs.legendProps(legendPosition, hidden) }),
|
|
184
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
185
|
+
recharts.Tooltip,
|
|
186
|
+
{
|
|
187
|
+
content: tooltip,
|
|
188
|
+
cursor: { fill: chunkLT3UC65O_cjs.BORDER, fillOpacity: 0.35, radius: 8 },
|
|
189
|
+
animationDuration: 150
|
|
190
|
+
}
|
|
191
|
+
),
|
|
192
|
+
series.map((s, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
193
|
+
recharts.Bar,
|
|
194
|
+
{
|
|
195
|
+
name: s.name,
|
|
196
|
+
dataKey: chunkK3R7JGOW_cjs.seriesKey(index),
|
|
197
|
+
fill: chunkLT3UC65O_cjs.seriesColor(index, colors),
|
|
198
|
+
maxBarSize: 56,
|
|
199
|
+
shape: boxShape(index, chunkLT3UC65O_cjs.seriesColor(index, colors), horizontal),
|
|
200
|
+
hide: hidden.hidden.has(chunkK3R7JGOW_cjs.seriesKey(index)),
|
|
201
|
+
...chunkTYQWZR3S_cjs.ANIMATION
|
|
202
|
+
},
|
|
203
|
+
chunkK3R7JGOW_cjs.seriesKey(index)
|
|
204
|
+
)),
|
|
205
|
+
chunkZ4LZFMDH_cjs.referenceMarks({ referenceLines, referenceBands, axis: horizontal ? "x" : "y" }),
|
|
206
|
+
children
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
exports.BoxPlotChart = BoxPlotChart;
|
|
213
|
+
//# sourceMappingURL=BoxPlotChart.cjs.map
|
|
214
|
+
//# sourceMappingURL=BoxPlotChart.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/BoxPlotChart.tsx"],"names":["jsx","useHiddenSeries","useAxis","useCategoryKeys","hasNoData","ChartEmpty","seriesKey","seriesColor","TooltipCard","jsxs","BarChart","frameProps","CartesianGrid","GRID_PROPS","Fragment","XAxis","xAxisTitle","YAxis","trimLabel","yAxisTitle","categoryAxis","Legend","legendProps","Tooltip","BORDER","Bar","ANIMATION","referenceMarks"],"mappings":"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","file":"BoxPlotChart.cjs","sourcesContent":["import {\n Bar,\n BarChart,\n CartesianGrid,\n Legend,\n Tooltip,\n XAxis,\n YAxis,\n type BarShapeProps,\n type TooltipContentProps,\n} from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { GRID_PROPS, useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { categoryAxis, trimLabel } from './core/categoryAxis';\nimport { useCategoryKeys } from './core/categoryKeys';\nimport { TooltipCard, type TooltipRow } from './core/ChartTooltip';\nimport { legendProps, useHiddenSeries } from './core/ChartLegend';\nimport { BORDER, seriesColor } from './core/colors';\nimport { hasNoData, seriesKey } from './core/data';\nimport { ChartEmpty, frameProps } from './core/frame';\nimport { referenceMarks } from './core/reference';\nimport type {\n ChartAxisTitleProps,\n ChartEmptyProps,\n ChartLegendProps,\n ChartProps,\n ChartReferenceProps,\n} from './types';\n\nexport type BoxPlotChartOrientation = 'vertical' | 'horizontal';\n\n/** One box, the five-number summary of a distribution. */\nexport type BoxPlotSummary = [min: number, q1: number, median: number, q3: number, max: number];\n\nexport type BoxPlotChartProps = ChartProps &\n ChartEmptyProps &\n ChartLegendProps &\n ChartAxisTitleProps &\n ChartReferenceProps & {\n /** One summary per category, in the order of `categories`. */\n series: { name: string; data: BoxPlotSummary[] }[];\n categories: string[];\n /** `vertical` (default) draws boxes upward; `horizontal` draws them rightward. */\n orientation?: BoxPlotChartOrientation;\n /** Override the default Cosmos palette, one color per series. */\n colors?: string[];\n /** Format the value axis labels and the tooltip values. */\n formatValue?: (value: number) => string;\n /** Show the legend (auto-true when 2+ series). */\n showLegend?: boolean;\n };\n\n// Top to bottom, the way a vertical box reads.\nconst ROWS = [\n ['Max', 4],\n ['Q3', 3],\n ['Median', 2],\n ['Q1', 1],\n ['Min', 0],\n] as const;\n\nconst summaryKey = (index: number) => `box${index}`;\n\ntype Row = { category: string } & Record<string, unknown>;\n\n// A bar's value is the span of the whiskers, so Recharts sizes and places it\n// and fits the value axis to it; the shape draws the box, the median and the\n// whiskers at the same scale. Recharts has no box plot of its own.\nconst boxShape = (index: number, color: string, horizontal: boolean) => (props: BarShapeProps) => {\n const { x, y, width, height } = props;\n const row = props.payload as Row;\n const summary = row[summaryKey(index)] as BoxPlotSummary | undefined;\n if (!summary) return null;\n const [min, q1, median, q3, max] = summary;\n const span = max - min || 1;\n const left = Math.min(x, x + width);\n const top = Math.min(y, y + height);\n const w = Math.abs(width);\n const h = Math.abs(height);\n // Position of a value along the value axis, and the cross-axis center.\n const at = (v: number) =>\n horizontal ? left + ((v - min) / span) * w : top + ((max - v) / span) * h;\n const mid = horizontal ? top + h / 2 : left + w / 2;\n const size = horizontal ? h : w;\n const cap = size * 0.25;\n const point = (value: number, across: number) =>\n horizontal ? { x: at(value), y: across } : { x: across, y: at(value) };\n const line = (\n from: { x: number; y: number },\n to: { x: number; y: number },\n key: string,\n wide = 1.5\n ) => (\n <line key={key} x1={from.x} y1={from.y} x2={to.x} y2={to.y} stroke={color} strokeWidth={wide} />\n );\n const [boxStart, boxEnd] = [at(q1), at(q3)];\n return (\n <g>\n {line(point(min, mid), point(q1, mid), 'lower')}\n {line(point(q3, mid), point(max, mid), 'upper')}\n {line(point(min, mid - cap), point(min, mid + cap), 'min')}\n {line(point(max, mid - cap), point(max, mid + cap), 'max')}\n <rect\n x={horizontal ? Math.min(boxStart, boxEnd) : mid - size / 2}\n y={horizontal ? mid - size / 2 : Math.min(boxStart, boxEnd)}\n width={horizontal ? Math.abs(boxEnd - boxStart) : size}\n height={horizontal ? size : Math.abs(boxEnd - boxStart)}\n rx={2}\n fill={color}\n fillOpacity={0.35}\n stroke={color}\n strokeWidth={1.5}\n />\n {line(point(median, mid - size / 2), point(median, mid + size / 2), 'median', 2.5)}\n </g>\n );\n};\n\n/** Distributions per category (min, quartiles, median, max), e.g. response times per service. */\nexport const BoxPlotChart = ({\n series,\n categories,\n orientation = 'vertical',\n colors,\n formatValue = String,\n xTitle,\n yTitle,\n referenceLines,\n referenceBands,\n showLegend,\n legendPosition = 'top',\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 320,\n width,\n}: BoxPlotChartProps) => {\n const hidden = useHiddenSeries();\n const axis = useAxis();\n // Recharts names the layout after the axis the categories sit on.\n const categoryKeys = useCategoryKeys(orientation === 'horizontal' ? 'vertical' : 'horizontal');\n const name = ariaLabel ?? `Box plot: ${series.map((s) => s.name).join(', ')}`;\n if (hasNoData(series)) {\n return <ChartEmpty message={emptyMessage} ariaLabel={name} height={height} width={width} />;\n }\n const horizontal = orientation === 'horizontal';\n const rows: Row[] = categories.map((category, i) => ({\n category,\n ...Object.fromEntries(\n series.flatMap((s, index) => {\n const summary = s.data[i];\n return summary\n ? [\n [summaryKey(index), summary],\n [seriesKey(index), [summary[0], summary[4]]],\n ]\n : [];\n })\n ),\n }));\n\n // The category, then the five numbers of each series shown, headed by its name when there are several.\n const tooltip = ({ active, payload, label }: Partial<TooltipContentProps>) => {\n const row = payload?.[0]?.payload as Row | undefined;\n if (!active || !row) return null;\n const lines = series.flatMap((s, index): TooltipRow[] => {\n const summary = row[summaryKey(index)] as BoxPlotSummary | undefined;\n if (!summary || hidden.hidden.has(seriesKey(index))) return [];\n const color = seriesColor(index, colors);\n return [\n ...(series.length > 1 ? [{ name: s.name, value: '', color }] : []),\n ...ROWS.map(([title, at]) => ({\n name: title,\n value: formatValue(summary[at]),\n color: series.length > 1 ? 'transparent' : color,\n })),\n ];\n });\n return <TooltipCard title={label} rows={lines} />;\n };\n\n return (\n <BarChart\n ref={categoryKeys}\n {...frameProps({ height, width, ariaLabel: name })}\n data={rows}\n // Recharts names the layout after the axis the categories sit on.\n layout={horizontal ? 'vertical' : 'horizontal'}\n margin={{ top: 4, right: 12, bottom: 0, left: 0 }}\n barGap={4}\n barCategoryGap=\"22%\"\n >\n <CartesianGrid\n {...GRID_PROPS}\n {...(horizontal ? { horizontal: false, vertical: true } : {})}\n />\n {horizontal ? (\n <>\n <XAxis\n type=\"number\"\n domain={['auto', 'auto']}\n tickFormatter={formatValue}\n {...axis}\n {...xAxisTitle(xTitle)}\n />\n <YAxis\n type=\"category\"\n dataKey=\"category\"\n width=\"auto\"\n tickFormatter={trimLabel}\n {...axis}\n {...yAxisTitle(yTitle)}\n />\n </>\n ) : (\n <>\n <XAxis\n dataKey=\"category\"\n {...axis}\n {...xAxisTitle(xTitle)}\n {...categoryAxis(categories, xTitle)}\n />\n <YAxis\n type=\"number\"\n domain={['auto', 'auto']}\n width=\"auto\"\n tickFormatter={formatValue}\n {...axis}\n {...yAxisTitle(yTitle)}\n />\n </>\n )}\n {(showLegend ?? series.length > 1) && <Legend {...legendProps(legendPosition, hidden)} />}\n <Tooltip\n content={tooltip}\n cursor={{ fill: BORDER, fillOpacity: 0.35, radius: 8 }}\n animationDuration={150}\n />\n {series.map((s, index) => (\n <Bar\n key={seriesKey(index)}\n name={s.name}\n dataKey={seriesKey(index)}\n fill={seriesColor(index, colors)}\n maxBarSize={56}\n shape={boxShape(index, seriesColor(index, colors), horizontal)}\n hide={hidden.hidden.has(seriesKey(index))}\n {...ANIMATION}\n />\n ))}\n {referenceMarks({ referenceLines, referenceBands, axis: horizontal ? 'x' : 'y' })}\n {children}\n </BarChart>\n );\n};\n"]}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCategoryKeys } from './chunk-FUZW3H5X.js';
|
|
3
|
+
import { referenceMarks } from './chunk-SGG7XKOY.js';
|
|
4
|
+
import { trimLabel, categoryAxis } from './chunk-HMH6DI7U.js';
|
|
5
|
+
import { useHiddenSeries, legendProps } from './chunk-6ALKZLN2.js';
|
|
6
|
+
import { ANIMATION } from './chunk-5C2RLJYZ.js';
|
|
7
|
+
import { useAxis, GRID_PROPS, xAxisTitle, yAxisTitle } from './chunk-RILUG7JB.js';
|
|
8
|
+
import { TooltipCard } from './chunk-VIOSQN4Z.js';
|
|
9
|
+
import { hasNoData, seriesKey } from './chunk-UJIV5PVI.js';
|
|
10
|
+
import { ChartEmpty, frameProps } from './chunk-3N43QT36.js';
|
|
11
|
+
import { BORDER, seriesColor } from './chunk-UATB2IRY.js';
|
|
12
|
+
import { BarChart, CartesianGrid, XAxis, YAxis, Legend, Tooltip, Bar } from 'recharts';
|
|
13
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
14
|
+
|
|
15
|
+
var ROWS = [
|
|
16
|
+
["Max", 4],
|
|
17
|
+
["Q3", 3],
|
|
18
|
+
["Median", 2],
|
|
19
|
+
["Q1", 1],
|
|
20
|
+
["Min", 0]
|
|
21
|
+
];
|
|
22
|
+
var summaryKey = (index) => `box${index}`;
|
|
23
|
+
var boxShape = (index, color, horizontal) => (props) => {
|
|
24
|
+
const { x, y, width, height } = props;
|
|
25
|
+
const row = props.payload;
|
|
26
|
+
const summary = row[summaryKey(index)];
|
|
27
|
+
if (!summary) return null;
|
|
28
|
+
const [min, q1, median, q3, max] = summary;
|
|
29
|
+
const span = max - min || 1;
|
|
30
|
+
const left = Math.min(x, x + width);
|
|
31
|
+
const top = Math.min(y, y + height);
|
|
32
|
+
const w = Math.abs(width);
|
|
33
|
+
const h = Math.abs(height);
|
|
34
|
+
const at = (v) => horizontal ? left + (v - min) / span * w : top + (max - v) / span * h;
|
|
35
|
+
const mid = horizontal ? top + h / 2 : left + w / 2;
|
|
36
|
+
const size = horizontal ? h : w;
|
|
37
|
+
const cap = size * 0.25;
|
|
38
|
+
const point = (value, across) => horizontal ? { x: at(value), y: across } : { x: across, y: at(value) };
|
|
39
|
+
const line = (from, to, key, wide = 1.5) => /* @__PURE__ */ jsx("line", { x1: from.x, y1: from.y, x2: to.x, y2: to.y, stroke: color, strokeWidth: wide }, key);
|
|
40
|
+
const [boxStart, boxEnd] = [at(q1), at(q3)];
|
|
41
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
42
|
+
line(point(min, mid), point(q1, mid), "lower"),
|
|
43
|
+
line(point(q3, mid), point(max, mid), "upper"),
|
|
44
|
+
line(point(min, mid - cap), point(min, mid + cap), "min"),
|
|
45
|
+
line(point(max, mid - cap), point(max, mid + cap), "max"),
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
"rect",
|
|
48
|
+
{
|
|
49
|
+
x: horizontal ? Math.min(boxStart, boxEnd) : mid - size / 2,
|
|
50
|
+
y: horizontal ? mid - size / 2 : Math.min(boxStart, boxEnd),
|
|
51
|
+
width: horizontal ? Math.abs(boxEnd - boxStart) : size,
|
|
52
|
+
height: horizontal ? size : Math.abs(boxEnd - boxStart),
|
|
53
|
+
rx: 2,
|
|
54
|
+
fill: color,
|
|
55
|
+
fillOpacity: 0.35,
|
|
56
|
+
stroke: color,
|
|
57
|
+
strokeWidth: 1.5
|
|
58
|
+
}
|
|
59
|
+
),
|
|
60
|
+
line(point(median, mid - size / 2), point(median, mid + size / 2), "median", 2.5)
|
|
61
|
+
] });
|
|
62
|
+
};
|
|
63
|
+
var BoxPlotChart = ({
|
|
64
|
+
series,
|
|
65
|
+
categories,
|
|
66
|
+
orientation = "vertical",
|
|
67
|
+
colors,
|
|
68
|
+
formatValue = String,
|
|
69
|
+
xTitle,
|
|
70
|
+
yTitle,
|
|
71
|
+
referenceLines,
|
|
72
|
+
referenceBands,
|
|
73
|
+
showLegend,
|
|
74
|
+
legendPosition = "top",
|
|
75
|
+
emptyMessage = "No data",
|
|
76
|
+
ariaLabel,
|
|
77
|
+
children,
|
|
78
|
+
height = 320,
|
|
79
|
+
width
|
|
80
|
+
}) => {
|
|
81
|
+
const hidden = useHiddenSeries();
|
|
82
|
+
const axis = useAxis();
|
|
83
|
+
const categoryKeys = useCategoryKeys(orientation === "horizontal" ? "vertical" : "horizontal");
|
|
84
|
+
const name = ariaLabel ?? `Box plot: ${series.map((s) => s.name).join(", ")}`;
|
|
85
|
+
if (hasNoData(series)) {
|
|
86
|
+
return /* @__PURE__ */ jsx(ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
87
|
+
}
|
|
88
|
+
const horizontal = orientation === "horizontal";
|
|
89
|
+
const rows = categories.map((category, i) => ({
|
|
90
|
+
category,
|
|
91
|
+
...Object.fromEntries(
|
|
92
|
+
series.flatMap((s, index) => {
|
|
93
|
+
const summary = s.data[i];
|
|
94
|
+
return summary ? [
|
|
95
|
+
[summaryKey(index), summary],
|
|
96
|
+
[seriesKey(index), [summary[0], summary[4]]]
|
|
97
|
+
] : [];
|
|
98
|
+
})
|
|
99
|
+
)
|
|
100
|
+
}));
|
|
101
|
+
const tooltip = ({ active, payload, label }) => {
|
|
102
|
+
const row = payload?.[0]?.payload;
|
|
103
|
+
if (!active || !row) return null;
|
|
104
|
+
const lines = series.flatMap((s, index) => {
|
|
105
|
+
const summary = row[summaryKey(index)];
|
|
106
|
+
if (!summary || hidden.hidden.has(seriesKey(index))) return [];
|
|
107
|
+
const color = seriesColor(index, colors);
|
|
108
|
+
return [
|
|
109
|
+
...series.length > 1 ? [{ name: s.name, value: "", color }] : [],
|
|
110
|
+
...ROWS.map(([title, at]) => ({
|
|
111
|
+
name: title,
|
|
112
|
+
value: formatValue(summary[at]),
|
|
113
|
+
color: series.length > 1 ? "transparent" : color
|
|
114
|
+
}))
|
|
115
|
+
];
|
|
116
|
+
});
|
|
117
|
+
return /* @__PURE__ */ jsx(TooltipCard, { title: label, rows: lines });
|
|
118
|
+
};
|
|
119
|
+
return /* @__PURE__ */ jsxs(
|
|
120
|
+
BarChart,
|
|
121
|
+
{
|
|
122
|
+
ref: categoryKeys,
|
|
123
|
+
...frameProps({ height, width, ariaLabel: name }),
|
|
124
|
+
data: rows,
|
|
125
|
+
layout: horizontal ? "vertical" : "horizontal",
|
|
126
|
+
margin: { top: 4, right: 12, bottom: 0, left: 0 },
|
|
127
|
+
barGap: 4,
|
|
128
|
+
barCategoryGap: "22%",
|
|
129
|
+
children: [
|
|
130
|
+
/* @__PURE__ */ jsx(
|
|
131
|
+
CartesianGrid,
|
|
132
|
+
{
|
|
133
|
+
...GRID_PROPS,
|
|
134
|
+
...horizontal ? { horizontal: false, vertical: true } : {}
|
|
135
|
+
}
|
|
136
|
+
),
|
|
137
|
+
horizontal ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
138
|
+
/* @__PURE__ */ jsx(
|
|
139
|
+
XAxis,
|
|
140
|
+
{
|
|
141
|
+
type: "number",
|
|
142
|
+
domain: ["auto", "auto"],
|
|
143
|
+
tickFormatter: formatValue,
|
|
144
|
+
...axis,
|
|
145
|
+
...xAxisTitle(xTitle)
|
|
146
|
+
}
|
|
147
|
+
),
|
|
148
|
+
/* @__PURE__ */ jsx(
|
|
149
|
+
YAxis,
|
|
150
|
+
{
|
|
151
|
+
type: "category",
|
|
152
|
+
dataKey: "category",
|
|
153
|
+
width: "auto",
|
|
154
|
+
tickFormatter: trimLabel,
|
|
155
|
+
...axis,
|
|
156
|
+
...yAxisTitle(yTitle)
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
160
|
+
/* @__PURE__ */ jsx(
|
|
161
|
+
XAxis,
|
|
162
|
+
{
|
|
163
|
+
dataKey: "category",
|
|
164
|
+
...axis,
|
|
165
|
+
...xAxisTitle(xTitle),
|
|
166
|
+
...categoryAxis(categories, xTitle)
|
|
167
|
+
}
|
|
168
|
+
),
|
|
169
|
+
/* @__PURE__ */ jsx(
|
|
170
|
+
YAxis,
|
|
171
|
+
{
|
|
172
|
+
type: "number",
|
|
173
|
+
domain: ["auto", "auto"],
|
|
174
|
+
width: "auto",
|
|
175
|
+
tickFormatter: formatValue,
|
|
176
|
+
...axis,
|
|
177
|
+
...yAxisTitle(yTitle)
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
] }),
|
|
181
|
+
(showLegend ?? series.length > 1) && /* @__PURE__ */ jsx(Legend, { ...legendProps(legendPosition, hidden) }),
|
|
182
|
+
/* @__PURE__ */ jsx(
|
|
183
|
+
Tooltip,
|
|
184
|
+
{
|
|
185
|
+
content: tooltip,
|
|
186
|
+
cursor: { fill: BORDER, fillOpacity: 0.35, radius: 8 },
|
|
187
|
+
animationDuration: 150
|
|
188
|
+
}
|
|
189
|
+
),
|
|
190
|
+
series.map((s, index) => /* @__PURE__ */ jsx(
|
|
191
|
+
Bar,
|
|
192
|
+
{
|
|
193
|
+
name: s.name,
|
|
194
|
+
dataKey: seriesKey(index),
|
|
195
|
+
fill: seriesColor(index, colors),
|
|
196
|
+
maxBarSize: 56,
|
|
197
|
+
shape: boxShape(index, seriesColor(index, colors), horizontal),
|
|
198
|
+
hide: hidden.hidden.has(seriesKey(index)),
|
|
199
|
+
...ANIMATION
|
|
200
|
+
},
|
|
201
|
+
seriesKey(index)
|
|
202
|
+
)),
|
|
203
|
+
referenceMarks({ referenceLines, referenceBands, axis: horizontal ? "x" : "y" }),
|
|
204
|
+
children
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export { BoxPlotChart };
|
|
211
|
+
//# sourceMappingURL=BoxPlotChart.js.map
|
|
212
|
+
//# sourceMappingURL=BoxPlotChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/BoxPlotChart.tsx"],"names":[],"mappings":"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","file":"BoxPlotChart.js","sourcesContent":["import {\n Bar,\n BarChart,\n CartesianGrid,\n Legend,\n Tooltip,\n XAxis,\n YAxis,\n type BarShapeProps,\n type TooltipContentProps,\n} from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { GRID_PROPS, useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { categoryAxis, trimLabel } from './core/categoryAxis';\nimport { useCategoryKeys } from './core/categoryKeys';\nimport { TooltipCard, type TooltipRow } from './core/ChartTooltip';\nimport { legendProps, useHiddenSeries } from './core/ChartLegend';\nimport { BORDER, seriesColor } from './core/colors';\nimport { hasNoData, seriesKey } from './core/data';\nimport { ChartEmpty, frameProps } from './core/frame';\nimport { referenceMarks } from './core/reference';\nimport type {\n ChartAxisTitleProps,\n ChartEmptyProps,\n ChartLegendProps,\n ChartProps,\n ChartReferenceProps,\n} from './types';\n\nexport type BoxPlotChartOrientation = 'vertical' | 'horizontal';\n\n/** One box, the five-number summary of a distribution. */\nexport type BoxPlotSummary = [min: number, q1: number, median: number, q3: number, max: number];\n\nexport type BoxPlotChartProps = ChartProps &\n ChartEmptyProps &\n ChartLegendProps &\n ChartAxisTitleProps &\n ChartReferenceProps & {\n /** One summary per category, in the order of `categories`. */\n series: { name: string; data: BoxPlotSummary[] }[];\n categories: string[];\n /** `vertical` (default) draws boxes upward; `horizontal` draws them rightward. */\n orientation?: BoxPlotChartOrientation;\n /** Override the default Cosmos palette, one color per series. */\n colors?: string[];\n /** Format the value axis labels and the tooltip values. */\n formatValue?: (value: number) => string;\n /** Show the legend (auto-true when 2+ series). */\n showLegend?: boolean;\n };\n\n// Top to bottom, the way a vertical box reads.\nconst ROWS = [\n ['Max', 4],\n ['Q3', 3],\n ['Median', 2],\n ['Q1', 1],\n ['Min', 0],\n] as const;\n\nconst summaryKey = (index: number) => `box${index}`;\n\ntype Row = { category: string } & Record<string, unknown>;\n\n// A bar's value is the span of the whiskers, so Recharts sizes and places it\n// and fits the value axis to it; the shape draws the box, the median and the\n// whiskers at the same scale. Recharts has no box plot of its own.\nconst boxShape = (index: number, color: string, horizontal: boolean) => (props: BarShapeProps) => {\n const { x, y, width, height } = props;\n const row = props.payload as Row;\n const summary = row[summaryKey(index)] as BoxPlotSummary | undefined;\n if (!summary) return null;\n const [min, q1, median, q3, max] = summary;\n const span = max - min || 1;\n const left = Math.min(x, x + width);\n const top = Math.min(y, y + height);\n const w = Math.abs(width);\n const h = Math.abs(height);\n // Position of a value along the value axis, and the cross-axis center.\n const at = (v: number) =>\n horizontal ? left + ((v - min) / span) * w : top + ((max - v) / span) * h;\n const mid = horizontal ? top + h / 2 : left + w / 2;\n const size = horizontal ? h : w;\n const cap = size * 0.25;\n const point = (value: number, across: number) =>\n horizontal ? { x: at(value), y: across } : { x: across, y: at(value) };\n const line = (\n from: { x: number; y: number },\n to: { x: number; y: number },\n key: string,\n wide = 1.5\n ) => (\n <line key={key} x1={from.x} y1={from.y} x2={to.x} y2={to.y} stroke={color} strokeWidth={wide} />\n );\n const [boxStart, boxEnd] = [at(q1), at(q3)];\n return (\n <g>\n {line(point(min, mid), point(q1, mid), 'lower')}\n {line(point(q3, mid), point(max, mid), 'upper')}\n {line(point(min, mid - cap), point(min, mid + cap), 'min')}\n {line(point(max, mid - cap), point(max, mid + cap), 'max')}\n <rect\n x={horizontal ? Math.min(boxStart, boxEnd) : mid - size / 2}\n y={horizontal ? mid - size / 2 : Math.min(boxStart, boxEnd)}\n width={horizontal ? Math.abs(boxEnd - boxStart) : size}\n height={horizontal ? size : Math.abs(boxEnd - boxStart)}\n rx={2}\n fill={color}\n fillOpacity={0.35}\n stroke={color}\n strokeWidth={1.5}\n />\n {line(point(median, mid - size / 2), point(median, mid + size / 2), 'median', 2.5)}\n </g>\n );\n};\n\n/** Distributions per category (min, quartiles, median, max), e.g. response times per service. */\nexport const BoxPlotChart = ({\n series,\n categories,\n orientation = 'vertical',\n colors,\n formatValue = String,\n xTitle,\n yTitle,\n referenceLines,\n referenceBands,\n showLegend,\n legendPosition = 'top',\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 320,\n width,\n}: BoxPlotChartProps) => {\n const hidden = useHiddenSeries();\n const axis = useAxis();\n // Recharts names the layout after the axis the categories sit on.\n const categoryKeys = useCategoryKeys(orientation === 'horizontal' ? 'vertical' : 'horizontal');\n const name = ariaLabel ?? `Box plot: ${series.map((s) => s.name).join(', ')}`;\n if (hasNoData(series)) {\n return <ChartEmpty message={emptyMessage} ariaLabel={name} height={height} width={width} />;\n }\n const horizontal = orientation === 'horizontal';\n const rows: Row[] = categories.map((category, i) => ({\n category,\n ...Object.fromEntries(\n series.flatMap((s, index) => {\n const summary = s.data[i];\n return summary\n ? [\n [summaryKey(index), summary],\n [seriesKey(index), [summary[0], summary[4]]],\n ]\n : [];\n })\n ),\n }));\n\n // The category, then the five numbers of each series shown, headed by its name when there are several.\n const tooltip = ({ active, payload, label }: Partial<TooltipContentProps>) => {\n const row = payload?.[0]?.payload as Row | undefined;\n if (!active || !row) return null;\n const lines = series.flatMap((s, index): TooltipRow[] => {\n const summary = row[summaryKey(index)] as BoxPlotSummary | undefined;\n if (!summary || hidden.hidden.has(seriesKey(index))) return [];\n const color = seriesColor(index, colors);\n return [\n ...(series.length > 1 ? [{ name: s.name, value: '', color }] : []),\n ...ROWS.map(([title, at]) => ({\n name: title,\n value: formatValue(summary[at]),\n color: series.length > 1 ? 'transparent' : color,\n })),\n ];\n });\n return <TooltipCard title={label} rows={lines} />;\n };\n\n return (\n <BarChart\n ref={categoryKeys}\n {...frameProps({ height, width, ariaLabel: name })}\n data={rows}\n // Recharts names the layout after the axis the categories sit on.\n layout={horizontal ? 'vertical' : 'horizontal'}\n margin={{ top: 4, right: 12, bottom: 0, left: 0 }}\n barGap={4}\n barCategoryGap=\"22%\"\n >\n <CartesianGrid\n {...GRID_PROPS}\n {...(horizontal ? { horizontal: false, vertical: true } : {})}\n />\n {horizontal ? (\n <>\n <XAxis\n type=\"number\"\n domain={['auto', 'auto']}\n tickFormatter={formatValue}\n {...axis}\n {...xAxisTitle(xTitle)}\n />\n <YAxis\n type=\"category\"\n dataKey=\"category\"\n width=\"auto\"\n tickFormatter={trimLabel}\n {...axis}\n {...yAxisTitle(yTitle)}\n />\n </>\n ) : (\n <>\n <XAxis\n dataKey=\"category\"\n {...axis}\n {...xAxisTitle(xTitle)}\n {...categoryAxis(categories, xTitle)}\n />\n <YAxis\n type=\"number\"\n domain={['auto', 'auto']}\n width=\"auto\"\n tickFormatter={formatValue}\n {...axis}\n {...yAxisTitle(yTitle)}\n />\n </>\n )}\n {(showLegend ?? series.length > 1) && <Legend {...legendProps(legendPosition, hidden)} />}\n <Tooltip\n content={tooltip}\n cursor={{ fill: BORDER, fillOpacity: 0.35, radius: 8 }}\n animationDuration={150}\n />\n {series.map((s, index) => (\n <Bar\n key={seriesKey(index)}\n name={s.name}\n dataKey={seriesKey(index)}\n fill={seriesColor(index, colors)}\n maxBarSize={56}\n shape={boxShape(index, seriesColor(index, colors), horizontal)}\n hide={hidden.hidden.has(seriesKey(index))}\n {...ANIMATION}\n />\n ))}\n {referenceMarks({ referenceLines, referenceBands, axis: horizontal ? 'x' : 'y' })}\n {children}\n </BarChart>\n );\n};\n"]}
|