basalt-ui 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/MIGRATING.md +78 -12
- package/agent/rules/basalt-state.md +1 -1
- package/configs/lefthook.yml +4 -1
- package/dist/charts/BandStrip.d.ts +7 -7
- package/dist/charts/BandStrip.d.ts.map +1 -1
- package/dist/charts/Bars.d.ts +4 -4
- package/dist/charts/Bars.d.ts.map +1 -1
- package/dist/charts/CartesianChart.d.ts.map +1 -1
- package/dist/charts/CartesianChart.js +6 -2
- package/dist/charts/ChartCard.d.ts +10 -10
- package/dist/charts/ChartCard.d.ts.map +1 -1
- package/dist/charts/ChartCard.js +2 -1
- package/dist/charts/Donut.d.ts +5 -5
- package/dist/charts/Donut.d.ts.map +1 -1
- package/dist/charts/DualPanel.d.ts +14 -10
- package/dist/charts/DualPanel.d.ts.map +1 -1
- package/dist/charts/DualPanel.js +32 -14
- package/dist/charts/Heatmap.d.ts +15 -15
- package/dist/charts/Heatmap.d.ts.map +1 -1
- package/dist/charts/Heatmap.js +2 -2
- package/dist/charts/Lines.js +2 -2
- package/dist/charts/MirroredBars.d.ts +9 -9
- package/dist/charts/MirroredBars.d.ts.map +1 -1
- package/dist/charts/MirroredBars.js +8 -7
- package/dist/charts/Sparkline.d.ts +6 -6
- package/dist/charts/Sparkline.d.ts.map +1 -1
- package/dist/charts/StackedArea.d.ts +2 -2
- package/dist/charts/StackedArea.d.ts.map +1 -1
- package/dist/charts/compile.d.ts +25 -2
- package/dist/charts/compile.d.ts.map +1 -1
- package/dist/charts/compile.js +204 -34
- package/dist/charts/index.d.ts +1 -0
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/index.js +3 -1
- package/dist/charts/marks.d.ts +8 -0
- package/dist/charts/marks.d.ts.map +1 -1
- package/dist/charts/marks.js +22 -1
- package/dist/charts/panel.js +2 -2
- package/dist/charts/types.d.ts +101 -61
- package/dist/charts/types.d.ts.map +1 -1
- package/dist/state/fields.d.ts +19 -3
- package/dist/state/fields.d.ts.map +1 -1
- package/dist/state/fields.js +14 -8
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/src/charts/BandStrip.tsx +12 -10
- package/src/charts/Bars.tsx +4 -4
- package/src/charts/CartesianChart.tsx +7 -2
- package/src/charts/ChartCard.tsx +17 -11
- package/src/charts/Donut.tsx +5 -5
- package/src/charts/DualPanel.tsx +50 -21
- package/src/charts/Heatmap.tsx +14 -14
- package/src/charts/Lines.tsx +2 -2
- package/src/charts/MirroredBars.tsx +16 -15
- package/src/charts/Sparkline.tsx +6 -6
- package/src/charts/StackedArea.tsx +2 -2
- package/src/charts/compile.ts +285 -36
- package/src/charts/index.ts +1 -0
- package/src/charts/marks.ts +35 -1
- package/src/charts/panel.tsx +2 -2
- package/src/charts/types.ts +105 -57
- package/src/state/fields.ts +55 -19
package/dist/charts/Heatmap.js
CHANGED
|
@@ -9,7 +9,7 @@ import { scaleQuantize } from "d3-scale";
|
|
|
9
9
|
import { useId, useMemo } from "react";
|
|
10
10
|
import { alpha, VX } from "../tokens/index.js";
|
|
11
11
|
import { resolveContainerClass } from "../tokens/size-classes.js";
|
|
12
|
-
import { strideTicks } from "./compile.js";
|
|
12
|
+
import { engineRow, strideTicks } from "./compile.js";
|
|
13
13
|
import { ChartEngine, idPrefixOf } from "./host.js";
|
|
14
14
|
import { useCoarsePointer } from "../common/use-media-query.js";
|
|
15
15
|
import { HEIGHT_MAX, HEIGHT_MIN } from "./box.js";
|
|
@@ -176,7 +176,7 @@ function Heatmap(props) {
|
|
|
176
176
|
...point.color && { color: point.color }
|
|
177
177
|
}
|
|
178
178
|
];
|
|
179
|
-
return { title: header(c), rows: [...value, ...extra] };
|
|
179
|
+
return { title: header(c), rows: [...value, ...extra].map(engineRow) };
|
|
180
180
|
}
|
|
181
181
|
} : false
|
|
182
182
|
};
|
package/dist/charts/Lines.js
CHANGED
|
@@ -8,7 +8,7 @@ import { VX } from "../tokens/index.js";
|
|
|
8
8
|
import { CartesianRung } from "./CartesianChart.js";
|
|
9
9
|
import { areaGradientId } from "./compile.js";
|
|
10
10
|
import { chartCurve } from "./curves.js";
|
|
11
|
-
import { lineMark, markersOf, yScaleOf } from "./marks.js";
|
|
11
|
+
import { drawnRows, lineMark, markersOf, yScaleOf } from "./marks.js";
|
|
12
12
|
import { rowX } from "./types.js";
|
|
13
13
|
const MAX_END_LABELS = 3;
|
|
14
14
|
const END_LABEL_MIN_GAP = 13;
|
|
@@ -80,7 +80,7 @@ function Lines(props) {
|
|
|
80
80
|
if (!s.area) continue;
|
|
81
81
|
out.push(
|
|
82
82
|
decorative(
|
|
83
|
-
areaY(plot
|
|
83
|
+
areaY(drawnRows(plot, s), {
|
|
84
84
|
id: `${s.key}-area`,
|
|
85
85
|
x: rowX,
|
|
86
86
|
y2: "y",
|
|
@@ -6,11 +6,11 @@ export type MirroredBarPane = {
|
|
|
6
6
|
* entry throws: the pane would vanish, which reads as a measured zero. */
|
|
7
7
|
key: string;
|
|
8
8
|
/** The pane's upper bound. `'auto'` (default) is its own visible maximum; a number pins it. */
|
|
9
|
-
max?: number | 'auto';
|
|
9
|
+
max?: number | 'auto' | undefined;
|
|
10
10
|
/** When `'auto'`: floors the upper bound, so a quiet window does not amplify noise to full height. */
|
|
11
|
-
autoMaxFloor?: number;
|
|
11
|
+
autoMaxFloor?: number | undefined;
|
|
12
12
|
/** Tick count for this pane's own axis. Default 3. */
|
|
13
|
-
ticks?: number;
|
|
13
|
+
ticks?: number | undefined;
|
|
14
14
|
/** Tick and tooltip formatter, in the pane's OWN units. */
|
|
15
15
|
format: (v: number) => string;
|
|
16
16
|
};
|
|
@@ -24,21 +24,21 @@ export type MirroredBarsProps<T, X extends ChartX = ChartX> = Pick<CartesianChar
|
|
|
24
24
|
/** Drawn below the baseline. */
|
|
25
25
|
down: MirroredBarPane;
|
|
26
26
|
/** The up pane's share of the height. Default 0.35: the pair is usually asymmetric. */
|
|
27
|
-
upFraction?: number;
|
|
27
|
+
upFraction?: number | undefined;
|
|
28
28
|
/** 0..1 of a bar's width that no source sample covers, drawn neutral across both panes. */
|
|
29
|
-
getAbsentFraction?: (d: T) => number;
|
|
29
|
+
getAbsentFraction?: ((d: T) => number) | undefined;
|
|
30
30
|
/** Per-datum bar opacity: a real but qualified measurement (a short bucket) drawn dimmer. */
|
|
31
|
-
getBarOpacity?: (d: T) => number;
|
|
31
|
+
getBarOpacity?: ((d: T) => number) | undefined;
|
|
32
32
|
/**
|
|
33
33
|
* Collapse adjacent data where one band per datum would be sub-pixel. `merge` is the consumer's
|
|
34
34
|
* (max, sum, or a rate from summed parts) and must keep `group[0]`'s x, the slot start.
|
|
35
35
|
*/
|
|
36
36
|
fold?: {
|
|
37
|
-
minBandPx?: number;
|
|
37
|
+
minBandPx?: number | undefined;
|
|
38
38
|
merge: (group: T[]) => T;
|
|
39
|
-
};
|
|
39
|
+
} | undefined;
|
|
40
40
|
/** Default `'leading'`: x is a slot's start. */
|
|
41
|
-
cursorResolution?: CartesianChartProps<T, X>['cursorResolution'];
|
|
41
|
+
cursorResolution?: CartesianChartProps<T, X>['cursorResolution'] | undefined;
|
|
42
42
|
};
|
|
43
43
|
export declare function MirroredBars<T, X extends ChartX = ChartX>(props: MirroredBarsProps<T, X>): ReactElement;
|
|
44
44
|
//# sourceMappingURL=MirroredBars.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MirroredBars.d.ts","sourceRoot":"","sources":["../../src/charts/MirroredBars.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AASzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,EAAW,MAAM,SAAS,CAAA;AAEhF,4BAA4B;AAC5B,MAAM,MAAM,eAAe,GAAG;IAC5B;8EAC0E;IAC1E,GAAG,EAAE,MAAM,CAAA;IACX,+FAA+F;IAC/F,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"MirroredBars.d.ts","sourceRoot":"","sources":["../../src/charts/MirroredBars.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AASzC,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,EAAW,MAAM,SAAS,CAAA;AAEhF,4BAA4B;AAC5B,MAAM,MAAM,eAAe,GAAG;IAC5B;8EAC0E;IAC1E,GAAG,EAAE,MAAM,CAAA;IACX,+FAA+F;IAC/F,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACjC,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,2DAA2D;IAC3D,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC9B,CAAA;AAED,oGAAoG;AACpG,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,IAAI,CACtC,WAAW,CAAC,CAAC,CAAC,EACd,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAChG,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,IAAI,CAChE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,WAAW,GACX,MAAM,GACN,GAAG,GACH,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,aAAa,GACb,SAAS,GACT,WAAW,GACX,OAAO,CACV,GAAG;IACF,qEAAqE;IACrE,MAAM,EAAE,SAAS,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAA;IACxC,gCAAgC;IAChC,EAAE,EAAE,eAAe,CAAA;IACnB,gCAAgC;IAChC,IAAI,EAAE,eAAe,CAAA;IACrB,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,2FAA2F;IAC3F,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IAClD,6FAA6F;IAC7F,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;IAC9C;;;OAGG;IACH,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAA;KAAE,GAAG,SAAS,CAAA;IAC/E,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAA;CAC7E,CAAA;AAgDD,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,EACvD,KAAK,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC7B,YAAY,CAwKd"}
|
|
@@ -6,7 +6,7 @@ import { scaleLinear } from "@tanstack/charts/scales/linear";
|
|
|
6
6
|
import { useCallback, useMemo } from "react";
|
|
7
7
|
import { VX, alpha } from "../tokens/index.js";
|
|
8
8
|
import { resolveContainerClass } from "../tokens/size-classes.js";
|
|
9
|
-
import { defaultFormatX, defaultNumberFormat, visibleSeries } from "./compile.js";
|
|
9
|
+
import { defaultFormatX, defaultNumberFormat, seriesRow, visibleSeries } from "./compile.js";
|
|
10
10
|
import { barMark, emphasis } from "./marks.js";
|
|
11
11
|
import { PanelRung, paneX, paneY, rowsOf } from "./panel.js";
|
|
12
12
|
import { xScaleFor } from "./scales.js";
|
|
@@ -161,12 +161,13 @@ function MirroredBars(props) {
|
|
|
161
161
|
const v = s.getValue(d);
|
|
162
162
|
if (s.tooltip === false || v === null || !Number.isFinite(v)) continue;
|
|
163
163
|
const fallback = s.key === up.key ? up.format : s.key === down.key ? down.format : defaultNumberFormat;
|
|
164
|
-
out.push(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
164
|
+
out.push(
|
|
165
|
+
seriesRow(
|
|
166
|
+
s,
|
|
167
|
+
s.formatValue ? s.formatValue(v, d) : fallback(v),
|
|
168
|
+
highlighted === s.key
|
|
169
|
+
)
|
|
170
|
+
);
|
|
170
171
|
}
|
|
171
172
|
return out;
|
|
172
173
|
}
|
|
@@ -8,18 +8,18 @@ export type SparklineProps = BasaltProps & {
|
|
|
8
8
|
/** Height in px. */
|
|
9
9
|
height: number;
|
|
10
10
|
/** Width in px. Default: the container's, measured by the host. */
|
|
11
|
-
width?: number;
|
|
11
|
+
width?: number | undefined;
|
|
12
12
|
/** Default `'line'`. */
|
|
13
|
-
mark?: 'line' | 'bar';
|
|
13
|
+
mark?: 'line' | 'bar' | undefined;
|
|
14
14
|
/** A `VX.*` ref or a series token. Default `VX.faint`. */
|
|
15
|
-
color?: string;
|
|
15
|
+
color?: string | undefined;
|
|
16
16
|
/** Paints the last point in `emphasisColor` — the one reading a trend beside a KPI is for. */
|
|
17
|
-
emphasizeLast?: boolean;
|
|
17
|
+
emphasizeLast?: boolean | undefined;
|
|
18
18
|
/** Default `VX.accent`. */
|
|
19
|
-
emphasisColor?: string;
|
|
19
|
+
emphasisColor?: string | undefined;
|
|
20
20
|
/** Pending / error / empty, the same contract as every other kind. The placeholder fills the
|
|
21
21
|
* sparkline's own `width` × `height`, so a loading tile does not shift when the trend lands. */
|
|
22
|
-
state?: ChartState;
|
|
22
|
+
state?: ChartState | undefined;
|
|
23
23
|
};
|
|
24
24
|
/** `useId` output (`«r1»`, `:r1:`) is not a safe SVG id fragment. */
|
|
25
25
|
export declare function Sparkline(props: SparklineProps): ReactElement;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sparkline.d.ts","sourceRoot":"","sources":["../../src/charts/Sparkline.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAQlD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IACvB,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"Sparkline.d.ts","sourceRoot":"","sources":["../../src/charts/Sparkline.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAQlD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACzC,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IACvB,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAA;IACjC,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,8FAA8F;IAC9F,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACnC,2BAA2B;IAC3B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC;oGACgG;IAChG,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;CAC/B,CAAA;AAiGD,qEAAqE;AAErE,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CAyC7D"}
|
|
@@ -3,13 +3,13 @@ import type { CartesianChartProps, ChartSeries, ChartX } from './types.js';
|
|
|
3
3
|
/** A band. Stacked areas read the left axis and draw no line, so the line fields are absent. */
|
|
4
4
|
export type StackedAreaBand<T> = Pick<ChartSeries<T>, 'key' | 'label' | 'color' | 'getValue' | 'formatValue' | 'tooltip' | 'legend' | 'role' | 'note'> & {
|
|
5
5
|
/** Default 0.85. */
|
|
6
|
-
fillOpacity?: number;
|
|
6
|
+
fillOpacity?: number | undefined;
|
|
7
7
|
};
|
|
8
8
|
export type StackedAreaProps<T, X extends ChartX = ChartX> = Omit<CartesianChartProps<T, X>, 'marks' | 'y' | 'y2' | 'series'> & {
|
|
9
9
|
/** The bands, bottom to top. */
|
|
10
10
|
series: readonly StackedAreaBand<T>[];
|
|
11
11
|
/** No `scale`: a log axis has no additive zero to stack from. */
|
|
12
|
-
y?: Omit<NonNullable<CartesianChartProps<T, X>['y']>, 'scale'
|
|
12
|
+
y?: Omit<NonNullable<CartesianChartProps<T, X>['y']>, 'scale'> | undefined;
|
|
13
13
|
};
|
|
14
14
|
export declare function StackedArea<T, X extends ChartX = ChartX>(props: StackedAreaProps<T, X>): ReactElement;
|
|
15
15
|
//# sourceMappingURL=StackedArea.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StackedArea.d.ts","sourceRoot":"","sources":["../../src/charts/StackedArea.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAKzC,OAAO,KAAK,EAAE,mBAAmB,EAAc,WAAW,EAAE,MAAM,EAAe,MAAM,SAAS,CAAA;AAIhG,gGAAgG;AAChG,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,IAAI,CACnC,WAAW,CAAC,CAAC,CAAC,EACd,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAChG,GAAG;IACF,oBAAoB;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"StackedArea.d.ts","sourceRoot":"","sources":["../../src/charts/StackedArea.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAKzC,OAAO,KAAK,EAAE,mBAAmB,EAAc,WAAW,EAAE,MAAM,EAAe,MAAM,SAAS,CAAA;AAIhG,gGAAgG;AAChG,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,IAAI,CACnC,WAAW,CAAC,CAAC,CAAC,EACd,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAChG,GAAG;IACF,oBAAoB;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,IAAI,CAC/D,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,EACzB,OAAO,GAAG,GAAG,GAAG,IAAI,GAAG,QAAQ,CAChC,GAAG;IACF,gCAAgC;IAChC,MAAM,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAA;IACrC,iEAAiE;IACjE,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;CAC3E,CAAA;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,EACtD,KAAK,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC5B,YAAY,CAqCd"}
|
package/dist/charts/compile.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ChartGradient, ChartPositionScaleOptions, ChartValue, ResponsiveChartDefinition } from '@tanstack/charts/types/core';
|
|
1
|
+
import type { ChartGradient, ChartPositionScaleOptions, ChartTooltipRow as EngineTooltipRow, ChartValue, ResponsiveChartDefinition } from '@tanstack/charts/types/core';
|
|
2
2
|
import type { ContainerClass } from '../tokens/size-classes.js';
|
|
3
3
|
import type { XScaleModel } from './scales.js';
|
|
4
|
-
import type { AxisConfig, CartesianChartProps, ChartSeries, ChartX } from './types.js';
|
|
4
|
+
import type { AxisConfig, CartesianChartProps, ChartSeries, ChartTooltipRow, ChartX, RefLine, ZoneSpec } from './types.js';
|
|
5
5
|
/**
|
|
6
6
|
* The compiled definition. Annotated on purpose: TanStack's inferred definition type names internal
|
|
7
7
|
* modules (`dist/scene`, `cursor-host-contract`) and fails declaration emit (TS2883 / TS4058).
|
|
@@ -35,6 +35,19 @@ export declare function utcHeaderDate(d: Date): string;
|
|
|
35
35
|
*/
|
|
36
36
|
export declare function dateTicks(domain: readonly [Date, Date], count: number, stepMs: number): Date[];
|
|
37
37
|
export declare function defaultFormatX(v: ChartValue): string;
|
|
38
|
+
/**
|
|
39
|
+
* A tooltip swatch is the engine's `background` shorthand, so a dashed one is a gradient: a 2px
|
|
40
|
+
* dashed line across the swatch's middle, in the row color.
|
|
41
|
+
*/
|
|
42
|
+
export declare const dashedSwatch: (color: string) => string;
|
|
43
|
+
/** A basalt tooltip row as the engine's: the swatch shape folded into the row color. */
|
|
44
|
+
export declare function engineRow(row: ChartTooltipRow & {
|
|
45
|
+
active?: boolean | undefined;
|
|
46
|
+
}): EngineTooltipRow;
|
|
47
|
+
/** A series row of a tooltip: the label with its note, the swatch following the series' dash. */
|
|
48
|
+
export declare function seriesRow(s: Pick<ChartSeries<never>, 'label' | 'note' | 'color' | 'dash'>, value: string, active: boolean): EngineTooltipRow;
|
|
49
|
+
/** Legend-only entries for the reference lines that name themselves, in line order. */
|
|
50
|
+
export declare function refLegendSeries<T>(refLines: readonly RefLine[] | undefined): ChartSeries<T>[];
|
|
38
51
|
/** The visible series: not toggled off, and not a companion whose parent is. */
|
|
39
52
|
export declare function visibleSeries<T>(series: readonly ChartSeries<T>[], hidden: ReadonlySet<string>): ChartSeries<T>[];
|
|
40
53
|
type YAxis = {
|
|
@@ -63,6 +76,16 @@ export declare function xGuide<X extends ChartX>(opts: {
|
|
|
63
76
|
/** Gradient resource id for a series' area fill; the host's `idPrefix` scopes it per chart. */
|
|
64
77
|
export declare const areaGradientId: (index: number) => string;
|
|
65
78
|
export declare function areaGradient(index: number, color: string): ChartGradient;
|
|
79
|
+
/**
|
|
80
|
+
* A series area filled by value zone: a vertical gradient whose stops sit at the zone boundaries.
|
|
81
|
+
* The engine writes `<linearGradient>` in the default `objectBoundingBox` units, so offsets are
|
|
82
|
+
* fractions of the AREA's own box, not of the plot: from the larger of the series' maximum and 0 down
|
|
83
|
+
* to the smaller of its minimum and 0, the baseline the area closes to even when the y domain
|
|
84
|
+
* excludes 0. A boundary at value `v` sits at `(ceiling - v) / (ceiling - floor)`. Hard edges:
|
|
85
|
+
* neighbouring zones meet at one offset; overlapping zones never run backwards. `null` when no zone
|
|
86
|
+
* reaches the area (the caller keeps the plain series-colour fade). Linear axes only.
|
|
87
|
+
*/
|
|
88
|
+
export declare function zoneAreaGradient(index: number, zones: readonly ZoneSpec[], values: readonly (number | null)[]): ChartGradient | null;
|
|
66
89
|
export declare function compileCartesian<T, X extends ChartX>(input: CartesianInput<T, X>): CartesianDefinition;
|
|
67
90
|
export {};
|
|
68
91
|
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/charts/compile.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAEV,aAAa,EAEb,yBAAyB,
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/charts/compile.ts"],"names":[],"mappings":"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"}
|
package/dist/charts/compile.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { crosshair } from "@tanstack/charts/crosshair";
|
|
2
2
|
import { decorative } from "@tanstack/charts/mark/decorative";
|
|
3
3
|
import { rect } from "@tanstack/charts/rect";
|
|
4
|
-
import { ruleY } from "@tanstack/charts/rule";
|
|
4
|
+
import { ruleX, ruleY } from "@tanstack/charts/rule";
|
|
5
5
|
import { scaleLinear } from "@tanstack/charts/scales/linear";
|
|
6
6
|
import { scaleUtc } from "d3-scale";
|
|
7
7
|
import { tooltip as tooltipHost } from "@tanstack/charts/tooltip";
|
|
@@ -9,6 +9,7 @@ import { portal } from "@tanstack/charts/tooltip/portal";
|
|
|
9
9
|
import { fmtCompact } from "../format/number.js";
|
|
10
10
|
import { VX } from "../tokens/index.js";
|
|
11
11
|
import { cursorBinding, sourceOnlyFocus } from "./cursor.js";
|
|
12
|
+
import { cursorDots } from "./marks.js";
|
|
12
13
|
import { resolveContainerClass } from "../tokens/size-classes.js";
|
|
13
14
|
import { resolveYDomain, xScaleFor, xZoneFractions, yScaleFor } from "./scales.js";
|
|
14
15
|
import { AXIS_LINE, CHART_THEME, CROSSHAIR, DASH, GRID_LINE } from "./theme.js";
|
|
@@ -47,6 +48,43 @@ function defaultFormatX(v) {
|
|
|
47
48
|
return String(v);
|
|
48
49
|
}
|
|
49
50
|
const clampTo = (v, [lo, hi]) => Math.min(Math.max(v, Math.min(lo, hi)), Math.max(lo, hi));
|
|
51
|
+
const dashedSwatch = (color) => `repeating-linear-gradient(90deg, ${color} 0 2px, transparent 2px 4px) center / 100% 2px no-repeat`;
|
|
52
|
+
function engineRow(row) {
|
|
53
|
+
const { label, value, color, swatch, active } = row;
|
|
54
|
+
return {
|
|
55
|
+
label,
|
|
56
|
+
value,
|
|
57
|
+
...color !== void 0 && { color: swatch === "dashed" ? dashedSwatch(color) : color },
|
|
58
|
+
...active && { active }
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function seriesRow(s, value, active) {
|
|
62
|
+
return engineRow({
|
|
63
|
+
label: s.note === void 0 ? s.label : `${s.label} \xB7 ${s.note}`,
|
|
64
|
+
value,
|
|
65
|
+
color: s.color,
|
|
66
|
+
swatch: s.dash === "dashed" ? "dashed" : "solid",
|
|
67
|
+
active
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const REF_KEY_PREFIX = "__ref-";
|
|
71
|
+
const refLegendKey = (index) => `${REF_KEY_PREFIX}${index}`;
|
|
72
|
+
function refLegendSeries(refLines) {
|
|
73
|
+
return (refLines ?? []).flatMap(
|
|
74
|
+
(r, i) => r.legend === void 0 ? [] : [
|
|
75
|
+
{
|
|
76
|
+
key: refLegendKey(i),
|
|
77
|
+
label: r.legend.label,
|
|
78
|
+
color: r.color,
|
|
79
|
+
role: "reference",
|
|
80
|
+
tooltip: false,
|
|
81
|
+
getValue: () => null,
|
|
82
|
+
...r.legend.mark !== void 0 && { mark: r.legend.mark },
|
|
83
|
+
...r.dashed && { dash: "dashed" }
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
);
|
|
87
|
+
}
|
|
50
88
|
function visibleSeries(series, hidden) {
|
|
51
89
|
return series.filter(
|
|
52
90
|
(s) => !hidden.has(s.key) && !(s.parent !== void 0 && hidden.has(s.parent))
|
|
@@ -124,6 +162,54 @@ function areaGradient(index, color) {
|
|
|
124
162
|
]
|
|
125
163
|
};
|
|
126
164
|
}
|
|
165
|
+
const areaTint = (color) => `color-mix(in srgb, ${color} var(--vx-area-top), transparent)`;
|
|
166
|
+
function zoneAreaGradient(index, zones, values) {
|
|
167
|
+
let floor = 0;
|
|
168
|
+
let ceiling = 0;
|
|
169
|
+
for (const v of values) {
|
|
170
|
+
if (v === null || !Number.isFinite(v)) continue;
|
|
171
|
+
if (v < floor) floor = v;
|
|
172
|
+
if (v > ceiling) ceiling = v;
|
|
173
|
+
}
|
|
174
|
+
const span = ceiling - floor;
|
|
175
|
+
if (span <= 0) return null;
|
|
176
|
+
const offsetOf = (v) => (ceiling - Math.min(ceiling, Math.max(floor, v))) / span;
|
|
177
|
+
const reaching = zones.filter((z) => !Number.isNaN(z.from) && !Number.isNaN(z.to) && z.to > floor && z.from < ceiling).toSorted((p, q) => q.to - p.to);
|
|
178
|
+
let previous = 0;
|
|
179
|
+
const stops = reaching.flatMap(
|
|
180
|
+
(z) => [offsetOf(z.to), offsetOf(z.from)].map((raw) => {
|
|
181
|
+
previous = Math.max(previous, raw);
|
|
182
|
+
return { offset: previous, color: areaTint(z.fill) };
|
|
183
|
+
})
|
|
184
|
+
);
|
|
185
|
+
if (stops.length === 0) return null;
|
|
186
|
+
return { id: areaGradientId(index), x1: 0, y1: 0, x2: 0, y2: 1, stops };
|
|
187
|
+
}
|
|
188
|
+
let warnedLogZones = false;
|
|
189
|
+
function guardLogZones(onLog) {
|
|
190
|
+
if (!onLog) return false;
|
|
191
|
+
const message = "area: 'zones' cannot use a log axis; use area: true";
|
|
192
|
+
if (process.env.NODE_ENV !== "production") throw new Error(message);
|
|
193
|
+
if (!warnedLogZones) console.error(message);
|
|
194
|
+
warnedLogZones = true;
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
function seriesAreaGradient(s, index, input, axes) {
|
|
198
|
+
const plain = areaGradient(
|
|
199
|
+
index,
|
|
200
|
+
typeof s.area === "string" && s.area !== "zones" ? s.area : s.color
|
|
201
|
+
);
|
|
202
|
+
if (s.area !== "zones") return plain;
|
|
203
|
+
const side = axes.onRight(s) ? "right" : "left";
|
|
204
|
+
const axisConfig = side === "right" ? input.y2 : input.y;
|
|
205
|
+
if (guardLogZones(axisConfig?.scale === "log")) return plain;
|
|
206
|
+
const zones = (input.zones ?? []).filter((z) => axes.scaleId(z.axisSide) === axes.scaleId(side));
|
|
207
|
+
return zoneAreaGradient(
|
|
208
|
+
index,
|
|
209
|
+
zones,
|
|
210
|
+
input.data.map((d) => s.getValue(d))
|
|
211
|
+
) ?? plain;
|
|
212
|
+
}
|
|
127
213
|
const isBar = (s) => s.mark === "bar";
|
|
128
214
|
const STACK_POSITIVE_KEY = "__stack+";
|
|
129
215
|
const STACK_NEGATIVE_KEY = "__stack-";
|
|
@@ -193,27 +279,73 @@ function resolveAxes(input, visible) {
|
|
|
193
279
|
scaleId: (side) => side === "right" && hasY2 ? "y2" : "y"
|
|
194
280
|
};
|
|
195
281
|
}
|
|
282
|
+
const edgeSides = (edge, lower, upper) => ({
|
|
283
|
+
lower: edge !== void 0 && (edge.side === lower || edge.side === "both"),
|
|
284
|
+
upper: edge !== void 0 && (edge.side === upper || edge.side === "both")
|
|
285
|
+
});
|
|
286
|
+
const edgePaint = (edge) => ({
|
|
287
|
+
stroke: edge.color,
|
|
288
|
+
strokeOpacity: 1,
|
|
289
|
+
strokeWidth: edge.width ?? 1,
|
|
290
|
+
...edge.dashed && { strokeDasharray: DASH }
|
|
291
|
+
});
|
|
292
|
+
const edgeRule = (position, [lo, hi], make) => position !== null && position > lo && position < hi ? [make(position)] : [];
|
|
196
293
|
function underlayMarks(input, model, axes) {
|
|
197
294
|
const fractionRows = [{ f0: 0, f1: 1 }];
|
|
198
|
-
const zones = (input.zones ?? []).
|
|
295
|
+
const zones = (input.zones ?? []).flatMap((z, i) => {
|
|
199
296
|
const domain = axes.axisOf(z.axisSide).domain;
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
})
|
|
297
|
+
const [lo, hi] = [Math.min(...domain), Math.max(...domain)];
|
|
298
|
+
const rule = (value, name) => edgeRule(
|
|
299
|
+
value,
|
|
300
|
+
[lo, hi],
|
|
301
|
+
(at) => decorative(
|
|
302
|
+
ruleY([at], {
|
|
303
|
+
id: `zone-${i}-${name}`,
|
|
304
|
+
yScale: axes.scaleId(z.axisSide),
|
|
305
|
+
...z.edge && edgePaint(z.edge)
|
|
306
|
+
})
|
|
307
|
+
)
|
|
212
308
|
);
|
|
309
|
+
const sides = edgeSides(z.edge, "bottom", "top");
|
|
310
|
+
return [
|
|
311
|
+
decorative(
|
|
312
|
+
rect(fractionRows, {
|
|
313
|
+
id: `zone-${i}`,
|
|
314
|
+
x1: "f0",
|
|
315
|
+
x2: "f1",
|
|
316
|
+
y1: () => clampTo(z.from, domain),
|
|
317
|
+
y2: () => clampTo(z.to, domain),
|
|
318
|
+
xScale: "zx",
|
|
319
|
+
yScale: axes.scaleId(z.axisSide),
|
|
320
|
+
fill: z.fill,
|
|
321
|
+
inset: 0
|
|
322
|
+
})
|
|
323
|
+
),
|
|
324
|
+
...sides.lower ? rule(Math.min(z.from, z.to), "bottom") : [],
|
|
325
|
+
...sides.upper ? rule(Math.max(z.from, z.to), "top") : []
|
|
326
|
+
];
|
|
213
327
|
});
|
|
214
328
|
const xZones = (input.xZones ?? []).flatMap((z, i) => {
|
|
215
329
|
const f = xZoneFractions(z, model);
|
|
216
330
|
if (!f) return [];
|
|
331
|
+
const sides = edgeSides(z.edge, "start", "end");
|
|
332
|
+
const widen = z.align === "edge" ? model.halfStep : 0;
|
|
333
|
+
const bound = (value, sign) => {
|
|
334
|
+
const fraction = value === void 0 ? null : model.fraction(value);
|
|
335
|
+
return fraction === null ? null : fraction + sign * widen;
|
|
336
|
+
};
|
|
337
|
+
const rule = (value, sign, name) => edgeRule(
|
|
338
|
+
bound(value, sign),
|
|
339
|
+
[0, 1],
|
|
340
|
+
(at) => decorative(
|
|
341
|
+
ruleX([at], {
|
|
342
|
+
id: `xzone-${i}-${name}`,
|
|
343
|
+
x: (v) => v,
|
|
344
|
+
xScale: "zx",
|
|
345
|
+
...z.edge && edgePaint(z.edge)
|
|
346
|
+
})
|
|
347
|
+
)
|
|
348
|
+
);
|
|
217
349
|
return [
|
|
218
350
|
decorative(
|
|
219
351
|
rect([{ f0: f[0], f1: f[1] }], {
|
|
@@ -226,20 +358,28 @@ function underlayMarks(input, model, axes) {
|
|
|
226
358
|
fill: z.fill,
|
|
227
359
|
inset: 0
|
|
228
360
|
})
|
|
229
|
-
)
|
|
361
|
+
),
|
|
362
|
+
// An omitted bound is the plot edge: nothing to draw a rule on.
|
|
363
|
+
...sides.lower ? rule(z.from, -1, "start") : [],
|
|
364
|
+
...sides.upper ? rule(z.to, 1, "end") : []
|
|
230
365
|
];
|
|
231
366
|
});
|
|
232
367
|
return [...zones, ...xZones];
|
|
233
368
|
}
|
|
234
|
-
const refLineMarks = (input, axes) => (input.refLines ?? []).
|
|
235
|
-
(r, i) =>
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
369
|
+
const refLineMarks = (input, axes) => (input.refLines ?? []).flatMap(
|
|
370
|
+
(r, i) => (
|
|
371
|
+
// A line that names itself in the legend can be toggled off there.
|
|
372
|
+
input.hidden?.has(refLegendKey(i)) ? [] : [
|
|
373
|
+
ruleY([r.value], {
|
|
374
|
+
id: `ref-${i}`,
|
|
375
|
+
stroke: r.color,
|
|
376
|
+
strokeOpacity: 1,
|
|
377
|
+
strokeWidth: 1,
|
|
378
|
+
yScale: axes.scaleId(r.axis),
|
|
379
|
+
...r.dashed && { strokeDasharray: DASH }
|
|
380
|
+
})
|
|
381
|
+
]
|
|
382
|
+
)
|
|
243
383
|
);
|
|
244
384
|
function buildScales(opts) {
|
|
245
385
|
const { input, model, axes, formatX, cls, zoneScale } = opts;
|
|
@@ -294,6 +434,17 @@ function rowsOf(input, visibleKeys) {
|
|
|
294
434
|
});
|
|
295
435
|
};
|
|
296
436
|
}
|
|
437
|
+
function cursorDotMarks(input, visible, axes) {
|
|
438
|
+
return visible.flatMap((s) => {
|
|
439
|
+
const { cursorValue } = s;
|
|
440
|
+
if (!cursorValue) return [];
|
|
441
|
+
const rows = input.data.flatMap((d) => {
|
|
442
|
+
const y = cursorValue(d);
|
|
443
|
+
return y === null || !Number.isFinite(y) ? [] : [{ x: input.x(d), y, series: s.key, datum: d }];
|
|
444
|
+
});
|
|
445
|
+
return [cursorDots(s, rows, axes.onRight(s) ? "y2" : void 0)];
|
|
446
|
+
});
|
|
447
|
+
}
|
|
297
448
|
function tooltipSpec(opts) {
|
|
298
449
|
const { input, axes, visible, keys, visibleKeys, formatX } = opts;
|
|
299
450
|
const hidden = input.series.filter((s) => !visibleKeys.has(s.key));
|
|
@@ -314,19 +465,32 @@ function tooltipSpec(opts) {
|
|
|
314
465
|
for (const s of rowSeries) {
|
|
315
466
|
const v = s.getValue(d);
|
|
316
467
|
if (v === null || !Number.isFinite(v)) continue;
|
|
317
|
-
rows.push(
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
468
|
+
rows.push(
|
|
469
|
+
seriesRow(
|
|
470
|
+
s,
|
|
471
|
+
s.formatValue ? s.formatValue(v, d) : axes.axisOf(axes.onRight(s) ? "right" : "left").format(v),
|
|
472
|
+
input.highlighted === s.key
|
|
473
|
+
)
|
|
474
|
+
);
|
|
323
475
|
}
|
|
324
476
|
const extra = (input.tooltip || void 0)?.rows?.(d, { visible, hidden }) ?? [];
|
|
325
|
-
return {
|
|
477
|
+
return {
|
|
478
|
+
title: tooltipHeader(input, formatX, x, d),
|
|
479
|
+
rows: [...rows, ...extra.map(engineRow)]
|
|
480
|
+
};
|
|
326
481
|
}
|
|
327
482
|
};
|
|
328
483
|
}
|
|
484
|
+
function guardReservedKeys(series) {
|
|
485
|
+
if (process.env.NODE_ENV === "production") return;
|
|
486
|
+
const clash = series.find((s) => s.key.startsWith(REF_KEY_PREFIX));
|
|
487
|
+
if (clash)
|
|
488
|
+
throw new Error(
|
|
489
|
+
`[basalt] CartesianChart: the series key "${clash.key}" is reserved (\`${REF_KEY_PREFIX}\` prefix names reference-line legend entries)`
|
|
490
|
+
);
|
|
491
|
+
}
|
|
329
492
|
function compileCartesian(input) {
|
|
493
|
+
guardReservedKeys(input.series);
|
|
330
494
|
const visible = visibleSeries(input.series, input.hidden ?? /* @__PURE__ */ new Set());
|
|
331
495
|
const visibleKeys = new Set(visible.map((s) => s.key));
|
|
332
496
|
const keys = new Set(input.series.map((s) => s.key));
|
|
@@ -334,10 +498,11 @@ function compileCartesian(input) {
|
|
|
334
498
|
const axes = resolveAxes(input, visible);
|
|
335
499
|
const under = underlayMarks(input, model, axes);
|
|
336
500
|
const over = refLineMarks(input, axes);
|
|
501
|
+
const dots = cursorDotMarks(input, visible, axes);
|
|
337
502
|
const rows = rowsOf(input, visibleKeys);
|
|
338
503
|
const formatX = (v) => input.formatX ? input.formatX(v) : defaultFormatX(v);
|
|
339
504
|
const gradients = input.series.flatMap(
|
|
340
|
-
(s, i) => s.area ? [
|
|
505
|
+
(s, i) => s.area ? [seriesAreaGradient(s, i, input, axes)] : []
|
|
341
506
|
);
|
|
342
507
|
return {
|
|
343
508
|
chart: ({ width, height }) => {
|
|
@@ -354,7 +519,7 @@ function compileCartesian(input) {
|
|
|
354
519
|
y2Domain: axes.right?.domain
|
|
355
520
|
});
|
|
356
521
|
return {
|
|
357
|
-
marks: [...under, ...kindMarks, ...over, crosshair({ x: CROSSHAIR, y: false })],
|
|
522
|
+
marks: [...under, ...kindMarks, ...dots, ...over, crosshair({ x: CROSSHAIR, y: false })],
|
|
358
523
|
scales: buildScales({ input, model, axes, formatX, cls, zoneScale: under.length > 0 }),
|
|
359
524
|
theme: CHART_THEME,
|
|
360
525
|
...gradients.length > 0 && { gradients },
|
|
@@ -379,13 +544,18 @@ export {
|
|
|
379
544
|
areaGradient,
|
|
380
545
|
areaGradientId,
|
|
381
546
|
compileCartesian,
|
|
547
|
+
dashedSwatch,
|
|
382
548
|
dateTicks,
|
|
383
549
|
defaultFormatX,
|
|
384
550
|
defaultNumberFormat,
|
|
551
|
+
engineRow,
|
|
552
|
+
refLegendSeries,
|
|
553
|
+
seriesRow,
|
|
385
554
|
strideTicks,
|
|
386
555
|
utcAxisDate,
|
|
387
556
|
utcHeaderDate,
|
|
388
557
|
visibleSeries,
|
|
389
558
|
xGuide,
|
|
390
|
-
yGuide
|
|
559
|
+
yGuide,
|
|
560
|
+
zoneAreaGradient
|
|
391
561
|
};
|
package/dist/charts/index.d.ts
CHANGED
|
@@ -17,5 +17,6 @@ export { DualPanel, type DualPanelProps, type DualPanelLine, type DualPanelBar }
|
|
|
17
17
|
export { MirroredBars, type MirroredBarsProps, type MirroredBarsSeries, type MirroredBarPane, } from './MirroredBars.js';
|
|
18
18
|
export { ChartCard, type ChartCardProps, type ChartCardSlot } from './ChartCard.js';
|
|
19
19
|
export { chartCursor } from './cursor.js';
|
|
20
|
+
export { chartCurve, type CurveName } from './curves.js';
|
|
20
21
|
export type { AxisConfig, CartesianChartProps, ChartLegendConfig, ChartMarks, ChartSeries, ChartState, ChartTooltipConfig, ChartTooltipRow, ChartX, CursorResolution, PlotContext, RefLine, ResponsiveChartHeight, Threshold, XZoneSpec, ZoneSpec, } from './types.js';
|
|
21
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/charts/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AACxF,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EACL,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,QAAQ,GACd,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AACjE,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AACnG,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,YAAY,EACV,UAAU,EACV,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,SAAS,EACT,SAAS,EACT,QAAQ,GACT,MAAM,SAAS,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/charts/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAC1E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AACxF,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EACL,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,QAAQ,GACd,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AACjE,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AACnG,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAA;AACrD,YAAY,EACV,UAAU,EACV,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,SAAS,EACT,SAAS,EACT,QAAQ,GACT,MAAM,SAAS,CAAA"}
|
package/dist/charts/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from "./MirroredBars.js";
|
|
15
15
|
import { ChartCard } from "./ChartCard.js";
|
|
16
16
|
import { chartCursor } from "./cursor.js";
|
|
17
|
+
import { chartCurve } from "./curves.js";
|
|
17
18
|
export {
|
|
18
19
|
BandStrip,
|
|
19
20
|
Bars,
|
|
@@ -26,5 +27,6 @@ export {
|
|
|
26
27
|
MirroredBars,
|
|
27
28
|
Sparkline,
|
|
28
29
|
StackedArea,
|
|
29
|
-
chartCursor
|
|
30
|
+
chartCursor,
|
|
31
|
+
chartCurve
|
|
30
32
|
};
|
package/dist/charts/marks.d.ts
CHANGED
|
@@ -4,9 +4,17 @@ import type { ChartMarks, ChartSeries, ChartX, PlotContext, PlotRow } from './ty
|
|
|
4
4
|
export declare function yScaleOf<T, X extends ChartX>(plot: PlotContext<T, X>, s: Pick<ChartSeries<T>, 'axis'>): 'y2' | undefined;
|
|
5
5
|
/** `1`, or `DIMMED` while ANOTHER legend entry (not this series, not its parent) is hovered. */
|
|
6
6
|
export declare function emphasis<T>(highlighted: string | null, s: Pick<ChartSeries<T>, 'key' | 'parent'>): number;
|
|
7
|
+
/** The rows a series' line and area are drawn through: all of them, or only the non-null ones. */
|
|
8
|
+
export declare function drawnRows<T, X extends ChartX>(plot: PlotContext<T, X>, s: Pick<ChartSeries<T>, 'key' | 'gaps'>): PlotRow<T, X>[];
|
|
7
9
|
export declare function lineMark<T, X extends ChartX>(plot: PlotContext<T, X>, s: ChartSeries<T>): ChartMarks[number];
|
|
8
10
|
/** A series' `getMarker` points as dots: one decorative mark per distinct paint. */
|
|
9
11
|
export declare function markersOf<T, X extends ChartX>(s: ChartSeries<T>, rows: readonly PlotRow<T, X>[], yScale: 'y2' | undefined): ChartMarks;
|
|
12
|
+
/**
|
|
13
|
+
* The cursor dot of a series the consumer draws itself (`ChartSeries.cursorValue`): a dot per datum,
|
|
14
|
+
* invisible until the cursor is on that datum's x. It is NOT decorative, so the engine counts it as
|
|
15
|
+
* a focus point and the shared cursor, the focus group and the tooltip reach the series.
|
|
16
|
+
*/
|
|
17
|
+
export declare function cursorDots<T, X extends ChartX>(s: ChartSeries<T>, rows: readonly PlotRow<T, X>[], yScale: 'y2' | undefined): ChartMarks[number];
|
|
10
18
|
export declare function barMark<TDatum>(rows: Iterable<TDatum>, options?: BarYOptions<TDatum>): ChartMarks[number];
|
|
11
19
|
/**
|
|
12
20
|
* A band fill drawn at `width` px: each pixel column of the plot keeps its first and last row and the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marks.d.ts","sourceRoot":"","sources":["../../src/charts/marks.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAQvD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEpF,0FAA0F;AAC1F,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAC1C,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,GAC9B,IAAI,GAAG,SAAS,CAElB;AAED,gGAAgG;AAChG,wBAAgB,QAAQ,CAAC,CAAC,EACxB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,GACxC,MAAM,CAER;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAC1C,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GAChB,UAAU,CAAC,MAAM,CAAC,CAcpB;AASD,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAC3C,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,EACjB,IAAI,EAAE,SAAS,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAC9B,MAAM,EAAE,IAAI,GAAG,SAAS,GACvB,UAAU,CAiCZ;AAUD,wBAAgB,OAAO,CAAC,MAAM,EAC5B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,EACtB,OAAO,GAAE,WAAW,CAAC,MAAM,CAAM,GAChC,UAAU,CAAC,MAAM,CAAC,CAKpB;AAyBD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EAC7D,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,GACrB,CAAC,EAAE,CA+CL"}
|
|
1
|
+
{"version":3,"file":"marks.d.ts","sourceRoot":"","sources":["../../src/charts/marks.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAQvD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEpF,0FAA0F;AAC1F,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAC1C,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,GAC9B,IAAI,GAAG,SAAS,CAElB;AAED,gGAAgG;AAChG,wBAAgB,QAAQ,CAAC,CAAC,EACxB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,GACxC,MAAM,CAER;AAED,kGAAkG;AAClG,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAC3C,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,GACtC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAGjB;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAC1C,IAAI,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GAChB,UAAU,CAAC,MAAM,CAAC,CAcpB;AASD,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAC3C,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,EACjB,IAAI,EAAE,SAAS,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAC9B,MAAM,EAAE,IAAI,GAAG,SAAS,GACvB,UAAU,CAiCZ;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAC5C,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,EACjB,IAAI,EAAE,SAAS,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAC9B,MAAM,EAAE,IAAI,GAAG,SAAS,GACvB,UAAU,CAAC,MAAM,CAAC,CAcpB;AAUD,wBAAgB,OAAO,CAAC,MAAM,EAC5B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,EACtB,OAAO,GAAE,WAAW,CAAC,MAAM,CAAM,GAChC,UAAU,CAAC,MAAM,CAAC,CAKpB;AAyBD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EAC7D,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,GACrB,CAAC,EAAE,CA+CL"}
|