@sckyzo/cosmos-charts 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +107 -22
  3. package/THIRD_PARTY_NOTICES.md +81 -0
  4. package/dist/BarChart.cjs +137 -0
  5. package/dist/BarChart.cjs.map +1 -0
  6. package/dist/BarChart.js +135 -0
  7. package/dist/BarChart.js.map +1 -0
  8. package/dist/BoxPlotChart.cjs +214 -0
  9. package/dist/BoxPlotChart.cjs.map +1 -0
  10. package/dist/BoxPlotChart.js +212 -0
  11. package/dist/BoxPlotChart.js.map +1 -0
  12. package/dist/BumpChart.cjs +328 -0
  13. package/dist/BumpChart.cjs.map +1 -0
  14. package/dist/BumpChart.js +326 -0
  15. package/dist/BumpChart.js.map +1 -0
  16. package/dist/CalendarChart.cjs +216 -0
  17. package/dist/CalendarChart.cjs.map +1 -0
  18. package/dist/CalendarChart.js +214 -0
  19. package/dist/CalendarChart.js.map +1 -0
  20. package/dist/DonutChart.cjs +122 -0
  21. package/dist/DonutChart.cjs.map +1 -0
  22. package/dist/DonutChart.js +120 -0
  23. package/dist/DonutChart.js.map +1 -0
  24. package/dist/FunnelChart.cjs +422 -0
  25. package/dist/FunnelChart.cjs.map +1 -0
  26. package/dist/FunnelChart.js +420 -0
  27. package/dist/FunnelChart.js.map +1 -0
  28. package/dist/GradientRadial.cjs +51 -0
  29. package/dist/GradientRadial.cjs.map +1 -0
  30. package/dist/GradientRadial.js +49 -0
  31. package/dist/GradientRadial.js.map +1 -0
  32. package/dist/HeatmapChart.cjs +146 -0
  33. package/dist/HeatmapChart.cjs.map +1 -0
  34. package/dist/HeatmapChart.js +144 -0
  35. package/dist/HeatmapChart.js.map +1 -0
  36. package/dist/LineAreaChart.cjs +98 -0
  37. package/dist/LineAreaChart.cjs.map +1 -0
  38. package/dist/LineAreaChart.js +96 -0
  39. package/dist/LineAreaChart.js.map +1 -0
  40. package/dist/MixedChart.cjs +195 -0
  41. package/dist/MixedChart.cjs.map +1 -0
  42. package/dist/MixedChart.js +193 -0
  43. package/dist/MixedChart.js.map +1 -0
  44. package/dist/RadarChart.cjs +109 -0
  45. package/dist/RadarChart.cjs.map +1 -0
  46. package/dist/RadarChart.js +107 -0
  47. package/dist/RadarChart.js.map +1 -0
  48. package/dist/RadialBarChart.cjs +99 -0
  49. package/dist/RadialBarChart.cjs.map +1 -0
  50. package/dist/RadialBarChart.js +97 -0
  51. package/dist/RadialBarChart.js.map +1 -0
  52. package/dist/RangeBarChart.cjs +218 -0
  53. package/dist/RangeBarChart.cjs.map +1 -0
  54. package/dist/RangeBarChart.js +216 -0
  55. package/dist/RangeBarChart.js.map +1 -0
  56. package/dist/RealtimeChart.cjs +173 -0
  57. package/dist/RealtimeChart.cjs.map +1 -0
  58. package/dist/RealtimeChart.js +171 -0
  59. package/dist/RealtimeChart.js.map +1 -0
  60. package/dist/ScatterChart.cjs +134 -0
  61. package/dist/ScatterChart.cjs.map +1 -0
  62. package/dist/ScatterChart.js +131 -0
  63. package/dist/ScatterChart.js.map +1 -0
  64. package/dist/SemiCircleGauge.cjs +142 -0
  65. package/dist/SemiCircleGauge.cjs.map +1 -0
  66. package/dist/SemiCircleGauge.js +140 -0
  67. package/dist/SemiCircleGauge.js.map +1 -0
  68. package/dist/Sparkline.cjs +117 -0
  69. package/dist/Sparkline.cjs.map +1 -0
  70. package/dist/Sparkline.js +115 -0
  71. package/dist/Sparkline.js.map +1 -0
  72. package/dist/StrokedGauge.cjs +94 -0
  73. package/dist/StrokedGauge.cjs.map +1 -0
  74. package/dist/StrokedGauge.js +92 -0
  75. package/dist/StrokedGauge.js.map +1 -0
  76. package/dist/TreemapChart.cjs +263 -0
  77. package/dist/TreemapChart.cjs.map +1 -0
  78. package/dist/TreemapChart.js +261 -0
  79. package/dist/TreemapChart.js.map +1 -0
  80. package/dist/WaterfallChart.cjs +235 -0
  81. package/dist/WaterfallChart.cjs.map +1 -0
  82. package/dist/WaterfallChart.js +233 -0
  83. package/dist/WaterfallChart.js.map +1 -0
  84. package/dist/WorldMap.cjs +2088 -0
  85. package/dist/WorldMap.cjs.map +1 -0
  86. package/dist/WorldMap.js +603 -0
  87. package/dist/WorldMap.js.map +1 -0
  88. package/dist/chunk-3N43QT36.js +60 -0
  89. package/dist/chunk-3N43QT36.js.map +1 -0
  90. package/dist/chunk-5C2RLJYZ.js +11 -0
  91. package/dist/chunk-5C2RLJYZ.js.map +1 -0
  92. package/dist/chunk-6ALKZLN2.js +127 -0
  93. package/dist/chunk-6ALKZLN2.js.map +1 -0
  94. package/dist/chunk-6BKLL7LZ.cjs +30 -0
  95. package/dist/chunk-6BKLL7LZ.cjs.map +1 -0
  96. package/dist/chunk-6NRRABPF.cjs +64 -0
  97. package/dist/chunk-6NRRABPF.cjs.map +1 -0
  98. package/dist/chunk-AAYHG7YK.cjs +30 -0
  99. package/dist/chunk-AAYHG7YK.cjs.map +1 -0
  100. package/dist/chunk-AOSO5QHL.js +19 -0
  101. package/dist/chunk-AOSO5QHL.js.map +1 -0
  102. package/dist/chunk-BFEDLXVW.js +12 -0
  103. package/dist/chunk-BFEDLXVW.js.map +1 -0
  104. package/dist/chunk-DBZQI4HM.cjs +14 -0
  105. package/dist/chunk-DBZQI4HM.cjs.map +1 -0
  106. package/dist/chunk-F2PMFYJ5.cjs +40 -0
  107. package/dist/chunk-F2PMFYJ5.cjs.map +1 -0
  108. package/dist/chunk-FUZW3H5X.js +38 -0
  109. package/dist/chunk-FUZW3H5X.js.map +1 -0
  110. package/dist/chunk-GDZLYYL2.js +27 -0
  111. package/dist/chunk-GDZLYYL2.js.map +1 -0
  112. package/dist/chunk-GVTMZYOM.cjs +30 -0
  113. package/dist/chunk-GVTMZYOM.cjs.map +1 -0
  114. package/dist/chunk-GZRMVE4X.cjs +131 -0
  115. package/dist/chunk-GZRMVE4X.cjs.map +1 -0
  116. package/dist/chunk-HMH6DI7U.js +27 -0
  117. package/dist/chunk-HMH6DI7U.js.map +1 -0
  118. package/dist/chunk-ICL5K2CW.js +280 -0
  119. package/dist/chunk-ICL5K2CW.js.map +1 -0
  120. package/dist/chunk-IW6EWB26.cjs +21 -0
  121. package/dist/chunk-IW6EWB26.cjs.map +1 -0
  122. package/dist/chunk-K3R7JGOW.cjs +18 -0
  123. package/dist/chunk-K3R7JGOW.cjs.map +1 -0
  124. package/dist/chunk-LT3UC65O.cjs +68 -0
  125. package/dist/chunk-LT3UC65O.cjs.map +1 -0
  126. package/dist/chunk-MN4CDVOS.cjs +63 -0
  127. package/dist/chunk-MN4CDVOS.cjs.map +1 -0
  128. package/dist/chunk-OCD6JIIX.js +23 -0
  129. package/dist/chunk-OCD6JIIX.js.map +1 -0
  130. package/dist/chunk-RILUG7JB.js +44 -0
  131. package/dist/chunk-RILUG7JB.js.map +1 -0
  132. package/dist/chunk-RLHGPHC7.cjs +51 -0
  133. package/dist/chunk-RLHGPHC7.cjs.map +1 -0
  134. package/dist/chunk-SGG7XKOY.js +58 -0
  135. package/dist/chunk-SGG7XKOY.js.map +1 -0
  136. package/dist/chunk-T3K6Q34U.cjs +82 -0
  137. package/dist/chunk-T3K6Q34U.cjs.map +1 -0
  138. package/dist/chunk-TPH5T3DA.cjs +282 -0
  139. package/dist/chunk-TPH5T3DA.cjs.map +1 -0
  140. package/dist/chunk-TYQWZR3S.cjs +13 -0
  141. package/dist/chunk-TYQWZR3S.cjs.map +1 -0
  142. package/dist/chunk-UATB2IRY.js +51 -0
  143. package/dist/chunk-UATB2IRY.js.map +1 -0
  144. package/dist/chunk-UJIV5PVI.js +13 -0
  145. package/dist/chunk-UJIV5PVI.js.map +1 -0
  146. package/dist/chunk-URNXLVSK.js +44 -0
  147. package/dist/chunk-URNXLVSK.js.map +1 -0
  148. package/dist/chunk-VIOSQN4Z.js +79 -0
  149. package/dist/chunk-VIOSQN4Z.js.map +1 -0
  150. package/dist/chunk-X3YZP5WF.cjs +46 -0
  151. package/dist/chunk-X3YZP5WF.cjs.map +1 -0
  152. package/dist/chunk-YWYF5CCJ.js +61 -0
  153. package/dist/chunk-YWYF5CCJ.js.map +1 -0
  154. package/dist/chunk-Z4LZFMDH.cjs +60 -0
  155. package/dist/chunk-Z4LZFMDH.cjs.map +1 -0
  156. package/dist/index.cjs +154 -1166
  157. package/dist/index.cjs.map +1 -1
  158. package/dist/index.d.cts +470 -80
  159. package/dist/index.d.ts +470 -80
  160. package/dist/index.js +23 -1144
  161. package/dist/index.js.map +1 -1
  162. package/dist/theme.cjs +88 -0
  163. package/dist/theme.cjs.map +1 -0
  164. package/dist/theme.js +84 -0
  165. package/dist/theme.js.map +1 -0
  166. package/package.json +23 -12
