@pharos-ds/charts 0.0.0-stage → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/LICENSE +24 -0
  3. package/README.md +117 -2
  4. package/dist/Chart.d.ts +62 -0
  5. package/dist/Chart.d.ts.map +1 -0
  6. package/dist/Chart.js +401 -0
  7. package/dist/ChartAxis.d.ts +37 -0
  8. package/dist/ChartAxis.d.ts.map +1 -0
  9. package/dist/ChartAxis.js +233 -0
  10. package/dist/ChartContext.d.ts +4 -0
  11. package/dist/ChartContext.d.ts.map +1 -0
  12. package/dist/ChartContext.js +15 -0
  13. package/dist/ChartGrid.d.ts +26 -0
  14. package/dist/ChartGrid.d.ts.map +1 -0
  15. package/dist/ChartGrid.js +118 -0
  16. package/dist/ChartLegend.d.ts +14 -0
  17. package/dist/ChartLegend.d.ts.map +1 -0
  18. package/dist/ChartLegend.js +62 -0
  19. package/dist/ChartSwatch.d.ts +36 -0
  20. package/dist/ChartSwatch.d.ts.map +1 -0
  21. package/dist/ChartSwatch.js +85 -0
  22. package/dist/ChartTooltip.d.ts +46 -0
  23. package/dist/ChartTooltip.d.ts.map +1 -0
  24. package/dist/ChartTooltip.js +330 -0
  25. package/dist/charts.css +33 -0
  26. package/dist/dataTable.d.ts +56 -0
  27. package/dist/dataTable.d.ts.map +1 -0
  28. package/dist/dataTable.js +88 -0
  29. package/dist/formatters.d.ts +37 -0
  30. package/dist/formatters.d.ts.map +1 -0
  31. package/dist/formatters.js +156 -0
  32. package/dist/getChartColors.d.ts +67 -0
  33. package/dist/getChartColors.d.ts.map +1 -0
  34. package/dist/getChartColors.js +191 -0
  35. package/dist/index.d.ts +17 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +19 -0
  38. package/dist/layout.d.ts +40 -0
  39. package/dist/layout.d.ts.map +1 -0
  40. package/dist/layout.js +322 -0
  41. package/dist/legend.d.ts +17 -0
  42. package/dist/legend.d.ts.map +1 -0
  43. package/dist/legend.js +40 -0
  44. package/dist/markColor.d.ts +20 -0
  45. package/dist/markColor.d.ts.map +1 -0
  46. package/dist/markColor.js +56 -0
  47. package/dist/marks/area.d.ts +19 -0
  48. package/dist/marks/area.d.ts.map +1 -0
  49. package/dist/marks/area.js +121 -0
  50. package/dist/marks/band.d.ts +9 -0
  51. package/dist/marks/band.d.ts.map +1 -0
  52. package/dist/marks/band.js +64 -0
  53. package/dist/marks/bar.d.ts +21 -0
  54. package/dist/marks/bar.d.ts.map +1 -0
  55. package/dist/marks/bar.js +161 -0
  56. package/dist/marks/candlestick.d.ts +16 -0
  57. package/dist/marks/candlestick.d.ts.map +1 -0
  58. package/dist/marks/candlestick.js +110 -0
  59. package/dist/marks/dot.d.ts +19 -0
  60. package/dist/marks/dot.d.ts.map +1 -0
  61. package/dist/marks/dot.js +98 -0
  62. package/dist/marks/dotGL.d.ts +16 -0
  63. package/dist/marks/dotGL.d.ts.map +1 -0
  64. package/dist/marks/dotGL.js +231 -0
  65. package/dist/marks/dotGLInteractive.d.ts +35 -0
  66. package/dist/marks/dotGLInteractive.d.ts.map +1 -0
  67. package/dist/marks/dotGLInteractive.js +584 -0
  68. package/dist/marks/errorBar.d.ts +29 -0
  69. package/dist/marks/errorBar.d.ts.map +1 -0
  70. package/dist/marks/errorBar.js +95 -0
  71. package/dist/marks/heatmapGL.d.ts +27 -0
  72. package/dist/marks/heatmapGL.d.ts.map +1 -0
  73. package/dist/marks/heatmapGL.js +335 -0
  74. package/dist/marks/index.d.ts +13 -0
  75. package/dist/marks/index.d.ts.map +1 -0
  76. package/dist/marks/index.js +14 -0
  77. package/dist/marks/line.d.ts +18 -0
  78. package/dist/marks/line.d.ts.map +1 -0
  79. package/dist/marks/line.js +83 -0
  80. package/dist/marks/referenceLine.d.ts +37 -0
  81. package/dist/marks/referenceLine.d.ts.map +1 -0
  82. package/dist/marks/referenceLine.js +204 -0
  83. package/dist/marks/streamGL.d.ts +41 -0
  84. package/dist/marks/streamGL.d.ts.map +1 -0
  85. package/dist/marks/streamGL.js +317 -0
  86. package/dist/tooltip.d.ts +38 -0
  87. package/dist/tooltip.d.ts.map +1 -0
  88. package/dist/tooltip.js +57 -0
  89. package/dist/types.d.ts +193 -0
  90. package/dist/types.d.ts.map +1 -0
  91. package/dist/types.js +70 -0
  92. package/dist/useChartColors.d.ts +16 -0
  93. package/dist/useChartColors.d.ts.map +1 -0
  94. package/dist/useChartColors.js +37 -0
  95. package/dist/utils.d.ts +15 -0
  96. package/dist/utils.d.ts.map +1 -0
  97. package/dist/utils.js +31 -0
  98. package/dist/webgl.d.ts +77 -0
  99. package/dist/webgl.d.ts.map +1 -0
  100. package/dist/webgl.js +235 -0
  101. package/package.json +71 -3
  102. package/src/Chart.doc.mjs +174 -0
  103. package/src/Chart.test.tsx +273 -0
  104. package/src/Chart.tsx +535 -0
  105. package/src/ChartAxis.tsx +289 -0
  106. package/src/ChartContext.ts +18 -0
  107. package/src/ChartGrid.tsx +136 -0
  108. package/src/ChartLegend.tsx +77 -0
  109. package/src/ChartSwatch.doc.mjs +17 -0
  110. package/src/ChartSwatch.tsx +89 -0
  111. package/src/ChartTooltip.tsx +452 -0
  112. package/src/charts.css.d.ts +3 -0
  113. package/src/dataTable.test.ts +86 -0
  114. package/src/dataTable.ts +124 -0
  115. package/src/formatters.ts +167 -0
  116. package/src/getChartColors.test.ts +114 -0
  117. package/src/getChartColors.ts +282 -0
  118. package/src/index.ts +88 -0
  119. package/src/layout.ts +372 -0
  120. package/src/legend.ts +44 -0
  121. package/src/markColor.ts +70 -0
  122. package/src/marks/area.tsx +142 -0
  123. package/src/marks/band.tsx +86 -0
  124. package/src/marks/bar.tsx +210 -0
  125. package/src/marks/candlestick.tsx +128 -0
  126. package/src/marks/dot.tsx +119 -0
  127. package/src/marks/dotGL.tsx +274 -0
  128. package/src/marks/dotGLInteractive.tsx +660 -0
  129. package/src/marks/errorBar.tsx +119 -0
  130. package/src/marks/heatmapGL.tsx +392 -0
  131. package/src/marks/index.ts +17 -0
  132. package/src/marks/line.tsx +118 -0
  133. package/src/marks/referenceLine.tsx +252 -0
  134. package/src/marks/streamGL.tsx +381 -0
  135. package/src/tooltip.ts +73 -0
  136. package/src/types.ts +212 -0
  137. package/src/useChartColors.ts +41 -0
  138. package/src/utils.ts +38 -0
  139. package/src/webgl.ts +262 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * @file types.ts
