@sckyzo/cosmos-charts 0.3.1 → 0.4.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 +16 -0
- package/README.md +21 -106
- package/dist/BarChart.cjs +2 -2
- package/dist/BarChart.js +1 -1
- package/dist/BoxPlotChart.cjs +2 -2
- package/dist/BoxPlotChart.js +1 -1
- package/dist/CalendarChart.cjs +2 -2
- package/dist/CalendarChart.js +1 -1
- package/dist/HeatmapChart.cjs +2 -2
- package/dist/HeatmapChart.js +1 -1
- package/dist/LineAreaChart.cjs +2 -2
- package/dist/LineAreaChart.js +1 -1
- package/dist/MixedChart.cjs +2 -2
- package/dist/MixedChart.js +1 -1
- package/dist/RangeBarChart.cjs +2 -2
- package/dist/RangeBarChart.js +1 -1
- package/dist/RealtimeChart.cjs +1 -1
- package/dist/RealtimeChart.cjs.map +1 -1
- package/dist/RealtimeChart.js +1 -1
- package/dist/RealtimeChart.js.map +1 -1
- package/dist/ScatterChart.cjs +2 -2
- package/dist/ScatterChart.js +1 -1
- package/dist/{chunk-ZWHCUYIN.cjs → chunk-GBJPNJWM.cjs} +69 -9
- package/dist/chunk-GBJPNJWM.cjs.map +1 -0
- package/dist/{chunk-XUGQ6VXO.cjs → chunk-RGDENOKY.cjs} +3 -3
- package/dist/chunk-RGDENOKY.cjs.map +1 -0
- package/dist/{chunk-ESVGCUJN.js → chunk-RXCGQ5QQ.js} +3 -3
- package/dist/chunk-RXCGQ5QQ.js.map +1 -0
- package/dist/{chunk-UL3SNXQR.js → chunk-V56L4SNY.js} +70 -10
- package/dist/chunk-V56L4SNY.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-ESVGCUJN.js.map +0 -1
- package/dist/chunk-UL3SNXQR.js.map +0 -1
- package/dist/chunk-XUGQ6VXO.cjs.map +0 -1
- package/dist/chunk-ZWHCUYIN.cjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ All notable changes to `@sckyzo/cosmos-charts` are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.1](https://github.com/SckyzO/cosmos/compare/@sckyzo/cosmos-charts@0.4.0...@sckyzo/cosmos-charts@0.4.1) (2026-10-31)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **charts:** fade a scrolling heat grid and drop values that don't fit ([e8ff4ab](https://github.com/SckyzO/cosmos/commit/e8ff4ab015777ac6e2d6ef015d324e412370f00a))
|
|
14
|
+
* **charts:** keep room for the lowest label of a RealtimeChart ([5dac109](https://github.com/SckyzO/cosmos/commit/5dac10929560e8034543c80a78c965285ee53336))
|
|
15
|
+
* **charts:** put a reference band's label at the bottom of the band ([13ee80b](https://github.com/SckyzO/cosmos/commit/13ee80b338034903b0f940abfbfb5acbfb641f1c))
|
|
16
|
+
|
|
17
|
+
## [0.4.0](https://github.com/SckyzO/cosmos/compare/@sckyzo/cosmos-charts@0.3.1...@sckyzo/cosmos-charts@0.4.0) (2026-10-30)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Documentation
|
|
21
|
+
|
|
22
|
+
* **charts:** add the `@source` line to the install steps ([80f1687](https://github.com/SckyzO/cosmos/commit/80f16872bb9e68ad13924034a15eb6d2a123695b))
|
|
23
|
+
|
|
8
24
|
## [0.3.1](https://github.com/SckyzO/cosmos/compare/@sckyzo/cosmos-charts@0.3.0...@sckyzo/cosmos-charts@0.3.1) (2026-10-30)
|
|
9
25
|
|
|
10
26
|
|
package/README.md
CHANGED
|
@@ -2,41 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@sckyzo/cosmos-charts)
|
|
4
4
|
|
|
5
|
-
Cosmos charts
|
|
5
|
+
Cosmos charts: opinionated chart wrappers themed for the Cosmos design system, drawn with
|
|
6
|
+
[Recharts](https://recharts.github.io/). Kept in a dedicated package so that `@sckyzo/cosmos-react`
|
|
7
|
+
consumers who don't render charts don't ship a chart library.
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Each chart is a module of its own and the package declares no side effects, so a bundler ships the charts you import and leaves the others out: `import { DonutChart } from '@sckyzo/cosmos-charts'` brings the donut, not the line or bar charts. `recharts` is a dependency of the package, installed with it. So are `d3-geo` and `topojson-client`, which only `WorldMap` loads: a bundler leaves them out unless you import it.
|
|
9
|
+
Each chart is a module of its own and the package declares no side effects, so a bundler ships
|
|
10
|
+
the charts you import and leaves the others out.
|
|
10
11
|
|
|
11
12
|
## Install
|
|
12
13
|
|
|
13
14
|
```bash
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
npm install @sckyzo/cosmos-charts
|
|
16
|
+
npm install react react-dom # peers, react 19+
|
|
16
17
|
```
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- **Text** is 12px at the normal text size and follows the text size setting; the font is inherited, and the axes make room for their labels again once a web font has loaded.
|
|
25
|
-
- **The tooltip and the legend are React**: a series name, a category or a title with markup shows as written. The legend keeps the series order, and an item is a button that hides and shows its series (Enter and Space work).
|
|
26
|
-
- **`children`** takes Recharts elements drawn inside the chart, after the ones it builds, for what a chart has no prop for.
|
|
27
|
-
|
|
28
|
-
```tsx
|
|
29
|
-
import { ReferenceLine } from 'recharts';
|
|
19
|
+
The three Cosmos packages share one version number: install the same version of each. The charts
|
|
20
|
+
read their colors from the CSS variables of `@sckyzo/cosmos-theme`, so they follow its themes and
|
|
21
|
+
accents; without the theme CSS they fall back to a built-in palette. To set the theme up, see
|
|
22
|
+
[Getting started](https://github.com/SckyzO/cosmos/blob/main/docs/getting-started.md). A few
|
|
23
|
+
charts carry Tailwind 4 classes, so point Tailwind at this package too, in the CSS file that
|
|
24
|
+
imports it, next to the `@source` line for `@sckyzo/cosmos-react`:
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
</LineAreaChart>;
|
|
26
|
+
```css
|
|
27
|
+
@source '../node_modules/@sckyzo/cosmos-charts/dist/**/*.{js,cjs}';
|
|
34
28
|
```
|
|
35
29
|
|
|
36
|
-
`children` reads the chart's data and axes, so a `y` is in the units of the series. Add `recharts` to your app at the version this package depends on (`3.10.1`): two copies of Recharts do not share a chart's context, and the elements would not find it. Pass CSS variables for colors (`var(--color-status-warn)`) and they follow the theme.
|
|
37
|
-
|
|
38
|
-
Animation is short (500 ms) and off under `prefers-reduced-motion`. A chart fills the width it is given and never widens its parent (`width` caps it).
|
|
39
|
-
|
|
40
30
|
## Use
|
|
41
31
|
|
|
42
32
|
```tsx
|
|
@@ -48,90 +38,15 @@ import { LineAreaChart } from '@sckyzo/cosmos-charts';
|
|
|
48
38
|
/>;
|
|
49
39
|
```
|
|
50
40
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Most charts take `colors`, which overrides the Cosmos palette, and `formatValue`, which formats the values in their labels and tooltips (a unit, a precision). `formatValue` can be any function: a new one on every render redraws nothing. The gauges (`GradientRadial`, `SemiCircleGauge`, `StrokedGauge`) also take `min` and `max` (default 0 and 100), a `color` for the arc (the accent by default; on `GradientRadial` the color the arc starts from), and show a percent unless given a `formatValue`. A gauge is an image named by its label and value (`ariaLabel` replaces the label in the name). `SemiCircleGauge` keeps the accent unless given `warnAt` or `critAt`, in the units of the value, which color its arc by status: the theme's success color below `warnAt`, its warning color from `warnAt` and its critical color from `critAt` (`color` replaces either). It also takes `showRange`, which writes `min` and `max` under the ends of its arc, and its `height` (a number of pixels, 120 by default) is the most it takes: the arc is as wide as its box allows, up to that height. It draws a mark across its arc at `target` (a value on the scale of `min` and `max`, stopped at an end when out of range), and the target joins its name after the value (`Load: 67%, target 80%`).
|
|
54
|
-
|
|
55
|
-
The charts with a horizontal and a vertical axis (`LineAreaChart`, `BarChart`, `MixedChart`, `HeatmapChart`, `BoxPlotChart`, `RangeBarChart`, `RealtimeChart`, `ScatterChart`, `BubbleChart` and `WaterfallChart`) take `xTitle`, drawn under the horizontal axis, and `yTitle`, drawn beside the vertical one, as plain text: a horizontal `BarChart` puts its values on the horizontal axis. `MixedChart` also takes `yRightTitle` for its second axis. Its series are `column`, `line` or `area` (a filled line, behind the columns), and `stackedColumns` piles the columns on each other, apart on each axis. `RealtimeChart` only has an x axis with `showTimeAxis`.
|
|
56
|
-
|
|
57
|
-
`LineAreaChart`, `BarChart`, `MixedChart`, `ScatterChart`, `BubbleChart`, `BoxPlotChart` and `RangeBarChart` take `referenceLines` and `referenceBands`: `{ value, label?, intent?, dashed? }` draws a line across the plot at a value of the value axis, `{ from, to, label?, intent? }` shades the plot between two values, behind the series. The value axis is the vertical one, the horizontal one on horizontal bars and boxes, and the time axis of `RangeBarChart` (the values are timestamps in milliseconds); `MixedChart` reads its left axis, or its right one when no series is on the left. `intent` (`neutral`, the default, `warning`, `danger` or `success`) picks the color from the theme, so a theme switch repaints it; a label is plain text that follows the text size. A mark outside the data makes the axis reach it. For a diagonal line, a vertical one or anything else, `children` takes a Recharts `ReferenceLine`.
|
|
58
|
-
|
|
59
|
-
`LineAreaChart` draws an area under each line; `variant="line"` draws the lines alone, `stacked` piles the series on each other, `markers` puts a dot on every point, and a series can take `style: 'dashed'` or `'step'` (a line that jumps from one value to the next) in place of the smooth curve.
|
|
60
|
-
|
|
61
|
-
`BarChart` colors each bar from its value with `colorByValue(value, index)` (a threshold, a ranking; `undefined` keeps the series color), gives each category a color of the palette with `distributed`, and draws the bars below zero in `negativeColor`; that is the order of precedence, and the tooltip chip of a bar follows the bar.
|
|
62
|
-
|
|
63
|
-
`Sparkline` draws an `area` (default), a `line` or `bar` columns; the bar scale starts at zero (the lower of 0 and the lowest value, unless `min` is set) and the values below zero hang under a dashed zero line in the danger color. It takes `label` and `formatValue` for its tooltip, and `min` and `max` to pin its scale: it fits its own data otherwise, so sparklines read against each other (the rows of a table) share the same two. In a KPI tile, pass it to the `chart` slot of `KpiCard` (`@sckyzo/cosmos-react`): `<KpiCard label="Requests/s" value="2.3k" chart={<Sparkline data={data} />} />`. The two packages do not depend on each other, so the chart is yours to pass.
|
|
64
|
-
|
|
65
|
-
`RealtimeChart` takes `min` and `max` for its y axis (0 and 100 by default), `showTimeAxis` to label the x axis with the time of each sample, and `warnLabel` and `critLabel` to rename the threshold labels.
|
|
66
|
-
|
|
67
|
-
`TreemapChart` writes the value of each tile under its name when given `showValues`, and draws its group headers in the card's colors. Its tiles take the text color that reads on them (white or black). `children` are drawn over the tiles, in the chart's own SVG space.
|
|
68
|
-
|
|
69
|
-
`HeatmapChart` is a grid of rounded cells, not a Recharts chart, so it takes no `children`. Its default scale is five steps of the accent mixed over the card, each told apart from the next and the lowest still a cell of its own on a dark card; `colors` replaces the steps and `ranges` sets thresholds with their own colors (a value on a bound shared by two ranges takes the later one). The grid is one tab stop: the arrow keys move between cells and show the tooltip of the cell they land on, Home and End go to the ends of the row, Ctrl+Home and Ctrl+End to the ends of the grid. Each cell is named `row, column: value` for screen readers.
|
|
70
|
-
|
|
71
|
-
`CalendarChart` is a day-by-day heatmap built on the same grid, so it takes no `children` either. `data` is `{ day: 'YYYY-MM-DD', value }[]` (a day listed twice adds up, a day with no entry is empty), `from` and `to` bound the days shown. The `calendar` layout draws one block per year, with the months named above their first full week and Mon / Wed / Fri beside the rows; `range` draws one continuous grid, with larger cells when it is short. Weeks start on Monday, or on Sunday with `weekStart={0}`; `locale` names the months, weekdays and dates. Days are read and drawn in UTC. The scale is the neutral track for a day with nothing, then four steps of the accent (the dark themes use lower shares and a light accent for the top one) splitting `(0, max]` evenly, with a "Less … More" key under the grid, right-aligned with it (`lessLabel` and `moreLabel` replace the words). A grid wider than its box scrolls inside it, the weekday names staying in view. The title and the total are the host's. Keyboard as `HeatmapChart`, one tab stop per year block.
|
|
72
|
-
|
|
73
|
-
`BumpChart` draws how a ranking changes over periods: `series` is `{ name, data: { x, rank }[] }[]`, 1 is the top, and the periods are every `x` once in the order they first appear. A series that enters late has no point before it enters, and ties are allowed (tied series are drawn apart around their rank). Each name is written at both ends of its line with its color, so there is no legend; on a narrow chart (under 560px) only the right-hand names stay, cut short, and where the periods get too close for the discs the points become dots. `points` is `rank` (default, a disc with the rank in it) or `dot`. A pointer over a line, a point or a name, or the arrows Up and Down on the keyboard (Escape lets go), gives that series a thicker line and fades the others. The tooltip, which Left and Right walk period by period, gives the period, the rank and the change from the previous period in words (`unchanged vs May`, `up 2 vs Apr`, `down 1 vs Mar`, `new entry`), never by color alone. `formatValue` formats the rank in the tooltip, and `children` takes Recharts elements, where a `y` is a rank.
|
|
74
|
-
|
|
75
|
-
`FunnelChart` draws one centred bar per stage, as wide as its value against the largest stage (the first, unless a stage grows), joined to the next by a translucent flow. The stages keep the order given and are never sorted: a stage larger than the one before it is allowed, and shows a rate over 100%. The names sit on the left; on the right, the value, a chip with the rate from the previous stage (`65.4%`, `100%` for the first) and, beside it, the rate from the first (`20.5% of Visits`); `showConversion={false}` leaves the values alone. The accent fades from the first stage to the last, and `colors` gives one color per stage instead. `formatValue` formats the values, percentages always have one decimal. In a box under 520px wide each name and value go on one line above their bar, and the rate from the first stage stays in the tooltip. Like `HeatmapChart` it is HTML and SVG, not a Recharts chart, so it takes no `children`: the flow joins two bars at their own edges, which a Recharts bar can't be drawn to do. It is one tab stop: the arrow keys, Home and End walk the stages and show the tooltip of the one they land on. Stages that are all at 0 draw `emptyMessage`.
|
|
76
|
-
|
|
77
|
-
`WaterfallChart` walks a running total through gains and losses: `data` is `{ label, value?, kind? }[]`. A step (the default `kind`) carries a signed `value` and floats between the total before and after it; a `subtotal` is drawn from 0 to the running total at that point (never the sum since the last cut); a `total` is drawn the same way, and a `value` on it sets the running total to it, which is how an opening balance, or a known balance mid-walk, is written. A step without a `value` counts as 0. Increases take the theme's success color, decreases its error color and totals the accent (subtotals the same, lighter); `colors: { positive, negative, total }` overrides them. The color is never alone: the value above a bar and the tooltip carry the sign (`+310k`, `−265k`, with a real minus; `formatValue` gets the magnitude) and the kind in words (Increase, Decrease, Subtotal, Total), and the tooltip of a step adds the running total after it. `showLabels` forces the values above the bars on or off (by default they show with 12 bars or fewer in a chart at least 480px wide), `showConnectors` (default on) draws the dashed line from the top of a bar to the next one. Below 480px the category names tilt. It takes `xTitle`, `yTitle` and `children`.
|
|
78
|
-
|
|
79
|
-
`WorldMap` colors the countries of a world map by value: `data` is `{ FR: 16400, US: 48200 }`, keyed by ISO 3166-1 alpha-2 code in upper case, and `geography` is a TopoJSON `Topology` with a `countries` object. The package ships no map data: you pass `world-atlas` (ISC), and the `110m` file is enough for a dashboard card (105 kB, 39 kB gzipped; `countries-50m.json` draws the small countries too). Antarctica is left out, and a code the map does not hold is not drawn.
|
|
80
|
-
|
|
81
|
-
```tsx
|
|
82
|
-
import { WorldMap } from '@sckyzo/cosmos-charts';
|
|
83
|
-
import type { Topology } from 'topojson-specification';
|
|
84
|
-
import world from 'world-atlas/countries-110m.json';
|
|
85
|
-
|
|
86
|
-
// An imported JSON file is typed as plain strings: the cast says it is a Topology.
|
|
87
|
-
<WorldMap
|
|
88
|
-
data={{ FR: 16400, US: 48200, DE: 21300 }}
|
|
89
|
-
geography={world as unknown as Topology}
|
|
90
|
-
label="visitors"
|
|
91
|
-
formatValue={(value) => `${(value / 1000).toFixed(1)}k`}
|
|
92
|
-
/>;
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
The scale has five steps of the accent, cut by quantiles of the values so that each holds about as many countries (a linear scale lets one large country wash the others out); a country without a value is gray. `min` and `max` clamp every value before the steps are cut, so a value over `max` counts as `max`: they pin the ends of the scale, and the legend starts at `min`. The legend gives the lower bound of each step (`2.7k+`, through `formatValue`) and a "No data" swatch; `showLegend={false}` hides it. It is its own SVG, so it takes no `children`, and a map with no value (an empty `data`, or no code the map holds) draws the bare map, with no legend and no `emptyMessage`. The map scales with the width it is given and keeps its proportions (about 2:1) unless `height` is set. It is one tab stop: the arrow keys walk the countries that have a value, largest first (Home and End go to the largest and the smallest), the one in focus is outlined and shows its card, and `onSelect(code)` is called by a click, or by Enter or Space on the country in focus. For screen readers the map is an image named by `ariaLabel`, and a visually hidden table (country, value, largest first) lists the data. `geography` needs `@types/topojson-specification` for its type, installed with the package.
|
|
96
|
-
|
|
97
|
-
`RadarChart` draws its polygons as large as its box allows and leaves the scale (0, 20 … 100) off them unless given `showScale`. `DonutChart` writes the total in the middle, and the value and name of the slice under the pointer in its place (`centerValue` and `centerLabel` replace the sum and "Total"; `variant="pie"` fills the disc and writes nothing in it; `legendValues` adds each slice's value and its share, in whole percents that add up to 100, to the legend, in columns when the legend is on a side); `RadialBarChart` does the same with the average and the ring.
|
|
98
|
-
|
|
99
|
-
The charts that draw a legend take `legendPosition` (`top`, `right`, `bottom` or `left`): the legend sits above the plot by default, below the donut on `DonutChart`. `left` and `right` are the sides of the screen, not of the line: a chart keeps its left-to-right axis in a right-to-left page, and its legend stays where you put it.
|
|
100
|
-
|
|
101
|
-
A chart with no series, or only empty ones, draws `emptyMessage` (default `No data`, an empty string for nothing) in place of the plot. The gauges, which always have a value, and `RealtimeChart`, which fills its own window, have no such prop.
|
|
102
|
-
|
|
103
|
-
For what a chart has no prop for, every chart but `HeatmapChart`, `CalendarChart`, `FunnelChart` and `WorldMap` takes `children` (see above).
|
|
104
|
-
|
|
105
|
-
Every chart takes an `ariaLabel`, the name screen readers read for it. Without one, the chart is named from its type and its series. Tab reaches a chart, and the arrow keys move from point to point and announce each one: ArrowRight goes to the next point, ArrowLeft to the previous one, and on a chart with its categories on the vertical axis (a horizontal `BarChart` or `BoxPlotChart`, `RangeBarChart`) ArrowDown and ArrowRight go to the next category and ArrowUp and ArrowLeft to the previous one. The gauges and `Sparkline` show a single value or a trend: they are named images, out of the tab order.
|
|
106
|
-
|
|
107
|
-
## Charts shipped
|
|
41
|
+
## Documentation
|
|
108
42
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
| `MixedChart` | Columns and lines, optional second y axis |
|
|
114
|
-
| `LineAreaChart` | Smooth area + gradient fill, legend when 2+ series |
|
|
115
|
-
| `RealtimeChart` | Live updates with WARN/CRIT threshold lines |
|
|
116
|
-
| `RadialBarChart` | Multi-series radial gauge |
|
|
117
|
-
| `GradientRadial` | Single gradient radial |
|
|
118
|
-
| `SemiCircleGauge` | Half-donut gauge |
|
|
119
|
-
| `StrokedGauge` | Dashed-stroke radial |
|
|
120
|
-
| `DonutChart` | Donut, legend below by default |
|
|
121
|
-
| `Sparkline` | Mini line, area or bar trend, no axes |
|
|
122
|
-
| `TreemapChart` | Repartition treemap |
|
|
123
|
-
| `HeatmapChart` | Rows × columns colored by value buckets or ranges (HTML grid) |
|
|
124
|
-
| `CalendarChart` | Day-by-day heatmap over a year or any range (HTML grid) |
|
|
125
|
-
| `BumpChart` | Rankings over periods, names at both ends (Recharts) |
|
|
126
|
-
| `RadarChart` | One polygon per series over named axes |
|
|
127
|
-
| `ScatterChart` / `BubbleChart` | Numeric x/y points; bubble size as a 3rd measure |
|
|
128
|
-
| `BoxPlotChart` | Min/quartiles/max boxes, vertical or horizontal |
|
|
129
|
-
| `FunnelChart` | Centred bars joined by a flow, with the conversion per stage |
|
|
130
|
-
| `WaterfallChart` | Running total through gains, losses, subtotals and totals |
|
|
131
|
-
| `WorldMap` | Countries colored by value in five quantile steps (own SVG) |
|
|
43
|
+
- [Charts guide](https://github.com/SckyzO/cosmos/blob/main/docs/guides/charts.md): how the colors follow the theme, the props every chart
|
|
44
|
+
shares, and each chart type.
|
|
45
|
+
- [Storybook](https://sckyzo.github.io/cosmos/?path=/docs/charts-line-area--docs): every chart with
|
|
46
|
+
its stories.
|
|
132
47
|
|
|
133
48
|
## License
|
|
134
49
|
|
|
135
|
-
MIT
|
|
50
|
+
MIT, see [LICENSE](https://github.com/SckyzO/cosmos/blob/main/LICENSE).
|
|
136
51
|
|
|
137
52
|
The charts are drawn with [Recharts](https://github.com/recharts/recharts) (MIT), which pulls in modules of [d3](https://d3js.org/) (ISC, and BSD-3-Clause for `d3-ease`). `WorldMap` also uses [d3-geo](https://github.com/d3/d3-geo) (ISC) and [topojson-client](https://github.com/topojson/topojson-client) (ISC). Their licenses apply to the code they ship. `d3-geo` ships ES modules only, so the CommonJS build carries it inside `WorldMap.cjs`, with the `d3-array` and `internmap` it pulls; `THIRD_PARTY_NOTICES.md` holds their licenses.
|
package/dist/BarChart.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
var chunkGVTMZYOM_cjs = require('./chunk-GVTMZYOM.cjs');
|
|
5
5
|
var chunkF2PMFYJ5_cjs = require('./chunk-F2PMFYJ5.cjs');
|
|
6
|
-
var
|
|
6
|
+
var chunkRGDENOKY_cjs = require('./chunk-RGDENOKY.cjs');
|
|
7
7
|
var chunkXMFBVMW7_cjs = require('./chunk-XMFBVMW7.cjs');
|
|
8
8
|
var chunkRCDTBZC2_cjs = require('./chunk-RCDTBZC2.cjs');
|
|
9
9
|
var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
|
|
@@ -125,7 +125,7 @@ var BarChart = ({
|
|
|
125
125
|
key
|
|
126
126
|
);
|
|
127
127
|
}),
|
|
128
|
-
|
|
128
|
+
chunkRGDENOKY_cjs.referenceMarks({ referenceLines, referenceBands, axis: horizontal ? "x" : "y" }),
|
|
129
129
|
children
|
|
130
130
|
]
|
|
131
131
|
}
|
package/dist/BarChart.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { roundedBarShape, isOuterInStack } from './chunk-GDZLYYL2.js';
|
|
3
3
|
import { useCategoryKeys } from './chunk-FUZW3H5X.js';
|
|
4
|
-
import { referenceMarks } from './chunk-
|
|
4
|
+
import { referenceMarks } from './chunk-RXCGQ5QQ.js';
|
|
5
5
|
import { trimLabel, categoryAxis } from './chunk-YMRNTIOK.js';
|
|
6
6
|
import { useHiddenSeries, legendProps } from './chunk-4AKHZNWP.js';
|
|
7
7
|
import { ANIMATION } from './chunk-5C2RLJYZ.js';
|
package/dist/BoxPlotChart.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var chunkF2PMFYJ5_cjs = require('./chunk-F2PMFYJ5.cjs');
|
|
5
|
-
var
|
|
5
|
+
var chunkRGDENOKY_cjs = require('./chunk-RGDENOKY.cjs');
|
|
6
6
|
var chunkXMFBVMW7_cjs = require('./chunk-XMFBVMW7.cjs');
|
|
7
7
|
var chunkRCDTBZC2_cjs = require('./chunk-RCDTBZC2.cjs');
|
|
8
8
|
var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
|
|
@@ -202,7 +202,7 @@ var BoxPlotChart = ({
|
|
|
202
202
|
},
|
|
203
203
|
chunkK3R7JGOW_cjs.seriesKey(index)
|
|
204
204
|
)),
|
|
205
|
-
|
|
205
|
+
chunkRGDENOKY_cjs.referenceMarks({ referenceLines, referenceBands, axis: horizontal ? "x" : "y" }),
|
|
206
206
|
children
|
|
207
207
|
]
|
|
208
208
|
}
|
package/dist/BoxPlotChart.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useCategoryKeys } from './chunk-FUZW3H5X.js';
|
|
3
|
-
import { referenceMarks } from './chunk-
|
|
3
|
+
import { referenceMarks } from './chunk-RXCGQ5QQ.js';
|
|
4
4
|
import { trimLabel, categoryAxis } from './chunk-YMRNTIOK.js';
|
|
5
5
|
import { useHiddenSeries, legendProps } from './chunk-4AKHZNWP.js';
|
|
6
6
|
import { ANIMATION } from './chunk-5C2RLJYZ.js';
|
package/dist/CalendarChart.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkGBJPNJWM_cjs = require('./chunk-GBJPNJWM.cjs');
|
|
5
5
|
require('./chunk-DBZQI4HM.cjs');
|
|
6
6
|
var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
|
|
7
7
|
require('./chunk-T3K6Q34U.cjs');
|
|
@@ -161,7 +161,7 @@ var CalendarChart = ({
|
|
|
161
161
|
grids.map(({ block, metrics: m, columns, cells, label }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-calendar-block": "", style: { minWidth: 0 }, children: [
|
|
162
162
|
blocks.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: "0 0 0.25rem", fontWeight: 600, color: chunkLT3UC65O_cjs.TEXT }, children: block.year }),
|
|
163
163
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
164
|
-
|
|
164
|
+
chunkGBJPNJWM_cjs.HeatGrid,
|
|
165
165
|
{
|
|
166
166
|
rows,
|
|
167
167
|
columns,
|
package/dist/CalendarChart.js
CHANGED
package/dist/HeatmapChart.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkGBJPNJWM_cjs = require('./chunk-GBJPNJWM.cjs');
|
|
5
5
|
require('./chunk-DBZQI4HM.cjs');
|
|
6
6
|
var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
|
|
7
7
|
require('./chunk-T3K6Q34U.cjs');
|
|
@@ -128,7 +128,7 @@ var HeatmapChart = ({
|
|
|
128
128
|
children: [
|
|
129
129
|
legend,
|
|
130
130
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: "1 1 0", minWidth: 0, minHeight: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
131
|
-
|
|
131
|
+
chunkGBJPNJWM_cjs.HeatGrid,
|
|
132
132
|
{
|
|
133
133
|
rows: series.map((s) => s.name),
|
|
134
134
|
columns: categories.map(String),
|
package/dist/HeatmapChart.js
CHANGED
package/dist/LineAreaChart.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkRGDENOKY_cjs = require('./chunk-RGDENOKY.cjs');
|
|
5
5
|
var chunkRCDTBZC2_cjs = require('./chunk-RCDTBZC2.cjs');
|
|
6
6
|
var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
|
|
7
7
|
var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
|
|
@@ -86,7 +86,7 @@ var LineAreaChart = ({
|
|
|
86
86
|
chunkK3R7JGOW_cjs.seriesKey(i)
|
|
87
87
|
);
|
|
88
88
|
}),
|
|
89
|
-
|
|
89
|
+
chunkRGDENOKY_cjs.referenceMarks({ referenceLines, referenceBands }),
|
|
90
90
|
children
|
|
91
91
|
]
|
|
92
92
|
}
|
package/dist/LineAreaChart.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { referenceMarks } from './chunk-
|
|
2
|
+
import { referenceMarks } from './chunk-RXCGQ5QQ.js';
|
|
3
3
|
import { useHiddenSeries, legendProps } from './chunk-4AKHZNWP.js';
|
|
4
4
|
import { ANIMATION } from './chunk-5C2RLJYZ.js';
|
|
5
5
|
import { useAxis, GRID_PROPS, xAxisTitle, yAxisTitle } from './chunk-DI2FBGKM.js';
|
package/dist/MixedChart.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var chunkGVTMZYOM_cjs = require('./chunk-GVTMZYOM.cjs');
|
|
5
|
-
var
|
|
5
|
+
var chunkRGDENOKY_cjs = require('./chunk-RGDENOKY.cjs');
|
|
6
6
|
var chunkXMFBVMW7_cjs = require('./chunk-XMFBVMW7.cjs');
|
|
7
7
|
var chunkRCDTBZC2_cjs = require('./chunk-RCDTBZC2.cjs');
|
|
8
8
|
var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
|
|
@@ -183,7 +183,7 @@ var MixedChart = ({
|
|
|
183
183
|
key
|
|
184
184
|
);
|
|
185
185
|
}),
|
|
186
|
-
|
|
186
|
+
chunkRGDENOKY_cjs.referenceMarks({ referenceLines, referenceBands, axisId: sides[0] }),
|
|
187
187
|
children
|
|
188
188
|
]
|
|
189
189
|
}
|
package/dist/MixedChart.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { roundedBarShape, isOuterInStack } from './chunk-GDZLYYL2.js';
|
|
3
|
-
import { referenceMarks } from './chunk-
|
|
3
|
+
import { referenceMarks } from './chunk-RXCGQ5QQ.js';
|
|
4
4
|
import { categoryAxis } from './chunk-YMRNTIOK.js';
|
|
5
5
|
import { useHiddenSeries, legendProps } from './chunk-4AKHZNWP.js';
|
|
6
6
|
import { ANIMATION } from './chunk-5C2RLJYZ.js';
|
package/dist/RangeBarChart.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var chunkF2PMFYJ5_cjs = require('./chunk-F2PMFYJ5.cjs');
|
|
5
|
-
var
|
|
5
|
+
var chunkRGDENOKY_cjs = require('./chunk-RGDENOKY.cjs');
|
|
6
6
|
var chunkRCDTBZC2_cjs = require('./chunk-RCDTBZC2.cjs');
|
|
7
7
|
var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
|
|
8
8
|
var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
|
|
@@ -206,7 +206,7 @@ var RangeBarChart = ({
|
|
|
206
206
|
},
|
|
207
207
|
chunkK3R7JGOW_cjs.seriesKey(index)
|
|
208
208
|
)),
|
|
209
|
-
|
|
209
|
+
chunkRGDENOKY_cjs.referenceMarks({ referenceLines, referenceBands, axis: "x" }),
|
|
210
210
|
children
|
|
211
211
|
]
|
|
212
212
|
}
|
package/dist/RangeBarChart.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useCategoryKeys } from './chunk-FUZW3H5X.js';
|
|
3
|
-
import { referenceMarks } from './chunk-
|
|
3
|
+
import { referenceMarks } from './chunk-RXCGQ5QQ.js';
|
|
4
4
|
import { useHiddenSeries, legendProps, ChartLegend } from './chunk-4AKHZNWP.js';
|
|
5
5
|
import { ANIMATION } from './chunk-5C2RLJYZ.js';
|
|
6
6
|
import { useAxis, xAxisTitle, yAxisTitle } from './chunk-DI2FBGKM.js';
|
package/dist/RealtimeChart.cjs
CHANGED
|
@@ -112,7 +112,7 @@ var RealtimeChart = ({
|
|
|
112
112
|
ariaLabel: ariaLabel ?? "Live values, newest on the right"
|
|
113
113
|
}),
|
|
114
114
|
data: samples,
|
|
115
|
-
margin: { top: 4, right: 12, bottom: 0, left: 0 },
|
|
115
|
+
margin: { top: 4, right: 12, bottom: showTimeAxis ? 0 : 10, left: 0 },
|
|
116
116
|
children: [
|
|
117
117
|
/* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { ...chunkG4WOPX4D_cjs.GRID_PROPS }),
|
|
118
118
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/RealtimeChart.tsx"],"names":["jsx","ReferenceLine","TEXT","TEXT_SIZE","useAxis","useState","useEffect","TooltipCard","SERIES","jsxs","LineChart","frameProps","CartesianGrid","GRID_PROPS","XAxis","xAxisTitle","YAxis","yAxisTitle","STATUS_WARN","STATUS_CRIT","Tooltip","BORDER","Line","PANEL"],"mappings":"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","file":"RealtimeChart.cjs","sourcesContent":["import { useEffect, useState } from 'react';\nimport {\n CartesianGrid,\n Line,\n LineChart,\n ReferenceLine,\n Tooltip,\n XAxis,\n YAxis,\n type TooltipContentProps,\n} from 'recharts';\nimport { GRID_PROPS, TEXT_SIZE, useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { TooltipCard } from './core/ChartTooltip';\nimport { BORDER, PANEL, SERIES, STATUS_CRIT, STATUS_WARN, TEXT } from './core/colors';\nimport { frameProps } from './core/frame';\nimport type { ChartAxisTitleProps, ChartProps } from './types';\n\nexport type RealtimeChartProps = ChartProps &\n ChartAxisTitleProps & {\n /** Sample generator — defaults to a noisy walk between 30 and 80. */\n generator?: () => number;\n /** Interval in ms — defaults to 2000. */\n intervalMs?: number;\n windowSize?: number;\n /** Bottom of the y axis. Default 0. */\n min?: number;\n /** Top of the y axis, above `min`. Default 100. */\n max?: number;\n warnThreshold?: number;\n critThreshold?: number;\n /** Text of the warning threshold's label. Default `WARN`; an empty string draws the line alone. */\n warnLabel?: string;\n /** Text of the critical threshold's label. Default `CRIT`; an empty string draws the line alone. */\n critLabel?: string;\n /**\n * Label the x axis with the time of each sample (`14:03:25`, in local time), and the\n * tooltip with it, and `xTitle` has an axis to name. Default off: no x axis.\n */\n showTimeAxis?: boolean;\n /** Format the y-axis labels and the tooltip values. */\n formatValue?: (value: number) => string;\n };\n\ntype Sample = { time: number; value: number };\n\n// The time axis reads as a clock.\nconst CLOCK = new Intl.DateTimeFormat('en-GB', {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hourCycle: 'h23',\n});\nconst clock = (timestamp: number) => CLOCK.format(timestamp);\n\n/** A threshold: a line in its status color, and a label on it unless `label` is empty. */\nconst Threshold = ({ y, label, color }: { y: number; label: string; color: string }) => (\n <ReferenceLine\n y={y}\n stroke={color}\n strokeWidth={1.5}\n strokeDasharray=\"6 4\"\n label={\n label === ''\n ? undefined\n : {\n value: label,\n position: 'insideTopRight',\n offset: 4,\n // Text on the card, whatever the status color: it reads on every theme.\n fill: TEXT,\n style: { fill: TEXT, fontSize: TEXT_SIZE, fontWeight: 600 },\n }\n }\n />\n);\n\n// One walk per chart: a module-level one made every instance continue the last.\nconst createDefaultGenerator = () => {\n let last = 50;\n return () => {\n last += (Math.random() - 0.5) * 8;\n last = Math.max(20, Math.min(95, last));\n return Math.round(last);\n };\n};\n\nexport const RealtimeChart = ({\n generator,\n intervalMs = 2000,\n windowSize = 30,\n min = 0,\n max = 100,\n warnThreshold = 70,\n critThreshold = 85,\n warnLabel = 'WARN',\n critLabel = 'CRIT',\n showTimeAxis = false,\n xTitle,\n yTitle,\n formatValue,\n ariaLabel,\n children,\n height = 240,\n width,\n}: RealtimeChartProps) => {\n const axis = useAxis();\n const [defaultGenerator] = useState(createDefaultGenerator);\n const generate = generator ?? defaultGenerator;\n // Each sample with the time it was taken, for the time axis. A window that\n // starts full is dated as if it had been filled at the sampling pace.\n const [mountedAt] = useState(Date.now);\n const [samples, setSamples] = useState<Sample[]>(() =>\n Array.from({ length: windowSize }, (_, index) => ({\n time: mountedAt - (windowSize - 1 - index) * intervalMs,\n value: generate(),\n }))\n );\n\n // A new windowSize trims the oldest samples or prepends new ones. Adjusted\n // while rendering, which React redoes at once without painting the old window.\n const [sizedFor, setSizedFor] = useState(windowSize);\n if (sizedFor !== windowSize) {\n setSizedFor(windowSize);\n const missing = windowSize - samples.length;\n const oldest = samples[0]?.time ?? mountedAt;\n setSamples(\n missing <= 0\n ? samples.slice(samples.length - windowSize)\n : [\n ...Array.from({ length: missing }, (_, index) => ({\n time: oldest - (missing - index) * intervalMs,\n value: generate(),\n })),\n ...samples,\n ]\n );\n }\n\n useEffect(() => {\n const id = setInterval(() => {\n setSamples((current) => [...current.slice(1), { time: Date.now(), value: generate() }]);\n }, intervalMs);\n return () => clearInterval(id);\n }, [generate, intervalMs]);\n\n const format = formatValue ?? String;\n\n // The card of the sample under the pointer, with its time when the axis shows it.\n const tooltip = ({ active, payload }: Partial<TooltipContentProps>) => {\n const sample = payload?.[0]?.payload as Sample | undefined;\n if (!active || !sample) return null;\n return (\n <TooltipCard\n title={showTimeAxis ? clock(sample.time) : undefined}\n rows={[{ name: 'value', value: format(sample.value), color: SERIES[0] }]}\n />\n );\n };\n\n return (\n <LineChart\n {...frameProps({\n height,\n width,\n ariaLabel: ariaLabel ?? 'Live values, newest on the right',\n })}\n data={samples}\n margin={{ top: 4, right: 12, bottom: 0, left: 0 }}\n >\n <CartesianGrid {...GRID_PROPS} />\n {/* The samples are not on a scale of their own unless the axis is the clock. */}\n <XAxis\n dataKey=\"time\"\n type=\"number\"\n domain={['dataMin', 'dataMax']}\n hide={!showTimeAxis}\n tickFormatter={clock}\n {...axis}\n {...(showTimeAxis ? xAxisTitle(xTitle) : {})}\n />\n <YAxis\n domain={[min, max]}\n allowDataOverflow\n // The bottom tick is `min`: keep it.\n interval={0}\n width=\"auto\"\n tickFormatter={formatValue}\n {...axis}\n {...yAxisTitle(yTitle)}\n />\n <Threshold y={warnThreshold} label={warnLabel} color={STATUS_WARN} />\n <Threshold y={critThreshold} label={critLabel} color={STATUS_CRIT} />\n <Tooltip\n content={tooltip}\n cursor={{ stroke: BORDER, strokeDasharray: '4 4' }}\n animationDuration={0}\n />\n <Line\n name=\"value\"\n dataKey=\"value\"\n type=\"monotone\"\n stroke={SERIES[0]}\n strokeWidth={2}\n dot={false}\n activeDot={{ r: 5, fill: PANEL, stroke: SERIES[0], strokeWidth: 2.5 }}\n // A new sample moves the window: no animation, so the line redraws steadily.\n isAnimationActive={false}\n />\n {children}\n </LineChart>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/RealtimeChart.tsx"],"names":["jsx","ReferenceLine","TEXT","TEXT_SIZE","useAxis","useState","useEffect","TooltipCard","SERIES","jsxs","LineChart","frameProps","CartesianGrid","GRID_PROPS","XAxis","xAxisTitle","YAxis","yAxisTitle","STATUS_WARN","STATUS_CRIT","Tooltip","BORDER","Line","PANEL"],"mappings":"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","file":"RealtimeChart.cjs","sourcesContent":["import { useEffect, useState } from 'react';\nimport {\n CartesianGrid,\n Line,\n LineChart,\n ReferenceLine,\n Tooltip,\n XAxis,\n YAxis,\n type TooltipContentProps,\n} from 'recharts';\nimport { GRID_PROPS, TEXT_SIZE, useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { TooltipCard } from './core/ChartTooltip';\nimport { BORDER, PANEL, SERIES, STATUS_CRIT, STATUS_WARN, TEXT } from './core/colors';\nimport { frameProps } from './core/frame';\nimport type { ChartAxisTitleProps, ChartProps } from './types';\n\nexport type RealtimeChartProps = ChartProps &\n ChartAxisTitleProps & {\n /** Sample generator — defaults to a noisy walk between 30 and 80. */\n generator?: () => number;\n /** Interval in ms — defaults to 2000. */\n intervalMs?: number;\n windowSize?: number;\n /** Bottom of the y axis. Default 0. */\n min?: number;\n /** Top of the y axis, above `min`. Default 100. */\n max?: number;\n warnThreshold?: number;\n critThreshold?: number;\n /** Text of the warning threshold's label. Default `WARN`; an empty string draws the line alone. */\n warnLabel?: string;\n /** Text of the critical threshold's label. Default `CRIT`; an empty string draws the line alone. */\n critLabel?: string;\n /**\n * Label the x axis with the time of each sample (`14:03:25`, in local time), and the\n * tooltip with it, and `xTitle` has an axis to name. Default off: no x axis.\n */\n showTimeAxis?: boolean;\n /** Format the y-axis labels and the tooltip values. */\n formatValue?: (value: number) => string;\n };\n\ntype Sample = { time: number; value: number };\n\n// The time axis reads as a clock.\nconst CLOCK = new Intl.DateTimeFormat('en-GB', {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hourCycle: 'h23',\n});\nconst clock = (timestamp: number) => CLOCK.format(timestamp);\n\n/** A threshold: a line in its status color, and a label on it unless `label` is empty. */\nconst Threshold = ({ y, label, color }: { y: number; label: string; color: string }) => (\n <ReferenceLine\n y={y}\n stroke={color}\n strokeWidth={1.5}\n strokeDasharray=\"6 4\"\n label={\n label === ''\n ? undefined\n : {\n value: label,\n position: 'insideTopRight',\n offset: 4,\n // Text on the card, whatever the status color: it reads on every theme.\n fill: TEXT,\n style: { fill: TEXT, fontSize: TEXT_SIZE, fontWeight: 600 },\n }\n }\n />\n);\n\n// One walk per chart: a module-level one made every instance continue the last.\nconst createDefaultGenerator = () => {\n let last = 50;\n return () => {\n last += (Math.random() - 0.5) * 8;\n last = Math.max(20, Math.min(95, last));\n return Math.round(last);\n };\n};\n\nexport const RealtimeChart = ({\n generator,\n intervalMs = 2000,\n windowSize = 30,\n min = 0,\n max = 100,\n warnThreshold = 70,\n critThreshold = 85,\n warnLabel = 'WARN',\n critLabel = 'CRIT',\n showTimeAxis = false,\n xTitle,\n yTitle,\n formatValue,\n ariaLabel,\n children,\n height = 240,\n width,\n}: RealtimeChartProps) => {\n const axis = useAxis();\n const [defaultGenerator] = useState(createDefaultGenerator);\n const generate = generator ?? defaultGenerator;\n // Each sample with the time it was taken, for the time axis. A window that\n // starts full is dated as if it had been filled at the sampling pace.\n const [mountedAt] = useState(Date.now);\n const [samples, setSamples] = useState<Sample[]>(() =>\n Array.from({ length: windowSize }, (_, index) => ({\n time: mountedAt - (windowSize - 1 - index) * intervalMs,\n value: generate(),\n }))\n );\n\n // A new windowSize trims the oldest samples or prepends new ones. Adjusted\n // while rendering, which React redoes at once without painting the old window.\n const [sizedFor, setSizedFor] = useState(windowSize);\n if (sizedFor !== windowSize) {\n setSizedFor(windowSize);\n const missing = windowSize - samples.length;\n const oldest = samples[0]?.time ?? mountedAt;\n setSamples(\n missing <= 0\n ? samples.slice(samples.length - windowSize)\n : [\n ...Array.from({ length: missing }, (_, index) => ({\n time: oldest - (missing - index) * intervalMs,\n value: generate(),\n })),\n ...samples,\n ]\n );\n }\n\n useEffect(() => {\n const id = setInterval(() => {\n setSamples((current) => [...current.slice(1), { time: Date.now(), value: generate() }]);\n }, intervalMs);\n return () => clearInterval(id);\n }, [generate, intervalMs]);\n\n const format = formatValue ?? String;\n\n // The card of the sample under the pointer, with its time when the axis shows it.\n const tooltip = ({ active, payload }: Partial<TooltipContentProps>) => {\n const sample = payload?.[0]?.payload as Sample | undefined;\n if (!active || !sample) return null;\n return (\n <TooltipCard\n title={showTimeAxis ? clock(sample.time) : undefined}\n rows={[{ name: 'value', value: format(sample.value), color: SERIES[0] }]}\n />\n );\n };\n\n return (\n <LineChart\n {...frameProps({\n height,\n width,\n ariaLabel: ariaLabel ?? 'Live values, newest on the right',\n })}\n data={samples}\n // The label of the lowest value is centred on the bottom edge of the plot: without the time\n // axis under it, the chart keeps room for its lower half, which was cut.\n margin={{ top: 4, right: 12, bottom: showTimeAxis ? 0 : 10, left: 0 }}\n >\n <CartesianGrid {...GRID_PROPS} />\n {/* The samples are not on a scale of their own unless the axis is the clock. */}\n <XAxis\n dataKey=\"time\"\n type=\"number\"\n domain={['dataMin', 'dataMax']}\n hide={!showTimeAxis}\n tickFormatter={clock}\n {...axis}\n {...(showTimeAxis ? xAxisTitle(xTitle) : {})}\n />\n <YAxis\n domain={[min, max]}\n allowDataOverflow\n // The bottom tick is `min`: keep it.\n interval={0}\n width=\"auto\"\n tickFormatter={formatValue}\n {...axis}\n {...yAxisTitle(yTitle)}\n />\n <Threshold y={warnThreshold} label={warnLabel} color={STATUS_WARN} />\n <Threshold y={critThreshold} label={critLabel} color={STATUS_CRIT} />\n <Tooltip\n content={tooltip}\n cursor={{ stroke: BORDER, strokeDasharray: '4 4' }}\n animationDuration={0}\n />\n <Line\n name=\"value\"\n dataKey=\"value\"\n type=\"monotone\"\n stroke={SERIES[0]}\n strokeWidth={2}\n dot={false}\n activeDot={{ r: 5, fill: PANEL, stroke: SERIES[0], strokeWidth: 2.5 }}\n // A new sample moves the window: no animation, so the line redraws steadily.\n isAnimationActive={false}\n />\n {children}\n </LineChart>\n );\n};\n"]}
|
package/dist/RealtimeChart.js
CHANGED
|
@@ -110,7 +110,7 @@ var RealtimeChart = ({
|
|
|
110
110
|
ariaLabel: ariaLabel ?? "Live values, newest on the right"
|
|
111
111
|
}),
|
|
112
112
|
data: samples,
|
|
113
|
-
margin: { top: 4, right: 12, bottom: 0, left: 0 },
|
|
113
|
+
margin: { top: 4, right: 12, bottom: showTimeAxis ? 0 : 10, left: 0 },
|
|
114
114
|
children: [
|
|
115
115
|
/* @__PURE__ */ jsx(CartesianGrid, { ...GRID_PROPS }),
|
|
116
116
|
/* @__PURE__ */ jsx(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/RealtimeChart.tsx"],"names":[],"mappings":";;;;;;;;;AA8CA,IAAM,KAAA,GAAQ,IAAI,IAAA,CAAK,cAAA,CAAe,OAAA,EAAS;AAAA,EAC7C,IAAA,EAAM,SAAA;AAAA,EACN,MAAA,EAAQ,SAAA;AAAA,EACR,MAAA,EAAQ,SAAA;AAAA,EACR,SAAA,EAAW;AACb,CAAC,CAAA;AACD,IAAM,KAAA,GAAQ,CAAC,SAAA,KAAsB,KAAA,CAAM,OAAO,SAAS,CAAA;AAG3D,IAAM,YAAY,CAAC,EAAE,CAAA,EAAG,KAAA,EAAO,OAAM,qBACnC,GAAA;AAAA,EAAC,aAAA;AAAA,EAAA;AAAA,IACC,CAAA;AAAA,IACA,MAAA,EAAQ,KAAA;AAAA,IACR,WAAA,EAAa,GAAA;AAAA,IACb,eAAA,EAAgB,KAAA;AAAA,IAChB,KAAA,EACE,KAAA,KAAU,EAAA,GACN,MAAA,GACA;AAAA,MACE,KAAA,EAAO,KAAA;AAAA,MACP,QAAA,EAAU,gBAAA;AAAA,MACV,MAAA,EAAQ,CAAA;AAAA;AAAA,MAER,IAAA,EAAM,IAAA;AAAA,MACN,OAAO,EAAE,IAAA,EAAM,MAAM,QAAA,EAAU,SAAA,EAAW,YAAY,GAAA;AAAI;AAC5D;AAER,CAAA;AAIF,IAAM,yBAAyB,MAAM;AACnC,EAAA,IAAI,IAAA,GAAO,EAAA;AACX,EAAA,OAAO,MAAM;AACX,IAAA,IAAA,IAAA,CAAS,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,IAAO,CAAA;AAChC,IAAA,IAAA,GAAO,KAAK,GAAA,CAAI,EAAA,EAAI,KAAK,GAAA,CAAI,EAAA,EAAI,IAAI,CAAC,CAAA;AACtC,IAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EACxB,CAAA;AACF,CAAA;AAEO,IAAM,gBAAgB,CAAC;AAAA,EAC5B,SAAA;AAAA,EACA,UAAA,GAAa,GAAA;AAAA,EACb,UAAA,GAAa,EAAA;AAAA,EACb,GAAA,GAAM,CAAA;AAAA,EACN,GAAA,GAAM,GAAA;AAAA,EACN,aAAA,GAAgB,EAAA;AAAA,EAChB,aAAA,GAAgB,EAAA;AAAA,EAChB,SAAA,GAAY,MAAA;AAAA,EACZ,SAAA,GAAY,MAAA;AAAA,EACZ,YAAA,GAAe,KAAA;AAAA,EACf,MAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA,GAAS,GAAA;AAAA,EACT;AACF,CAAA,KAA0B;AACxB,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,CAAC,gBAAgB,CAAA,GAAI,QAAA,CAAS,sBAAsB,CAAA;AAC1D,EAAA,MAAM,WAAW,SAAA,IAAa,gBAAA;AAG9B,EAAA,MAAM,CAAC,SAAS,CAAA,GAAI,QAAA,CAAS,KAAK,GAAG,CAAA;AACrC,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,QAAA;AAAA,IAAmB,MAC/C,MAAM,IAAA,CAAK,EAAE,QAAQ,UAAA,EAAW,EAAG,CAAC,CAAA,EAAG,KAAA,MAAW;AAAA,MAChD,IAAA,EAAM,SAAA,GAAA,CAAa,UAAA,GAAa,CAAA,GAAI,KAAA,IAAS,UAAA;AAAA,MAC7C,OAAO,QAAA;AAAS,KAClB,CAAE;AAAA,GACJ;AAIA,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,UAAU,CAAA;AACnD,EAAA,IAAI,aAAa,UAAA,EAAY;AAC3B,IAAA,WAAA,CAAY,UAAU,CAAA;AACtB,IAAA,MAAM,OAAA,GAAU,aAAa,OAAA,CAAQ,MAAA;AACrC,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,CAAC,CAAA,EAAG,IAAA,IAAQ,SAAA;AACnC,IAAA,UAAA;AAAA,MACE,WAAW,CAAA,GACP,OAAA,CAAQ,MAAM,OAAA,CAAQ,MAAA,GAAS,UAAU,CAAA,GACzC;AAAA,QACE,GAAG,MAAM,IAAA,CAAK,EAAE,QAAQ,OAAA,EAAQ,EAAG,CAAC,CAAA,EAAG,KAAA,MAAW;AAAA,UAChD,IAAA,EAAM,MAAA,GAAA,CAAU,OAAA,GAAU,KAAA,IAAS,UAAA;AAAA,UACnC,OAAO,QAAA;AAAS,SAClB,CAAE,CAAA;AAAA,QACF,GAAG;AAAA;AACL,KACN;AAAA,EACF;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,EAAA,GAAK,YAAY,MAAM;AAC3B,MAAA,UAAA,CAAW,CAAC,OAAA,KAAY,CAAC,GAAG,OAAA,CAAQ,MAAM,CAAC,CAAA,EAAG,EAAE,IAAA,EAAM,KAAK,GAAA,EAAI,EAAG,OAAO,QAAA,EAAS,EAAG,CAAC,CAAA;AAAA,IACxF,GAAG,UAAU,CAAA;AACb,IAAA,OAAO,MAAM,cAAc,EAAE,CAAA;AAAA,EAC/B,CAAA,EAAG,CAAC,QAAA,EAAU,UAAU,CAAC,CAAA;AAEzB,EAAA,MAAM,SAAS,WAAA,IAAe,MAAA;AAG9B,EAAA,MAAM,OAAA,GAAU,CAAC,EAAE,MAAA,EAAQ,SAAQ,KAAoC;AACrE,IAAA,MAAM,MAAA,GAAS,OAAA,GAAU,CAAC,CAAA,EAAG,OAAA;AAC7B,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ,OAAO,IAAA;AAC/B,IAAA,uBACE,GAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,YAAA,GAAe,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA,GAAI,MAAA;AAAA,QAC3C,IAAA,EAAM,CAAC,EAAE,IAAA,EAAM,SAAS,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA,EAAG,KAAA,EAAO,MAAA,CAAO,CAAC,GAAG;AAAA;AAAA,KACzE;AAAA,EAEJ,CAAA;AAEA,EAAA,uBACE,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACE,GAAG,UAAA,CAAW;AAAA,QACb,MAAA;AAAA,QACA,KAAA;AAAA,QACA,WAAW,SAAA,IAAa;AAAA,OACzB,CAAA;AAAA,MACD,IAAA,EAAM,OAAA;AAAA,MACN,MAAA,EAAQ,EAAE,GAAA,EAAK,CAAA,EAAG,OAAO,EAAA,EAAI,MAAA,EAAQ,CAAA,EAAG,IAAA,EAAM,CAAA,EAAE;AAAA,MAEhD,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,aAAA,EAAA,EAAe,GAAG,UAAA,EAAY,CAAA;AAAA,wBAE/B,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAQ,MAAA;AAAA,YACR,IAAA,EAAK,QAAA;AAAA,YACL,MAAA,EAAQ,CAAC,SAAA,EAAW,SAAS,CAAA;AAAA,YAC7B,MAAM,CAAC,YAAA;AAAA,YACP,aAAA,EAAe,KAAA;AAAA,YACd,GAAG,IAAA;AAAA,YACH,GAAI,YAAA,GAAe,UAAA,CAAW,MAAM,IAAI;AAAC;AAAA,SAC5C;AAAA,wBACA,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAG,CAAA;AAAA,YACjB,iBAAA,EAAiB,IAAA;AAAA,YAEjB,QAAA,EAAU,CAAA;AAAA,YACV,KAAA,EAAM,MAAA;AAAA,YACN,aAAA,EAAe,WAAA;AAAA,YACd,GAAG,IAAA;AAAA,YACH,GAAG,WAAW,MAAM;AAAA;AAAA,SACvB;AAAA,4BACC,SAAA,EAAA,EAAU,CAAA,EAAG,eAAe,KAAA,EAAO,SAAA,EAAW,OAAO,WAAA,EAAa,CAAA;AAAA,4BAClE,SAAA,EAAA,EAAU,CAAA,EAAG,eAAe,KAAA,EAAO,SAAA,EAAW,OAAO,WAAA,EAAa,CAAA;AAAA,wBACnE,GAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,OAAA;AAAA,YACT,MAAA,EAAQ,EAAE,MAAA,EAAQ,MAAA,EAAQ,iBAAiB,KAAA,EAAM;AAAA,YACjD,iBAAA,EAAmB;AAAA;AAAA,SACrB;AAAA,wBACA,GAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,OAAA;AAAA,YACL,OAAA,EAAQ,OAAA;AAAA,YACR,IAAA,EAAK,UAAA;AAAA,YACL,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,YAChB,WAAA,EAAa,CAAA;AAAA,YACb,GAAA,EAAK,KAAA;AAAA,YACL,SAAA,EAAW,EAAE,CAAA,EAAG,CAAA,EAAG,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,MAAA,CAAO,CAAC,CAAA,EAAG,WAAA,EAAa,GAAA,EAAI;AAAA,YAEpE,iBAAA,EAAmB;AAAA;AAAA,SACrB;AAAA,QACC;AAAA;AAAA;AAAA,GACH;AAEJ","file":"RealtimeChart.js","sourcesContent":["import { useEffect, useState } from 'react';\nimport {\n CartesianGrid,\n Line,\n LineChart,\n ReferenceLine,\n Tooltip,\n XAxis,\n YAxis,\n type TooltipContentProps,\n} from 'recharts';\nimport { GRID_PROPS, TEXT_SIZE, useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { TooltipCard } from './core/ChartTooltip';\nimport { BORDER, PANEL, SERIES, STATUS_CRIT, STATUS_WARN, TEXT } from './core/colors';\nimport { frameProps } from './core/frame';\nimport type { ChartAxisTitleProps, ChartProps } from './types';\n\nexport type RealtimeChartProps = ChartProps &\n ChartAxisTitleProps & {\n /** Sample generator — defaults to a noisy walk between 30 and 80. */\n generator?: () => number;\n /** Interval in ms — defaults to 2000. */\n intervalMs?: number;\n windowSize?: number;\n /** Bottom of the y axis. Default 0. */\n min?: number;\n /** Top of the y axis, above `min`. Default 100. */\n max?: number;\n warnThreshold?: number;\n critThreshold?: number;\n /** Text of the warning threshold's label. Default `WARN`; an empty string draws the line alone. */\n warnLabel?: string;\n /** Text of the critical threshold's label. Default `CRIT`; an empty string draws the line alone. */\n critLabel?: string;\n /**\n * Label the x axis with the time of each sample (`14:03:25`, in local time), and the\n * tooltip with it, and `xTitle` has an axis to name. Default off: no x axis.\n */\n showTimeAxis?: boolean;\n /** Format the y-axis labels and the tooltip values. */\n formatValue?: (value: number) => string;\n };\n\ntype Sample = { time: number; value: number };\n\n// The time axis reads as a clock.\nconst CLOCK = new Intl.DateTimeFormat('en-GB', {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hourCycle: 'h23',\n});\nconst clock = (timestamp: number) => CLOCK.format(timestamp);\n\n/** A threshold: a line in its status color, and a label on it unless `label` is empty. */\nconst Threshold = ({ y, label, color }: { y: number; label: string; color: string }) => (\n <ReferenceLine\n y={y}\n stroke={color}\n strokeWidth={1.5}\n strokeDasharray=\"6 4\"\n label={\n label === ''\n ? undefined\n : {\n value: label,\n position: 'insideTopRight',\n offset: 4,\n // Text on the card, whatever the status color: it reads on every theme.\n fill: TEXT,\n style: { fill: TEXT, fontSize: TEXT_SIZE, fontWeight: 600 },\n }\n }\n />\n);\n\n// One walk per chart: a module-level one made every instance continue the last.\nconst createDefaultGenerator = () => {\n let last = 50;\n return () => {\n last += (Math.random() - 0.5) * 8;\n last = Math.max(20, Math.min(95, last));\n return Math.round(last);\n };\n};\n\nexport const RealtimeChart = ({\n generator,\n intervalMs = 2000,\n windowSize = 30,\n min = 0,\n max = 100,\n warnThreshold = 70,\n critThreshold = 85,\n warnLabel = 'WARN',\n critLabel = 'CRIT',\n showTimeAxis = false,\n xTitle,\n yTitle,\n formatValue,\n ariaLabel,\n children,\n height = 240,\n width,\n}: RealtimeChartProps) => {\n const axis = useAxis();\n const [defaultGenerator] = useState(createDefaultGenerator);\n const generate = generator ?? defaultGenerator;\n // Each sample with the time it was taken, for the time axis. A window that\n // starts full is dated as if it had been filled at the sampling pace.\n const [mountedAt] = useState(Date.now);\n const [samples, setSamples] = useState<Sample[]>(() =>\n Array.from({ length: windowSize }, (_, index) => ({\n time: mountedAt - (windowSize - 1 - index) * intervalMs,\n value: generate(),\n }))\n );\n\n // A new windowSize trims the oldest samples or prepends new ones. Adjusted\n // while rendering, which React redoes at once without painting the old window.\n const [sizedFor, setSizedFor] = useState(windowSize);\n if (sizedFor !== windowSize) {\n setSizedFor(windowSize);\n const missing = windowSize - samples.length;\n const oldest = samples[0]?.time ?? mountedAt;\n setSamples(\n missing <= 0\n ? samples.slice(samples.length - windowSize)\n : [\n ...Array.from({ length: missing }, (_, index) => ({\n time: oldest - (missing - index) * intervalMs,\n value: generate(),\n })),\n ...samples,\n ]\n );\n }\n\n useEffect(() => {\n const id = setInterval(() => {\n setSamples((current) => [...current.slice(1), { time: Date.now(), value: generate() }]);\n }, intervalMs);\n return () => clearInterval(id);\n }, [generate, intervalMs]);\n\n const format = formatValue ?? String;\n\n // The card of the sample under the pointer, with its time when the axis shows it.\n const tooltip = ({ active, payload }: Partial<TooltipContentProps>) => {\n const sample = payload?.[0]?.payload as Sample | undefined;\n if (!active || !sample) return null;\n return (\n <TooltipCard\n title={showTimeAxis ? clock(sample.time) : undefined}\n rows={[{ name: 'value', value: format(sample.value), color: SERIES[0] }]}\n />\n );\n };\n\n return (\n <LineChart\n {...frameProps({\n height,\n width,\n ariaLabel: ariaLabel ?? 'Live values, newest on the right',\n })}\n data={samples}\n margin={{ top: 4, right: 12, bottom: 0, left: 0 }}\n >\n <CartesianGrid {...GRID_PROPS} />\n {/* The samples are not on a scale of their own unless the axis is the clock. */}\n <XAxis\n dataKey=\"time\"\n type=\"number\"\n domain={['dataMin', 'dataMax']}\n hide={!showTimeAxis}\n tickFormatter={clock}\n {...axis}\n {...(showTimeAxis ? xAxisTitle(xTitle) : {})}\n />\n <YAxis\n domain={[min, max]}\n allowDataOverflow\n // The bottom tick is `min`: keep it.\n interval={0}\n width=\"auto\"\n tickFormatter={formatValue}\n {...axis}\n {...yAxisTitle(yTitle)}\n />\n <Threshold y={warnThreshold} label={warnLabel} color={STATUS_WARN} />\n <Threshold y={critThreshold} label={critLabel} color={STATUS_CRIT} />\n <Tooltip\n content={tooltip}\n cursor={{ stroke: BORDER, strokeDasharray: '4 4' }}\n animationDuration={0}\n />\n <Line\n name=\"value\"\n dataKey=\"value\"\n type=\"monotone\"\n stroke={SERIES[0]}\n strokeWidth={2}\n dot={false}\n activeDot={{ r: 5, fill: PANEL, stroke: SERIES[0], strokeWidth: 2.5 }}\n // A new sample moves the window: no animation, so the line redraws steadily.\n isAnimationActive={false}\n />\n {children}\n </LineChart>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/RealtimeChart.tsx"],"names":[],"mappings":"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","file":"RealtimeChart.js","sourcesContent":["import { useEffect, useState } from 'react';\nimport {\n CartesianGrid,\n Line,\n LineChart,\n ReferenceLine,\n Tooltip,\n XAxis,\n YAxis,\n type TooltipContentProps,\n} from 'recharts';\nimport { GRID_PROPS, TEXT_SIZE, useAxis, xAxisTitle, yAxisTitle } from './core/axes';\nimport { TooltipCard } from './core/ChartTooltip';\nimport { BORDER, PANEL, SERIES, STATUS_CRIT, STATUS_WARN, TEXT } from './core/colors';\nimport { frameProps } from './core/frame';\nimport type { ChartAxisTitleProps, ChartProps } from './types';\n\nexport type RealtimeChartProps = ChartProps &\n ChartAxisTitleProps & {\n /** Sample generator — defaults to a noisy walk between 30 and 80. */\n generator?: () => number;\n /** Interval in ms — defaults to 2000. */\n intervalMs?: number;\n windowSize?: number;\n /** Bottom of the y axis. Default 0. */\n min?: number;\n /** Top of the y axis, above `min`. Default 100. */\n max?: number;\n warnThreshold?: number;\n critThreshold?: number;\n /** Text of the warning threshold's label. Default `WARN`; an empty string draws the line alone. */\n warnLabel?: string;\n /** Text of the critical threshold's label. Default `CRIT`; an empty string draws the line alone. */\n critLabel?: string;\n /**\n * Label the x axis with the time of each sample (`14:03:25`, in local time), and the\n * tooltip with it, and `xTitle` has an axis to name. Default off: no x axis.\n */\n showTimeAxis?: boolean;\n /** Format the y-axis labels and the tooltip values. */\n formatValue?: (value: number) => string;\n };\n\ntype Sample = { time: number; value: number };\n\n// The time axis reads as a clock.\nconst CLOCK = new Intl.DateTimeFormat('en-GB', {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hourCycle: 'h23',\n});\nconst clock = (timestamp: number) => CLOCK.format(timestamp);\n\n/** A threshold: a line in its status color, and a label on it unless `label` is empty. */\nconst Threshold = ({ y, label, color }: { y: number; label: string; color: string }) => (\n <ReferenceLine\n y={y}\n stroke={color}\n strokeWidth={1.5}\n strokeDasharray=\"6 4\"\n label={\n label === ''\n ? undefined\n : {\n value: label,\n position: 'insideTopRight',\n offset: 4,\n // Text on the card, whatever the status color: it reads on every theme.\n fill: TEXT,\n style: { fill: TEXT, fontSize: TEXT_SIZE, fontWeight: 600 },\n }\n }\n />\n);\n\n// One walk per chart: a module-level one made every instance continue the last.\nconst createDefaultGenerator = () => {\n let last = 50;\n return () => {\n last += (Math.random() - 0.5) * 8;\n last = Math.max(20, Math.min(95, last));\n return Math.round(last);\n };\n};\n\nexport const RealtimeChart = ({\n generator,\n intervalMs = 2000,\n windowSize = 30,\n min = 0,\n max = 100,\n warnThreshold = 70,\n critThreshold = 85,\n warnLabel = 'WARN',\n critLabel = 'CRIT',\n showTimeAxis = false,\n xTitle,\n yTitle,\n formatValue,\n ariaLabel,\n children,\n height = 240,\n width,\n}: RealtimeChartProps) => {\n const axis = useAxis();\n const [defaultGenerator] = useState(createDefaultGenerator);\n const generate = generator ?? defaultGenerator;\n // Each sample with the time it was taken, for the time axis. A window that\n // starts full is dated as if it had been filled at the sampling pace.\n const [mountedAt] = useState(Date.now);\n const [samples, setSamples] = useState<Sample[]>(() =>\n Array.from({ length: windowSize }, (_, index) => ({\n time: mountedAt - (windowSize - 1 - index) * intervalMs,\n value: generate(),\n }))\n );\n\n // A new windowSize trims the oldest samples or prepends new ones. Adjusted\n // while rendering, which React redoes at once without painting the old window.\n const [sizedFor, setSizedFor] = useState(windowSize);\n if (sizedFor !== windowSize) {\n setSizedFor(windowSize);\n const missing = windowSize - samples.length;\n const oldest = samples[0]?.time ?? mountedAt;\n setSamples(\n missing <= 0\n ? samples.slice(samples.length - windowSize)\n : [\n ...Array.from({ length: missing }, (_, index) => ({\n time: oldest - (missing - index) * intervalMs,\n value: generate(),\n })),\n ...samples,\n ]\n );\n }\n\n useEffect(() => {\n const id = setInterval(() => {\n setSamples((current) => [...current.slice(1), { time: Date.now(), value: generate() }]);\n }, intervalMs);\n return () => clearInterval(id);\n }, [generate, intervalMs]);\n\n const format = formatValue ?? String;\n\n // The card of the sample under the pointer, with its time when the axis shows it.\n const tooltip = ({ active, payload }: Partial<TooltipContentProps>) => {\n const sample = payload?.[0]?.payload as Sample | undefined;\n if (!active || !sample) return null;\n return (\n <TooltipCard\n title={showTimeAxis ? clock(sample.time) : undefined}\n rows={[{ name: 'value', value: format(sample.value), color: SERIES[0] }]}\n />\n );\n };\n\n return (\n <LineChart\n {...frameProps({\n height,\n width,\n ariaLabel: ariaLabel ?? 'Live values, newest on the right',\n })}\n data={samples}\n // The label of the lowest value is centred on the bottom edge of the plot: without the time\n // axis under it, the chart keeps room for its lower half, which was cut.\n margin={{ top: 4, right: 12, bottom: showTimeAxis ? 0 : 10, left: 0 }}\n >\n <CartesianGrid {...GRID_PROPS} />\n {/* The samples are not on a scale of their own unless the axis is the clock. */}\n <XAxis\n dataKey=\"time\"\n type=\"number\"\n domain={['dataMin', 'dataMax']}\n hide={!showTimeAxis}\n tickFormatter={clock}\n {...axis}\n {...(showTimeAxis ? xAxisTitle(xTitle) : {})}\n />\n <YAxis\n domain={[min, max]}\n allowDataOverflow\n // The bottom tick is `min`: keep it.\n interval={0}\n width=\"auto\"\n tickFormatter={formatValue}\n {...axis}\n {...yAxisTitle(yTitle)}\n />\n <Threshold y={warnThreshold} label={warnLabel} color={STATUS_WARN} />\n <Threshold y={critThreshold} label={critLabel} color={STATUS_CRIT} />\n <Tooltip\n content={tooltip}\n cursor={{ stroke: BORDER, strokeDasharray: '4 4' }}\n animationDuration={0}\n />\n <Line\n name=\"value\"\n dataKey=\"value\"\n type=\"monotone\"\n stroke={SERIES[0]}\n strokeWidth={2}\n dot={false}\n activeDot={{ r: 5, fill: PANEL, stroke: SERIES[0], strokeWidth: 2.5 }}\n // A new sample moves the window: no animation, so the line redraws steadily.\n isAnimationActive={false}\n />\n {children}\n </LineChart>\n );\n};\n"]}
|
package/dist/ScatterChart.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkRGDENOKY_cjs = require('./chunk-RGDENOKY.cjs');
|
|
5
5
|
var chunkRCDTBZC2_cjs = require('./chunk-RCDTBZC2.cjs');
|
|
6
6
|
var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
|
|
7
7
|
var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
|
|
@@ -115,7 +115,7 @@ var XYChart = ({
|
|
|
115
115
|
chunkK3R7JGOW_cjs.seriesKey(index)
|
|
116
116
|
);
|
|
117
117
|
}),
|
|
118
|
-
|
|
118
|
+
chunkRGDENOKY_cjs.referenceMarks({ referenceLines, referenceBands }),
|
|
119
119
|
children
|
|
120
120
|
]
|
|
121
121
|
}
|
package/dist/ScatterChart.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { referenceMarks } from './chunk-
|
|
2
|
+
import { referenceMarks } from './chunk-RXCGQ5QQ.js';
|
|
3
3
|
import { useHiddenSeries, legendProps } from './chunk-4AKHZNWP.js';
|
|
4
4
|
import { ANIMATION } from './chunk-5C2RLJYZ.js';
|
|
5
5
|
import { useAxis, xAxisTitle, yAxisTitle } from './chunk-DI2FBGKM.js';
|