@@ -0,0 +1,134 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var chunkZ4LZFMDH_cjs = require('./chunk-Z4LZFMDH.cjs');
5
+ var chunkGZRMVE4X_cjs = require('./chunk-GZRMVE4X.cjs');
6
+ var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
7
+ var chunkRLHGPHC7_cjs = require('./chunk-RLHGPHC7.cjs');
8
+ var chunkT3K6Q34U_cjs = require('./chunk-T3K6Q34U.cjs');
9
+ var chunkK3R7JGOW_cjs = require('./chunk-K3R7JGOW.cjs');
10
+ var chunk6NRRABPF_cjs = require('./chunk-6NRRABPF.cjs');
11
+ var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
12
+ var recharts = require('recharts');
13
+ var jsxRuntime = require('react/jsx-runtime');
14
+
15
+ var formatNumber = (value) => String(Number(value.toFixed(2)));
16
+ var POINT_AREA = 113;
17
+ var BUBBLE_AREAS = [60, 1100];
18
+ var XYChart = ({
19
+ series,
20
+ bubbles,
21
+ colors,
22
+ formatX = formatNumber,
23
+ formatY = formatNumber,
24
+ xTitle,
25
+ yTitle,
26
+ referenceLines,
27
+ referenceBands,
28
+ showLegend,
29
+ legendPosition = "top",
30
+ emptyMessage = "No data",
31
+ ariaLabel,
32
+ children,
33
+ height = 320,
34
+ width
35
+ }) => {
36
+ const hidden = chunkGZRMVE4X_cjs.useHiddenSeries();
37
+ const axis = chunkRLHGPHC7_cjs.useAxis();
38
+ const name = ariaLabel ?? `${bubbles ? "Bubble" : "Scatter"} chart: ${series.map((s) => s.name).join(", ")}`;
39
+ if (chunkK3R7JGOW_cjs.hasNoData(series)) {
40
+ return /* @__PURE__ */ jsxRuntime.jsx(chunk6NRRABPF_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
41
+ }
42
+ const tooltip = ({ active, payload }) => {
43
+ const point = payload?.[0]?.payload;
44
+ if (!active || !point) return null;
45
+ const color = chunkLT3UC65O_cjs.seriesColor(point.series, colors);
46
+ const none = "transparent";
47
+ return /* @__PURE__ */ jsxRuntime.jsx(
48
+ chunkT3K6Q34U_cjs.TooltipCard,
49
+ {
50
+ title: point.label,
51
+ rows: [
52
+ { name: series[point.series].name, value: "", color },
53
+ { name: xTitle ?? "x", value: formatX(point.x), color: none },
54
+ { name: yTitle ?? "y", value: formatY(point.y), color: none },
55
+ ...bubbles && point.z !== void 0 ? [{ name: bubbles.sizeTitle, value: bubbles.formatSize(point.z), color: none }] : []
56
+ ]
57
+ }
58
+ );
59
+ };
60
+ return /* @__PURE__ */ jsxRuntime.jsxs(
61
+ recharts.ScatterChart,
62
+ {
63
+ ...chunk6NRRABPF_cjs.frameProps({ height, width, ariaLabel: name }),
64
+ margin: { top: 4, right: bubbles ? 24 : 12, bottom: 0, left: 0 },
65
+ children: [
66
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { stroke: chunkLT3UC65O_cjs.GRID, strokeDasharray: "4 4" }),
67
+ /* @__PURE__ */ jsxRuntime.jsx(
68
+ recharts.XAxis,
69
+ {
70
+ type: "number",
71
+ dataKey: "x",
72
+ name: xTitle ?? "x",
73
+ domain: ["auto", "auto"],
74
+ tickFormatter: formatX,
75
+ ...axis,
76
+ ...chunkRLHGPHC7_cjs.xAxisTitle(xTitle)
77
+ }
78
+ ),
79
+ /* @__PURE__ */ jsxRuntime.jsx(
80
+ recharts.YAxis,
81
+ {
82
+ type: "number",
83
+ dataKey: "y",
84
+ name: yTitle ?? "y",
85
+ domain: ["auto", "auto"],
86
+ width: "auto",
87
+ tickFormatter: formatY,
88
+ ...axis,
89
+ ...chunkRLHGPHC7_cjs.yAxisTitle(yTitle)
90
+ }
91
+ ),
92
+ bubbles ? /* @__PURE__ */ jsxRuntime.jsx(recharts.ZAxis, { type: "number", dataKey: "z", name: bubbles.sizeTitle, range: BUBBLE_AREAS }) : /* @__PURE__ */ jsxRuntime.jsx(recharts.ZAxis, { type: "number", range: [POINT_AREA, POINT_AREA] }),
93
+ (showLegend ?? series.length > 1) && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { ...chunkGZRMVE4X_cjs.legendProps(legendPosition, hidden) }),
94
+ /* @__PURE__ */ jsxRuntime.jsx(
95
+ recharts.Tooltip,
96
+ {
97
+ content: tooltip,
98
+ cursor: { stroke: chunkLT3UC65O_cjs.BORDER, strokeDasharray: "4 4" },
99
+ animationDuration: 150
100
+ }
101
+ ),
102
+ series.map((s, index) => {
103
+ const color = chunkLT3UC65O_cjs.seriesColor(index, colors);
104
+ return /* @__PURE__ */ jsxRuntime.jsx(
105
+ recharts.Scatter,
106
+ {
107
+ name: s.name,
108
+ dataKey: chunkK3R7JGOW_cjs.seriesKey(index),
109
+ data: s.data.map((point) => ({ ...point, series: index })),
110
+ fill: color,
111
+ ...bubbles ? { fillOpacity: 0.6, stroke: color, strokeWidth: 1 } : {},
112
+ hide: hidden.hidden.has(chunkK3R7JGOW_cjs.seriesKey(index)),
113
+ ...chunkTYQWZR3S_cjs.ANIMATION
114
+ },
115
+ chunkK3R7JGOW_cjs.seriesKey(index)
116
+ );
117
+ }),
118
+ chunkZ4LZFMDH_cjs.referenceMarks({ referenceLines, referenceBands }),
119
+ children
120
+ ]
121
+ }
122
+ );
123
+ };
124
+ var ScatterChart = (props) => /* @__PURE__ */ jsxRuntime.jsx(XYChart, { ...props });
125
+ var BubbleChart = ({
126
+ sizeTitle = "Size",
127
+ formatSize = formatNumber,
128
+ ...props
129
+ }) => /* @__PURE__ */ jsxRuntime.jsx(XYChart, { ...props, bubbles: { sizeTitle, formatSize } });
130
+
131
+ exports.BubbleChart = BubbleChart;
132
+ exports.ScatterChart = ScatterChart;
133
+ //# sourceMappingURL=ScatterChart.cjs.map
134
+ //# sourceMappingURL=ScatterChart.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ScatterChart.tsx"],"names":["useHiddenSeries","useAxis","hasNoData","ChartEmpty","seriesColor","jsx","TooltipCard","jsxs","RechartsScatterChart","frameProps","CartesianGrid","GRID","XAxis","xAxisTitle","YAxis","yAxisTitle","ZAxis","Legend","legendProps","Tooltip","BORDER","Scatter","seriesKey","ANIMATION","referenceMarks"],"mappings":"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","file":"ScatterChart.cjs","sourcesContent":["import {\n CartesianGrid,\n Legend,\n Scatter,\n ScatterChart as RechartsScatterChart,\n Tooltip,\n XAxis,\n YAxis,\n ZAxis,\n type TooltipContentProps,\n} from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { TooltipCard } from './core/ChartTooltip';\nimport { legendProps, useHiddenSeries } from './core/ChartLegend';\nimport { BORDER, GRID, seriesColor } from './core/colors';\nimport { hasNoData, seriesKey } from './core/data';\nimport { ChartEmpty, frameProps } from './core/frame';\nimport { referenceMarks } from './core/reference';\nimport type { ChartEmptyProps, ChartLegendProps, ChartProps, ChartReferenceProps } from './types';\n\nexport type ScatterPoint = {\n x: number;\n y: number;\n /** Names the point in the tooltip title: a node, a host, a rack. */\n label?: string;\n};\n\nexport type BubblePoint = ScatterPoint & {\n /** Third measure, drawn as the bubble size. */\n z: number;\n};\n\ntype XYChartProps = ChartProps &\n ChartEmptyProps &\n ChartLegendProps &\n ChartReferenceProps & {\n /** Title under the x-axis. Also labels the x value in the tooltip (default `x`). */\n xTitle?: string;\n /** Title beside the y-axis. Also labels the y value in the tooltip (default `y`). */\n yTitle?: string;\n /** Override the default Cosmos palette, one color per series. */\n colors?: string[];\n /** Format the x-axis labels and the tooltip's x value (default: at most two decimals). */\n formatX?: (value: number) => string;\n /** Format the y-axis labels and the tooltip's y value (default: at most two decimals). */\n formatY?: (value: number) => string;\n /** Show the legend (auto-true when 2+ series). */\n showLegend?: boolean;\n };\n\nexport type ScatterChartProps = XYChartProps & {\n series: { name: string; data: ScatterPoint[] }[];\n};\n\nexport type BubbleChartProps = XYChartProps & {\n series: { name: string; data: BubblePoint[] }[];\n /** Labels the size in the tooltip. Default `Size`. */\n sizeTitle?: string;\n /** Format the size in the tooltip (default: at most two decimals). */\n formatSize?: (value: number) => string;\n};\n\n/** Drops the float noise of computed values: 33.333333 reads 33.33. */\nconst formatNumber = (value: number) => String(Number(value.toFixed(2)));\n\n// The area of a point, in px², for the Scatter chart: a 6px radius disc.\nconst POINT_AREA = 113;\n// The areas of the smallest and the largest bubble.\nconst BUBBLE_AREAS: [number, number] = [60, 1100];\n\ntype Bubbles = { sizeTitle: string; formatSize: (value: number) => string };\n\ntype XYProps = XYChartProps & {\n series: { name: string; data: (ScatterPoint & { z?: number })[] }[];\n bubbles?: Bubbles;\n};\n\nconst XYChart = ({\n series,\n bubbles,\n colors,\n formatX = formatNumber,\n formatY = formatNumber,\n xTitle,\n yTitle,\n referenceLines,\n referenceBands,\n showLegend,\n legendPosition = 'top',\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 320,\n width,\n}: XYProps) => {\n const hidden = useHiddenSeries();\n const axis = useAxis();\n const name =\n ariaLabel ?? `${bubbles ? 'Bubble' : 'Scatter'} chart: ${series.map((s) => s.name).join(', ')}`;\n if (hasNoData(series)) {\n return <ChartEmpty message={emptyMessage} ariaLabel={name} height={height} width={width} />;\n }\n\n // The card of the point under the pointer: its label, the series, then one\n // row per measure.\n const tooltip = ({ active, payload }: Partial<TooltipContentProps>) => {\n const point = payload?.[0]?.payload as\n (ScatterPoint & { z?: number; series: number }) | undefined;\n if (!active || !point) return null;\n const color = seriesColor(point.series, colors);\n const none = 'transparent';\n return (\n <TooltipCard\n title={point.label}\n rows={[\n { name: series[point.series].name, value: '', color },\n { name: xTitle ?? 'x', value: formatX(point.x), color: none },\n { name: yTitle ?? 'y', value: formatY(point.y), color: none },\n ...(bubbles && point.z !== undefined\n ? [{ name: bubbles.sizeTitle, value: bubbles.formatSize(point.z), color: none }]\n : []),\n ]}\n />\n );\n };\n\n return (\n <RechartsScatterChart\n {...frameProps({ height, width, ariaLabel: name })}\n margin={{ top: 4, right: bubbles ? 24 : 12, bottom: 0, left: 0 }}\n >\n <CartesianGrid stroke={GRID} strokeDasharray=\"4 4\" />\n <XAxis\n type=\"number\"\n dataKey=\"x\"\n name={xTitle ?? 'x'}\n domain={['auto', 'auto']}\n tickFormatter={formatX}\n {...axis}\n {...xAxisTitle(xTitle)}\n />\n <YAxis\n type=\"number\"\n dataKey=\"y\"\n name={yTitle ?? 'y'}\n domain={['auto', 'auto']}\n width=\"auto\"\n tickFormatter={formatY}\n {...axis}\n {...yAxisTitle(yTitle)}\n />\n {bubbles ? (\n <ZAxis type=\"number\" dataKey=\"z\" name={bubbles.sizeTitle} range={BUBBLE_AREAS} />\n ) : (\n <ZAxis type=\"number\" range={[POINT_AREA, POINT_AREA]} />\n )}\n {(showLegend ?? series.length > 1) && <Legend {...legendProps(legendPosition, hidden)} />}\n <Tooltip\n content={tooltip}\n cursor={{ stroke: BORDER, strokeDasharray: '4 4' }}\n animationDuration={150}\n />\n {series.map((s, index) => {\n const color = seriesColor(index, colors);\n return (\n <Scatter\n key={seriesKey(index)}\n name={s.name}\n dataKey={seriesKey(index)}\n data={s.data.map((point) => ({ ...point, series: index }))}\n fill={color}\n // Translucent bubbles, outlined in their own color, keep the overlapping ones readable.\n {...(bubbles ? { fillOpacity: 0.6, stroke: color, strokeWidth: 1 } : {})}\n hide={hidden.hidden.has(seriesKey(index))}\n {...ANIMATION}\n />\n );\n })}\n {referenceMarks({ referenceLines, referenceBands })}\n {children}\n </RechartsScatterChart>\n );\n};\n\n/** Points on two numeric axes, e.g. latency against load, one point per node. */\nexport const ScatterChart = (props: ScatterChartProps) => <XYChart {...props} />;\n\n/** A scatter chart whose bubble size carries a third measure (`z`), e.g. request volume. */\nexport const BubbleChart = ({\n sizeTitle = 'Size',\n formatSize = formatNumber,\n ...props\n}: BubbleChartProps) => <XYChart {...props} bubbles={{ sizeTitle, formatSize }} />;\n"]}
@@ -0,0 +1,131 @@
1
+ "use client";
2
+ import { referenceMarks } from './chunk-SGG7XKOY.js';
3
+ import { useHiddenSeries, legendProps } from './chunk-6ALKZLN2.js';
4
+ import { ANIMATION } from './chunk-5C2RLJYZ.js';
5
+ import { useAxis, xAxisTitle, yAxisTitle } from './chunk-RILUG7JB.js';
6
+ import { TooltipCard } from './chunk-VIOSQN4Z.js';
7
+ import { hasNoData, seriesKey } from './chunk-UJIV5PVI.js';
8
+ import { ChartEmpty, frameProps } from './chunk-3N43QT36.js';
9
+ import { GRID, BORDER, seriesColor } from './chunk-UATB2IRY.js';
10
+ import { ScatterChart as ScatterChart$1, CartesianGrid, XAxis, YAxis, ZAxis, Legend, Tooltip, Scatter } from 'recharts';
11
+ import { jsx, jsxs } from 'react/jsx-runtime';
12
+
13
+ var formatNumber = (value) => String(Number(value.toFixed(2)));
14
+ var POINT_AREA = 113;
15
+ var BUBBLE_AREAS = [60, 1100];
16
+ var XYChart = ({
17
+ series,
18
+ bubbles,
19
+ colors,
20
+ formatX = formatNumber,
21
+ formatY = formatNumber,
22
+ xTitle,
23
+ yTitle,
24
+ referenceLines,
25
+ referenceBands,
26
+ showLegend,
27
+ legendPosition = "top",
28
+ emptyMessage = "No data",
29
+ ariaLabel,
30
+ children,
31
+ height = 320,
32
+ width
33
+ }) => {
34
+ const hidden = useHiddenSeries();
35
+ const axis = useAxis();
36
+ const name = ariaLabel ?? `${bubbles ? "Bubble" : "Scatter"} chart: ${series.map((s) => s.name).join(", ")}`;
37
+ if (hasNoData(series)) {
38
+ return /* @__PURE__ */ jsx(ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
39
+ }
40
+ const tooltip = ({ active, payload }) => {
41
+ const point = payload?.[0]?.payload;
42
+ if (!active || !point) return null;
43
+ const color = seriesColor(point.series, colors);
44
+ const none = "transparent";
45
+ return /* @__PURE__ */ jsx(
46
+ TooltipCard,
47
+ {
48
+ title: point.label,
49
+ rows: [
50
+ { name: series[point.series].name, value: "", color },
51
+ { name: xTitle ?? "x", value: formatX(point.x), color: none },
52
+ { name: yTitle ?? "y", value: formatY(point.y), color: none },
53
+ ...bubbles && point.z !== void 0 ? [{ name: bubbles.sizeTitle, value: bubbles.formatSize(point.z), color: none }] : []
54
+ ]
55
+ }
56
+ );
57
+ };
58
+ return /* @__PURE__ */ jsxs(
59
+ ScatterChart$1,
60
+ {
61
+ ...frameProps({ height, width, ariaLabel: name }),
62
+ margin: { top: 4, right: bubbles ? 24 : 12, bottom: 0, left: 0 },
63
+ children: [
64
+ /* @__PURE__ */ jsx(CartesianGrid, { stroke: GRID, strokeDasharray: "4 4" }),
65
+ /* @__PURE__ */ jsx(
66
+ XAxis,
67
+ {
68
+ type: "number",
69
+ dataKey: "x",
70
+ name: xTitle ?? "x",
71
+ domain: ["auto", "auto"],
72
+ tickFormatter: formatX,
73
+ ...axis,
74
+ ...xAxisTitle(xTitle)
75
+ }
76
+ ),
77
+ /* @__PURE__ */ jsx(
78
+ YAxis,
79
+ {
80
+ type: "number",
81
+ dataKey: "y",
82
+ name: yTitle ?? "y",
83
+ domain: ["auto", "auto"],
84
+ width: "auto",
85
+ tickFormatter: formatY,
86
+ ...axis,
87
+ ...yAxisTitle(yTitle)
88
+ }
89
+ ),
90
+ bubbles ? /* @__PURE__ */ jsx(ZAxis, { type: "number", dataKey: "z", name: bubbles.sizeTitle, range: BUBBLE_AREAS }) : /* @__PURE__ */ jsx(ZAxis, { type: "number", range: [POINT_AREA, POINT_AREA] }),
91
+ (showLegend ?? series.length > 1) && /* @__PURE__ */ jsx(Legend, { ...legendProps(legendPosition, hidden) }),
92
+ /* @__PURE__ */ jsx(
93
+ Tooltip,
94
+ {
95
+ content: tooltip,
96
+ cursor: { stroke: BORDER, strokeDasharray: "4 4" },
97
+ animationDuration: 150
98
+ }
99
+ ),
100
+ series.map((s, index) => {
101
+ const color = seriesColor(index, colors);
102
+ return /* @__PURE__ */ jsx(
103
+ Scatter,
104
+ {
105
+ name: s.name,
106
+ dataKey: seriesKey(index),
107
+ data: s.data.map((point) => ({ ...point, series: index })),
108
+ fill: color,
109
+ ...bubbles ? { fillOpacity: 0.6, stroke: color, strokeWidth: 1 } : {},
110
+ hide: hidden.hidden.has(seriesKey(index)),
111
+ ...ANIMATION
112
+ },
113
+ seriesKey(index)
114
+ );
115
+ }),
116
+ referenceMarks({ referenceLines, referenceBands }),
117
+ children
118
+ ]
119
+ }
120
+ );
121
+ };
122
+ var ScatterChart = (props) => /* @__PURE__ */ jsx(XYChart, { ...props });
123
+ var BubbleChart = ({
124
+ sizeTitle = "Size",
125
+ formatSize = formatNumber,
126
+ ...props
127
+ }) => /* @__PURE__ */ jsx(XYChart, { ...props, bubbles: { sizeTitle, formatSize } });
128
+
129
+ export { BubbleChart, ScatterChart };
130
+ //# sourceMappingURL=ScatterChart.js.map
131
+ //# sourceMappingURL=ScatterChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ScatterChart.tsx"],"names":["RechartsScatterChart"],"mappings":"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","file":"ScatterChart.js","sourcesContent":["import {\n CartesianGrid,\n Legend,\n Scatter,\n ScatterChart as RechartsScatterChart,\n Tooltip,\n XAxis,\n YAxis,\n ZAxis,\n type TooltipContentProps,\n} from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { TooltipCard } from './core/ChartTooltip';\nimport { legendProps, useHiddenSeries } from './core/ChartLegend';\nimport { BORDER, GRID, seriesColor } from './core/colors';\nimport { hasNoData, seriesKey } from './core/data';\nimport { ChartEmpty, frameProps } from './core/frame';\nimport { referenceMarks } from './core/reference';\nimport type { ChartEmptyProps, ChartLegendProps, ChartProps, ChartReferenceProps } from './types';\n\nexport type ScatterPoint = {\n x: number;\n y: number;\n /** Names the point in the tooltip title: a node, a host, a rack. */\n label?: string;\n};\n\nexport type BubblePoint = ScatterPoint & {\n /** Third measure, drawn as the bubble size. */\n z: number;\n};\n\ntype XYChartProps = ChartProps &\n ChartEmptyProps &\n ChartLegendProps &\n ChartReferenceProps & {\n /** Title under the x-axis. Also labels the x value in the tooltip (default `x`). */\n xTitle?: string;\n /** Title beside the y-axis. Also labels the y value in the tooltip (default `y`). */\n yTitle?: string;\n /** Override the default Cosmos palette, one color per series. */\n colors?: string[];\n /** Format the x-axis labels and the tooltip's x value (default: at most two decimals). */\n formatX?: (value: number) => string;\n /** Format the y-axis labels and the tooltip's y value (default: at most two decimals). */\n formatY?: (value: number) => string;\n /** Show the legend (auto-true when 2+ series). */\n showLegend?: boolean;\n };\n\nexport type ScatterChartProps = XYChartProps & {\n series: { name: string; data: ScatterPoint[] }[];\n};\n\nexport type BubbleChartProps = XYChartProps & {\n series: { name: string; data: BubblePoint[] }[];\n /** Labels the size in the tooltip. Default `Size`. */\n sizeTitle?: string;\n /** Format the size in the tooltip (default: at most two decimals). */\n formatSize?: (value: number) => string;\n};\n\n/** Drops the float noise of computed values: 33.333333 reads 33.33. */\nconst formatNumber = (value: number) => String(Number(value.toFixed(2)));\n\n// The area of a point, in px², for the Scatter chart: a 6px radius disc.\nconst POINT_AREA = 113;\n// The areas of the smallest and the largest bubble.\nconst BUBBLE_AREAS: [number, number] = [60, 1100];\n\ntype Bubbles = { sizeTitle: string; formatSize: (value: number) => string };\n\ntype XYProps = XYChartProps & {\n series: { name: string; data: (ScatterPoint & { z?: number })[] }[];\n bubbles?: Bubbles;\n};\n\nconst XYChart = ({\n series,\n bubbles,\n colors,\n formatX = formatNumber,\n formatY = formatNumber,\n xTitle,\n yTitle,\n referenceLines,\n referenceBands,\n showLegend,\n legendPosition = 'top',\n emptyMessage = 'No data',\n ariaLabel,\n children,\n height = 320,\n width,\n}: XYProps) => {\n const hidden = useHiddenSeries();\n const axis = useAxis();\n const name =\n ariaLabel ?? `${bubbles ? 'Bubble' : 'Scatter'} chart: ${series.map((s) => s.name).join(', ')}`;\n if (hasNoData(series)) {\n return <ChartEmpty message={emptyMessage} ariaLabel={name} height={height} width={width} />;\n }\n\n // The card of the point under the pointer: its label, the series, then one\n // row per measure.\n const tooltip = ({ active, payload }: Partial<TooltipContentProps>) => {\n const point = payload?.[0]?.payload as\n (ScatterPoint & { z?: number; series: number }) | undefined;\n if (!active || !point) return null;\n const color = seriesColor(point.series, colors);\n const none = 'transparent';\n return (\n <TooltipCard\n title={point.label}\n rows={[\n { name: series[point.series].name, value: '', color },\n { name: xTitle ?? 'x', value: formatX(point.x), color: none },\n { name: yTitle ?? 'y', value: formatY(point.y), color: none },\n ...(bubbles && point.z !== undefined\n ? [{ name: bubbles.sizeTitle, value: bubbles.formatSize(point.z), color: none }]\n : []),\n ]}\n />\n );\n };\n\n return (\n <RechartsScatterChart\n {...frameProps({ height, width, ariaLabel: name })}\n margin={{ top: 4, right: bubbles ? 24 : 12, bottom: 0, left: 0 }}\n >\n <CartesianGrid stroke={GRID} strokeDasharray=\"4 4\" />\n <XAxis\n type=\"number\"\n dataKey=\"x\"\n name={xTitle ?? 'x'}\n domain={['auto', 'auto']}\n tickFormatter={formatX}\n {...axis}\n {...xAxisTitle(xTitle)}\n />\n <YAxis\n type=\"number\"\n dataKey=\"y\"\n name={yTitle ?? 'y'}\n domain={['auto', 'auto']}\n width=\"auto\"\n tickFormatter={formatY}\n {...axis}\n {...yAxisTitle(yTitle)}\n />\n {bubbles ? (\n <ZAxis type=\"number\" dataKey=\"z\" name={bubbles.sizeTitle} range={BUBBLE_AREAS} />\n ) : (\n <ZAxis type=\"number\" range={[POINT_AREA, POINT_AREA]} />\n )}\n {(showLegend ?? series.length > 1) && <Legend {...legendProps(legendPosition, hidden)} />}\n <Tooltip\n content={tooltip}\n cursor={{ stroke: BORDER, strokeDasharray: '4 4' }}\n animationDuration={150}\n />\n {series.map((s, index) => {\n const color = seriesColor(index, colors);\n return (\n <Scatter\n key={seriesKey(index)}\n name={s.name}\n dataKey={seriesKey(index)}\n data={s.data.map((point) => ({ ...point, series: index }))}\n fill={color}\n // Translucent bubbles, outlined in their own color, keep the overlapping ones readable.\n {...(bubbles ? { fillOpacity: 0.6, stroke: color, strokeWidth: 1 } : {})}\n hide={hidden.hidden.has(seriesKey(index))}\n {...ANIMATION}\n />\n );\n })}\n {referenceMarks({ referenceLines, referenceBands })}\n {children}\n </RechartsScatterChart>\n );\n};\n\n/** Points on two numeric axes, e.g. latency against load, one point per node. */\nexport const ScatterChart = (props: ScatterChartProps) => <XYChart {...props} />;\n\n/** A scatter chart whose bubble size carries a third measure (`z`), e.g. request volume. */\nexport const BubbleChart = ({\n sizeTitle = 'Size',\n formatSize = formatNumber,\n ...props\n}: BubbleChartProps) => <XYChart {...props} bubbles={{ sizeTitle, formatSize }} />;\n"]}
@@ -0,0 +1,142 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var chunkIW6EWB26_cjs = require('./chunk-IW6EWB26.cjs');
5
+ var chunkAAYHG7YK_cjs = require('./chunk-AAYHG7YK.cjs');
6
+ var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
7
+ var chunk6NRRABPF_cjs = require('./chunk-6NRRABPF.cjs');
8
+ var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
9
+ var recharts = require('recharts');
10
+ var jsxRuntime = require('react/jsx-runtime');
11
+
12
+ var RANGE_ROW = 20;
13
+ var EDGE_ROW = 4;
14
+ var valueSize = (radius) => radius >= 110 ? "var(--text-3xl, 1.875rem)" : radius >= 80 ? "var(--text-2xl, 1.5rem)" : "var(--text-xl, 1.25rem)";
15
+ var Face = ({ radius, value, label, showRange, range }) => {
16
+ const area = recharts.usePlotArea();
17
+ if (!area) return null;
18
+ const cx = area.x + area.width / 2;
19
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
20
+ /* @__PURE__ */ jsxRuntime.jsxs("text", { "data-chart-center": "", textAnchor: "middle", pointerEvents: "none", children: [
21
+ /* @__PURE__ */ jsxRuntime.jsx(
22
+ "tspan",
23
+ {
24
+ x: cx,
25
+ y: radius - (label ? 24 : 8),
26
+ fill: chunkLT3UC65O_cjs.TEXT,
27
+ fontWeight: 700,
28
+ style: { fontSize: valueSize(radius) },
29
+ children: value
30
+ }
31
+ ),
32
+ label && /* @__PURE__ */ jsxRuntime.jsx("tspan", { x: cx, y: radius - 6, fill: chunkLT3UC65O_cjs.MUTED, style: { fontSize: "var(--text-xs, 0.75rem)" }, children: label })
33
+ ] }),
34
+ showRange && [-1, 1].map((side, i) => /* @__PURE__ */ jsxRuntime.jsx(
35
+ "text",
36
+ {
37
+ "data-chart-range": "",
38
+ x: cx + side * radius,
39
+ y: radius + 14,
40
+ textAnchor: side < 0 ? "start" : "end",
41
+ fill: chunkLT3UC65O_cjs.MUTED,
42
+ pointerEvents: "none",
43
+ style: { fontSize: "var(--text-2xs, 0.6875rem)" },
44
+ children: range[i]
45
+ },
46
+ side
47
+ ))
48
+ ] });
49
+ };
50
+ var Target = ({ radius, thickness, share }) => {
51
+ const area = recharts.usePlotArea();
52
+ if (!area) return null;
53
+ const mark = chunkAAYHG7YK_cjs.arcMark(
54
+ { cx: area.x + area.width / 2, cy: radius },
55
+ { inner: radius - thickness - 4, outer: radius + 4 },
56
+ share
57
+ );
58
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-chart-target": "", pointerEvents: "none", strokeLinecap: "round", children: [
59
+ /* @__PURE__ */ jsxRuntime.jsx("line", { ...mark, stroke: chunkLT3UC65O_cjs.PANEL, strokeWidth: 6 }),
60
+ /* @__PURE__ */ jsxRuntime.jsx("line", { ...mark, stroke: chunkLT3UC65O_cjs.TEXT, strokeWidth: 3 })
61
+ ] });
62
+ };
63
+ var SemiCircleGauge = ({
64
+ value,
65
+ label = "",
66
+ color,
67
+ min = 0,
68
+ max = 100,
69
+ warnAt,
70
+ critAt,
71
+ formatValue = chunkAAYHG7YK_cjs.percent,
72
+ showRange = false,
73
+ target,
74
+ ariaLabel,
75
+ children,
76
+ height = 120,
77
+ width
78
+ }) => {
79
+ const { ref: box, width: boxWidth } = chunkIW6EWB26_cjs.useElementWidth();
80
+ const text = formatValue(value);
81
+ const row = showRange ? RANGE_ROW : EDGE_ROW;
82
+ const radius = boxWidth === void 0 ? 0 : Math.floor(Math.min(boxWidth / 2, height - row));
83
+ const thickness = Math.min(24, Math.max(8, Math.round(radius * 0.2)));
84
+ const byStatus = warnAt !== void 0 || critAt !== void 0;
85
+ const arc = color ?? (byStatus ? chunkAAYHG7YK_cjs.statusColor(value, warnAt, critAt) : chunkLT3UC65O_cjs.SERIES[0]);
86
+ return /* @__PURE__ */ jsxRuntime.jsx(
87
+ "div",
88
+ {
89
+ ref: box,
90
+ style: { width: width ?? "100%", maxWidth: "100%", height: radius + row, minHeight: row },
91
+ children: radius > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
92
+ recharts.RadialBarChart,
93
+ {
94
+ ...chunk6NRRABPF_cjs.frameProps({
95
+ height: radius + row,
96
+ width: "100%",
97
+ ariaLabel: chunkAAYHG7YK_cjs.gaugeName(ariaLabel ?? (label || "Gauge"), text) + (target === void 0 ? "" : `, target ${formatValue(target)}`),
98
+ keyboard: false
99
+ }),
100
+ data: [{ name: label || "value", value: chunkAAYHG7YK_cjs.clampTo(value, min, max) }],
101
+ cx: "50%",
102
+ cy: radius,
103
+ startAngle: 180,
104
+ endAngle: 0,
105
+ innerRadius: radius - thickness,
106
+ outerRadius: radius,
107
+ barSize: thickness,
108
+ margin: { top: 0, right: 0, bottom: 0, left: 0 },
109
+ children: [
110
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.PolarAngleAxis, { type: "number", domain: [min, max], tick: false, axisLine: false }),
111
+ /* @__PURE__ */ jsxRuntime.jsx(
112
+ recharts.RadialBar,
113
+ {
114
+ dataKey: "value",
115
+ fill: arc,
116
+ cornerRadius: thickness / 2,
117
+ background: { fill: chunkLT3UC65O_cjs.TRACK, cornerRadius: thickness / 2 },
118
+ ...chunkTYQWZR3S_cjs.ANIMATION
119
+ }
120
+ ),
121
+ /* @__PURE__ */ jsxRuntime.jsx(
122
+ Face,
123
+ {
124
+ radius,
125
+ value: text,
126
+ label,
127
+ showRange,
128
+ range: [formatValue(min), formatValue(max)]
129
+ }
130
+ ),
131
+ target !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(Target, { radius, thickness, share: chunkAAYHG7YK_cjs.rangeShare(target, min, max) }),
132
+ children
133
+ ]
134
+ }
135
+ )
136
+ }
137
+ );
138
+ };
139
+
140
+ exports.SemiCircleGauge = SemiCircleGauge;
141
+ //# sourceMappingURL=SemiCircleGauge.cjs.map
142
+ //# sourceMappingURL=SemiCircleGauge.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/SemiCircleGauge.tsx"],"names":["usePlotArea","jsxs","Fragment","jsx","TEXT","MUTED","arcMark","PANEL","percent","useElementWidth","statusColor","SERIES","RadialBarChart","frameProps","gaugeName","clampTo","PolarAngleAxis","RadialBar","TRACK","ANIMATION","rangeShare"],"mappings":"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","file":"SemiCircleGauge.cjs","sourcesContent":["import { PolarAngleAxis, RadialBar, RadialBarChart, usePlotArea } from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { MUTED, PANEL, SERIES, TEXT, TRACK } from './core/colors';\nimport { frameProps } from './core/frame';\nimport { arcMark, clampTo, gaugeName, percent, rangeShare, statusColor } from './core/gauge';\nimport { useElementWidth } from './core/useElementWidth';\nimport type { ChartProps } from './types';\n\nexport type SemiCircleGaugeProps = Omit<ChartProps, 'height'> & {\n value: number;\n label?: string;\n /**\n * Color of the arc. Default: the accent, or the theme's status colors when\n * `warnAt` or `critAt` is set.\n */\n color?: string;\n /** Value at the start of the arc. Default 0. */\n min?: number;\n /** Value at the end of the arc, above `min`. Default 100. Out of range, the arc stops at an end. */\n max?: number;\n /**\n * Value from which the arc turns to the theme's warning color. Setting it (or\n * `critAt`) colors the arc by status: the theme's success color below, the\n * warning color from `warnAt`, the critical color from `critAt`. Without\n * either, the arc keeps one color, so a gauge where higher is better (an\n * uptime, a score) does not turn red.\n */\n warnAt?: number;\n /** Value from which the arc turns to the theme's critical color. See `warnAt`. */\n critAt?: number;\n /**\n * Format the center value, from `value` itself (not its share of the range), and the\n * `showRange` labels. Default: `67%`.\n */\n formatValue?: (value: number) => string;\n /** Write `min` and `max`, formatted, under the two ends of the arc. Default off. */\n showRange?: boolean;\n /**\n * A goal on the scale of `min`–`max`, drawn as a mark across the arc. Out of range, the mark\n * stops at an end of the arc, as the arc does. The target, formatted by `formatValue`, is read\n * after the value in the name of the gauge.\n */\n target?: number;\n /**\n * The most the gauge takes, in pixels (default 120). The arc is as wide as the box allows, up\n * to this height: in a narrower box the gauge is shorter, never taller.\n */\n height?: number;\n};\n\n// Room under the arc: the `showRange` labels, and a margin without them.\nconst RANGE_ROW = 20;\nconst EDGE_ROW = 4;\n// The value, from the text tokens, large enough for the arc it sits in.\nconst valueSize = (radius: number) =>\n radius >= 110\n ? 'var(--text-3xl, 1.875rem)'\n : radius >= 80\n ? 'var(--text-2xl, 1.5rem)'\n : 'var(--text-xl, 1.25rem)';\n\ntype FaceProps = {\n radius: number;\n value: string;\n label: string;\n showRange: boolean;\n range: [string, string];\n};\n\n// The value over its label on the base of the arc, inside its hollow, and the\n// ends of the range under the two ends of the arc, starting at its outer edge\n// so a long one is not cut by the box. Plain SVG text.\nconst Face = ({ radius, value, label, showRange, range }: FaceProps) => {\n const area = usePlotArea();\n if (!area) return null;\n const cx = area.x + area.width / 2;\n return (\n <>\n <text data-chart-center=\"\" textAnchor=\"middle\" pointerEvents=\"none\">\n <tspan\n x={cx}\n y={radius - (label ? 24 : 8)}\n fill={TEXT}\n fontWeight={700}\n style={{ fontSize: valueSize(radius) }}\n >\n {value}\n </tspan>\n {label && (\n <tspan x={cx} y={radius - 6} fill={MUTED} style={{ fontSize: 'var(--text-xs, 0.75rem)' }}>\n {label}\n </tspan>\n )}\n </text>\n {showRange &&\n ([-1, 1] as const).map((side, i) => (\n <text\n key={side}\n data-chart-range=\"\"\n x={cx + side * radius}\n y={radius + 14}\n textAnchor={side < 0 ? 'start' : 'end'}\n fill={MUTED}\n pointerEvents=\"none\"\n style={{ fontSize: 'var(--text-2xs, 0.6875rem)' }}\n >\n {range[i]}\n </text>\n ))}\n </>\n );\n};\n\ntype TargetProps = { radius: number; thickness: number; share: number };\n\n// A radial mark across the arc, a little longer than it is thick: a dark line over a\n// halo in the card's color, so it reads on the arc, on the track and on the card.\nconst Target = ({ radius, thickness, share }: TargetProps) => {\n const area = usePlotArea();\n if (!area) return null;\n const mark = arcMark(\n { cx: area.x + area.width / 2, cy: radius },\n { inner: radius - thickness - 4, outer: radius + 4 },\n share\n );\n return (\n <g data-chart-target=\"\" pointerEvents=\"none\" strokeLinecap=\"round\">\n <line {...mark} stroke={PANEL} strokeWidth={6} />\n <line {...mark} stroke={TEXT} strokeWidth={3} />\n </g>\n );\n};\n\nexport const SemiCircleGauge = ({\n value,\n label = '',\n color,\n min = 0,\n max = 100,\n warnAt,\n critAt,\n formatValue = percent,\n showRange = false,\n target,\n ariaLabel,\n children,\n height = 120,\n width,\n}: SemiCircleGaugeProps) => {\n const { ref: box, width: boxWidth } = useElementWidth();\n const text = formatValue(value);\n const row = showRange ? RANGE_ROW : EDGE_ROW;\n // The arc fills the width, up to the height it is allowed.\n const radius = boxWidth === undefined ? 0 : Math.floor(Math.min(boxWidth / 2, height - row));\n const thickness = Math.min(24, Math.max(8, Math.round(radius * 0.2)));\n const byStatus = warnAt !== undefined || critAt !== undefined;\n const arc = color ?? (byStatus ? statusColor(value, warnAt, critAt) : SERIES[0]);\n return (\n <div\n ref={box}\n style={{ width: width ?? '100%', maxWidth: '100%', height: radius + row, minHeight: row }}\n >\n {radius > 0 && (\n <RadialBarChart\n {...frameProps({\n height: radius + row,\n width: '100%',\n ariaLabel:\n gaugeName(ariaLabel ?? (label || 'Gauge'), text) +\n (target === undefined ? '' : `, target ${formatValue(target)}`),\n keyboard: false,\n })}\n data={[{ name: label || 'value', value: clampTo(value, min, max) }]}\n cx=\"50%\"\n cy={radius}\n startAngle={180}\n endAngle={0}\n innerRadius={radius - thickness}\n outerRadius={radius}\n barSize={thickness}\n margin={{ top: 0, right: 0, bottom: 0, left: 0 }}\n >\n <PolarAngleAxis type=\"number\" domain={[min, max]} tick={false} axisLine={false} />\n <RadialBar\n dataKey=\"value\"\n fill={arc}\n cornerRadius={thickness / 2}\n background={{ fill: TRACK, cornerRadius: thickness / 2 }}\n {...ANIMATION}\n />\n <Face\n radius={radius}\n value={text}\n label={label}\n showRange={showRange}\n range={[formatValue(min), formatValue(max)]}\n />\n {target !== undefined && (\n <Target radius={radius} thickness={thickness} share={rangeShare(target, min, max)} />\n )}\n {children}\n </RadialBarChart>\n )}\n </div>\n );\n};\n"]}
@@ -0,0 +1,140 @@
1
+ "use client";
2
+ import { useElementWidth } from './chunk-AOSO5QHL.js';
3
+ import { percent, statusColor, rangeShare, clampTo, gaugeName, arcMark } from './chunk-OCD6JIIX.js';
4
+ import { ANIMATION } from './chunk-5C2RLJYZ.js';
5
+ import { frameProps } from './chunk-3N43QT36.js';
6
+ import { SERIES, TRACK, TEXT, MUTED, PANEL } from './chunk-UATB2IRY.js';
7
+ import { RadialBarChart, PolarAngleAxis, RadialBar, usePlotArea } from 'recharts';
8
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
+
10
+ var RANGE_ROW = 20;
11
+ var EDGE_ROW = 4;
12
+ var valueSize = (radius) => radius >= 110 ? "var(--text-3xl, 1.875rem)" : radius >= 80 ? "var(--text-2xl, 1.5rem)" : "var(--text-xl, 1.25rem)";
13
+ var Face = ({ radius, value, label, showRange, range }) => {
14
+ const area = usePlotArea();
15
+ if (!area) return null;
16
+ const cx = area.x + area.width / 2;
17
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
18
+ /* @__PURE__ */ jsxs("text", { "data-chart-center": "", textAnchor: "middle", pointerEvents: "none", children: [
19
+ /* @__PURE__ */ jsx(
20
+ "tspan",
21
+ {
22
+ x: cx,
23
+ y: radius - (label ? 24 : 8),
24
+ fill: TEXT,
25
+ fontWeight: 700,
26
+ style: { fontSize: valueSize(radius) },
27
+ children: value
28
+ }
29
+ ),
30
+ label && /* @__PURE__ */ jsx("tspan", { x: cx, y: radius - 6, fill: MUTED, style: { fontSize: "var(--text-xs, 0.75rem)" }, children: label })
31
+ ] }),
32
+ showRange && [-1, 1].map((side, i) => /* @__PURE__ */ jsx(
33
+ "text",
34
+ {
35
+ "data-chart-range": "",
36
+ x: cx + side * radius,
37
+ y: radius + 14,
38
+ textAnchor: side < 0 ? "start" : "end",
39
+ fill: MUTED,
40
+ pointerEvents: "none",
41
+ style: { fontSize: "var(--text-2xs, 0.6875rem)" },
42
+ children: range[i]
43
+ },
44
+ side
45
+ ))
46
+ ] });
47
+ };
48
+ var Target = ({ radius, thickness, share }) => {
49
+ const area = usePlotArea();
50
+ if (!area) return null;
51
+ const mark = arcMark(
52
+ { cx: area.x + area.width / 2, cy: radius },
53
+ { inner: radius - thickness - 4, outer: radius + 4 },
54
+ share
55
+ );
56
+ return /* @__PURE__ */ jsxs("g", { "data-chart-target": "", pointerEvents: "none", strokeLinecap: "round", children: [
57
+ /* @__PURE__ */ jsx("line", { ...mark, stroke: PANEL, strokeWidth: 6 }),
58
+ /* @__PURE__ */ jsx("line", { ...mark, stroke: TEXT, strokeWidth: 3 })
59
+ ] });
60
+ };
61
+ var SemiCircleGauge = ({
62
+ value,
63
+ label = "",
64
+ color,
65
+ min = 0,
66
+ max = 100,
67
+ warnAt,
68
+ critAt,
69
+ formatValue = percent,
70
+ showRange = false,
71
+ target,
72
+ ariaLabel,
73
+ children,
74
+ height = 120,
75
+ width
76
+ }) => {
77
+ const { ref: box, width: boxWidth } = useElementWidth();
78
+ const text = formatValue(value);
79
+ const row = showRange ? RANGE_ROW : EDGE_ROW;
80
+ const radius = boxWidth === void 0 ? 0 : Math.floor(Math.min(boxWidth / 2, height - row));
81
+ const thickness = Math.min(24, Math.max(8, Math.round(radius * 0.2)));
82
+ const byStatus = warnAt !== void 0 || critAt !== void 0;
83
+ const arc = color ?? (byStatus ? statusColor(value, warnAt, critAt) : SERIES[0]);
84
+ return /* @__PURE__ */ jsx(
85
+ "div",
86
+ {
87
+ ref: box,
88
+ style: { width: width ?? "100%", maxWidth: "100%", height: radius + row, minHeight: row },
89
+ children: radius > 0 && /* @__PURE__ */ jsxs(
90
+ RadialBarChart,
91
+ {
92
+ ...frameProps({
93
+ height: radius + row,
94
+ width: "100%",
95
+ ariaLabel: gaugeName(ariaLabel ?? (label || "Gauge"), text) + (target === void 0 ? "" : `, target ${formatValue(target)}`),
96
+ keyboard: false
97
+ }),
98
+ data: [{ name: label || "value", value: clampTo(value, min, max) }],
99
+ cx: "50%",
100
+ cy: radius,
101
+ startAngle: 180,
102
+ endAngle: 0,
103
+ innerRadius: radius - thickness,
104
+ outerRadius: radius,
105
+ barSize: thickness,
106
+ margin: { top: 0, right: 0, bottom: 0, left: 0 },
107
+ children: [
108
+ /* @__PURE__ */ jsx(PolarAngleAxis, { type: "number", domain: [min, max], tick: false, axisLine: false }),
109
+ /* @__PURE__ */ jsx(
110
+ RadialBar,
111
+ {
112
+ dataKey: "value",
113
+ fill: arc,
114
+ cornerRadius: thickness / 2,
115
+ background: { fill: TRACK, cornerRadius: thickness / 2 },
116
+ ...ANIMATION
117
+ }
118
+ ),
119
+ /* @__PURE__ */ jsx(
120
+ Face,
121
+ {
122
+ radius,
123
+ value: text,
124
+ label,
125
+ showRange,
126
+ range: [formatValue(min), formatValue(max)]
127
+ }
128
+ ),
129
+ target !== void 0 && /* @__PURE__ */ jsx(Target, { radius, thickness, share: rangeShare(target, min, max) }),
130
+ children
131
+ ]
132
+ }
133
+ )
134
+ }
135
+ );
136
+ };
137
+
138
+ export { SemiCircleGauge };
139
+ //# sourceMappingURL=SemiCircleGauge.js.map
140
+ //# sourceMappingURL=SemiCircleGauge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/SemiCircleGauge.tsx"],"names":[],"mappings":";;;;;;;;;AAmDA,IAAM,SAAA,GAAY,EAAA;AAClB,IAAM,QAAA,GAAW,CAAA;AAEjB,IAAM,SAAA,GAAY,CAAC,MAAA,KACjB,MAAA,IAAU,MACN,2BAAA,GACA,MAAA,IAAU,KACR,yBAAA,GACA,yBAAA;AAaR,IAAM,IAAA,GAAO,CAAC,EAAE,MAAA,EAAQ,OAAO,KAAA,EAAO,SAAA,EAAW,OAAM,KAAiB;AACtE,EAAA,MAAM,OAAO,WAAA,EAAY;AACzB,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,KAAA,GAAQ,CAAA;AACjC,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,UAAK,mBAAA,EAAkB,EAAA,EAAG,UAAA,EAAW,QAAA,EAAS,eAAc,MAAA,EAC3D,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,CAAA,EAAG,EAAA;AAAA,UACH,CAAA,EAAG,MAAA,IAAU,KAAA,GAAQ,EAAA,GAAK,CAAA,CAAA;AAAA,UAC1B,IAAA,EAAM,IAAA;AAAA,UACN,UAAA,EAAY,GAAA;AAAA,UACZ,KAAA,EAAO,EAAE,QAAA,EAAU,SAAA,CAAU,MAAM,CAAA,EAAE;AAAA,UAEpC,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,MACC,KAAA,oBACC,GAAA,CAAC,OAAA,EAAA,EAAM,CAAA,EAAG,IAAI,CAAA,EAAG,MAAA,GAAS,CAAA,EAAG,IAAA,EAAM,OAAO,KAAA,EAAO,EAAE,QAAA,EAAU,yBAAA,IAC1D,QAAA,EAAA,KAAA,EACH;AAAA,KAAA,EAEJ,CAAA;AAAA,IACC,SAAA,IACE,CAAC,EAAA,EAAI,CAAC,EAAY,GAAA,CAAI,CAAC,MAAM,CAAA,qBAC5B,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QAEC,kBAAA,EAAiB,EAAA;AAAA,QACjB,CAAA,EAAG,KAAK,IAAA,GAAO,MAAA;AAAA,QACf,GAAG,MAAA,GAAS,EAAA;AAAA,QACZ,UAAA,EAAY,IAAA,GAAO,CAAA,GAAI,OAAA,GAAU,KAAA;AAAA,QACjC,IAAA,EAAM,KAAA;AAAA,QACN,aAAA,EAAc,MAAA;AAAA,QACd,KAAA,EAAO,EAAE,QAAA,EAAU,4BAAA,EAA6B;AAAA,QAE/C,gBAAM,CAAC;AAAA,OAAA;AAAA,MATH;AAAA,KAWR;AAAA,GAAA,EACL,CAAA;AAEJ,CAAA;AAMA,IAAM,SAAS,CAAC,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAM,KAAmB;AAC5D,EAAA,MAAM,OAAO,WAAA,EAAY;AACzB,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,MAAM,IAAA,GAAO,OAAA;AAAA,IACX,EAAE,IAAI,IAAA,CAAK,CAAA,GAAI,KAAK,KAAA,GAAQ,CAAA,EAAG,IAAI,MAAA,EAAO;AAAA,IAC1C,EAAE,KAAA,EAAO,MAAA,GAAS,YAAY,CAAA,EAAG,KAAA,EAAO,SAAS,CAAA,EAAE;AAAA,IACnD;AAAA,GACF;AACA,EAAA,4BACG,GAAA,EAAA,EAAE,mBAAA,EAAkB,IAAG,aAAA,EAAc,MAAA,EAAO,eAAc,OAAA,EACzD,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAM,GAAG,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,aAAa,CAAA,EAAG,CAAA;AAAA,wBAC9C,MAAA,EAAA,EAAM,GAAG,MAAM,MAAA,EAAQ,IAAA,EAAM,aAAa,CAAA,EAAG;AAAA,GAAA,EAChD,CAAA;AAEJ,CAAA;AAEO,IAAM,kBAAkB,CAAC;AAAA,EAC9B,KAAA;AAAA,EACA,KAAA,GAAQ,EAAA;AAAA,EACR,KAAA;AAAA,EACA,GAAA,GAAM,CAAA;AAAA,EACN,GAAA,GAAM,GAAA;AAAA,EACN,MAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA,GAAc,OAAA;AAAA,EACd,SAAA,GAAY,KAAA;AAAA,EACZ,MAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA,GAAS,GAAA;AAAA,EACT;AACF,CAAA,KAA4B;AAC1B,EAAA,MAAM,EAAE,GAAA,EAAK,GAAA,EAAK,KAAA,EAAO,QAAA,KAAa,eAAA,EAAgB;AACtD,EAAA,MAAM,IAAA,GAAO,YAAY,KAAK,CAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,YAAY,SAAA,GAAY,QAAA;AAEpC,EAAA,MAAM,MAAA,GAAS,QAAA,KAAa,MAAA,GAAY,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,QAAA,GAAW,CAAA,EAAG,MAAA,GAAS,GAAG,CAAC,CAAA;AAC3F,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,GAAG,CAAC,CAAC,CAAA;AACpE,EAAA,MAAM,QAAA,GAAW,MAAA,KAAW,MAAA,IAAa,MAAA,KAAW,MAAA;AACpD,EAAA,MAAM,GAAA,GAAM,UAAU,QAAA,GAAW,WAAA,CAAY,OAAO,MAAA,EAAQ,MAAM,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA,CAAA;AAC9E,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,GAAA;AAAA,MACL,KAAA,EAAO,EAAE,KAAA,EAAO,KAAA,IAAS,MAAA,EAAQ,QAAA,EAAU,MAAA,EAAQ,MAAA,EAAQ,MAAA,GAAS,GAAA,EAAK,SAAA,EAAW,GAAA,EAAI;AAAA,MAEvF,mBAAS,CAAA,oBACR,IAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACE,GAAG,UAAA,CAAW;AAAA,YACb,QAAQ,MAAA,GAAS,GAAA;AAAA,YACjB,KAAA,EAAO,MAAA;AAAA,YACP,SAAA,EACE,SAAA,CAAU,SAAA,KAAc,KAAA,IAAS,OAAA,CAAA,EAAU,IAAI,CAAA,IAC9C,MAAA,KAAW,MAAA,GAAY,EAAA,GAAK,CAAA,SAAA,EAAY,WAAA,CAAY,MAAM,CAAC,CAAA,CAAA,CAAA;AAAA,YAC9D,QAAA,EAAU;AAAA,WACX,CAAA;AAAA,UACD,IAAA,EAAM,CAAC,EAAE,IAAA,EAAM,KAAA,IAAS,OAAA,EAAS,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,GAAA,EAAK,GAAG,CAAA,EAAG,CAAA;AAAA,UAClE,EAAA,EAAG,KAAA;AAAA,UACH,EAAA,EAAI,MAAA;AAAA,UACJ,UAAA,EAAY,GAAA;AAAA,UACZ,QAAA,EAAU,CAAA;AAAA,UACV,aAAa,MAAA,GAAS,SAAA;AAAA,UACtB,WAAA,EAAa,MAAA;AAAA,UACb,OAAA,EAAS,SAAA;AAAA,UACT,MAAA,EAAQ,EAAE,GAAA,EAAK,CAAA,EAAG,OAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAG,IAAA,EAAM,CAAA,EAAE;AAAA,UAE/C,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,cAAA,EAAA,EAAe,IAAA,EAAK,QAAA,EAAS,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAG,CAAA,EAAG,IAAA,EAAM,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,CAAA;AAAA,4BAChF,GAAA;AAAA,cAAC,SAAA;AAAA,cAAA;AAAA,gBACC,OAAA,EAAQ,OAAA;AAAA,gBACR,IAAA,EAAM,GAAA;AAAA,gBACN,cAAc,SAAA,GAAY,CAAA;AAAA,gBAC1B,YAAY,EAAE,IAAA,EAAM,KAAA,EAAO,YAAA,EAAc,YAAY,CAAA,EAAE;AAAA,gBACtD,GAAG;AAAA;AAAA,aACN;AAAA,4BACA,GAAA;AAAA,cAAC,IAAA;AAAA,cAAA;AAAA,gBACC,MAAA;AAAA,gBACA,KAAA,EAAO,IAAA;AAAA,gBACP,KAAA;AAAA,gBACA,SAAA;AAAA,gBACA,OAAO,CAAC,WAAA,CAAY,GAAG,CAAA,EAAG,WAAA,CAAY,GAAG,CAAC;AAAA;AAAA,aAC5C;AAAA,YACC,MAAA,KAAW,MAAA,oBACV,GAAA,CAAC,MAAA,EAAA,EAAO,MAAA,EAAgB,SAAA,EAAsB,KAAA,EAAO,UAAA,CAAW,MAAA,EAAQ,GAAA,EAAK,GAAG,CAAA,EAAG,CAAA;AAAA,YAEpF;AAAA;AAAA;AAAA;AACH;AAAA,GAEJ;AAEJ","file":"SemiCircleGauge.js","sourcesContent":["import { PolarAngleAxis, RadialBar, RadialBarChart, usePlotArea } from 'recharts';\nimport { ANIMATION } from './core/animation';\nimport { MUTED, PANEL, SERIES, TEXT, TRACK } from './core/colors';\nimport { frameProps } from './core/frame';\nimport { arcMark, clampTo, gaugeName, percent, rangeShare, statusColor } from './core/gauge';\nimport { useElementWidth } from './core/useElementWidth';\nimport type { ChartProps } from './types';\n\nexport type SemiCircleGaugeProps = Omit<ChartProps, 'height'> & {\n value: number;\n label?: string;\n /**\n * Color of the arc. Default: the accent, or the theme's status colors when\n * `warnAt` or `critAt` is set.\n */\n color?: string;\n /** Value at the start of the arc. Default 0. */\n min?: number;\n /** Value at the end of the arc, above `min`. Default 100. Out of range, the arc stops at an end. */\n max?: number;\n /**\n * Value from which the arc turns to the theme's warning color. Setting it (or\n * `critAt`) colors the arc by status: the theme's success color below, the\n * warning color from `warnAt`, the critical color from `critAt`. Without\n * either, the arc keeps one color, so a gauge where higher is better (an\n * uptime, a score) does not turn red.\n */\n warnAt?: number;\n /** Value from which the arc turns to the theme's critical color. See `warnAt`. */\n critAt?: number;\n /**\n * Format the center value, from `value` itself (not its share of the range), and the\n * `showRange` labels. Default: `67%`.\n */\n formatValue?: (value: number) => string;\n /** Write `min` and `max`, formatted, under the two ends of the arc. Default off. */\n showRange?: boolean;\n /**\n * A goal on the scale of `min`–`max`, drawn as a mark across the arc. Out of range, the mark\n * stops at an end of the arc, as the arc does. The target, formatted by `formatValue`, is read\n * after the value in the name of the gauge.\n */\n target?: number;\n /**\n * The most the gauge takes, in pixels (default 120). The arc is as wide as the box allows, up\n * to this height: in a narrower box the gauge is shorter, never taller.\n */\n height?: number;\n};\n\n// Room under the arc: the `showRange` labels, and a margin without them.\nconst RANGE_ROW = 20;\nconst EDGE_ROW = 4;\n// The value, from the text tokens, large enough for the arc it sits in.\nconst valueSize = (radius: number) =>\n radius >= 110\n ? 'var(--text-3xl, 1.875rem)'\n : radius >= 80\n ? 'var(--text-2xl, 1.5rem)'\n : 'var(--text-xl, 1.25rem)';\n\ntype FaceProps = {\n radius: number;\n value: string;\n label: string;\n showRange: boolean;\n range: [string, string];\n};\n\n// The value over its label on the base of the arc, inside its hollow, and the\n// ends of the range under the two ends of the arc, starting at its outer edge\n// so a long one is not cut by the box. Plain SVG text.\nconst Face = ({ radius, value, label, showRange, range }: FaceProps) => {\n const area = usePlotArea();\n if (!area) return null;\n const cx = area.x + area.width / 2;\n return (\n <>\n <text data-chart-center=\"\" textAnchor=\"middle\" pointerEvents=\"none\">\n <tspan\n x={cx}\n y={radius - (label ? 24 : 8)}\n fill={TEXT}\n fontWeight={700}\n style={{ fontSize: valueSize(radius) }}\n >\n {value}\n </tspan>\n {label && (\n <tspan x={cx} y={radius - 6} fill={MUTED} style={{ fontSize: 'var(--text-xs, 0.75rem)' }}>\n {label}\n </tspan>\n )}\n </text>\n {showRange &&\n ([-1, 1] as const).map((side, i) => (\n <text\n key={side}\n data-chart-range=\"\"\n x={cx + side * radius}\n y={radius + 14}\n textAnchor={side < 0 ? 'start' : 'end'}\n fill={MUTED}\n pointerEvents=\"none\"\n style={{ fontSize: 'var(--text-2xs, 0.6875rem)' }}\n >\n {range[i]}\n </text>\n ))}\n </>\n );\n};\n\ntype TargetProps = { radius: number; thickness: number; share: number };\n\n// A radial mark across the arc, a little longer than it is thick: a dark line over a\n// halo in the card's color, so it reads on the arc, on the track and on the card.\nconst Target = ({ radius, thickness, share }: TargetProps) => {\n const area = usePlotArea();\n if (!area) return null;\n const mark = arcMark(\n { cx: area.x + area.width / 2, cy: radius },\n { inner: radius - thickness - 4, outer: radius + 4 },\n share\n );\n return (\n <g data-chart-target=\"\" pointerEvents=\"none\" strokeLinecap=\"round\">\n <line {...mark} stroke={PANEL} strokeWidth={6} />\n <line {...mark} stroke={TEXT} strokeWidth={3} />\n </g>\n );\n};\n\nexport const SemiCircleGauge = ({\n value,\n label = '',\n color,\n min = 0,\n max = 100,\n warnAt,\n critAt,\n formatValue = percent,\n showRange = false,\n target,\n ariaLabel,\n children,\n height = 120,\n width,\n}: SemiCircleGaugeProps) => {\n const { ref: box, width: boxWidth } = useElementWidth();\n const text = formatValue(value);\n const row = showRange ? RANGE_ROW : EDGE_ROW;\n // The arc fills the width, up to the height it is allowed.\n const radius = boxWidth === undefined ? 0 : Math.floor(Math.min(boxWidth / 2, height - row));\n const thickness = Math.min(24, Math.max(8, Math.round(radius * 0.2)));\n const byStatus = warnAt !== undefined || critAt !== undefined;\n const arc = color ?? (byStatus ? statusColor(value, warnAt, critAt) : SERIES[0]);\n return (\n <div\n ref={box}\n style={{ width: width ?? '100%', maxWidth: '100%', height: radius + row, minHeight: row }}\n >\n {radius > 0 && (\n <RadialBarChart\n {...frameProps({\n height: radius + row,\n width: '100%',\n ariaLabel:\n gaugeName(ariaLabel ?? (label || 'Gauge'), text) +\n (target === undefined ? '' : `, target ${formatValue(target)}`),\n keyboard: false,\n })}\n data={[{ name: label || 'value', value: clampTo(value, min, max) }]}\n cx=\"50%\"\n cy={radius}\n startAngle={180}\n endAngle={0}\n innerRadius={radius - thickness}\n outerRadius={radius}\n barSize={thickness}\n margin={{ top: 0, right: 0, bottom: 0, left: 0 }}\n >\n <PolarAngleAxis type=\"number\" domain={[min, max]} tick={false} axisLine={false} />\n <RadialBar\n dataKey=\"value\"\n fill={arc}\n cornerRadius={thickness / 2}\n background={{ fill: TRACK, cornerRadius: thickness / 2 }}\n {...ANIMATION}\n />\n <Face\n radius={radius}\n value={text}\n label={label}\n showRange={showRange}\n range={[formatValue(min), formatValue(max)]}\n />\n {target !== undefined && (\n <Target radius={radius} thickness={thickness} share={rangeShare(target, min, max)} />\n )}\n {children}\n </RadialBarChart>\n )}\n </div>\n );\n};\n"]}