3
+ * @output Core types for the v2 chart architecture
4
+ * @position Foundation — consumed by layout, renderers, and interactions
5
+ */
6
+ import type { ReactNode } from 'react';
7
+ import type { ScaleLinear, ScaleBand } from 'd3-scale';
8
+ export type ChartScale = ScaleLinear<number, number> | ScaleBand<string>;
9
+ /**
10
+ * A color for a mark: either a constant CSS color/token, or an accessor that
11
+ * returns a color per datum (for per-element coloring, e.g. positive/negative).
12
+ */
13
+ export type ColorAccessor = string | ((datum: Record<string, unknown>, index: number) => string);
14
+ /**
15
+ * Fallback series color used when a mark has neither an explicit color nor a
16
+ * palette color assigned by the chart root. Uses an EMITTED core token
17
+ * (`--color-accent`) — the data-viz `--color-data-*` tokens are JS-only values
18
+ * (resolved via useChartColors), not CSS custom properties, so `var(--color-data-*)`
19
+ * would render nothing. The chart root normally assigns a resolved palette color,
20
+ * so this is only a last-resort fallback.
21
+ */
22
+ export declare const DEFAULT_SERIES_COLOR = "var(--color-accent)";
23
+ /**
24
+ * Controls how the y-axis domain is derived when no explicit `yDomain` is given:
25
+ * - `'auto'` (default) — bar/area marks pin an honest zero baseline; continuous-
26
+ * only charts (line/dot/…) get a little headroom so points don't touch edges.
27
+ * - `'zero'` — symmetric around zero (good for +/- data like profit/loss).
28
+ * - `'data'` — tight fit to the data extent (no zero forcing, no headroom).
29
+ */
30
+ export type YBaseline = 'auto' | 'zero' | 'data';
31
+ export interface ChartMargin {
32
+ top: number;
33
+ right: number;
34
+ bottom: number;
35
+ left: number;
36
+ }
37
+ /** Resolved pixel position for a single data point in a series */
38
+ export interface ResolvedPoint {
39
+ /** Pixel x in plot area coordinates */
40
+ px: number;
41
+ /** Pixel y in plot area coordinates (top of mark) */
42
+ py: number;
43
+ /** Pixel y baseline (bottom of mark) — differs from py when stacked */
44
+ py0: number;
45
+ /** Index into the data array */
46
+ dataIndex: number;
47
+ }
48
+ /** Context passed to resolve() and render() on each series */
49
+ export interface SeriesContext {
50
+ data: Record<string, unknown>[];
51
+ xKey: string;
52
+ xScale: ChartScale;
53
+ yScale: ScaleLinear<number, number>;
54
+ /**
55
+ * Categorical y band scale for row-based marks (e.g. heatmap). Present only
56
+ * when a series declares `layout.yBandKey`; in that case the y-axis is
57
+ * categorical and the linear `yScale` is unused/degenerate.
58
+ */
59
+ yBandScale?: ScaleBand<string>;
60
+ /** Width of the plot area */
61
+ width: number;
62
+ /** Height of the plot area */
63
+ height: number;
64
+ }
65
+ /**
66
+ * The standardized shape every mark helper returns.
67
+ * Each mark type is self-contained: it knows how to resolve positions
68
+ * and how to render itself. The chart root just iterates and calls.
69
+ *
70
+ * A SeriesDef instance is single-use: the layout/render pass annotates it in
71
+ * place (`_uid`, `_isTopOfStack`, `_resolvedColor`), so a given def must belong
72
+ * to exactly one <Chart>. Build a fresh series array per chart rather than
73
+ * sharing the same mark objects across charts.
74
+ */
75
+ export interface SeriesDef {
76
+ /** Mark type identifier */
77
+ readonly type: string;
78
+ /**
79
+ * Semantic key for this series — typically the dataKey. Used as a
80
+ * human-readable label fallback and for stack/group coordination. It is NOT
81
+ * guaranteed unique (two series can share a dataKey), so it must never be
82
+ * used as a Map key or React key — use `_uid` for identity instead.
83
+ */
84
+ readonly key: string;
85
+ /** Data keys this series reads from — used to compute y domain */
86
+ readonly dataKeys: string[];
87
+ /**
88
+ * Collision-free per-instance identity, assigned by the layout pass from the
89
+ * series' position in the `series` array. This is the key used for the
90
+ * resolved map, React keys, and tooltip/hover lookups. Never set it yourself.
91
+ */
92
+ _uid?: string;
93
+ /** Whether this series is the topmost in its stack (set during layout) */
94
+ _isTopOfStack?: boolean;
95
+ /** Static color for legend display. Undefined if color is dynamic (accessor function). */
96
+ readonly color?: string;
97
+ /**
98
+ * Palette color assigned by the chart root for series that don't supply a
99
+ * static color (auto-colored or accessor-colored). Used as the render fallback
100
+ * and the legend/tooltip representative color. Never set it yourself.
101
+ */
102
+ _resolvedColor?: string;
103
+ /** Human-readable label for legend. Falls back to key if not provided. */
104
+ readonly label?: string;
105
+ /** Layout hints the chart root uses for cross-series coordination */
106
+ readonly layout: {
107
+ /** Stack group — series with same stack accumulate */
108
+ stack?: string;
109
+ /** Bar group — series with same group subdivide bandwidth */
110
+ group?: string;
111
+ /** Whether this series contributes to y-domain zero inclusion */
112
+ includeZero?: boolean;
113
+ /**
114
+ * When set, the chart's y-axis is a band scale built from this data key's
115
+ * unique values (categorical rows, e.g. a heatmap's days) rather than a
116
+ * linear value scale. The layout pass exposes it to marks and the axis as
117
+ * `yBandScale`, so a left `<ChartAxis>` renders the categories aligned to
118
+ * each row. A heatmap should also declare `dataKeys: []` so it doesn't feed
119
+ * the (now unused) linear y-domain.
120
+ */
121
+ yBandKey?: string;
122
+ };
123
+ /**
124
+ * Resolve pixel positions for each data point.
125
+ * Called by the chart root during the layout pass.
126
+ * Receives pre-computed stack offsets if stacked.
127
+ */
128
+ resolve(ctx: SeriesContext, stackOffsets?: {
129
+ y0: number;
130
+ y1: number;
131
+ }[], groupInfo?: {
132
+ index: number;
133
+ count: number;
134
+ }): ResolvedPoint[];
135
+ /**
136
+ * Render the mark given resolved positions.
137
+ * Called by the chart root during the render pass.
138
+ * Returns SVG elements (or manages its own canvas for WebGL).
139
+ */
140
+ render(resolved: ResolvedPoint[], ctx: SeriesContext): ReactNode;
141
+ }
142
+ /** Resolved positions for all series */
143
+ export type ResolvedPositions = Map<string, ResolvedPoint[]>;
144
+ /** Pointer event normalized to plot-area coordinates */
145
+ export interface ChartPointerEvent {
146
+ x: number;
147
+ y: number;
148
+ nearest: (ResolvedPoint & {
149
+ seriesKey: string;
150
+ }) | null;
151
+ active: boolean;
152
+ }
153
+ /**
154
+ * Which way the chart reads. `'vertical'` (default): categories along x, values
155
+ * grow up. `'horizontal'`: categories along y, values grow right (horizontal
156
+ * bars). Marks always resolve in the vertical "plot space"; the chart root
157
+ * transposes them on screen.
158
+ */
159
+ export type ChartOrientation = 'vertical' | 'horizontal';
160
+ /** Context provided by Chart to interaction children */
161
+ export interface ChartContext {
162
+ /**
163
+ * Chart orientation. Chrome (axes, grid) receives display-space scales: for
164
+ * `'horizontal'`, `xScale` is the value scale and `yBandScale` the category
165
+ * scale. `resolved` points stay in plot space (see `ChartOrientation`).
166
+ */
167
+ orientation?: ChartOrientation;
168
+ width: number;
169
+ height: number;
170
+ margin: ChartMargin;
171
+ data: Record<string, unknown>[];
172
+ xKey: string;
173
+ xScale: ChartScale;
174
+ yScale: ScaleLinear<number, number>;
175
+ /**
176
+ * Categorical y band scale (e.g. heatmap rows), present when a series declares
177
+ * `layout.yBandKey`. Chrome that renders the y-axis (`ChartAxis`) should
178
+ * prefer this over the linear `yScale` when it exists.
179
+ */
180
+ yBandScale?: ScaleBand<string>;
181
+ resolved: Map<string, ResolvedPoint[]>;
182
+ onPointer: (handler: (e: ChartPointerEvent) => void) => () => void;
183
+ svgRef: React.RefObject<SVGSVGElement | null>;
184
+ }
185
+ /**
186
+ * Series mark types that are utility / annotation marks rather than primary
187
+ * data. They're skipped from chrome surfaces (legend, tooltip rows) since
188
+ * they don't represent values the user is comparing.
189
+ */
190
+ export declare const UTILITY_MARK_TYPES: ReadonlySet<string>;
191
+ /** True if the series type is a utility / annotation mark. */
192
+ export declare function isUtilityMarkType(type: string): boolean;
193
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,70 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file types.ts
5
+ * @output Core types for the v2 chart architecture
6
+ * @position Foundation — consumed by layout, renderers, and interactions
7
+ */
8
+
9
+ /**
10
+ * A color for a mark: either a constant CSS color/token, or an accessor that
11
+ * returns a color per datum (for per-element coloring, e.g. positive/negative).
12
+ */
13
+
14
+ /**
15
+ * Fallback series color used when a mark has neither an explicit color nor a
16
+ * palette color assigned by the chart root. Uses an EMITTED core token
17
+ * (`--color-accent`) — the data-viz `--color-data-*` tokens are JS-only values
18
+ * (resolved via useChartColors), not CSS custom properties, so `var(--color-data-*)`
19
+ * would render nothing. The chart root normally assigns a resolved palette color,
20
+ * so this is only a last-resort fallback.
21
+ */
22
+ export const DEFAULT_SERIES_COLOR = 'var(--color-accent)';
23
+
24
+ /**
25
+ * Controls how the y-axis domain is derived when no explicit `yDomain` is given:
26
+ * - `'auto'` (default) — bar/area marks pin an honest zero baseline; continuous-
27
+ * only charts (line/dot/…) get a little headroom so points don't touch edges.
28
+ * - `'zero'` — symmetric around zero (good for +/- data like profit/loss).
29
+ * - `'data'` — tight fit to the data extent (no zero forcing, no headroom).
30
+ */
31
+
32
+ /** Resolved pixel position for a single data point in a series */
33
+
34
+ /** Context passed to resolve() and render() on each series */
35
+
36
+ /**
37
+ * The standardized shape every mark helper returns.
38
+ * Each mark type is self-contained: it knows how to resolve positions
39
+ * and how to render itself. The chart root just iterates and calls.
40
+ *
41
+ * A SeriesDef instance is single-use: the layout/render pass annotates it in
42
+ * place (`_uid`, `_isTopOfStack`, `_resolvedColor`), so a given def must belong
43
+ * to exactly one <Chart>. Build a fresh series array per chart rather than
44
+ * sharing the same mark objects across charts.
45
+ */
46
+
47
+ /** Resolved positions for all series */
48
+
49
+ /** Pointer event normalized to plot-area coordinates */
50
+
51
+ /**
52
+ * Which way the chart reads. `'vertical'` (default): categories along x, values
53
+ * grow up. `'horizontal'`: categories along y, values grow right (horizontal
54
+ * bars). Marks always resolve in the vertical "plot space"; the chart root
55
+ * transposes them on screen.
56
+ */
57
+
58
+ /** Context provided by Chart to interaction children */
59
+
60
+ /**
61
+ * Series mark types that are utility / annotation marks rather than primary
62
+ * data. They're skipped from chrome surfaces (legend, tooltip rows) since
63
+ * they don't represent values the user is comparing.
64
+ */
65
+ export const UTILITY_MARK_TYPES = new Set(['referenceLine', 'errorBar', 'band']);
66
+
67
+ /** True if the series type is a utility / annotation mark. */
68
+ export function isUtilityMarkType(type) {
69
+ return UTILITY_MARK_TYPES.has(type);
70
+ }
@@ -0,0 +1,16 @@
1
+ import type { ChartColorsAPI } from './getChartColors';
2
+ /**
3
+ * Theme-aware chart colors. Resolves data-viz tokens from the current
4
+ * theme context — respects light/dark mode and custom themes.
5
+ *
6
+ * @example
7
+ * ```
8
+ * const colors = useChartColors();
9
+ * colors.categorical(5)
10
+ * colors.sequential.blue(3)
11
+ * colors.diverging.positiveNegative(5)
12
+ * colors.alpha('#0171E3', 0.5)
13
+ * ```
14
+ */
15
+ export declare function useChartColors(): ChartColorsAPI;
16
+ //# sourceMappingURL=useChartColors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChartColors.d.ts","sourceRoot":"","sources":["../src/useChartColors.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,IAAI,cAAc,CAU/C"}
@@ -0,0 +1,37 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file useChartColors.ts
5
+ * @output Theme-aware chart color palette hook
6
+ * @position React hook wrapping getChartColors — resolves from live theme context
7
+ *
8
+ * Returns a stable reference across renders — the palette only rebuilds when the
9
+ * resolved theme tokens change (theme or color mode), so consumers can safely
10
+ * use the result in effect/memo dependency arrays.
11
+ */
12
+
13
+ import { useMemo } from 'react';
14
+ import { useTheme } from '@pharos-ds/core/theme';
15
+ import { getChartColorsFromResolver } from "./getChartColors.js";
16
+ /**
17
+ * Theme-aware chart colors. Resolves data-viz tokens from the current
18
+ * theme context — respects light/dark mode and custom themes.
19
+ *
20
+ * @example
21
+ * ```
22
+ * const colors = useChartColors();
23
+ * colors.categorical(5)
24
+ * colors.sequential.blue(3)
25
+ * colors.diverging.positiveNegative(5)
26
+ * colors.alpha('#0171E3', 0.5)
27
+ * ```
28
+ */
29
+ export function useChartColors() {
30
+ // Depend on the memoized token map (stable per theme + mode), not useTheme's
31
+ // `token` function, which is a fresh closure on every render and would defeat
32
+ // memoization — returning a new palette object each render.
33
+ const {
34
+ tokens
35
+ } = useTheme();
36
+ return useMemo(() => getChartColorsFromResolver(name => tokens[name] ?? ''), [tokens]);
37
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @file utils.ts
3
+ * @output Shared utilities for chart components
4
+ * @position Internal helpers; consumed by mark, axis, and interaction components
5
+ */
6
+ import type { ScaleBand } from 'd3-scale';
7
+ import type { ChartScale } from './types';
8
+ /** Type guard for d3 band scales */
9
+ export declare function isBandScale(scale: ChartScale): scale is ScaleBand<string>;
10
+ /**
11
+ * Get the x pixel position for a datum using the chart's xKey and xScale.
12
+ * For band scales, returns the center of the band.
13
+ */
14
+ export declare function xPixel(d: Record<string, unknown>, xKey: string, xScale: ChartScale): number;
15
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AACxC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AAExC,oCAAoC;AACpC,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,KAAK,IAAI,SAAS,CAAC,MAAM,CAAC,CAEzE;AAED;;;GAGG;AACH,wBAAgB,MAAM,CACpB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GACjB,MAAM,CAaR"}
package/dist/utils.js ADDED
@@ -0,0 +1,31 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file utils.ts
5
+ * @output Shared utilities for chart components
6
+ * @position Internal helpers; consumed by mark, axis, and interaction components
7
+ */
8
+
9
+ /** Type guard for d3 band scales */
10
+ export function isBandScale(scale) {
11
+ return typeof scale === 'function' && 'bandwidth' in scale;
12
+ }
13
+
14
+ /**
15
+ * Get the x pixel position for a datum using the chart's xKey and xScale.
16
+ * For band scales, returns the center of the band.
17
+ */
18
+ export function xPixel(d, xKey, xScale) {
19
+ const raw = d[xKey];
20
+ if (isBandScale(xScale)) {
21
+ return (xScale(String(raw)) ?? 0) + xScale.bandwidth() / 2;
22
+ }
23
+ // Not a band scale → the guard narrows `xScale` to the linear scale, so no
24
+ // cast is needed. Coerce explicitly: finite numbers pass through, Date/
25
+ // numeric-string map as d3 would. Anything that coerces to a non-finite value
26
+ // — a non-numeric (→ NaN) or a raw ±Infinity — collapses to NaN, a single
27
+ // off-canvas sentinel that marks already skip, rather than a silently wrong
28
+ // position (d3 maps ±Infinity to an out-of-range pixel, not off-canvas).
29
+ const value = typeof raw === 'number' ? raw : Number(raw);
30
+ return Number.isFinite(value) ? xScale(value) : NaN;
31
+ }
@@ -0,0 +1,77 @@
1
+ /** Compile a WebGL shader, returns null on failure */
2
+ export declare function compileShader(gl: WebGLRenderingContext, type: number, src: string): WebGLShader | null;
3
+ /** Link a vertex + fragment shader into a program */
4
+ export declare function createProgram(gl: WebGLRenderingContext, vertSrc: string, fragSrc: string): WebGLProgram | null;
5
+ /**
6
+ * Parse a hex color to [r, g, b] floats in 0-1.
7
+ *
8
+ * Accepts `#rgb`, `#rgba`, `#rrggbb`, and `#rrggbbaa`, with or without the
9
+ * leading `#` (any alpha byte is ignored). Non-hex input — CSS custom
10
+ * properties, `rgb()`, named colors, or malformed strings — returns a neutral
11
+ * fallback rather than producing NaN, so the GPU never receives a bad uniform.
12
+ */
13
+ export declare function hexToGL(hex: string): [number, number, number];
14
+ /** DPR with 2x supersampling for crisp circles. SSR-safe (falls back to 2). */
15
+ export declare function getCanvasDPR(): number;
16
+ /**
17
+ * Create or get a WebGL context with correct alpha settings.
18
+ * Uses premultiplied alpha for correct compositing over the page.
19
+ */
20
+ export declare function getWebGLContext(canvas: HTMLCanvasElement): WebGLRenderingContext | null;
21
+ /**
22
+ * Set up standard GL state for chart rendering:
23
+ * - Clear with transparent
24
+ * - Enable premultiplied alpha blending
25
+ */
26
+ export declare function setupGLState(gl: WebGLRenderingContext): void;
27
+ /**
28
+ * Size a canvas for sharp rendering, accounting for DPR.
29
+ * Returns the DPR used.
30
+ */
31
+ export declare function sizeCanvas(canvas: HTMLCanvasElement, width: number, height: number): number;
32
+ /**
33
+ * Mount a canvas as an absolute-positioned sibling to an SVG element.
34
+ * Automatically aligns with the SVG marker's position — no manual margin
35
+ * offset needed. This is a Tier 1 guarantee: the canvas lands exactly
36
+ * where the SVG content area is, regardless of chart margins or transforms.
37
+ *
38
+ * Call from a useEffect. Returns a cleanup function.
39
+ */
40
+ export declare function mountCanvasOverSVG(svgMarker: SVGGraphicsElement, canvas: HTMLCanvasElement, width: number, height: number): (() => void) | undefined;
41
+ /**
42
+ * Register WebGL context-loss/restore handlers on a canvas.
43
+ *
44
+ * Calling `preventDefault()` on the lost event is REQUIRED — without it the
45
+ * browser will never fire `webglcontextrestored`. `onLost` should drop any
46
+ * cached GL handles (they are all invalid after loss); `onRestored` should
47
+ * trigger a rebuild + redraw.
48
+ *
49
+ * Returns a cleanup that removes both listeners.
50
+ */
51
+ export declare function registerContextLossHandlers(canvas: HTMLCanvasElement, onLost: () => void, onRestored: () => void): () => void;
52
+ /**
53
+ * Eagerly release a WebGL context and its GPU resources on teardown.
54
+ *
55
+ * Browsers cap the number of live contexts (~16), so freeing on unmount rather
56
+ * than waiting for GC prevents "too many active WebGL contexts" failures when
57
+ * many charts mount/unmount over a session.
58
+ */
59
+ export declare function loseContext(gl: WebGLRenderingContext): void;
60
+ /**
61
+ * GLSL fragment for premultiplied-alpha circle with smoothstep AA.
62
+ * Use in fragment shaders that render point sprites.
63
+ *
64
+ * Expects:
65
+ * - varying float v_alpha (the final alpha before edge AA)
66
+ * - uniform vec3 u_color
67
+ *
68
+ * Returns: gl_FragColor with premultiplied alpha
69
+ */
70
+ export declare const CIRCLE_FRAG_BODY = "\n vec2 coord = gl_PointCoord - vec2(0.5);\n float dist = length(coord);\n if (dist > 0.5) discard;\n float edge = 1.0 - smoothstep(0.48, 0.5, dist);\n float a = v_alpha * edge;\n gl_FragColor = vec4(u_color * a, a);\n";
71
+ /**
72
+ * Smoothstep compensation factor for gl_PointSize.
73
+ * The visible circle radius is 0.48 of the point sprite (smoothstep starts there),
74
+ * so we scale up by 1/0.96 to match SVG circle radius exactly.
75
+ */
76
+ export declare const POINT_SIZE_COMPENSATION: number;
77
+ //# sourceMappingURL=webgl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webgl.d.ts","sourceRoot":"","sources":["../src/webgl.ts"],"names":[],"mappings":"AAmBA,sDAAsD;AACtD,wBAAgB,aAAa,CAC3B,EAAE,EAAE,qBAAqB,EACzB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,WAAW,GAAG,IAAI,CAYpB;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAC3B,EAAE,EAAE,qBAAqB,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,YAAY,GAAG,IAAI,CAiCrB;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAE7D;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,IAAI,MAAM,CAGrC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,iBAAiB,GACxB,qBAAqB,GAAG,IAAI,CAM9B;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,qBAAqB,GAAG,IAAI,CAK5D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM,CASR;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,kBAAkB,EAC7B,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAwC1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,MAAM,IAAI,EAClB,UAAU,EAAE,MAAM,IAAI,GACrB,MAAM,IAAI,CAWZ;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,qBAAqB,GAAG,IAAI,CAK3D;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,iPAO5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,QAAa,CAAC"}