@pharos-ds/charts 0.0.0-bootstrap.0 → 1.0.10-canary.2189f39

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 +118 -0
  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 +72 -4
  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,231 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file marks/dotGL.tsx
5
+ * @output WebGL scatter — canvas overlay, single draw call
6
+ *
7
+ * GL context, program, and vertex buffer are created once and reused across
8
+ * redraws; all are released (and the context eagerly lost) on unmount. Handles
9
+ * context loss/restore and skips non-finite points.
10
+ */
11
+
12
+ import { useRef, useEffect, useMemo, useState } from 'react';
13
+ import { hexToGL, getWebGLContext, setupGLState, sizeCanvas, mountCanvasOverSVG, createProgram, registerContextLossHandlers, loseContext, POINT_SIZE_COMPENSATION } from "../webgl.js";
14
+ import { jsx as _jsx } from "react/jsx-runtime";
15
+ const VERT = `
16
+ attribute vec2 a_position;
17
+ uniform vec2 u_resolution;
18
+ uniform float u_size;
19
+ void main() {
20
+ vec2 clip = (a_position / u_resolution) * 2.0 - 1.0;
21
+ gl_Position = vec4(clip.x, -clip.y, 0.0, 1.0);
22
+ gl_PointSize = u_size * ${POINT_SIZE_COMPENSATION.toFixed(6)};
23
+ }
24
+ `;
25
+ const FRAG = `
26
+ precision mediump float;
27
+ uniform vec3 u_color;
28
+ uniform float u_opacity;
29
+ void main() {
30
+ vec2 coord = gl_PointCoord - vec2(0.5);
31
+ float dist = length(coord);
32
+ if (dist > 0.5) discard;
33
+ float edge = 1.0 - smoothstep(0.48, 0.5, dist);
34
+ float a = u_opacity * edge;
35
+ gl_FragColor = vec4(u_color * a, a);
36
+ }
37
+ `;
38
+ /**
39
+ * Inline component returned by render() — owns the WebGL canvas lifecycle. The
40
+ * canvas is mounted as a sibling of the SVG (via a marker <g>) for sharp Retina
41
+ * output without foreignObject blur.
42
+ */
43
+ function DotGLCanvas({
44
+ resolved,
45
+ color,
46
+ size,
47
+ opacity,
48
+ width,
49
+ height
50
+ }) {
51
+ const canvasRef = useRef(null);
52
+ const glRef = useRef(null);
53
+ const programRef = useRef(null);
54
+ const bufferRef = useRef(null);
55
+ const locsRef = useRef(null);
56
+ const markerRef = useRef(null);
57
+ // Bumped on context restore to force the draw effect to rebuild + repaint.
58
+ const [contextEpoch, setContextEpoch] = useState(0);
59
+ const positions = useMemo(() => {
60
+ const out = [];
61
+ for (const p of resolved) {
62
+ if (Number.isFinite(p.px) && Number.isFinite(p.py)) {
63
+ out.push(p.px, p.py);
64
+ }
65
+ }
66
+ return new Float32Array(out);
67
+ }, [resolved]);
68
+
69
+ // Mount the canvas outside the SVG and wire context-loss recovery. The canvas
70
+ // element persists across resizes; only its DOM attachment is re-established.
71
+ useEffect(() => {
72
+ const marker = markerRef.current;
73
+ if (!marker) {
74
+ return;
75
+ }
76
+ if (!canvasRef.current) {
77
+ canvasRef.current = document.createElement('canvas');
78
+ }
79
+ const canvas = canvasRef.current;
80
+ const detach = mountCanvasOverSVG(marker, canvas, width, height);
81
+ const unregister = registerContextLossHandlers(canvas, () => {
82
+ glRef.current = null;
83
+ programRef.current = null;
84
+ bufferRef.current = null;
85
+ locsRef.current = null;
86
+ }, () => setContextEpoch(e => e + 1));
87
+ return () => {
88
+ unregister();
89
+ detach?.();
90
+ };
91
+ }, [width, height]);
92
+
93
+ // Draw. The context, program, and buffer are created lazily once and reused;
94
+ // only vertex data + uniforms are re-uploaded per redraw.
95
+ useEffect(() => {
96
+ const canvas = canvasRef.current;
97
+ if (!canvas || width <= 0 || height <= 0) {
98
+ return;
99
+ }
100
+ const dpr = sizeCanvas(canvas, width, height);
101
+ if (!glRef.current) {
102
+ glRef.current = getWebGLContext(canvas);
103
+ }
104
+ const gl = glRef.current;
105
+ if (!gl || gl.isContextLost()) {
106
+ return;
107
+ }
108
+ if (!programRef.current) {
109
+ programRef.current = createProgram(gl, VERT, FRAG);
110
+ locsRef.current = null;
111
+ }
112
+ const program = programRef.current;
113
+ if (!program) {
114
+ return;
115
+ }
116
+ if (!bufferRef.current) {
117
+ bufferRef.current = gl.createBuffer();
118
+ }
119
+ const buffer = bufferRef.current;
120
+ if (!buffer) {
121
+ return;
122
+ }
123
+ if (!locsRef.current) {
124
+ locsRef.current = {
125
+ aPosition: gl.getAttribLocation(program, 'a_position'),
126
+ uResolution: gl.getUniformLocation(program, 'u_resolution'),
127
+ uColor: gl.getUniformLocation(program, 'u_color'),
128
+ uSize: gl.getUniformLocation(program, 'u_size'),
129
+ uOpacity: gl.getUniformLocation(program, 'u_opacity')
130
+ };
131
+ }
132
+ const locs = locsRef.current;
133
+ gl.viewport(0, 0, canvas.width, canvas.height);
134
+ setupGLState(gl);
135
+ gl.useProgram(program);
136
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
137
+ gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
138
+ gl.enableVertexAttribArray(locs.aPosition);
139
+ gl.vertexAttribPointer(locs.aPosition, 2, gl.FLOAT, false, 0, 0);
140
+ const [r, g, b] = hexToGL(color);
141
+ gl.uniform2f(locs.uResolution, width, height);
142
+ gl.uniform3f(locs.uColor, r, g, b);
143
+ gl.uniform1f(locs.uSize, size * dpr);
144
+ gl.uniform1f(locs.uOpacity, opacity);
145
+ gl.drawArrays(gl.POINTS, 0, positions.length / 2);
146
+ }, [width, height, color, size, opacity, positions, contextEpoch]);
147
+
148
+ // Release all GL resources on unmount.
149
+ useEffect(() => {
150
+ return () => {
151
+ const gl = glRef.current;
152
+ if (gl) {
153
+ if (bufferRef.current) {
154
+ gl.deleteBuffer(bufferRef.current);
155
+ }
156
+ if (programRef.current) {
157
+ gl.deleteProgram(programRef.current);
158
+ }
159
+ loseContext(gl);
160
+ }
161
+ glRef.current = null;
162
+ programRef.current = null;
163
+ bufferRef.current = null;
164
+ locsRef.current = null;
165
+ };
166
+ }, []);
167
+ if (width <= 0 || height <= 0) {
168
+ return null;
169
+ }
170
+ return /*#__PURE__*/_jsx("g", {
171
+ ref: markerRef
172
+ });
173
+ }
174
+
175
+ /**
176
+ * WebGL scatter plot. Canvas mounted outside SVG for sharp Retina rendering.
177
+ *
178
+ * @example
179
+ * ```
180
+ * series={[dotGL('value', {color: '#4f46e5'})]}
181
+ * ```
182
+ */
183
+ export function dotGL(dataKey, options) {
184
+ const {
185
+ color
186
+ } = options;
187
+ const size = options.size ?? 6;
188
+ const opacity = options.opacity ?? 0.8;
189
+ return {
190
+ type: 'dotGL',
191
+ key: dataKey,
192
+ dataKeys: [dataKey],
193
+ layout: {},
194
+ resolve(ctx) {
195
+ const {
196
+ data,
197
+ xKey,
198
+ xScale,
199
+ yScale
200
+ } = ctx;
201
+ const points = [];
202
+ for (let i = 0; i < data.length; i++) {
203
+ const d = data[i];
204
+ let px;
205
+ if ('bandwidth' in xScale) {
206
+ px = (xScale(String(d[xKey])) ?? 0) + xScale.bandwidth() / 2;
207
+ } else {
208
+ px = xScale(d[xKey]);
209
+ }
210
+ const v = typeof d[dataKey] === 'number' ? d[dataKey] : 0;
211
+ points.push({
212
+ px,
213
+ py: yScale(v),
214
+ py0: yScale(0),
215
+ dataIndex: i
216
+ });
217
+ }
218
+ return points;
219
+ },
220
+ render(resolved, ctx) {
221
+ return /*#__PURE__*/_jsx(DotGLCanvas, {
222
+ resolved: resolved,
223
+ color: color,
224
+ size: size,
225
+ opacity: opacity,
226
+ width: ctx.width,
227
+ height: ctx.height
228
+ });
229
+ }
230
+ };
231
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @file marks/dotGLInteractive.tsx
3
+ * @output WebGL scatter with GPU color-picking for O(1) nearest-point hover
4
+ *
5
+ * Each point gets a unique color encoding its index. On hover, readPixels
6
+ * from an offscreen framebuffer decodes the hovered index — no JS iteration.
7
+ *
8
+ * Two GL contexts (visible + offscreen pick) plus their programs, buffers,
9
+ * framebuffer, and pick texture are created once and reused. The pick texture
10
+ * is re-allocated only when the drawing-buffer size changes, and everything is
11
+ * released (both contexts eagerly lost) on unmount. Recovers from context loss.
12
+ */
13
+ import { type ReactNode } from 'react';
14
+ import type { SeriesDef } from '../types';
15
+ export interface DotGLInteractiveOptions {
16
+ color: string;
17
+ size?: number;
18
+ opacity?: number;
19
+ /** Custom tooltip renderer. Receives datum and index. */
20
+ renderTooltip?: (datum: Record<string, unknown>, index: number) => ReactNode;
21
+ }
22
+ /**
23
+ * WebGL scatter with GPU color-picking hover. O(1) hit detection via offscreen
24
+ * framebuffer — no JS iteration regardless of point count.
25
+ *
26
+ * @example
27
+ * ```
28
+ * series={[dotGLInteractive('value', {
29
+ * color: '#4f46e5',
30
+ * renderTooltip: (d, i) => <span>{d.name}: {d.value}</span>,
31
+ * })]}
32
+ * ```
33
+ */
34
+ export declare function dotGLInteractive(dataKey: string, options: DotGLInteractiveOptions): SeriesDef;
35
+ //# sourceMappingURL=dotGLInteractive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dotGLInteractive.d.ts","sourceRoot":"","sources":["../../src/marks/dotGLInteractive.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAgB,MAAM,UAAU,CAAC;AASvD,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;CAC9E;AAgjBD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,uBAAuB,GAC/B,SAAS,CA8CX"}