@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,148 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkZWHCUYIN_cjs = require('./chunk-ZWHCUYIN.cjs');
|
|
5
|
+
require('./chunk-DBZQI4HM.cjs');
|
|
6
|
+
var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
|
|
7
|
+
require('./chunk-T3K6Q34U.cjs');
|
|
8
|
+
var chunkK3R7JGOW_cjs = require('./chunk-K3R7JGOW.cjs');
|
|
9
|
+
var chunkSR2ESX3R_cjs = require('./chunk-SR2ESX3R.cjs');
|
|
10
|
+
var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
|
|
11
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
12
|
+
|
|
13
|
+
var NICE_STEPS = [1, 2, 2.5, 3, 4, 5, 6, 8, 10];
|
|
14
|
+
var niceStep = (value) => {
|
|
15
|
+
const magnitude = 10 ** Math.floor(Math.log10(value));
|
|
16
|
+
const step = NICE_STEPS.find((m) => m * magnitude >= value) ?? 10;
|
|
17
|
+
return step * magnitude;
|
|
18
|
+
};
|
|
19
|
+
var round = (value) => Number(value.toPrecision(12));
|
|
20
|
+
var evenRanges = (values, colors) => {
|
|
21
|
+
const finite = values.filter(Number.isFinite);
|
|
22
|
+
if (finite.length === 0 || colors.length === 0) return [];
|
|
23
|
+
const min = finite.reduce((a, b) => Math.min(a, b));
|
|
24
|
+
const max = finite.reduce((a, b) => Math.max(a, b));
|
|
25
|
+
let step = niceStep((max - min) / colors.length || Math.abs(max) || 1);
|
|
26
|
+
let start = Math.floor(min / step) * step;
|
|
27
|
+
while (start + step * colors.length < max) {
|
|
28
|
+
step = niceStep(step * 1.001);
|
|
29
|
+
start = Math.floor(min / step) * step;
|
|
30
|
+
}
|
|
31
|
+
return colors.map((color, i) => ({
|
|
32
|
+
from: round(start + step * i),
|
|
33
|
+
to: round(start + step * (i + 1)),
|
|
34
|
+
color
|
|
35
|
+
}));
|
|
36
|
+
};
|
|
37
|
+
var rangeOf = (value, ranges) => [...ranges].reverse().find((range) => value >= range.from && value <= range.to);
|
|
38
|
+
var legendStyle = (position) => {
|
|
39
|
+
const column = position === "left" || position === "right";
|
|
40
|
+
return {
|
|
41
|
+
display: "flex",
|
|
42
|
+
flexDirection: column ? "column" : "row",
|
|
43
|
+
flexWrap: "wrap",
|
|
44
|
+
gap: column ? "0.375rem" : "0.25rem 1rem",
|
|
45
|
+
margin: 0,
|
|
46
|
+
padding: 0,
|
|
47
|
+
listStyle: "none",
|
|
48
|
+
fontSize: chunkG4WOPX4D_cjs.TEXT_SIZE,
|
|
49
|
+
color: chunkLT3UC65O_cjs.MUTED
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
var SIDES = {
|
|
53
|
+
top: { flexDirection: "column" },
|
|
54
|
+
bottom: { flexDirection: "column-reverse" },
|
|
55
|
+
left: { flexDirection: "row" },
|
|
56
|
+
right: { flexDirection: "row-reverse" }
|
|
57
|
+
};
|
|
58
|
+
var HeatmapChart = ({
|
|
59
|
+
series,
|
|
60
|
+
categories,
|
|
61
|
+
colors,
|
|
62
|
+
ranges,
|
|
63
|
+
formatValue = String,
|
|
64
|
+
xTitle,
|
|
65
|
+
yTitle,
|
|
66
|
+
showValues = false,
|
|
67
|
+
showLegend = true,
|
|
68
|
+
legendPosition = "top",
|
|
69
|
+
emptyMessage = "No data",
|
|
70
|
+
ariaLabel,
|
|
71
|
+
height = 320,
|
|
72
|
+
width
|
|
73
|
+
}) => {
|
|
74
|
+
const name = ariaLabel ?? `Heatmap: ${series.map((s) => s.name).join(", ")}`;
|
|
75
|
+
if (chunkK3R7JGOW_cjs.hasNoData(series)) {
|
|
76
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkSR2ESX3R_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
77
|
+
}
|
|
78
|
+
const colorRanges = (ranges ?? evenRanges(
|
|
79
|
+
series.flatMap((s) => s.data),
|
|
80
|
+
colors ?? chunkLT3UC65O_cjs.SEQUENTIAL
|
|
81
|
+
)).map((range) => ({
|
|
82
|
+
...range,
|
|
83
|
+
name: range.name ?? `${formatValue(range.from)} \u2013 ${formatValue(range.to)}`
|
|
84
|
+
}));
|
|
85
|
+
const cells = series.flatMap(
|
|
86
|
+
(s, row) => s.data.flatMap(
|
|
87
|
+
(value, column) => Number.isFinite(value) ? [
|
|
88
|
+
{
|
|
89
|
+
row,
|
|
90
|
+
column,
|
|
91
|
+
color: rangeOf(value, colorRanges)?.color ?? chunkLT3UC65O_cjs.seriesColor(row),
|
|
92
|
+
title: String(categories[column] ?? column),
|
|
93
|
+
label: s.name,
|
|
94
|
+
value: formatValue(value),
|
|
95
|
+
text: showValues ? formatValue(value) : void 0
|
|
96
|
+
}
|
|
97
|
+
] : []
|
|
98
|
+
)
|
|
99
|
+
);
|
|
100
|
+
const legend = showLegend && /* @__PURE__ */ jsxRuntime.jsx("ul", { "data-heat-legend": "", style: legendStyle(legendPosition), children: colorRanges.map((range, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: { display: "flex", alignItems: "center", gap: "0.375rem" }, children: [
|
|
101
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
102
|
+
"span",
|
|
103
|
+
{
|
|
104
|
+
"aria-hidden": true,
|
|
105
|
+
style: {
|
|
106
|
+
width: "0.625rem",
|
|
107
|
+
height: "0.625rem",
|
|
108
|
+
borderRadius: 3,
|
|
109
|
+
background: range.color
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
),
|
|
113
|
+
range.name
|
|
114
|
+
] }, i)) });
|
|
115
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
116
|
+
"div",
|
|
117
|
+
{
|
|
118
|
+
style: {
|
|
119
|
+
// The axes keep their order under `dir="rtl"`, and so do the legend's sides.
|
|
120
|
+
direction: "ltr",
|
|
121
|
+
display: "flex",
|
|
122
|
+
gap: "1rem",
|
|
123
|
+
width: width ?? "100%",
|
|
124
|
+
height,
|
|
125
|
+
maxWidth: "100%",
|
|
126
|
+
...SIDES[legendPosition]
|
|
127
|
+
},
|
|
128
|
+
children: [
|
|
129
|
+
legend,
|
|
130
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: "1 1 0", minWidth: 0, minHeight: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
131
|
+
chunkZWHCUYIN_cjs.HeatGrid,
|
|
132
|
+
{
|
|
133
|
+
rows: series.map((s) => s.name),
|
|
134
|
+
columns: categories.map(String),
|
|
135
|
+
cells,
|
|
136
|
+
ariaLabel: name,
|
|
137
|
+
xTitle,
|
|
138
|
+
yTitle
|
|
139
|
+
}
|
|
140
|
+
) })
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
exports.HeatmapChart = HeatmapChart;
|
|
147
|
+
//# sourceMappingURL=HeatmapChart.cjs.map
|
|
148
|
+
//# sourceMappingURL=HeatmapChart.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/HeatmapChart.tsx"],"names":["TEXT_SIZE","MUTED","hasNoData","ChartEmpty","SEQUENTIAL","seriesColor","jsx","jsxs","HeatGrid"],"mappings":"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","file":"HeatmapChart.cjs","sourcesContent":["import type { CSSProperties } from 'react';\nimport { TEXT_SIZE } from './core/axes';\nimport { MUTED, SEQUENTIAL, seriesColor } from './core/colors';\nimport { hasNoData } from './core/data';\nimport { ChartEmpty } from './core/frame';\nimport { HeatGrid, type HeatCell } from './core/HeatGrid';\nimport type {\n ChartAxisTitleProps,\n ChartEmptyProps,\n ChartLegendPosition,\n ChartLegendProps,\n ChartProps,\n} from './types';\n\nexport type HeatmapColorRange = {\n /** Lowest value of the range, inclusive. */\n from: number;\n /** Highest value of the range, inclusive. A value on a shared bound takes the later range. */\n to: number;\n color: string;\n /** Legend label. Default: `from – to`, formatted with `formatValue`. */\n name?: string;\n};\n\nexport type HeatmapChartProps = Omit<ChartProps, 'children'> &\n ChartEmptyProps &\n ChartLegendProps &\n ChartAxisTitleProps & {\n /** One row per series, drawn top to bottom; one value per category. */\n series: { name: string; data: number[] }[];\n categories: (string | number)[];\n /**\n * Color steps, low to high, spread over the data range in buckets with\n * round bounds. Default: five steps of the current accent, mixed over the\n * card.\n */\n colors?: string[];\n /**\n * Explicit color ranges (thresholds such as OK / WARN / CRIT), which take\n * precedence over `colors`. Cover every value: a cell outside all ranges\n * falls back to a series color.\n */\n ranges?: HeatmapColorRange[];\n /** Format the values in the tooltip, the legend and the cells. */\n formatValue?: (value: number) => string;\n /** Print each value inside its cell. */\n showValues?: boolean;\n /** Show the color legend. Default true. */\n showLegend?: boolean;\n };\n\n// Round bucket sizes, × 10^n. Finer than 1-2-5 so that the buckets fit the\n// data instead of leaving the top colors unused.\nconst NICE_STEPS = [1, 2, 2.5, 3, 4, 5, 6, 8, 10];\n\n/** The smallest round bucket size that is at least `value`. */\nconst niceStep = (value: number): number => {\n const magnitude = 10 ** Math.floor(Math.log10(value));\n const step = NICE_STEPS.find((m) => m * magnitude >= value) ?? 10;\n return step * magnitude;\n};\n\n// Drops the float noise of `start + i * step` (0.30000000000000004).\nconst round = (value: number) => Number(value.toPrecision(12));\n\n/** `colors.length` contiguous ranges with round bounds covering every value. */\nconst evenRanges = (values: number[], colors: string[]): HeatmapColorRange[] => {\n const finite = values.filter(Number.isFinite);\n if (finite.length === 0 || colors.length === 0) return [];\n const min = finite.reduce((a, b) => Math.min(a, b));\n const max = finite.reduce((a, b) => Math.max(a, b));\n let step = niceStep((max - min) / colors.length || Math.abs(max) || 1);\n let start = Math.floor(min / step) * step;\n // Flooring the start can leave the top value out: take the next round step.\n while (start + step * colors.length < max) {\n step = niceStep(step * 1.001);\n start = Math.floor(min / step) * step;\n }\n return colors.map((color, i) => ({\n from: round(start + step * i),\n to: round(start + step * (i + 1)),\n color,\n }));\n};\n\n/** The range a value falls in; on a bound shared by two ranges, the later one. */\nconst rangeOf = (value: number, ranges: HeatmapColorRange[]) =>\n [...ranges].reverse().find((range) => value >= range.from && value <= range.to);\n\nconst legendStyle = (position: ChartLegendPosition): CSSProperties => {\n const column = position === 'left' || position === 'right';\n return {\n display: 'flex',\n flexDirection: column ? 'column' : 'row',\n flexWrap: 'wrap',\n gap: column ? '0.375rem' : '0.25rem 1rem',\n margin: 0,\n padding: 0,\n listStyle: 'none',\n fontSize: TEXT_SIZE,\n color: MUTED,\n };\n};\n\nconst SIDES: Record<ChartLegendPosition, CSSProperties> = {\n top: { flexDirection: 'column' },\n bottom: { flexDirection: 'column-reverse' },\n left: { flexDirection: 'row' },\n right: { flexDirection: 'row-reverse' },\n};\n\nexport const HeatmapChart = ({\n series,\n categories,\n colors,\n ranges,\n formatValue = String,\n xTitle,\n yTitle,\n showValues = false,\n showLegend = true,\n legendPosition = 'top',\n emptyMessage = 'No data',\n ariaLabel,\n height = 320,\n width,\n}: HeatmapChartProps) => {\n const name = ariaLabel ?? `Heatmap: ${series.map((s) => s.name).join(', ')}`;\n if (hasNoData(series)) {\n return <ChartEmpty message={emptyMessage} ariaLabel={name} height={height} width={width} />;\n }\n const colorRanges = (\n ranges ??\n evenRanges(\n series.flatMap((s) => s.data),\n colors ?? SEQUENTIAL\n )\n ).map((range) => ({\n ...range,\n name: range.name ?? `${formatValue(range.from)} – ${formatValue(range.to)}`,\n }));\n const cells = series.flatMap((s, row) =>\n s.data.flatMap((value, column): HeatCell[] =>\n Number.isFinite(value)\n ? [\n {\n row,\n column,\n color: rangeOf(value, colorRanges)?.color ?? seriesColor(row),\n title: String(categories[column] ?? column),\n label: s.name,\n value: formatValue(value),\n text: showValues ? formatValue(value) : undefined,\n },\n ]\n : []\n )\n );\n const legend = showLegend && (\n <ul data-heat-legend=\"\" style={legendStyle(legendPosition)}>\n {colorRanges.map((range, i) => (\n <li key={i} style={{ display: 'flex', alignItems: 'center', gap: '0.375rem' }}>\n <span\n aria-hidden\n style={{\n width: '0.625rem',\n height: '0.625rem',\n borderRadius: 3,\n background: range.color,\n }}\n />\n {range.name}\n </li>\n ))}\n </ul>\n );\n return (\n <div\n style={{\n // The axes keep their order under `dir=\"rtl\"`, and so do the legend's sides.\n direction: 'ltr',\n display: 'flex',\n gap: '1rem',\n width: width ?? '100%',\n height,\n maxWidth: '100%',\n ...SIDES[legendPosition],\n }}\n >\n {legend}\n <div style={{ flex: '1 1 0', minWidth: 0, minHeight: 0 }}>\n <HeatGrid\n rows={series.map((s) => s.name)}\n columns={categories.map(String)}\n cells={cells}\n ariaLabel={name}\n xTitle={xTitle}\n yTitle={yTitle}\n />\n </div>\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { HeatGrid } from './chunk-UL3SNXQR.js';
|
|
3
|
+
import './chunk-BFEDLXVW.js';
|
|
4
|
+
import { TEXT_SIZE } from './chunk-DI2FBGKM.js';
|
|
5
|
+
import './chunk-VIOSQN4Z.js';
|
|
6
|
+
import { hasNoData } from './chunk-UJIV5PVI.js';
|
|
7
|
+
import { ChartEmpty } from './chunk-56WD3OHA.js';
|
|
8
|
+
import { seriesColor, SEQUENTIAL, MUTED } from './chunk-UATB2IRY.js';
|
|
9
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
10
|
+
|
|
11
|
+
var NICE_STEPS = [1, 2, 2.5, 3, 4, 5, 6, 8, 10];
|
|
12
|
+
var niceStep = (value) => {
|
|
13
|
+
const magnitude = 10 ** Math.floor(Math.log10(value));
|
|
14
|
+
const step = NICE_STEPS.find((m) => m * magnitude >= value) ?? 10;
|
|
15
|
+
return step * magnitude;
|
|
16
|
+
};
|
|
17
|
+
var round = (value) => Number(value.toPrecision(12));
|
|
18
|
+
var evenRanges = (values, colors) => {
|
|
19
|
+
const finite = values.filter(Number.isFinite);
|
|
20
|
+
if (finite.length === 0 || colors.length === 0) return [];
|
|
21
|
+
const min = finite.reduce((a, b) => Math.min(a, b));
|
|
22
|
+
const max = finite.reduce((a, b) => Math.max(a, b));
|
|
23
|
+
let step = niceStep((max - min) / colors.length || Math.abs(max) || 1);
|
|
24
|
+
let start = Math.floor(min / step) * step;
|
|
25
|
+
while (start + step * colors.length < max) {
|
|
26
|
+
step = niceStep(step * 1.001);
|
|
27
|
+
start = Math.floor(min / step) * step;
|
|
28
|
+
}
|
|
29
|
+
return colors.map((color, i) => ({
|
|
30
|
+
from: round(start + step * i),
|
|
31
|
+
to: round(start + step * (i + 1)),
|
|
32
|
+
color
|
|
33
|
+
}));
|
|
34
|
+
};
|
|
35
|
+
var rangeOf = (value, ranges) => [...ranges].reverse().find((range) => value >= range.from && value <= range.to);
|
|
36
|
+
var legendStyle = (position) => {
|
|
37
|
+
const column = position === "left" || position === "right";
|
|
38
|
+
return {
|
|
39
|
+
display: "flex",
|
|
40
|
+
flexDirection: column ? "column" : "row",
|
|
41
|
+
flexWrap: "wrap",
|
|
42
|
+
gap: column ? "0.375rem" : "0.25rem 1rem",
|
|
43
|
+
margin: 0,
|
|
44
|
+
padding: 0,
|
|
45
|
+
listStyle: "none",
|
|
46
|
+
fontSize: TEXT_SIZE,
|
|
47
|
+
color: MUTED
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
var SIDES = {
|
|
51
|
+
top: { flexDirection: "column" },
|
|
52
|
+
bottom: { flexDirection: "column-reverse" },
|
|
53
|
+
left: { flexDirection: "row" },
|
|
54
|
+
right: { flexDirection: "row-reverse" }
|
|
55
|
+
};
|
|
56
|
+
var HeatmapChart = ({
|
|
57
|
+
series,
|
|
58
|
+
categories,
|
|
59
|
+
colors,
|
|
60
|
+
ranges,
|
|
61
|
+
formatValue = String,
|
|
62
|
+
xTitle,
|
|
63
|
+
yTitle,
|
|
64
|
+
showValues = false,
|
|
65
|
+
showLegend = true,
|
|
66
|
+
legendPosition = "top",
|
|
67
|
+
emptyMessage = "No data",
|
|
68
|
+
ariaLabel,
|
|
69
|
+
height = 320,
|
|
70
|
+
width
|
|
71
|
+
}) => {
|
|
72
|
+
const name = ariaLabel ?? `Heatmap: ${series.map((s) => s.name).join(", ")}`;
|
|
73
|
+
if (hasNoData(series)) {
|
|
74
|
+
return /* @__PURE__ */ jsx(ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
75
|
+
}
|
|
76
|
+
const colorRanges = (ranges ?? evenRanges(
|
|
77
|
+
series.flatMap((s) => s.data),
|
|
78
|
+
colors ?? SEQUENTIAL
|
|
79
|
+
)).map((range) => ({
|
|
80
|
+
...range,
|
|
81
|
+
name: range.name ?? `${formatValue(range.from)} \u2013 ${formatValue(range.to)}`
|
|
82
|
+
}));
|
|
83
|
+
const cells = series.flatMap(
|
|
84
|
+
(s, row) => s.data.flatMap(
|
|
85
|
+
(value, column) => Number.isFinite(value) ? [
|
|
86
|
+
{
|
|
87
|
+
row,
|
|
88
|
+
column,
|
|
89
|
+
color: rangeOf(value, colorRanges)?.color ?? seriesColor(row),
|
|
90
|
+
title: String(categories[column] ?? column),
|
|
91
|
+
label: s.name,
|
|
92
|
+
value: formatValue(value),
|
|
93
|
+
text: showValues ? formatValue(value) : void 0
|
|
94
|
+
}
|
|
95
|
+
] : []
|
|
96
|
+
)
|
|
97
|
+
);
|
|
98
|
+
const legend = showLegend && /* @__PURE__ */ jsx("ul", { "data-heat-legend": "", style: legendStyle(legendPosition), children: colorRanges.map((range, i) => /* @__PURE__ */ jsxs("li", { style: { display: "flex", alignItems: "center", gap: "0.375rem" }, children: [
|
|
99
|
+
/* @__PURE__ */ jsx(
|
|
100
|
+
"span",
|
|
101
|
+
{
|
|
102
|
+
"aria-hidden": true,
|
|
103
|
+
style: {
|
|
104
|
+
width: "0.625rem",
|
|
105
|
+
height: "0.625rem",
|
|
106
|
+
borderRadius: 3,
|
|
107
|
+
background: range.color
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
range.name
|
|
112
|
+
] }, i)) });
|
|
113
|
+
return /* @__PURE__ */ jsxs(
|
|
114
|
+
"div",
|
|
115
|
+
{
|
|
116
|
+
style: {
|
|
117
|
+
// The axes keep their order under `dir="rtl"`, and so do the legend's sides.
|
|
118
|
+
direction: "ltr",
|
|
119
|
+
display: "flex",
|
|
120
|
+
gap: "1rem",
|
|
121
|
+
width: width ?? "100%",
|
|
122
|
+
height,
|
|
123
|
+
maxWidth: "100%",
|
|
124
|
+
...SIDES[legendPosition]
|
|
125
|
+
},
|
|
126
|
+
children: [
|
|
127
|
+
legend,
|
|
128
|
+
/* @__PURE__ */ jsx("div", { style: { flex: "1 1 0", minWidth: 0, minHeight: 0 }, children: /* @__PURE__ */ jsx(
|
|
129
|
+
HeatGrid,
|
|
130
|
+
{
|
|
131
|
+
rows: series.map((s) => s.name),
|
|
132
|
+
columns: categories.map(String),
|
|
133
|
+
cells,
|
|
134
|
+
ariaLabel: name,
|
|
135
|
+
xTitle,
|
|
136
|
+
yTitle
|
|
137
|
+
}
|
|
138
|
+
) })
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export { HeatmapChart };
|
|
145
|
+
//# sourceMappingURL=HeatmapChart.js.map
|
|
146
|
+
//# sourceMappingURL=HeatmapChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/HeatmapChart.tsx"],"names":[],"mappings":"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","file":"HeatmapChart.js","sourcesContent":["import type { CSSProperties } from 'react';\nimport { TEXT_SIZE } from './core/axes';\nimport { MUTED, SEQUENTIAL, seriesColor } from './core/colors';\nimport { hasNoData } from './core/data';\nimport { ChartEmpty } from './core/frame';\nimport { HeatGrid, type HeatCell } from './core/HeatGrid';\nimport type {\n ChartAxisTitleProps,\n ChartEmptyProps,\n ChartLegendPosition,\n ChartLegendProps,\n ChartProps,\n} from './types';\n\nexport type HeatmapColorRange = {\n /** Lowest value of the range, inclusive. */\n from: number;\n /** Highest value of the range, inclusive. A value on a shared bound takes the later range. */\n to: number;\n color: string;\n /** Legend label. Default: `from – to`, formatted with `formatValue`. */\n name?: string;\n};\n\nexport type HeatmapChartProps = Omit<ChartProps, 'children'> &\n ChartEmptyProps &\n ChartLegendProps &\n ChartAxisTitleProps & {\n /** One row per series, drawn top to bottom; one value per category. */\n series: { name: string; data: number[] }[];\n categories: (string | number)[];\n /**\n * Color steps, low to high, spread over the data range in buckets with\n * round bounds. Default: five steps of the current accent, mixed over the\n * card.\n */\n colors?: string[];\n /**\n * Explicit color ranges (thresholds such as OK / WARN / CRIT), which take\n * precedence over `colors`. Cover every value: a cell outside all ranges\n * falls back to a series color.\n */\n ranges?: HeatmapColorRange[];\n /** Format the values in the tooltip, the legend and the cells. */\n formatValue?: (value: number) => string;\n /** Print each value inside its cell. */\n showValues?: boolean;\n /** Show the color legend. Default true. */\n showLegend?: boolean;\n };\n\n// Round bucket sizes, × 10^n. Finer than 1-2-5 so that the buckets fit the\n// data instead of leaving the top colors unused.\nconst NICE_STEPS = [1, 2, 2.5, 3, 4, 5, 6, 8, 10];\n\n/** The smallest round bucket size that is at least `value`. */\nconst niceStep = (value: number): number => {\n const magnitude = 10 ** Math.floor(Math.log10(value));\n const step = NICE_STEPS.find((m) => m * magnitude >= value) ?? 10;\n return step * magnitude;\n};\n\n// Drops the float noise of `start + i * step` (0.30000000000000004).\nconst round = (value: number) => Number(value.toPrecision(12));\n\n/** `colors.length` contiguous ranges with round bounds covering every value. */\nconst evenRanges = (values: number[], colors: string[]): HeatmapColorRange[] => {\n const finite = values.filter(Number.isFinite);\n if (finite.length === 0 || colors.length === 0) return [];\n const min = finite.reduce((a, b) => Math.min(a, b));\n const max = finite.reduce((a, b) => Math.max(a, b));\n let step = niceStep((max - min) / colors.length || Math.abs(max) || 1);\n let start = Math.floor(min / step) * step;\n // Flooring the start can leave the top value out: take the next round step.\n while (start + step * colors.length < max) {\n step = niceStep(step * 1.001);\n start = Math.floor(min / step) * step;\n }\n return colors.map((color, i) => ({\n from: round(start + step * i),\n to: round(start + step * (i + 1)),\n color,\n }));\n};\n\n/** The range a value falls in; on a bound shared by two ranges, the later one. */\nconst rangeOf = (value: number, ranges: HeatmapColorRange[]) =>\n [...ranges].reverse().find((range) => value >= range.from && value <= range.to);\n\nconst legendStyle = (position: ChartLegendPosition): CSSProperties => {\n const column = position === 'left' || position === 'right';\n return {\n display: 'flex',\n flexDirection: column ? 'column' : 'row',\n flexWrap: 'wrap',\n gap: column ? '0.375rem' : '0.25rem 1rem',\n margin: 0,\n padding: 0,\n listStyle: 'none',\n fontSize: TEXT_SIZE,\n color: MUTED,\n };\n};\n\nconst SIDES: Record<ChartLegendPosition, CSSProperties> = {\n top: { flexDirection: 'column' },\n bottom: { flexDirection: 'column-reverse' },\n left: { flexDirection: 'row' },\n right: { flexDirection: 'row-reverse' },\n};\n\nexport const HeatmapChart = ({\n series,\n categories,\n colors,\n ranges,\n formatValue = String,\n xTitle,\n yTitle,\n showValues = false,\n showLegend = true,\n legendPosition = 'top',\n emptyMessage = 'No data',\n ariaLabel,\n height = 320,\n width,\n}: HeatmapChartProps) => {\n const name = ariaLabel ?? `Heatmap: ${series.map((s) => s.name).join(', ')}`;\n if (hasNoData(series)) {\n return <ChartEmpty message={emptyMessage} ariaLabel={name} height={height} width={width} />;\n }\n const colorRanges = (\n ranges ??\n evenRanges(\n series.flatMap((s) => s.data),\n colors ?? SEQUENTIAL\n )\n ).map((range) => ({\n ...range,\n name: range.name ?? `${formatValue(range.from)} – ${formatValue(range.to)}`,\n }));\n const cells = series.flatMap((s, row) =>\n s.data.flatMap((value, column): HeatCell[] =>\n Number.isFinite(value)\n ? [\n {\n row,\n column,\n color: rangeOf(value, colorRanges)?.color ?? seriesColor(row),\n title: String(categories[column] ?? column),\n label: s.name,\n value: formatValue(value),\n text: showValues ? formatValue(value) : undefined,\n },\n ]\n : []\n )\n );\n const legend = showLegend && (\n <ul data-heat-legend=\"\" style={legendStyle(legendPosition)}>\n {colorRanges.map((range, i) => (\n <li key={i} style={{ display: 'flex', alignItems: 'center', gap: '0.375rem' }}>\n <span\n aria-hidden\n style={{\n width: '0.625rem',\n height: '0.625rem',\n borderRadius: 3,\n background: range.color,\n }}\n />\n {range.name}\n </li>\n ))}\n </ul>\n );\n return (\n <div\n style={{\n // The axes keep their order under `dir=\"rtl\"`, and so do the legend's sides.\n direction: 'ltr',\n display: 'flex',\n gap: '1rem',\n width: width ?? '100%',\n height,\n maxWidth: '100%',\n ...SIDES[legendPosition],\n }}\n >\n {legend}\n <div style={{ flex: '1 1 0', minWidth: 0, minHeight: 0 }}>\n <HeatGrid\n rows={series.map((s) => s.name)}\n columns={categories.map(String)}\n cells={cells}\n ariaLabel={name}\n xTitle={xTitle}\n yTitle={yTitle}\n />\n </div>\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunkXUGQ6VXO_cjs = require('./chunk-XUGQ6VXO.cjs');
|
|
5
|
+
var chunkRCDTBZC2_cjs = require('./chunk-RCDTBZC2.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 react = require('react');
|
|
13
|
+
var recharts = require('recharts');
|
|
14
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
15
|
+
|
|
16
|
+
var DASH = "6 4";
|
|
17
|
+
var LineAreaChart = ({
|
|
18
|
+
series,
|
|
19
|
+
categories,
|
|
20
|
+
colors,
|
|
21
|
+
formatValue,
|
|
22
|
+
xTitle,
|
|
23
|
+
yTitle,
|
|
24
|
+
referenceLines,
|
|
25
|
+
referenceBands,
|
|
26
|
+
emptyMessage = "No data",
|
|
27
|
+
ariaLabel,
|
|
28
|
+
children,
|
|
29
|
+
height = 280,
|
|
30
|
+
width,
|
|
31
|
+
showLegend,
|
|
32
|
+
legendPosition = "top",
|
|
33
|
+
variant = "area",
|
|
34
|
+
stacked = false,
|
|
35
|
+
markers = false
|
|
36
|
+
}) => {
|
|
37
|
+
const uid = chunkK3R7JGOW_cjs.safeId(react.useId());
|
|
38
|
+
const hidden = chunkRCDTBZC2_cjs.useHiddenSeries();
|
|
39
|
+
const axis = chunkG4WOPX4D_cjs.useAxis();
|
|
40
|
+
const name = ariaLabel ?? `Area chart: ${series.map((s) => s.name).join(", ")}`;
|
|
41
|
+
if (chunkK3R7JGOW_cjs.hasNoData(series)) {
|
|
42
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkSR2ESX3R_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
43
|
+
}
|
|
44
|
+
const legendVisible = showLegend ?? series.length > 1;
|
|
45
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
46
|
+
recharts.AreaChart,
|
|
47
|
+
{
|
|
48
|
+
...chunkSR2ESX3R_cjs.frameProps({ height, width, ariaLabel: name }),
|
|
49
|
+
data: chunkK3R7JGOW_cjs.toRows(categories, series),
|
|
50
|
+
margin: { top: 4, right: 8, bottom: 0, left: 0 },
|
|
51
|
+
children: [
|
|
52
|
+
variant === "area" && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: series.map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: `${uid}-${i}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
53
|
+
/* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: chunkLT3UC65O_cjs.seriesColor(i, colors), stopOpacity: 0.32 }),
|
|
54
|
+
/* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: chunkLT3UC65O_cjs.seriesColor(i, colors), stopOpacity: 0 })
|
|
55
|
+
] }, chunkK3R7JGOW_cjs.seriesKey(i))) }),
|
|
56
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...chunkG4WOPX4D_cjs.GRID_PROPS }),
|
|
57
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { dataKey: "category", ...axis, ...chunkG4WOPX4D_cjs.xAxisTitle(xTitle) }),
|
|
58
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { width: "auto", tickFormatter: formatValue, ...axis, ...chunkG4WOPX4D_cjs.yAxisTitle(yTitle) }),
|
|
59
|
+
legendVisible && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { ...chunkRCDTBZC2_cjs.legendProps(legendPosition, hidden) }),
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
61
|
+
recharts.Tooltip,
|
|
62
|
+
{
|
|
63
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(chunkT3K6Q34U_cjs.ChartTooltip, { format: formatValue }),
|
|
64
|
+
cursor: { stroke: chunkLT3UC65O_cjs.BORDER, strokeDasharray: "4 4" },
|
|
65
|
+
animationDuration: 150
|
|
66
|
+
}
|
|
67
|
+
),
|
|
68
|
+
series.map((s, i) => {
|
|
69
|
+
const color = chunkLT3UC65O_cjs.seriesColor(i, colors);
|
|
70
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
71
|
+
recharts.Area,
|
|
72
|
+
{
|
|
73
|
+
name: s.name,
|
|
74
|
+
dataKey: chunkK3R7JGOW_cjs.seriesKey(i),
|
|
75
|
+
type: s.style === "step" ? "step" : "monotone",
|
|
76
|
+
stroke: color,
|
|
77
|
+
strokeWidth: 2.25,
|
|
78
|
+
strokeDasharray: s.style === "dashed" ? DASH : void 0,
|
|
79
|
+
stackId: stacked ? "stack" : void 0,
|
|
80
|
+
fill: variant === "area" ? `url(#${uid}-${i})` : "none",
|
|
81
|
+
dot: markers ? { r: 3.5, fill: chunkLT3UC65O_cjs.PANEL, stroke: color, strokeWidth: 2 } : false,
|
|
82
|
+
activeDot: { r: 5, fill: chunkLT3UC65O_cjs.PANEL, stroke: color, strokeWidth: 2.5 },
|
|
83
|
+
hide: hidden.hidden.has(chunkK3R7JGOW_cjs.seriesKey(i)),
|
|
84
|
+
...chunkTYQWZR3S_cjs.ANIMATION
|
|
85
|
+
},
|
|
86
|
+
chunkK3R7JGOW_cjs.seriesKey(i)
|
|
87
|
+
);
|
|
88
|
+
}),
|
|
89
|
+
chunkXUGQ6VXO_cjs.referenceMarks({ referenceLines, referenceBands }),
|
|
90
|
+
children
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
exports.LineAreaChart = LineAreaChart;
|
|
97
|
+
//# sourceMappingURL=LineAreaChart.cjs.map
|
|
98
|
+
//# sourceMappingURL=LineAreaChart.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/LineAreaChart.tsx"],"names":["safeId","useId","useHiddenSeries","useAxis","hasNoData","ChartEmpty","jsxs","AreaChart","frameProps","toRows","jsx","seriesColor","seriesKey","CartesianGrid","GRID_PROPS","XAxis","xAxisTitle","YAxis","yAxisTitle","Legend","legendProps","Tooltip","ChartTooltip","BORDER","Area","PANEL","ANIMATION","referenceMarks"],"mappings":"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","file":"LineAreaChart.cjs","sourcesContent":["import { useId } from 'react';\nimport { Area, AreaChart, CartesianGrid, Legend, Tooltip, XAxis, YAxis } from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { GRID_PROPS, useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { ChartTooltip } from './core/ChartTooltip';\nimport { legendProps, useHiddenSeries } from './core/ChartLegend';\nimport { BORDER, 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 type {\n ChartAxisTitleProps,\n ChartEmptyProps,\n ChartLegendProps,\n ChartProps,\n ChartReferenceProps,\n} from './types';\n\nexport type LineAreaChartVariant = 'area' | 'line';\n\n/** How a series is drawn: a `solid` smooth curve, a `dashed` one, or a `step` line that jumps from value to value. */\nexport type LineAreaChartSeriesStyle = 'solid' | 'dashed' | 'step';\n\n// The dash of a `dashed` series, as the reference lines have it.\nconst DASH = '6 4';\n\nexport type LineAreaChartProps = ChartProps &\n ChartEmptyProps &\n ChartLegendProps &\n ChartAxisTitleProps &\n ChartReferenceProps & {\n series: {\n name: string;\n data: number[];\n /** `solid` (default), `dashed` or `step`: a line that jumps from one value to the next, such as a quota or a replica count. */\n style?: LineAreaChartSeriesStyle;\n }[];\n categories: (string | number)[];\n /** Override the default Cosmos palette. */\n colors?: string[];\n /** Format the y-axis labels and the tooltip values. */\n formatValue?: (value: number) => string;\n /** Show the legend (auto-true when 2+ series). */\n showLegend?: boolean;\n /** `area` (default) fills under each line with a gradient; `line` draws the lines alone. */\n variant?: LineAreaChartVariant;\n /** Pile the series on each other, so the top line is the sum: the share of each in a total. */\n stacked?: boolean;\n /** Mark every data point with a dot. Default off: a dot appears under the pointer only. */\n markers?: boolean;\n };\n\nexport const LineAreaChart = ({\n series,\n categories,\n colors,\n formatValue,\n xTitle,\n yTitle,\n referenceLines,\n referenceBands,\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 280,\n width,\n showLegend,\n legendPosition = 'top',\n variant = 'area',\n stacked = false,\n markers = false,\n}: LineAreaChartProps) => {\n const uid = safeId(useId());\n const hidden = useHiddenSeries();\n const axis = useAxis();\n const name = ariaLabel ?? `Area 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 return (\n <AreaChart\n {...frameProps({ height, width, ariaLabel: name })}\n data={toRows(categories, series)}\n margin={{ top: 4, right: 8, bottom: 0, left: 0 }}\n >\n {variant === 'area' && (\n <defs>\n {series.map((_, i) => (\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 ))}\n </defs>\n )}\n <CartesianGrid {...GRID_PROPS} />\n <XAxis dataKey=\"category\" {...axis} {...xAxisTitle(xTitle)} />\n <YAxis width=\"auto\" tickFormatter={formatValue} {...axis} {...yAxisTitle(yTitle)} />\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 const color = seriesColor(i, colors);\n return (\n <Area\n key={seriesKey(i)}\n name={s.name}\n dataKey={seriesKey(i)}\n type={s.style === 'step' ? 'step' : 'monotone'}\n stroke={color}\n strokeWidth={2.25}\n strokeDasharray={s.style === 'dashed' ? DASH : undefined}\n stackId={stacked ? 'stack' : undefined}\n fill={variant === 'area' ? `url(#${uid}-${i})` : 'none'}\n dot={markers ? { r: 3.5, fill: PANEL, stroke: color, strokeWidth: 2 } : false}\n activeDot={{ r: 5, fill: PANEL, stroke: color, strokeWidth: 2.5 }}\n hide={hidden.hidden.has(seriesKey(i))}\n {...ANIMATION}\n />\n );\n })}\n {referenceMarks({ referenceLines, referenceBands })}\n {children}\n </AreaChart>\n );\n};\n"]}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { referenceMarks } from './chunk-ESVGCUJN.js';
|
|
3
|
+
import { useHiddenSeries, legendProps } from './chunk-4AKHZNWP.js';
|
|
4
|
+
import { ANIMATION } from './chunk-5C2RLJYZ.js';
|
|
5
|
+
import { useAxis, GRID_PROPS, xAxisTitle, yAxisTitle } from './chunk-DI2FBGKM.js';
|
|
6
|
+
import { ChartTooltip } from './chunk-VIOSQN4Z.js';
|
|
7
|
+
import { safeId, hasNoData, seriesKey, toRows } from './chunk-UJIV5PVI.js';
|
|
8
|
+
import { ChartEmpty, frameProps } from './chunk-56WD3OHA.js';
|
|
9
|
+
import { seriesColor, BORDER, PANEL } from './chunk-UATB2IRY.js';
|
|
10
|
+
import { useId } from 'react';
|
|
11
|
+
import { AreaChart, CartesianGrid, XAxis, YAxis, Legend, Tooltip, Area } from 'recharts';
|
|
12
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
13
|
+
|
|
14
|
+
var DASH = "6 4";
|
|
15
|
+
var LineAreaChart = ({
|
|
16
|
+
series,
|
|
17
|
+
categories,
|
|
18
|
+
colors,
|
|
19
|
+
formatValue,
|
|
20
|
+
xTitle,
|
|
21
|
+
yTitle,
|
|
22
|
+
referenceLines,
|
|
23
|
+
referenceBands,
|
|
24
|
+
emptyMessage = "No data",
|
|
25
|
+
ariaLabel,
|
|
26
|
+
children,
|
|
27
|
+
height = 280,
|
|
28
|
+
width,
|
|
29
|
+
showLegend,
|
|
30
|
+
legendPosition = "top",
|
|
31
|
+
variant = "area",
|
|
32
|
+
stacked = false,
|
|
33
|
+
markers = false
|
|
34
|
+
}) => {
|
|
35
|
+
const uid = safeId(useId());
|
|
36
|
+
const hidden = useHiddenSeries();
|
|
37
|
+
const axis = useAxis();
|
|
38
|
+
const name = ariaLabel ?? `Area chart: ${series.map((s) => s.name).join(", ")}`;
|
|
39
|
+
if (hasNoData(series)) {
|
|
40
|
+
return /* @__PURE__ */ jsx(ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
|
|
41
|
+
}
|
|
42
|
+
const legendVisible = showLegend ?? series.length > 1;
|
|
43
|
+
return /* @__PURE__ */ jsxs(
|
|
44
|
+
AreaChart,
|
|
45
|
+
{
|
|
46
|
+
...frameProps({ height, width, ariaLabel: name }),
|
|
47
|
+
data: toRows(categories, series),
|
|
48
|
+
margin: { top: 4, right: 8, bottom: 0, left: 0 },
|
|
49
|
+
children: [
|
|
50
|
+
variant === "area" && /* @__PURE__ */ jsx("defs", { children: series.map((_, i) => /* @__PURE__ */ jsxs("linearGradient", { id: `${uid}-${i}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
51
|
+
/* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: seriesColor(i, colors), stopOpacity: 0.32 }),
|
|
52
|
+
/* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: seriesColor(i, colors), stopOpacity: 0 })
|
|
53
|
+
] }, seriesKey(i))) }),
|
|
54
|
+
/* @__PURE__ */ jsx(CartesianGrid, { ...GRID_PROPS }),
|
|
55
|
+
/* @__PURE__ */ jsx(XAxis, { dataKey: "category", ...axis, ...xAxisTitle(xTitle) }),
|
|
56
|
+
/* @__PURE__ */ jsx(YAxis, { width: "auto", tickFormatter: formatValue, ...axis, ...yAxisTitle(yTitle) }),
|
|
57
|
+
legendVisible && /* @__PURE__ */ jsx(Legend, { ...legendProps(legendPosition, hidden) }),
|
|
58
|
+
/* @__PURE__ */ jsx(
|
|
59
|
+
Tooltip,
|
|
60
|
+
{
|
|
61
|
+
content: /* @__PURE__ */ jsx(ChartTooltip, { format: formatValue }),
|
|
62
|
+
cursor: { stroke: BORDER, strokeDasharray: "4 4" },
|
|
63
|
+
animationDuration: 150
|
|
64
|
+
}
|
|
65
|
+
),
|
|
66
|
+
series.map((s, i) => {
|
|
67
|
+
const color = seriesColor(i, colors);
|
|
68
|
+
return /* @__PURE__ */ jsx(
|
|
69
|
+
Area,
|
|
70
|
+
{
|
|
71
|
+
name: s.name,
|
|
72
|
+
dataKey: seriesKey(i),
|
|
73
|
+
type: s.style === "step" ? "step" : "monotone",
|
|
74
|
+
stroke: color,
|
|
75
|
+
strokeWidth: 2.25,
|
|
76
|
+
strokeDasharray: s.style === "dashed" ? DASH : void 0,
|
|
77
|
+
stackId: stacked ? "stack" : void 0,
|
|
78
|
+
fill: variant === "area" ? `url(#${uid}-${i})` : "none",
|
|
79
|
+
dot: markers ? { r: 3.5, fill: PANEL, stroke: color, strokeWidth: 2 } : false,
|
|
80
|
+
activeDot: { r: 5, fill: PANEL, stroke: color, strokeWidth: 2.5 },
|
|
81
|
+
hide: hidden.hidden.has(seriesKey(i)),
|
|
82
|
+
...ANIMATION
|
|
83
|
+
},
|
|
84
|
+
seriesKey(i)
|
|
85
|
+
);
|
|
86
|
+
}),
|
|
87
|
+
referenceMarks({ referenceLines, referenceBands }),
|
|
88
|
+
children
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export { LineAreaChart };
|
|
95
|
+
//# sourceMappingURL=LineAreaChart.js.map
|
|
96
|
+
//# sourceMappingURL=LineAreaChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/LineAreaChart.tsx"],"names":[],"mappings":"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","file":"LineAreaChart.js","sourcesContent":["import { useId } from 'react';\nimport { Area, AreaChart, CartesianGrid, Legend, Tooltip, XAxis, YAxis } from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { GRID_PROPS, useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { ChartTooltip } from './core/ChartTooltip';\nimport { legendProps, useHiddenSeries } from './core/ChartLegend';\nimport { BORDER, 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 type {\n ChartAxisTitleProps,\n ChartEmptyProps,\n ChartLegendProps,\n ChartProps,\n ChartReferenceProps,\n} from './types';\n\nexport type LineAreaChartVariant = 'area' | 'line';\n\n/** How a series is drawn: a `solid` smooth curve, a `dashed` one, or a `step` line that jumps from value to value. */\nexport type LineAreaChartSeriesStyle = 'solid' | 'dashed' | 'step';\n\n// The dash of a `dashed` series, as the reference lines have it.\nconst DASH = '6 4';\n\nexport type LineAreaChartProps = ChartProps &\n ChartEmptyProps &\n ChartLegendProps &\n ChartAxisTitleProps &\n ChartReferenceProps & {\n series: {\n name: string;\n data: number[];\n /** `solid` (default), `dashed` or `step`: a line that jumps from one value to the next, such as a quota or a replica count. */\n style?: LineAreaChartSeriesStyle;\n }[];\n categories: (string | number)[];\n /** Override the default Cosmos palette. */\n colors?: string[];\n /** Format the y-axis labels and the tooltip values. */\n formatValue?: (value: number) => string;\n /** Show the legend (auto-true when 2+ series). */\n showLegend?: boolean;\n /** `area` (default) fills under each line with a gradient; `line` draws the lines alone. */\n variant?: LineAreaChartVariant;\n /** Pile the series on each other, so the top line is the sum: the share of each in a total. */\n stacked?: boolean;\n /** Mark every data point with a dot. Default off: a dot appears under the pointer only. */\n markers?: boolean;\n };\n\nexport const LineAreaChart = ({\n series,\n categories,\n colors,\n formatValue,\n xTitle,\n yTitle,\n referenceLines,\n referenceBands,\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 280,\n width,\n showLegend,\n legendPosition = 'top',\n variant = 'area',\n stacked = false,\n markers = false,\n}: LineAreaChartProps) => {\n const uid = safeId(useId());\n const hidden = useHiddenSeries();\n const axis = useAxis();\n const name = ariaLabel ?? `Area 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 return (\n <AreaChart\n {...frameProps({ height, width, ariaLabel: name })}\n data={toRows(categories, series)}\n margin={{ top: 4, right: 8, bottom: 0, left: 0 }}\n >\n {variant === 'area' && (\n <defs>\n {series.map((_, i) => (\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 ))}\n </defs>\n )}\n <CartesianGrid {...GRID_PROPS} />\n <XAxis dataKey=\"category\" {...axis} {...xAxisTitle(xTitle)} />\n <YAxis width=\"auto\" tickFormatter={formatValue} {...axis} {...yAxisTitle(yTitle)} />\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 const color = seriesColor(i, colors);\n return (\n <Area\n key={seriesKey(i)}\n name={s.name}\n dataKey={seriesKey(i)}\n type={s.style === 'step' ? 'step' : 'monotone'}\n stroke={color}\n strokeWidth={2.25}\n strokeDasharray={s.style === 'dashed' ? DASH : undefined}\n stackId={stacked ? 'stack' : undefined}\n fill={variant === 'area' ? `url(#${uid}-${i})` : 'none'}\n dot={markers ? { r: 3.5, fill: PANEL, stroke: color, strokeWidth: 2 } : false}\n activeDot={{ r: 5, fill: PANEL, stroke: color, strokeWidth: 2.5 }}\n hide={hidden.hidden.has(seriesKey(i))}\n {...ANIMATION}\n />\n );\n })}\n {referenceMarks({ referenceLines, referenceBands })}\n {children}\n </AreaChart>\n );\n};\n"]}
|