@sckyzo/cosmos-charts 0.2.0 → 0.3.1
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 +98 -0
- package/README.md +107 -22
- 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 +218 -0
- package/dist/CalendarChart.cjs.map +1 -0
- package/dist/CalendarChart.js +216 -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 +424 -0
- package/dist/FunnelChart.cjs.map +1 -0
- package/dist/FunnelChart.js +422 -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 +148 -0
- package/dist/HeatmapChart.cjs.map +1 -0
- package/dist/HeatmapChart.js +146 -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-4AKHZNWP.js +127 -0
- package/dist/chunk-4AKHZNWP.js.map +1 -0
- package/dist/chunk-56WD3OHA.js +62 -0
- package/dist/chunk-56WD3OHA.js.map +1 -0
- package/dist/chunk-5C2RLJYZ.js +11 -0
- package/dist/chunk-5C2RLJYZ.js.map +1 -0
- package/dist/chunk-6FGJZBTC.js +61 -0
- package/dist/chunk-6FGJZBTC.js.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-CMBNNLIV.cjs +63 -0
- package/dist/chunk-CMBNNLIV.cjs.map +1 -0
- package/dist/chunk-DBZQI4HM.cjs +14 -0
- package/dist/chunk-DBZQI4HM.cjs.map +1 -0
- package/dist/chunk-DI2FBGKM.js +44 -0
- package/dist/chunk-DI2FBGKM.js.map +1 -0
- package/dist/chunk-ESVGCUJN.js +58 -0
- package/dist/chunk-ESVGCUJN.js.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-G4WOPX4D.cjs +51 -0
- package/dist/chunk-G4WOPX4D.cjs.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-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-OCD6JIIX.js +23 -0
- package/dist/chunk-OCD6JIIX.js.map +1 -0
- package/dist/chunk-RCDTBZC2.cjs +131 -0
- package/dist/chunk-RCDTBZC2.cjs.map +1 -0
- package/dist/chunk-SR2ESX3R.cjs +66 -0
- package/dist/chunk-SR2ESX3R.cjs.map +1 -0
- package/dist/chunk-T3K6Q34U.cjs +82 -0
- package/dist/chunk-T3K6Q34U.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-UL3SNXQR.js +280 -0
- package/dist/chunk-UL3SNXQR.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-XMFBVMW7.cjs +30 -0
- package/dist/chunk-XMFBVMW7.cjs.map +1 -0
- package/dist/chunk-XUGQ6VXO.cjs +60 -0
- package/dist/chunk-XUGQ6VXO.cjs.map +1 -0
- package/dist/chunk-YMRNTIOK.js +27 -0
- package/dist/chunk-YMRNTIOK.js.map +1 -0
- package/dist/chunk-ZWHCUYIN.cjs +282 -0
- package/dist/chunk-ZWHCUYIN.cjs.map +1 -0
- package/dist/index.cjs +154 -1166
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +470 -80
- package/dist/index.d.ts +470 -80
- package/dist/index.js +23 -1144
- 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 +23 -12
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkGVTMZYOM_cjs = require('./chunk-GVTMZYOM.cjs');
|
|
5
|
+
var chunkXUGQ6VXO_cjs = require('./chunk-XUGQ6VXO.cjs');
|
|
6
|
+
var chunkXMFBVMW7_cjs = require('./chunk-XMFBVMW7.cjs');
|
|
7
|
+
var chunkRCDTBZC2_cjs = require('./chunk-RCDTBZC2.cjs');
|
|
8
|
+
var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
|
|
9
|
+
var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
|
|
10
|
+
var chunkT3K6Q34U_cjs = require('./chunk-T3K6Q34U.cjs');
|
|
11
|
+
var chunkK3R7JGOW_cjs = require('./chunk-K3R7JGOW.cjs');
|
|
12
|
+
var chunkSR2ESX3R_cjs = require('./chunk-SR2ESX3R.cjs');
|
|
13
|
+
var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
|
|
14
|
+
var react = require('react');
|
|
15
|
+
var recharts = require('recharts');
|
|
16
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
17
|
+
|
|
18
|
+
var SIDES = ["left", "right"];
|
|
19
|
+
var axisOf = (s) => s.axis ?? "left";
|
|
20
|
+
var rightAxisTitle = (title) => title ? {
|
|
21
|
+
label: {
|
|
22
|
+
value: title,
|
|
23
|
+
angle: 90,
|
|
24
|
+
position: "insideRight",
|
|
25
|
+
offset: 4,
|
|
26
|
+
fill: chunkLT3UC65O_cjs.MUTED,
|
|
27
|
+
style: { fill: chunkLT3UC65O_cjs.MUTED, fontSize: chunkG4WOPX4D_cjs.TEXT_SIZE, textAnchor: "middle" }
|
|
28
|
+
}
|
|
29
|
+
} : {};
|
|
30
|
+
var MixedChart = ({
|
|
31
|
+
series,
|
|
32
|
+
categories,
|
|
33
|
+
colors,
|
|
34
|
+
formatValue,
|
|
35
|
+
formatRightValue,
|
|
36
|
+
xTitle,
|
|
37
|
+
yTitle,
|
|
38
|
+
yRightTitle,
|
|
39
|
+
referenceLines,
|
|
40
|
+
referenceBands,
|
|
41
|
+
showLegend,
|
|
42
|
+
legendPosition = "top",
|
|
43
|
+
stackedColumns = false,
|
|
44
|
+
emptyMessage = "No data",
|
|
45
|
+
ariaLabel,
|
|
46
|
+
children,
|
|
47
|
+
height = 320,
|
|
48
|
+
width
|
|
49
|
+
}) => {
|
|
50
|
+
const uid = chunkK3R7JGOW_cjs.safeId(react.useId());
|
|
51
|
+
const hidden = chunkRCDTBZC2_cjs.useHiddenSeries();
|
|
52
|
+
const axis = chunkG4WOPX4D_cjs.useAxis();
|
|
53
|
+
const name = ariaLabel ?? `Mixed chart: ${series.map((s) => s.name).join(", ")}`;
|
|
54
|
+
if (chunkK3R7JGOW_cjs.hasNoData(series)) {
|
|
55
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkSR2ESX3R_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
56
|
+
}
|
|
57
|
+
const formatters = { left: formatValue, right: formatRightValue };
|
|
58
|
+
const usedSides = SIDES.filter((side) => series.some((s) => axisOf(s) === side));
|
|
59
|
+
const sides = usedSides.length > 0 ? usedSides : SIDES.slice(0, 1);
|
|
60
|
+
const tooltip = ({ active, payload, label }) => {
|
|
61
|
+
if (!active || !payload?.length) return null;
|
|
62
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
63
|
+
chunkT3K6Q34U_cjs.TooltipCard,
|
|
64
|
+
{
|
|
65
|
+
title: label,
|
|
66
|
+
rows: payload.map((item) => {
|
|
67
|
+
const s = series[Number(String(item.dataKey).slice(1))];
|
|
68
|
+
const format = formatters[axisOf(s)] ?? String;
|
|
69
|
+
return {
|
|
70
|
+
name: String(item.name),
|
|
71
|
+
value: format(Number(item.value)),
|
|
72
|
+
color: String(item.color)
|
|
73
|
+
};
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
const stackKeys = (side) => series.flatMap(
|
|
79
|
+
(s, i) => s.type === "column" && axisOf(s) === side && !hidden.hidden.has(chunkK3R7JGOW_cjs.seriesKey(i)) ? [chunkK3R7JGOW_cjs.seriesKey(i)] : []
|
|
80
|
+
);
|
|
81
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
82
|
+
recharts.ComposedChart,
|
|
83
|
+
{
|
|
84
|
+
...chunkSR2ESX3R_cjs.frameProps({ height, width, ariaLabel: name }),
|
|
85
|
+
data: chunkK3R7JGOW_cjs.toRows(categories, series),
|
|
86
|
+
...stackedColumns ? { stackOffset: "sign" } : {},
|
|
87
|
+
margin: { top: 4, right: 8, bottom: 0, left: 0 },
|
|
88
|
+
barGap: 4,
|
|
89
|
+
barCategoryGap: "22%",
|
|
90
|
+
children: [
|
|
91
|
+
series.some((s) => s.type === "area") && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: series.map(
|
|
92
|
+
(s, i) => s.type === "area" ? /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: `${uid}-${i}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
93
|
+
/* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: chunkLT3UC65O_cjs.seriesColor(i, colors), stopOpacity: 0.32 }),
|
|
94
|
+
/* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: chunkLT3UC65O_cjs.seriesColor(i, colors), stopOpacity: 0 })
|
|
95
|
+
] }, chunkK3R7JGOW_cjs.seriesKey(i)) : null
|
|
96
|
+
) }),
|
|
97
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...chunkG4WOPX4D_cjs.GRID_PROPS }),
|
|
98
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
99
|
+
recharts.XAxis,
|
|
100
|
+
{
|
|
101
|
+
dataKey: "category",
|
|
102
|
+
...axis,
|
|
103
|
+
...chunkG4WOPX4D_cjs.xAxisTitle(xTitle),
|
|
104
|
+
...chunkXMFBVMW7_cjs.categoryAxis(categories, xTitle)
|
|
105
|
+
}
|
|
106
|
+
),
|
|
107
|
+
sides.map((side) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
108
|
+
recharts.YAxis,
|
|
109
|
+
{
|
|
110
|
+
yAxisId: side,
|
|
111
|
+
orientation: side,
|
|
112
|
+
width: "auto",
|
|
113
|
+
tickFormatter: formatters[side],
|
|
114
|
+
...axis,
|
|
115
|
+
...side === "left" ? chunkG4WOPX4D_cjs.yAxisTitle(yTitle) : rightAxisTitle(yRightTitle)
|
|
116
|
+
},
|
|
117
|
+
side
|
|
118
|
+
)),
|
|
119
|
+
(showLegend ?? series.length > 1) && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { ...chunkRCDTBZC2_cjs.legendProps(legendPosition, hidden) }),
|
|
120
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
121
|
+
recharts.Tooltip,
|
|
122
|
+
{
|
|
123
|
+
content: tooltip,
|
|
124
|
+
cursor: { fill: chunkLT3UC65O_cjs.BORDER, fillOpacity: 0.35, radius: 8 },
|
|
125
|
+
animationDuration: 150
|
|
126
|
+
}
|
|
127
|
+
),
|
|
128
|
+
series.map((s, i) => {
|
|
129
|
+
const key = chunkK3R7JGOW_cjs.seriesKey(i);
|
|
130
|
+
const color = chunkLT3UC65O_cjs.seriesColor(i, colors);
|
|
131
|
+
if (s.type === "area") {
|
|
132
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
133
|
+
recharts.Area,
|
|
134
|
+
{
|
|
135
|
+
name: s.name,
|
|
136
|
+
dataKey: key,
|
|
137
|
+
yAxisId: axisOf(s),
|
|
138
|
+
type: "monotone",
|
|
139
|
+
stroke: color,
|
|
140
|
+
strokeWidth: 2.25,
|
|
141
|
+
fill: `url(#${uid}-${i})`,
|
|
142
|
+
dot: false,
|
|
143
|
+
activeDot: { r: 5, fill: chunkLT3UC65O_cjs.PANEL, stroke: color, strokeWidth: 2.5 },
|
|
144
|
+
hide: hidden.hidden.has(key),
|
|
145
|
+
...chunkTYQWZR3S_cjs.ANIMATION
|
|
146
|
+
},
|
|
147
|
+
key
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
return s.type === "line" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
151
|
+
recharts.Line,
|
|
152
|
+
{
|
|
153
|
+
name: s.name,
|
|
154
|
+
dataKey: key,
|
|
155
|
+
yAxisId: axisOf(s),
|
|
156
|
+
type: "monotone",
|
|
157
|
+
stroke: color,
|
|
158
|
+
strokeWidth: 3,
|
|
159
|
+
dot: false,
|
|
160
|
+
activeDot: { r: 5, fill: chunkLT3UC65O_cjs.PANEL, stroke: color, strokeWidth: 2.5 },
|
|
161
|
+
hide: hidden.hidden.has(key),
|
|
162
|
+
...chunkTYQWZR3S_cjs.ANIMATION
|
|
163
|
+
},
|
|
164
|
+
key
|
|
165
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
166
|
+
recharts.Bar,
|
|
167
|
+
{
|
|
168
|
+
name: s.name,
|
|
169
|
+
dataKey: key,
|
|
170
|
+
yAxisId: axisOf(s),
|
|
171
|
+
fill: color,
|
|
172
|
+
stackId: stackedColumns ? `stack-${axisOf(s)}` : void 0,
|
|
173
|
+
maxBarSize: 44,
|
|
174
|
+
shape: chunkGVTMZYOM_cjs.roundedBarShape({
|
|
175
|
+
layout: "horizontal",
|
|
176
|
+
radius: 4,
|
|
177
|
+
dataKey: key,
|
|
178
|
+
isOuter: stackedColumns ? chunkGVTMZYOM_cjs.isOuterInStack(stackKeys(axisOf(s)), key) : void 0
|
|
179
|
+
}),
|
|
180
|
+
hide: hidden.hidden.has(key),
|
|
181
|
+
...chunkTYQWZR3S_cjs.ANIMATION
|
|
182
|
+
},
|
|
183
|
+
key
|
|
184
|
+
);
|
|
185
|
+
}),
|
|
186
|
+
chunkXUGQ6VXO_cjs.referenceMarks({ referenceLines, referenceBands, axisId: sides[0] }),
|
|
187
|
+
children
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
exports.MixedChart = MixedChart;
|
|
194
|
+
//# sourceMappingURL=MixedChart.cjs.map
|
|
195
|
+
//# sourceMappingURL=MixedChart.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/MixedChart.tsx"],"names":["MUTED","TEXT_SIZE","safeId","useId","useHiddenSeries","useAxis","hasNoData","ChartEmpty","jsx","TooltipCard","seriesKey","jsxs","ComposedChart","frameProps","toRows","seriesColor","CartesianGrid","GRID_PROPS","XAxis","xAxisTitle","categoryAxis","YAxis","yAxisTitle","Legend","legendProps","Tooltip","BORDER","Area","PANEL","ANIMATION","Line","Bar","roundedBarShape","isOuterInStack","referenceMarks"],"mappings":"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","file":"MixedChart.cjs","sourcesContent":["import { useId } from 'react';\nimport {\n Area,\n Bar,\n CartesianGrid,\n ComposedChart,\n Legend,\n Line,\n Tooltip,\n XAxis,\n YAxis,\n type TooltipContentProps,\n} from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { GRID_PROPS, TEXT_SIZE, useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { categoryAxis } from './core/categoryAxis';\nimport { TooltipCard } from './core/ChartTooltip';\nimport { legendProps, useHiddenSeries } from './core/ChartLegend';\nimport { BORDER, MUTED, PANEL, seriesColor } from './core/colors';\nimport { hasNoData, safeId, 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 MixedChartAxis = 'left' | 'right';\n\nexport type MixedChartSeries = {\n name: string;\n /** `column` draws bars, `line` draws a line over them, `area` fills under a line, behind the bars. */\n type: 'line' | 'column' | 'area';\n data: number[];\n /** The y axis the series is read on. Any `right` series adds a second axis. Default `left`. */\n axis?: MixedChartAxis;\n};\n\nexport type MixedChartProps = ChartProps &\n ChartEmptyProps &\n ChartLegendProps &\n ChartAxisTitleProps &\n ChartReferenceProps & {\n /** Lines and columns on one category axis. */\n series: MixedChartSeries[];\n categories: (string | number)[];\n /** Override the default Cosmos palette. */\n colors?: string[];\n /** Format the left axis labels and the tooltip values of its series. */\n formatValue?: (value: number) => string;\n /** Format the right axis labels and the tooltip values of its series. */\n formatRightValue?: (value: number) => string;\n /**\n * Title beside the right axis. `yTitle` names the left one. With one axis only, that axis\n * takes the title of its side.\n */\n yRightTitle?: string;\n /** Show the legend (auto-true when 2+ series). */\n showLegend?: boolean;\n /** Pile the `column` series on each other instead of grouping them side by side; the columns of each axis stack apart. */\n stackedColumns?: boolean;\n };\n\nconst SIDES: MixedChartAxis[] = ['left', 'right'];\nconst axisOf = (s: MixedChartSeries): MixedChartAxis => s.axis ?? 'left';\n\n// The title of the right axis reads top to bottom, mirroring the left one.\nconst rightAxisTitle = (title?: string) =>\n title\n ? ({\n label: {\n value: title,\n angle: 90,\n position: 'insideRight',\n offset: 4,\n fill: MUTED,\n style: { fill: MUTED, fontSize: TEXT_SIZE, textAnchor: 'middle' },\n },\n } as const)\n : {};\n\nexport const MixedChart = ({\n series,\n categories,\n colors,\n formatValue,\n formatRightValue,\n xTitle,\n yTitle,\n yRightTitle,\n referenceLines,\n referenceBands,\n showLegend,\n legendPosition = 'top',\n stackedColumns = false,\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 320,\n width,\n}: MixedChartProps) => {\n const uid = safeId(useId());\n const hidden = useHiddenSeries();\n const axis = useAxis();\n const name = ariaLabel ?? `Mixed 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 formatters = { left: formatValue, right: formatRightValue };\n const usedSides = SIDES.filter((side) => series.some((s) => axisOf(s) === side));\n const sides = usedSides.length > 0 ? usedSides : SIDES.slice(0, 1);\n\n // Each value in the format of its series' axis; the card is the shared one.\n const tooltip = ({ active, payload, label }: Partial<TooltipContentProps>) => {\n if (!active || !payload?.length) return null;\n return (\n <TooltipCard\n title={label}\n rows={payload.map((item) => {\n const s = series[Number(String(item.dataKey).slice(1))];\n const format = formatters[axisOf(s)] ?? String;\n return {\n name: String(item.name),\n value: format(Number(item.value)),\n color: String(item.color),\n };\n })}\n />\n );\n };\n\n // The columns on each axis stack apart, and only the outer segment of a stack is rounded.\n const stackKeys = (side: MixedChartAxis) =>\n series.flatMap((s, i) =>\n s.type === 'column' && axisOf(s) === side && !hidden.hidden.has(seriesKey(i))\n ? [seriesKey(i)]\n : []\n );\n\n return (\n <ComposedChart\n {...frameProps({ height, width, ariaLabel: name })}\n data={toRows(categories, series)}\n // Stacks of both signs: the negative values stack down from zero, apart from the positive ones.\n {...(stackedColumns ? { stackOffset: 'sign' as const } : {})}\n margin={{ top: 4, right: 8, bottom: 0, left: 0 }}\n barGap={4}\n barCategoryGap=\"22%\"\n >\n {series.some((s) => s.type === 'area') && (\n <defs>\n {series.map((s, i) =>\n s.type === 'area' ? (\n <linearGradient key={seriesKey(i)} id={`${uid}-${i}`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={seriesColor(i, colors)} stopOpacity={0.32} />\n <stop offset=\"100%\" stopColor={seriesColor(i, colors)} stopOpacity={0} />\n </linearGradient>\n ) : null\n )}\n </defs>\n )}\n <CartesianGrid {...GRID_PROPS} />\n <XAxis\n dataKey=\"category\"\n {...axis}\n {...xAxisTitle(xTitle)}\n {...categoryAxis(categories, xTitle)}\n />\n {sides.map((side) => (\n <YAxis\n key={side}\n yAxisId={side}\n orientation={side}\n width=\"auto\"\n tickFormatter={formatters[side]}\n {...axis}\n {...(side === 'left' ? yAxisTitle(yTitle) : rightAxisTitle(yRightTitle))}\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, i) => {\n const key = seriesKey(i);\n const color = seriesColor(i, colors);\n if (s.type === 'area') {\n return (\n <Area\n key={key}\n name={s.name}\n dataKey={key}\n yAxisId={axisOf(s)}\n type=\"monotone\"\n stroke={color}\n strokeWidth={2.25}\n fill={`url(#${uid}-${i})`}\n dot={false}\n activeDot={{ r: 5, fill: PANEL, stroke: color, strokeWidth: 2.5 }}\n hide={hidden.hidden.has(key)}\n {...ANIMATION}\n />\n );\n }\n return s.type === 'line' ? (\n <Line\n key={key}\n name={s.name}\n dataKey={key}\n yAxisId={axisOf(s)}\n type=\"monotone\"\n stroke={color}\n strokeWidth={3}\n dot={false}\n activeDot={{ r: 5, fill: PANEL, stroke: color, strokeWidth: 2.5 }}\n hide={hidden.hidden.has(key)}\n {...ANIMATION}\n />\n ) : (\n <Bar\n key={key}\n name={s.name}\n dataKey={key}\n yAxisId={axisOf(s)}\n fill={color}\n stackId={stackedColumns ? `stack-${axisOf(s)}` : undefined}\n maxBarSize={44}\n shape={roundedBarShape({\n layout: 'horizontal',\n radius: 4,\n dataKey: key,\n isOuter: stackedColumns ? isOuterInStack(stackKeys(axisOf(s)), key) : undefined,\n })}\n hide={hidden.hidden.has(key)}\n {...ANIMATION}\n />\n );\n })}\n {referenceMarks({ referenceLines, referenceBands, axisId: sides[0] })}\n {children}\n </ComposedChart>\n );\n};\n"]}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { roundedBarShape, isOuterInStack } from './chunk-GDZLYYL2.js';
|
|
3
|
+
import { referenceMarks } from './chunk-ESVGCUJN.js';
|
|
4
|
+
import { categoryAxis } from './chunk-YMRNTIOK.js';
|
|
5
|
+
import { useHiddenSeries, legendProps } from './chunk-4AKHZNWP.js';
|
|
6
|
+
import { ANIMATION } from './chunk-5C2RLJYZ.js';
|
|
7
|
+
import { useAxis, GRID_PROPS, xAxisTitle, yAxisTitle, TEXT_SIZE } from './chunk-DI2FBGKM.js';
|
|
8
|
+
import { TooltipCard } from './chunk-VIOSQN4Z.js';
|
|
9
|
+
import { safeId, hasNoData, seriesKey, toRows } from './chunk-UJIV5PVI.js';
|
|
10
|
+
import { ChartEmpty, frameProps } from './chunk-56WD3OHA.js';
|
|
11
|
+
import { seriesColor, BORDER, PANEL, MUTED } from './chunk-UATB2IRY.js';
|
|
12
|
+
import { useId } from 'react';
|
|
13
|
+
import { ComposedChart, CartesianGrid, XAxis, YAxis, Legend, Tooltip, Area, Line, Bar } from 'recharts';
|
|
14
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
15
|
+
|
|
16
|
+
var SIDES = ["left", "right"];
|
|
17
|
+
var axisOf = (s) => s.axis ?? "left";
|
|
18
|
+
var rightAxisTitle = (title) => title ? {
|
|
19
|
+
label: {
|
|
20
|
+
value: title,
|
|
21
|
+
angle: 90,
|
|
22
|
+
position: "insideRight",
|
|
23
|
+
offset: 4,
|
|
24
|
+
fill: MUTED,
|
|
25
|
+
style: { fill: MUTED, fontSize: TEXT_SIZE, textAnchor: "middle" }
|
|
26
|
+
}
|
|
27
|
+
} : {};
|
|
28
|
+
var MixedChart = ({
|
|
29
|
+
series,
|
|
30
|
+
categories,
|
|
31
|
+
colors,
|
|
32
|
+
formatValue,
|
|
33
|
+
formatRightValue,
|
|
34
|
+
xTitle,
|
|
35
|
+
yTitle,
|
|
36
|
+
yRightTitle,
|
|
37
|
+
referenceLines,
|
|
38
|
+
referenceBands,
|
|
39
|
+
showLegend,
|
|
40
|
+
legendPosition = "top",
|
|
41
|
+
stackedColumns = false,
|
|
42
|
+
emptyMessage = "No data",
|
|
43
|
+
ariaLabel,
|
|
44
|
+
children,
|
|
45
|
+
height = 320,
|
|
46
|
+
width
|
|
47
|
+
}) => {
|
|
48
|
+
const uid = safeId(useId());
|
|
49
|
+
const hidden = useHiddenSeries();
|
|
50
|
+
const axis = useAxis();
|
|
51
|
+
const name = ariaLabel ?? `Mixed chart: ${series.map((s) => s.name).join(", ")}`;
|
|
52
|
+
if (hasNoData(series)) {
|
|
53
|
+
return /* @__PURE__ */ jsx(ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
54
|
+
}
|
|
55
|
+
const formatters = { left: formatValue, right: formatRightValue };
|
|
56
|
+
const usedSides = SIDES.filter((side) => series.some((s) => axisOf(s) === side));
|
|
57
|
+
const sides = usedSides.length > 0 ? usedSides : SIDES.slice(0, 1);
|
|
58
|
+
const tooltip = ({ active, payload, label }) => {
|
|
59
|
+
if (!active || !payload?.length) return null;
|
|
60
|
+
return /* @__PURE__ */ jsx(
|
|
61
|
+
TooltipCard,
|
|
62
|
+
{
|
|
63
|
+
title: label,
|
|
64
|
+
rows: payload.map((item) => {
|
|
65
|
+
const s = series[Number(String(item.dataKey).slice(1))];
|
|
66
|
+
const format = formatters[axisOf(s)] ?? String;
|
|
67
|
+
return {
|
|
68
|
+
name: String(item.name),
|
|
69
|
+
value: format(Number(item.value)),
|
|
70
|
+
color: String(item.color)
|
|
71
|
+
};
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
const stackKeys = (side) => series.flatMap(
|
|
77
|
+
(s, i) => s.type === "column" && axisOf(s) === side && !hidden.hidden.has(seriesKey(i)) ? [seriesKey(i)] : []
|
|
78
|
+
);
|
|
79
|
+
return /* @__PURE__ */ jsxs(
|
|
80
|
+
ComposedChart,
|
|
81
|
+
{
|
|
82
|
+
...frameProps({ height, width, ariaLabel: name }),
|
|
83
|
+
data: toRows(categories, series),
|
|
84
|
+
...stackedColumns ? { stackOffset: "sign" } : {},
|
|
85
|
+
margin: { top: 4, right: 8, bottom: 0, left: 0 },
|
|
86
|
+
barGap: 4,
|
|
87
|
+
barCategoryGap: "22%",
|
|
88
|
+
children: [
|
|
89
|
+
series.some((s) => s.type === "area") && /* @__PURE__ */ jsx("defs", { children: series.map(
|
|
90
|
+
(s, i) => s.type === "area" ? /* @__PURE__ */ jsxs("linearGradient", { id: `${uid}-${i}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
91
|
+
/* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: seriesColor(i, colors), stopOpacity: 0.32 }),
|
|
92
|
+
/* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: seriesColor(i, colors), stopOpacity: 0 })
|
|
93
|
+
] }, seriesKey(i)) : null
|
|
94
|
+
) }),
|
|
95
|
+
/* @__PURE__ */ jsx(CartesianGrid, { ...GRID_PROPS }),
|
|
96
|
+
/* @__PURE__ */ jsx(
|
|
97
|
+
XAxis,
|
|
98
|
+
{
|
|
99
|
+
dataKey: "category",
|
|
100
|
+
...axis,
|
|
101
|
+
...xAxisTitle(xTitle),
|
|
102
|
+
...categoryAxis(categories, xTitle)
|
|
103
|
+
}
|
|
104
|
+
),
|
|
105
|
+
sides.map((side) => /* @__PURE__ */ jsx(
|
|
106
|
+
YAxis,
|
|
107
|
+
{
|
|
108
|
+
yAxisId: side,
|
|
109
|
+
orientation: side,
|
|
110
|
+
width: "auto",
|
|
111
|
+
tickFormatter: formatters[side],
|
|
112
|
+
...axis,
|
|
113
|
+
...side === "left" ? yAxisTitle(yTitle) : rightAxisTitle(yRightTitle)
|
|
114
|
+
},
|
|
115
|
+
side
|
|
116
|
+
)),
|
|
117
|
+
(showLegend ?? series.length > 1) && /* @__PURE__ */ jsx(Legend, { ...legendProps(legendPosition, hidden) }),
|
|
118
|
+
/* @__PURE__ */ jsx(
|
|
119
|
+
Tooltip,
|
|
120
|
+
{
|
|
121
|
+
content: tooltip,
|
|
122
|
+
cursor: { fill: BORDER, fillOpacity: 0.35, radius: 8 },
|
|
123
|
+
animationDuration: 150
|
|
124
|
+
}
|
|
125
|
+
),
|
|
126
|
+
series.map((s, i) => {
|
|
127
|
+
const key = seriesKey(i);
|
|
128
|
+
const color = seriesColor(i, colors);
|
|
129
|
+
if (s.type === "area") {
|
|
130
|
+
return /* @__PURE__ */ jsx(
|
|
131
|
+
Area,
|
|
132
|
+
{
|
|
133
|
+
name: s.name,
|
|
134
|
+
dataKey: key,
|
|
135
|
+
yAxisId: axisOf(s),
|
|
136
|
+
type: "monotone",
|
|
137
|
+
stroke: color,
|
|
138
|
+
strokeWidth: 2.25,
|
|
139
|
+
fill: `url(#${uid}-${i})`,
|
|
140
|
+
dot: false,
|
|
141
|
+
activeDot: { r: 5, fill: PANEL, stroke: color, strokeWidth: 2.5 },
|
|
142
|
+
hide: hidden.hidden.has(key),
|
|
143
|
+
...ANIMATION
|
|
144
|
+
},
|
|
145
|
+
key
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
return s.type === "line" ? /* @__PURE__ */ jsx(
|
|
149
|
+
Line,
|
|
150
|
+
{
|
|
151
|
+
name: s.name,
|
|
152
|
+
dataKey: key,
|
|
153
|
+
yAxisId: axisOf(s),
|
|
154
|
+
type: "monotone",
|
|
155
|
+
stroke: color,
|
|
156
|
+
strokeWidth: 3,
|
|
157
|
+
dot: false,
|
|
158
|
+
activeDot: { r: 5, fill: PANEL, stroke: color, strokeWidth: 2.5 },
|
|
159
|
+
hide: hidden.hidden.has(key),
|
|
160
|
+
...ANIMATION
|
|
161
|
+
},
|
|
162
|
+
key
|
|
163
|
+
) : /* @__PURE__ */ jsx(
|
|
164
|
+
Bar,
|
|
165
|
+
{
|
|
166
|
+
name: s.name,
|
|
167
|
+
dataKey: key,
|
|
168
|
+
yAxisId: axisOf(s),
|
|
169
|
+
fill: color,
|
|
170
|
+
stackId: stackedColumns ? `stack-${axisOf(s)}` : void 0,
|
|
171
|
+
maxBarSize: 44,
|
|
172
|
+
shape: roundedBarShape({
|
|
173
|
+
layout: "horizontal",
|
|
174
|
+
radius: 4,
|
|
175
|
+
dataKey: key,
|
|
176
|
+
isOuter: stackedColumns ? isOuterInStack(stackKeys(axisOf(s)), key) : void 0
|
|
177
|
+
}),
|
|
178
|
+
hide: hidden.hidden.has(key),
|
|
179
|
+
...ANIMATION
|
|
180
|
+
},
|
|
181
|
+
key
|
|
182
|
+
);
|
|
183
|
+
}),
|
|
184
|
+
referenceMarks({ referenceLines, referenceBands, axisId: sides[0] }),
|
|
185
|
+
children
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
export { MixedChart };
|
|
192
|
+
//# sourceMappingURL=MixedChart.js.map
|
|
193
|
+
//# sourceMappingURL=MixedChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/MixedChart.tsx"],"names":[],"mappings":"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","file":"MixedChart.js","sourcesContent":["import { useId } from 'react';\nimport {\n Area,\n Bar,\n CartesianGrid,\n ComposedChart,\n Legend,\n Line,\n Tooltip,\n XAxis,\n YAxis,\n type TooltipContentProps,\n} from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { GRID_PROPS, TEXT_SIZE, useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { categoryAxis } from './core/categoryAxis';\nimport { TooltipCard } from './core/ChartTooltip';\nimport { legendProps, useHiddenSeries } from './core/ChartLegend';\nimport { BORDER, MUTED, PANEL, seriesColor } from './core/colors';\nimport { hasNoData, safeId, 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 MixedChartAxis = 'left' | 'right';\n\nexport type MixedChartSeries = {\n name: string;\n /** `column` draws bars, `line` draws a line over them, `area` fills under a line, behind the bars. */\n type: 'line' | 'column' | 'area';\n data: number[];\n /** The y axis the series is read on. Any `right` series adds a second axis. Default `left`. */\n axis?: MixedChartAxis;\n};\n\nexport type MixedChartProps = ChartProps &\n ChartEmptyProps &\n ChartLegendProps &\n ChartAxisTitleProps &\n ChartReferenceProps & {\n /** Lines and columns on one category axis. */\n series: MixedChartSeries[];\n categories: (string | number)[];\n /** Override the default Cosmos palette. */\n colors?: string[];\n /** Format the left axis labels and the tooltip values of its series. */\n formatValue?: (value: number) => string;\n /** Format the right axis labels and the tooltip values of its series. */\n formatRightValue?: (value: number) => string;\n /**\n * Title beside the right axis. `yTitle` names the left one. With one axis only, that axis\n * takes the title of its side.\n */\n yRightTitle?: string;\n /** Show the legend (auto-true when 2+ series). */\n showLegend?: boolean;\n /** Pile the `column` series on each other instead of grouping them side by side; the columns of each axis stack apart. */\n stackedColumns?: boolean;\n };\n\nconst SIDES: MixedChartAxis[] = ['left', 'right'];\nconst axisOf = (s: MixedChartSeries): MixedChartAxis => s.axis ?? 'left';\n\n// The title of the right axis reads top to bottom, mirroring the left one.\nconst rightAxisTitle = (title?: string) =>\n title\n ? ({\n label: {\n value: title,\n angle: 90,\n position: 'insideRight',\n offset: 4,\n fill: MUTED,\n style: { fill: MUTED, fontSize: TEXT_SIZE, textAnchor: 'middle' },\n },\n } as const)\n : {};\n\nexport const MixedChart = ({\n series,\n categories,\n colors,\n formatValue,\n formatRightValue,\n xTitle,\n yTitle,\n yRightTitle,\n referenceLines,\n referenceBands,\n showLegend,\n legendPosition = 'top',\n stackedColumns = false,\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 320,\n width,\n}: MixedChartProps) => {\n const uid = safeId(useId());\n const hidden = useHiddenSeries();\n const axis = useAxis();\n const name = ariaLabel ?? `Mixed 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 formatters = { left: formatValue, right: formatRightValue };\n const usedSides = SIDES.filter((side) => series.some((s) => axisOf(s) === side));\n const sides = usedSides.length > 0 ? usedSides : SIDES.slice(0, 1);\n\n // Each value in the format of its series' axis; the card is the shared one.\n const tooltip = ({ active, payload, label }: Partial<TooltipContentProps>) => {\n if (!active || !payload?.length) return null;\n return (\n <TooltipCard\n title={label}\n rows={payload.map((item) => {\n const s = series[Number(String(item.dataKey).slice(1))];\n const format = formatters[axisOf(s)] ?? String;\n return {\n name: String(item.name),\n value: format(Number(item.value)),\n color: String(item.color),\n };\n })}\n />\n );\n };\n\n // The columns on each axis stack apart, and only the outer segment of a stack is rounded.\n const stackKeys = (side: MixedChartAxis) =>\n series.flatMap((s, i) =>\n s.type === 'column' && axisOf(s) === side && !hidden.hidden.has(seriesKey(i))\n ? [seriesKey(i)]\n : []\n );\n\n return (\n <ComposedChart\n {...frameProps({ height, width, ariaLabel: name })}\n data={toRows(categories, series)}\n // Stacks of both signs: the negative values stack down from zero, apart from the positive ones.\n {...(stackedColumns ? { stackOffset: 'sign' as const } : {})}\n margin={{ top: 4, right: 8, bottom: 0, left: 0 }}\n barGap={4}\n barCategoryGap=\"22%\"\n >\n {series.some((s) => s.type === 'area') && (\n <defs>\n {series.map((s, i) =>\n s.type === 'area' ? (\n <linearGradient key={seriesKey(i)} id={`${uid}-${i}`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={seriesColor(i, colors)} stopOpacity={0.32} />\n <stop offset=\"100%\" stopColor={seriesColor(i, colors)} stopOpacity={0} />\n </linearGradient>\n ) : null\n )}\n </defs>\n )}\n <CartesianGrid {...GRID_PROPS} />\n <XAxis\n dataKey=\"category\"\n {...axis}\n {...xAxisTitle(xTitle)}\n {...categoryAxis(categories, xTitle)}\n />\n {sides.map((side) => (\n <YAxis\n key={side}\n yAxisId={side}\n orientation={side}\n width=\"auto\"\n tickFormatter={formatters[side]}\n {...axis}\n {...(side === 'left' ? yAxisTitle(yTitle) : rightAxisTitle(yRightTitle))}\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, i) => {\n const key = seriesKey(i);\n const color = seriesColor(i, colors);\n if (s.type === 'area') {\n return (\n <Area\n key={key}\n name={s.name}\n dataKey={key}\n yAxisId={axisOf(s)}\n type=\"monotone\"\n stroke={color}\n strokeWidth={2.25}\n fill={`url(#${uid}-${i})`}\n dot={false}\n activeDot={{ r: 5, fill: PANEL, stroke: color, strokeWidth: 2.5 }}\n hide={hidden.hidden.has(key)}\n {...ANIMATION}\n />\n );\n }\n return s.type === 'line' ? (\n <Line\n key={key}\n name={s.name}\n dataKey={key}\n yAxisId={axisOf(s)}\n type=\"monotone\"\n stroke={color}\n strokeWidth={3}\n dot={false}\n activeDot={{ r: 5, fill: PANEL, stroke: color, strokeWidth: 2.5 }}\n hide={hidden.hidden.has(key)}\n {...ANIMATION}\n />\n ) : (\n <Bar\n key={key}\n name={s.name}\n dataKey={key}\n yAxisId={axisOf(s)}\n fill={color}\n stackId={stackedColumns ? `stack-${axisOf(s)}` : undefined}\n maxBarSize={44}\n shape={roundedBarShape({\n layout: 'horizontal',\n radius: 4,\n dataKey: key,\n isOuter: stackedColumns ? isOuterInStack(stackKeys(axisOf(s)), key) : undefined,\n })}\n hide={hidden.hidden.has(key)}\n {...ANIMATION}\n />\n );\n })}\n {referenceMarks({ referenceLines, referenceBands, axisId: sides[0] })}\n {children}\n </ComposedChart>\n );\n};\n"]}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkRCDTBZC2_cjs = require('./chunk-RCDTBZC2.cjs');
|
|
5
|
+
var chunkIW6EWB26_cjs = require('./chunk-IW6EWB26.cjs');
|
|
6
|
+
var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
|
|
7
|
+
var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
|
|
8
|
+
var chunkT3K6Q34U_cjs = require('./chunk-T3K6Q34U.cjs');
|
|
9
|
+
var chunkK3R7JGOW_cjs = require('./chunk-K3R7JGOW.cjs');
|
|
10
|
+
var chunkSR2ESX3R_cjs = require('./chunk-SR2ESX3R.cjs');
|
|
11
|
+
var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
|
|
12
|
+
var recharts = require('recharts');
|
|
13
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
14
|
+
|
|
15
|
+
// src/radarSize.ts
|
|
16
|
+
var NAME_BAND = 44;
|
|
17
|
+
var NAME_GAP = 14;
|
|
18
|
+
var NAME_CHAR = 6.5;
|
|
19
|
+
var LEGEND_ROW = 40;
|
|
20
|
+
var LEGEND_COLUMN = 120;
|
|
21
|
+
var MIN_SIZE = 40;
|
|
22
|
+
var radarSize = ({ height, width, categories, legend }) => {
|
|
23
|
+
const widest = Math.max(0, ...categories.map((name) => name.length)) * NAME_CHAR;
|
|
24
|
+
const vertical = height - NAME_BAND - (legend === "top" || legend === "bottom" ? LEGEND_ROW : 0);
|
|
25
|
+
const horizontal = width - 2 * (widest + NAME_GAP) - (legend === "left" || legend === "right" ? LEGEND_COLUMN : 0);
|
|
26
|
+
return Math.max(MIN_SIZE, Math.floor(Math.min(vertical, horizontal) / 2));
|
|
27
|
+
};
|
|
28
|
+
var RadarChart = ({
|
|
29
|
+
series,
|
|
30
|
+
categories,
|
|
31
|
+
colors,
|
|
32
|
+
formatValue,
|
|
33
|
+
showLegend,
|
|
34
|
+
legendPosition = "top",
|
|
35
|
+
max,
|
|
36
|
+
showScale = false,
|
|
37
|
+
emptyMessage = "No data",
|
|
38
|
+
ariaLabel,
|
|
39
|
+
children,
|
|
40
|
+
height = 340,
|
|
41
|
+
width
|
|
42
|
+
}) => {
|
|
43
|
+
const hidden = chunkRCDTBZC2_cjs.useHiddenSeries();
|
|
44
|
+
const { ref: box, width: boxWidth } = chunkIW6EWB26_cjs.useElementWidth();
|
|
45
|
+
const name = ariaLabel ?? `Radar chart: ${series.map((s) => s.name).join(", ")}`;
|
|
46
|
+
if (chunkK3R7JGOW_cjs.hasNoData(series)) {
|
|
47
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkSR2ESX3R_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
48
|
+
}
|
|
49
|
+
const legendVisible = showLegend ?? series.length > 1;
|
|
50
|
+
const radius = typeof height === "number" && boxWidth ? radarSize({
|
|
51
|
+
height,
|
|
52
|
+
width: boxWidth,
|
|
53
|
+
categories,
|
|
54
|
+
legend: legendVisible ? legendPosition : void 0
|
|
55
|
+
}) : "70%";
|
|
56
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: box, style: { width: width ?? "100%", maxWidth: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
57
|
+
recharts.RadarChart,
|
|
58
|
+
{
|
|
59
|
+
...chunkSR2ESX3R_cjs.frameProps({ height, width: "100%", ariaLabel: name }),
|
|
60
|
+
data: chunkK3R7JGOW_cjs.toRows(categories, series),
|
|
61
|
+
outerRadius: radius,
|
|
62
|
+
margin: { top: 0, right: 0, bottom: 0, left: 0 },
|
|
63
|
+
children: [
|
|
64
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.PolarGrid, { stroke: chunkLT3UC65O_cjs.GRID }),
|
|
65
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.PolarAngleAxis, { dataKey: "category", tick: chunkG4WOPX4D_cjs.AXIS.tick, tickLine: false }),
|
|
66
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
67
|
+
recharts.PolarRadiusAxis,
|
|
68
|
+
{
|
|
69
|
+
angle: 90,
|
|
70
|
+
domain: [0, max ?? "auto"],
|
|
71
|
+
tickCount: 6,
|
|
72
|
+
tickFormatter: formatValue,
|
|
73
|
+
tick: showScale ? { fill: chunkLT3UC65O_cjs.MUTED, style: { fontSize: chunkG4WOPX4D_cjs.TEXT_SIZE } } : false,
|
|
74
|
+
axisLine: false
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
legendVisible && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { ...chunkRCDTBZC2_cjs.legendProps(legendPosition, hidden) }),
|
|
78
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
79
|
+
recharts.Tooltip,
|
|
80
|
+
{
|
|
81
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(chunkT3K6Q34U_cjs.ChartTooltip, { format: formatValue }),
|
|
82
|
+
cursor: { stroke: chunkLT3UC65O_cjs.BORDER, strokeDasharray: "4 4" },
|
|
83
|
+
animationDuration: 150
|
|
84
|
+
}
|
|
85
|
+
),
|
|
86
|
+
series.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
87
|
+
recharts.Radar,
|
|
88
|
+
{
|
|
89
|
+
name: s.name,
|
|
90
|
+
dataKey: chunkK3R7JGOW_cjs.seriesKey(i),
|
|
91
|
+
stroke: chunkLT3UC65O_cjs.seriesColor(i, colors),
|
|
92
|
+
strokeWidth: 2,
|
|
93
|
+
fill: chunkLT3UC65O_cjs.seriesColor(i, colors),
|
|
94
|
+
fillOpacity: 0.15,
|
|
95
|
+
dot: { r: 3, fill: chunkLT3UC65O_cjs.seriesColor(i, colors), fillOpacity: 1, strokeWidth: 0 },
|
|
96
|
+
hide: hidden.hidden.has(chunkK3R7JGOW_cjs.seriesKey(i)),
|
|
97
|
+
...chunkTYQWZR3S_cjs.ANIMATION
|
|
98
|
+
},
|
|
99
|
+
chunkK3R7JGOW_cjs.seriesKey(i)
|
|
100
|
+
)),
|
|
101
|
+
children
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
) });
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
exports.RadarChart = RadarChart;
|
|
108
|
+
//# sourceMappingURL=RadarChart.cjs.map
|
|
109
|
+
//# sourceMappingURL=RadarChart.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/radarSize.ts","../src/RadarChart.tsx"],"names":["useHiddenSeries","useElementWidth","hasNoData","ChartEmpty","jsx","jsxs","RechartsRadarChart","frameProps","toRows","PolarGrid","GRID","PolarAngleAxis","AXIS","PolarRadiusAxis","MUTED","TEXT_SIZE","Legend","legendProps","Tooltip","ChartTooltip","BORDER","Radar","seriesKey","seriesColor","ANIMATION"],"mappings":"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","file":"RadarChart.cjs","sourcesContent":["import type { ChartLegendPosition } from './types';\n\n// Recharts draws the axis names outside the outer polygon and does not make\n// room for them, so the radius is sized from the smaller side of the plot less\n// the room the names need (12px text): above and below the polygons, and beside\n// them.\nconst NAME_BAND = 44;\nconst NAME_GAP = 14;\nconst NAME_CHAR = 6.5;\n// What a legend takes from the plot, on the side it sits on.\nconst LEGEND_ROW = 40;\nconst LEGEND_COLUMN = 120;\nconst MIN_SIZE = 40;\n\ntype RadarSizeParams = {\n /** The height and width of the chart, in pixels. */\n height: number;\n width: number;\n categories: readonly string[];\n /** The side the legend sits on, if it is drawn. */\n legend?: ChartLegendPosition;\n};\n\n/**\n * The radius, in pixels, of the outer polygon of a radar: the largest one that\n * leaves room for the axis names around it in a chart of this size.\n */\nexport const radarSize = ({ height, width, categories, legend }: RadarSizeParams): number => {\n const widest = Math.max(0, ...categories.map((name) => name.length)) * NAME_CHAR;\n const vertical = height - NAME_BAND - (legend === 'top' || legend === 'bottom' ? LEGEND_ROW : 0);\n const horizontal =\n width - 2 * (widest + NAME_GAP) - (legend === 'left' || legend === 'right' ? LEGEND_COLUMN : 0);\n return Math.max(MIN_SIZE, Math.floor(Math.min(vertical, horizontal) / 2));\n};\n","import {\n Legend,\n PolarAngleAxis,\n PolarGrid,\n PolarRadiusAxis,\n Radar,\n RadarChart as RechartsRadarChart,\n Tooltip,\n} from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { AXIS, TEXT_SIZE } from './core/axes';\nimport { legendProps, useHiddenSeries } from './core/ChartLegend';\nimport { ChartTooltip } from './core/ChartTooltip';\nimport { BORDER, GRID, MUTED, seriesColor } from './core/colors';\nimport { hasNoData, seriesKey, toRows } from './core/data';\nimport { ChartEmpty, frameProps } from './core/frame';\nimport { radarSize } from './radarSize';\nimport { useElementWidth } from './core/useElementWidth';\nimport type { ChartEmptyProps, ChartLegendProps, ChartProps } from './types';\n\nexport type RadarChartProps = ChartProps &\n ChartEmptyProps &\n ChartLegendProps & {\n /** One polygon per series; one value per category, in the same order. */\n series: { name: string; data: number[] }[];\n /** The axes, clockwise from the top. */\n categories: string[];\n /** Override the default Cosmos palette. */\n colors?: string[];\n /** Format the scale labels and the tooltip values. */\n formatValue?: (value: number) => string;\n /** Show the legend (auto-true when 2+ series). */\n showLegend?: boolean;\n /** Top of the scale, e.g. 100 for scores. Default: rounded up from the data. */\n max?: number;\n /**\n * Write the scale on the polygons (0, 20 … 100). Default off: the labels sit on the\n * polygons and the tooltip gives the values. `max` and `formatValue` still apply.\n */\n showScale?: boolean;\n };\n\nexport const RadarChart = ({\n series,\n categories,\n colors,\n formatValue,\n showLegend,\n legendPosition = 'top',\n max,\n showScale = false,\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 340,\n width,\n}: RadarChartProps) => {\n const hidden = useHiddenSeries();\n const { ref: box, width: boxWidth } = useElementWidth();\n const name = ariaLabel ?? `Radar 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 legendVisible = showLegend ?? series.length > 1;\n // The polygons as large as the box allows, less the room of the axis names\n // and the legend. A height that is not a number of pixels, or a box not\n // measured yet, leaves it to a share of the plot.\n const radius =\n typeof height === 'number' && boxWidth\n ? radarSize({\n height,\n width: boxWidth,\n categories,\n legend: legendVisible ? legendPosition : undefined,\n })\n : '70%';\n return (\n <div ref={box} style={{ width: width ?? '100%', maxWidth: '100%' }}>\n <RechartsRadarChart\n {...frameProps({ height, width: '100%', ariaLabel: name })}\n data={toRows(categories, series)}\n outerRadius={radius}\n margin={{ top: 0, right: 0, bottom: 0, left: 0 }}\n >\n <PolarGrid stroke={GRID} />\n <PolarAngleAxis dataKey=\"category\" tick={AXIS.tick} tickLine={false} />\n <PolarRadiusAxis\n angle={90}\n domain={[0, max ?? 'auto']}\n tickCount={6}\n tickFormatter={formatValue}\n tick={showScale ? { fill: MUTED, style: { fontSize: TEXT_SIZE } } : false}\n axisLine={false}\n />\n {legendVisible && <Legend {...legendProps(legendPosition, hidden)} />}\n <Tooltip\n content={<ChartTooltip format={formatValue} />}\n cursor={{ stroke: BORDER, strokeDasharray: '4 4' }}\n animationDuration={150}\n />\n {series.map((s, i) => (\n <Radar\n key={seriesKey(i)}\n name={s.name}\n dataKey={seriesKey(i)}\n stroke={seriesColor(i, colors)}\n strokeWidth={2}\n fill={seriesColor(i, colors)}\n fillOpacity={0.15}\n dot={{ r: 3, fill: seriesColor(i, colors), fillOpacity: 1, strokeWidth: 0 }}\n hide={hidden.hidden.has(seriesKey(i))}\n {...ANIMATION}\n />\n ))}\n {children}\n </RechartsRadarChart>\n </div>\n );\n};\n"]}
|