@pharos-ds/charts 0.0.0-bootstrap.0 → 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.
- package/CHANGELOG.md +73 -0
- package/LICENSE +24 -0
- package/README.md +118 -0
- package/dist/Chart.d.ts +62 -0
- package/dist/Chart.d.ts.map +1 -0
- package/dist/Chart.js +401 -0
- package/dist/ChartAxis.d.ts +37 -0
- package/dist/ChartAxis.d.ts.map +1 -0
- package/dist/ChartAxis.js +233 -0
- package/dist/ChartContext.d.ts +4 -0
- package/dist/ChartContext.d.ts.map +1 -0
- package/dist/ChartContext.js +15 -0
- package/dist/ChartGrid.d.ts +26 -0
- package/dist/ChartGrid.d.ts.map +1 -0
- package/dist/ChartGrid.js +118 -0
- package/dist/ChartLegend.d.ts +14 -0
- package/dist/ChartLegend.d.ts.map +1 -0
- package/dist/ChartLegend.js +62 -0
- package/dist/ChartSwatch.d.ts +36 -0
- package/dist/ChartSwatch.d.ts.map +1 -0
- package/dist/ChartSwatch.js +85 -0
- package/dist/ChartTooltip.d.ts +46 -0
- package/dist/ChartTooltip.d.ts.map +1 -0
- package/dist/ChartTooltip.js +330 -0
- package/dist/charts.css +33 -0
- package/dist/dataTable.d.ts +56 -0
- package/dist/dataTable.d.ts.map +1 -0
- package/dist/dataTable.js +88 -0
- package/dist/formatters.d.ts +37 -0
- package/dist/formatters.d.ts.map +1 -0
- package/dist/formatters.js +156 -0
- package/dist/getChartColors.d.ts +67 -0
- package/dist/getChartColors.d.ts.map +1 -0
- package/dist/getChartColors.js +191 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/layout.d.ts +40 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +322 -0
- package/dist/legend.d.ts +17 -0
- package/dist/legend.d.ts.map +1 -0
- package/dist/legend.js +40 -0
- package/dist/markColor.d.ts +20 -0
- package/dist/markColor.d.ts.map +1 -0
- package/dist/markColor.js +56 -0
- package/dist/marks/area.d.ts +19 -0
- package/dist/marks/area.d.ts.map +1 -0
- package/dist/marks/area.js +121 -0
- package/dist/marks/band.d.ts +9 -0
- package/dist/marks/band.d.ts.map +1 -0
- package/dist/marks/band.js +64 -0
- package/dist/marks/bar.d.ts +21 -0
- package/dist/marks/bar.d.ts.map +1 -0
- package/dist/marks/bar.js +161 -0
- package/dist/marks/candlestick.d.ts +16 -0
- package/dist/marks/candlestick.d.ts.map +1 -0
- package/dist/marks/candlestick.js +110 -0
- package/dist/marks/dot.d.ts +19 -0
- package/dist/marks/dot.d.ts.map +1 -0
- package/dist/marks/dot.js +98 -0
- package/dist/marks/dotGL.d.ts +16 -0
- package/dist/marks/dotGL.d.ts.map +1 -0
- package/dist/marks/dotGL.js +231 -0
- package/dist/marks/dotGLInteractive.d.ts +35 -0
- package/dist/marks/dotGLInteractive.d.ts.map +1 -0
- package/dist/marks/dotGLInteractive.js +584 -0
- package/dist/marks/errorBar.d.ts +29 -0
- package/dist/marks/errorBar.d.ts.map +1 -0
- package/dist/marks/errorBar.js +95 -0
- package/dist/marks/heatmapGL.d.ts +27 -0
- package/dist/marks/heatmapGL.d.ts.map +1 -0
- package/dist/marks/heatmapGL.js +335 -0
- package/dist/marks/index.d.ts +13 -0
- package/dist/marks/index.d.ts.map +1 -0
- package/dist/marks/index.js +14 -0
- package/dist/marks/line.d.ts +18 -0
- package/dist/marks/line.d.ts.map +1 -0
- package/dist/marks/line.js +83 -0
- package/dist/marks/referenceLine.d.ts +37 -0
- package/dist/marks/referenceLine.d.ts.map +1 -0
- package/dist/marks/referenceLine.js +204 -0
- package/dist/marks/streamGL.d.ts +41 -0
- package/dist/marks/streamGL.d.ts.map +1 -0
- package/dist/marks/streamGL.js +317 -0
- package/dist/tooltip.d.ts +38 -0
- package/dist/tooltip.d.ts.map +1 -0
- package/dist/tooltip.js +57 -0
- package/dist/types.d.ts +193 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +70 -0
- package/dist/useChartColors.d.ts +16 -0
- package/dist/useChartColors.d.ts.map +1 -0
- package/dist/useChartColors.js +37 -0
- package/dist/utils.d.ts +15 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +31 -0
- package/dist/webgl.d.ts +77 -0
- package/dist/webgl.d.ts.map +1 -0
- package/dist/webgl.js +235 -0
- package/package.json +72 -4
- package/src/Chart.doc.mjs +174 -0
- package/src/Chart.test.tsx +273 -0
- package/src/Chart.tsx +535 -0
- package/src/ChartAxis.tsx +289 -0
- package/src/ChartContext.ts +18 -0
- package/src/ChartGrid.tsx +136 -0
- package/src/ChartLegend.tsx +77 -0
- package/src/ChartSwatch.doc.mjs +17 -0
- package/src/ChartSwatch.tsx +89 -0
- package/src/ChartTooltip.tsx +452 -0
- package/src/charts.css.d.ts +3 -0
- package/src/dataTable.test.ts +86 -0
- package/src/dataTable.ts +124 -0
- package/src/formatters.ts +167 -0
- package/src/getChartColors.test.ts +114 -0
- package/src/getChartColors.ts +282 -0
- package/src/index.ts +88 -0
- package/src/layout.ts +372 -0
- package/src/legend.ts +44 -0
- package/src/markColor.ts +70 -0
- package/src/marks/area.tsx +142 -0
- package/src/marks/band.tsx +86 -0
- package/src/marks/bar.tsx +210 -0
- package/src/marks/candlestick.tsx +128 -0
- package/src/marks/dot.tsx +119 -0
- package/src/marks/dotGL.tsx +274 -0
- package/src/marks/dotGLInteractive.tsx +660 -0
- package/src/marks/errorBar.tsx +119 -0
- package/src/marks/heatmapGL.tsx +392 -0
- package/src/marks/index.ts +17 -0
- package/src/marks/line.tsx +118 -0
- package/src/marks/referenceLine.tsx +252 -0
- package/src/marks/streamGL.tsx +381 -0
- package/src/tooltip.ts +73 -0
- package/src/types.ts +212 -0
- package/src/useChartColors.ts +41 -0
- package/src/utils.ts +38 -0
- package/src/webgl.ts +262 -0
package/dist/webgl.js
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file webgl.ts
|
|
5
|
+
* @output Shared WebGL utilities for chart components
|
|
6
|
+
* @position Internal helpers; consumed by all GL mark components
|
|
7
|
+
*
|
|
8
|
+
* Provides:
|
|
9
|
+
* - Canvas mounting outside SVG (avoids foreignObject DPR blur)
|
|
10
|
+
* - Premultiplied alpha setup (correct compositing over page)
|
|
11
|
+
* - Shader compilation helpers
|
|
12
|
+
* - Smoothstep circle fragment for crisp point sprites
|
|
13
|
+
* - Hex-to-GL color conversion via the shared @pharos-ds/core/utils/color
|
|
14
|
+
* parsers (fallback instead of NaN)
|
|
15
|
+
* - Context-loss registration + eager context teardown helpers
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { parseHex, toGLFloats } from '@pharos-ds/core/utils';
|
|
19
|
+
|
|
20
|
+
/** Compile a WebGL shader, returns null on failure */
|
|
21
|
+
export function compileShader(gl, type, src) {
|
|
22
|
+
const s = gl.createShader(type);
|
|
23
|
+
if (!s) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
gl.shaderSource(s, src);
|
|
27
|
+
gl.compileShader(s);
|
|
28
|
+
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {
|
|
29
|
+
gl.deleteShader(s);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return s;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Link a vertex + fragment shader into a program */
|
|
36
|
+
export function createProgram(gl, vertSrc, fragSrc) {
|
|
37
|
+
const vs = compileShader(gl, gl.VERTEX_SHADER, vertSrc);
|
|
38
|
+
const fs = compileShader(gl, gl.FRAGMENT_SHADER, fragSrc);
|
|
39
|
+
if (!vs || !fs) {
|
|
40
|
+
// One shader may have compiled while the other failed — free the survivor
|
|
41
|
+
// so the failure path never leaks a shader object.
|
|
42
|
+
if (vs) {
|
|
43
|
+
gl.deleteShader(vs);
|
|
44
|
+
}
|
|
45
|
+
if (fs) {
|
|
46
|
+
gl.deleteShader(fs);
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
const p = gl.createProgram();
|
|
51
|
+
if (!p) {
|
|
52
|
+
gl.deleteShader(vs);
|
|
53
|
+
gl.deleteShader(fs);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
gl.attachShader(p, vs);
|
|
57
|
+
gl.attachShader(p, fs);
|
|
58
|
+
gl.linkProgram(p);
|
|
59
|
+
// The shaders are now linked into the program; flag them for deletion so the
|
|
60
|
+
// GPU frees them once the program is deleted instead of leaving them attached
|
|
61
|
+
// (and allocated) for the program's whole lifetime.
|
|
62
|
+
gl.deleteShader(vs);
|
|
63
|
+
gl.deleteShader(fs);
|
|
64
|
+
if (!gl.getProgramParameter(p, gl.LINK_STATUS)) {
|
|
65
|
+
gl.deleteProgram(p);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
return p;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Parse a hex color to [r, g, b] floats in 0-1.
|
|
73
|
+
*
|
|
74
|
+
* Accepts `#rgb`, `#rgba`, `#rrggbb`, and `#rrggbbaa`, with or without the
|
|
75
|
+
* leading `#` (any alpha byte is ignored). Non-hex input — CSS custom
|
|
76
|
+
* properties, `rgb()`, named colors, or malformed strings — returns a neutral
|
|
77
|
+
* fallback rather than producing NaN, so the GPU never receives a bad uniform.
|
|
78
|
+
*/
|
|
79
|
+
export function hexToGL(hex) {
|
|
80
|
+
return toGLFloats(parseHex(hex));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** DPR with 2x supersampling for crisp circles. SSR-safe (falls back to 2). */
|
|
84
|
+
export function getCanvasDPR() {
|
|
85
|
+
const base = typeof window !== 'undefined' ? window.devicePixelRatio : 0;
|
|
86
|
+
return (base || 2) * 2;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Create or get a WebGL context with correct alpha settings.
|
|
91
|
+
* Uses premultiplied alpha for correct compositing over the page.
|
|
92
|
+
*/
|
|
93
|
+
export function getWebGLContext(canvas) {
|
|
94
|
+
return canvas.getContext('webgl', {
|
|
95
|
+
alpha: true,
|
|
96
|
+
premultipliedAlpha: true,
|
|
97
|
+
antialias: true
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Set up standard GL state for chart rendering:
|
|
103
|
+
* - Clear with transparent
|
|
104
|
+
* - Enable premultiplied alpha blending
|
|
105
|
+
*/
|
|
106
|
+
export function setupGLState(gl) {
|
|
107
|
+
gl.clearColor(0, 0, 0, 0);
|
|
108
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
109
|
+
gl.enable(gl.BLEND);
|
|
110
|
+
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Size a canvas for sharp rendering, accounting for DPR.
|
|
115
|
+
* Returns the DPR used.
|
|
116
|
+
*/
|
|
117
|
+
export function sizeCanvas(canvas, width, height) {
|
|
118
|
+
const dpr = getCanvasDPR();
|
|
119
|
+
// The drawing buffer must be a positive integer — a 0-sized (or fractional)
|
|
120
|
+
// buffer makes GL viewport/draw calls silently fail.
|
|
121
|
+
canvas.width = Math.max(1, Math.round(width * dpr));
|
|
122
|
+
canvas.height = Math.max(1, Math.round(height * dpr));
|
|
123
|
+
canvas.style.width = `${Math.max(0, width)}px`;
|
|
124
|
+
canvas.style.height = `${Math.max(0, height)}px`;
|
|
125
|
+
return dpr;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Mount a canvas as an absolute-positioned sibling to an SVG element.
|
|
130
|
+
* Automatically aligns with the SVG marker's position — no manual margin
|
|
131
|
+
* offset needed. This is a Tier 1 guarantee: the canvas lands exactly
|
|
132
|
+
* where the SVG content area is, regardless of chart margins or transforms.
|
|
133
|
+
*
|
|
134
|
+
* Call from a useEffect. Returns a cleanup function.
|
|
135
|
+
*/
|
|
136
|
+
export function mountCanvasOverSVG(svgMarker, canvas, width, height) {
|
|
137
|
+
const svg = svgMarker.ownerSVGElement;
|
|
138
|
+
if (!svg) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const parent = svg.parentElement;
|
|
142
|
+
if (!parent) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (getComputedStyle(parent).position === 'static') {
|
|
146
|
+
parent.style.position = 'relative';
|
|
147
|
+
}
|
|
148
|
+
canvas.style.position = 'absolute';
|
|
149
|
+
canvas.style.pointerEvents = 'none';
|
|
150
|
+
|
|
151
|
+
// Compute offset from the SVG marker's actual screen position.
|
|
152
|
+
// The marker sits inside the chart's <g transform="translate(margin)">
|
|
153
|
+
// so its bounding rect includes the margin offset automatically.
|
|
154
|
+
// This is a Tier 1 guarantee — we derive position from the SVG, not from props.
|
|
155
|
+
const parentRect = parent.getBoundingClientRect();
|
|
156
|
+
const markerCTM = svgMarker.getScreenCTM();
|
|
157
|
+
if (markerCTM) {
|
|
158
|
+
canvas.style.left = `${markerCTM.e - parentRect.left}px`;
|
|
159
|
+
canvas.style.top = `${markerCTM.f - parentRect.top}px`;
|
|
160
|
+
} else {
|
|
161
|
+
canvas.style.left = '0';
|
|
162
|
+
canvas.style.top = '0';
|
|
163
|
+
}
|
|
164
|
+
canvas.style.width = `${width}px`;
|
|
165
|
+
canvas.style.height = `${height}px`;
|
|
166
|
+
parent.appendChild(canvas);
|
|
167
|
+
return () => {
|
|
168
|
+
if (canvas.parentElement === parent) {
|
|
169
|
+
parent.removeChild(canvas);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Register WebGL context-loss/restore handlers on a canvas.
|
|
176
|
+
*
|
|
177
|
+
* Calling `preventDefault()` on the lost event is REQUIRED — without it the
|
|
178
|
+
* browser will never fire `webglcontextrestored`. `onLost` should drop any
|
|
179
|
+
* cached GL handles (they are all invalid after loss); `onRestored` should
|
|
180
|
+
* trigger a rebuild + redraw.
|
|
181
|
+
*
|
|
182
|
+
* Returns a cleanup that removes both listeners.
|
|
183
|
+
*/
|
|
184
|
+
export function registerContextLossHandlers(canvas, onLost, onRestored) {
|
|
185
|
+
const handleLost = e => {
|
|
186
|
+
e.preventDefault();
|
|
187
|
+
onLost();
|
|
188
|
+
};
|
|
189
|
+
canvas.addEventListener('webglcontextlost', handleLost, false);
|
|
190
|
+
canvas.addEventListener('webglcontextrestored', onRestored, false);
|
|
191
|
+
return () => {
|
|
192
|
+
canvas.removeEventListener('webglcontextlost', handleLost, false);
|
|
193
|
+
canvas.removeEventListener('webglcontextrestored', onRestored, false);
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Eagerly release a WebGL context and its GPU resources on teardown.
|
|
199
|
+
*
|
|
200
|
+
* Browsers cap the number of live contexts (~16), so freeing on unmount rather
|
|
201
|
+
* than waiting for GC prevents "too many active WebGL contexts" failures when
|
|
202
|
+
* many charts mount/unmount over a session.
|
|
203
|
+
*/
|
|
204
|
+
export function loseContext(gl) {
|
|
205
|
+
const ext = gl.getExtension('WEBGL_lose_context');
|
|
206
|
+
if (ext) {
|
|
207
|
+
ext.loseContext();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* GLSL fragment for premultiplied-alpha circle with smoothstep AA.
|
|
213
|
+
* Use in fragment shaders that render point sprites.
|
|
214
|
+
*
|
|
215
|
+
* Expects:
|
|
216
|
+
* - varying float v_alpha (the final alpha before edge AA)
|
|
217
|
+
* - uniform vec3 u_color
|
|
218
|
+
*
|
|
219
|
+
* Returns: gl_FragColor with premultiplied alpha
|
|
220
|
+
*/
|
|
221
|
+
export const CIRCLE_FRAG_BODY = `
|
|
222
|
+
vec2 coord = gl_PointCoord - vec2(0.5);
|
|
223
|
+
float dist = length(coord);
|
|
224
|
+
if (dist > 0.5) discard;
|
|
225
|
+
float edge = 1.0 - smoothstep(0.48, 0.5, dist);
|
|
226
|
+
float a = v_alpha * edge;
|
|
227
|
+
gl_FragColor = vec4(u_color * a, a);
|
|
228
|
+
`;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Smoothstep compensation factor for gl_PointSize.
|
|
232
|
+
* The visible circle radius is 0.48 of the point sprite (smoothstep starts there),
|
|
233
|
+
* so we scale up by 1/0.96 to match SVG circle radius exactly.
|
|
234
|
+
*/
|
|
235
|
+
export const POINT_SIZE_COMPENSATION = 1.0 / 0.96;
|
package/package.json
CHANGED
|
@@ -1,6 +1,74 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pharos-ds/charts",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.10",
|
|
4
|
+
"displayName": "Pharos Charts",
|
|
5
|
+
"private": false,
|
|
6
|
+
"description": "Pharos charts — a config-model data visualization library (d3-based) with bar, line, area and more, themed by Pharos tokens and accessible by default.",
|
|
7
|
+
"author": "Caio Silvestre",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"homepage": "https://github.com/Lex-Energia/alexandria-ds#readme",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/Lex-Energia/alexandria-ds.git",
|
|
13
|
+
"directory": "packages/charts"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/Lex-Energia/alexandria-ds/issues"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"pharos",
|
|
20
|
+
"charts",
|
|
21
|
+
"data-visualization",
|
|
22
|
+
"design-system"
|
|
23
|
+
],
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"module": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"sideEffects": [
|
|
29
|
+
"**/*.css"
|
|
30
|
+
],
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"src",
|
|
34
|
+
"README.md",
|
|
35
|
+
"CHANGELOG.md"
|
|
36
|
+
],
|
|
37
|
+
"exports": {
|
|
38
|
+
".": {
|
|
39
|
+
"source": "./src/index.ts",
|
|
40
|
+
"types": "./dist/index.d.ts",
|
|
41
|
+
"default": "./dist/index.js"
|
|
42
|
+
},
|
|
43
|
+
"./charts.css": {
|
|
44
|
+
"types": "./src/charts.css.d.ts",
|
|
45
|
+
"default": "./dist/charts.css"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"@pharos-ds/core": "1.0.10",
|
|
50
|
+
"@stylexjs/stylex": "^0.19.0",
|
|
51
|
+
"react": ">=19.0.0",
|
|
52
|
+
"react-dom": ">=19.0.0"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"d3-array": "^3.2.4",
|
|
56
|
+
"d3-scale": "^4.0.2",
|
|
57
|
+
"d3-shape": "^3.2.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@types/d3-scale": "^4.0.9",
|
|
61
|
+
"@types/d3-shape": "^3.1.8"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "rm -rf dist && pnpm build:esm && tsc --project tsconfig.build.json && pnpm build:css && node ../../scripts/check-no-dev-jsx.mjs",
|
|
65
|
+
"build:esm": "babel src --out-dir dist --extensions .ts,.tsx --out-file-extension .js --ignore \"**/*.test.ts,**/*.test.tsx,**/__tests__/**,**/*.perf.test.*,**/*.doc.mjs,**/*.d.ts,**/*.css,**/*.css.d.ts\" --config-file ./babel.config.cjs",
|
|
66
|
+
"build:css": "node ../../scripts/build-css.mjs --package charts",
|
|
67
|
+
"dev": "babel src --watch --out-dir dist --extensions .ts,.tsx --out-file-extension .js --ignore \"**/*.test.*,**/*.doc.mjs,**/*.d.ts,**/*.css*\" --config-file ./babel.config.cjs",
|
|
68
|
+
"test": "vitest run --root ../..",
|
|
69
|
+
"test:watch": "vitest --root ../..",
|
|
70
|
+
"lint": "eslint src",
|
|
71
|
+
"typecheck:docs": "tsc --project tsconfig.docs.json",
|
|
72
|
+
"typecheck": "tsc --project tsconfig.json --noEmit"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/** @type {import('../../core/src/docs-types').ComponentDoc} */
|
|
4
|
+
|
|
5
|
+
export const docs = {
|
|
6
|
+
name: 'Chart',
|
|
7
|
+
displayName: 'Chart',
|
|
8
|
+
group: 'Charts',
|
|
9
|
+
category: 'Data Visualization',
|
|
10
|
+
keywords: [
|
|
11
|
+
'chart',
|
|
12
|
+
'graph',
|
|
13
|
+
'bar',
|
|
14
|
+
'line',
|
|
15
|
+
'area',
|
|
16
|
+
'horizontal bar',
|
|
17
|
+
'data visualization',
|
|
18
|
+
'dataviz',
|
|
19
|
+
'accessible chart',
|
|
20
|
+
],
|
|
21
|
+
|
|
22
|
+
usage: {
|
|
23
|
+
description:
|
|
24
|
+
'Config-model chart: pass `data`, the `xKey` that identifies each row and a `series` array of mark factories (`bar`, `line`, `area`, `dot`, `band`, `referenceLine`, `errorBar`, `candlestick` and WebGL variants). One x/y scale is shared by every mark, axis and grid line. Series without an explicit `color` take the theme categorical palette in order (Pharos: azul, roxo, laranja, amarelo, chumbo), resolved for the active light/dark mode. Accessible by default: the SVG is `role="img"` named by `aria-label` → `title` → series labels, `subtitle`/`description` become its description, and a visually hidden data table carries the values for screen readers. Dist consumers import `@pharos-ds/core/pharos.css` and `@pharos-ds/charts/charts.css`; no StyleX compiler is needed.',
|
|
25
|
+
bestPractices: [
|
|
26
|
+
{
|
|
27
|
+
guidance: true,
|
|
28
|
+
description:
|
|
29
|
+
'Give every chart a `title` (or `aria-label` when the visible heading lives outside the chart, e.g. in a Card header).',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
guidance: true,
|
|
33
|
+
description:
|
|
34
|
+
'Add a `description` that states the takeaway ("Instagram lidera com 120 leads") — the hidden table has the numbers, the description has the meaning.',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
guidance: true,
|
|
38
|
+
description:
|
|
39
|
+
'Use `orientation="horizontal"` for long category names or rankings; pair it with `<ChartAxis position="left" />` (categories) and `<ChartAxis position="bottom" />` (values), and widen `margin.left` to fit the labels.',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
guidance: true,
|
|
43
|
+
description:
|
|
44
|
+
'Let series take palette colors (omit `color`) so light/dark mode and the brand order work automatically.',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
guidance: false,
|
|
48
|
+
description:
|
|
49
|
+
'Turn off `dataTable` unless the same data is already on the page as a real table — it is the text alternative for screen-reader users.',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
guidance: false,
|
|
53
|
+
description:
|
|
54
|
+
'Rely on the tooltip to convey values: it is pointer-only (no keyboard focus), so anything essential must be in the table, the description or visible labels.',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
guidance: false,
|
|
58
|
+
description:
|
|
59
|
+
'Share one series array between charts: each `<Chart>` annotates its series defs, so build a fresh array per chart.',
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
props: [
|
|
65
|
+
{
|
|
66
|
+
name: 'data',
|
|
67
|
+
type: 'Record<string, unknown>[]',
|
|
68
|
+
description: 'Rows to plot. Each row has the x value under `xKey` plus one value per series data key.',
|
|
69
|
+
required: true,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'xKey',
|
|
73
|
+
type: 'string',
|
|
74
|
+
description: 'Key of the x value. Strings make a categorical (band) axis, numbers a linear one.',
|
|
75
|
+
required: true,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'series',
|
|
79
|
+
type: 'SeriesDef[]',
|
|
80
|
+
description: 'Marks to draw, built with the mark factories (`bar("leads")`, `line("meta", {label: "Meta"})`, …). Order sets palette order and draw order.',
|
|
81
|
+
required: true,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'title',
|
|
85
|
+
type: 'string',
|
|
86
|
+
description: 'Visible heading above the chart. Also the accessible name and the hidden table caption unless `aria-label` is set.',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'subtitle',
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: 'Visible supporting line under the title; part of the SVG description (`aria-describedby`).',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'aria-label',
|
|
95
|
+
type: 'string',
|
|
96
|
+
description: 'Accessible name of the chart image. Defaults to `title`, then to the data series labels joined by commas.',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'description',
|
|
100
|
+
type: 'string',
|
|
101
|
+
description: 'Text alternative summarizing the chart (trend, highlights). Not visible; exposed through `aria-describedby` after `subtitle`.',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'dataTable',
|
|
105
|
+
type: 'boolean | { xLabel?: string; formatX?: (value) => string; formatValue?: (value, series, dataKey) => string; maxRows?: number }',
|
|
106
|
+
description: 'Visually hidden `<table>` generated from `data`: caption = accessible name, header row = x label + series labels, one row per x value. Utility marks (band, errorBar, referenceLine) get no column. Omitted above `maxRows` rows (default 1000). Pass `false` to opt out.',
|
|
107
|
+
default: 'true',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'orientation',
|
|
111
|
+
type: "'vertical' | 'horizontal'",
|
|
112
|
+
description: 'Horizontal puts categories on the y-axis and grows values to the right (horizontal bars). Axes and grid follow; use the `tooltip` prop rather than a `ChartTooltip` child.',
|
|
113
|
+
default: "'vertical'",
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: 'height',
|
|
117
|
+
type: 'number',
|
|
118
|
+
description: 'Height of the plot SVG in px. Width always fills the container.',
|
|
119
|
+
default: '300',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'margin',
|
|
123
|
+
type: 'Partial<{top: number; right: number; bottom: number; left: number}>',
|
|
124
|
+
description: 'Space reserved around the plot for axis labels.',
|
|
125
|
+
default: '{top: 24, right: 24, bottom: 32, left: 48}',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'grid',
|
|
129
|
+
type: 'ReactNode',
|
|
130
|
+
description: 'Grid slot, usually `<ChartGrid />` (follows the value axis by default).',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'axes',
|
|
134
|
+
type: 'ReactNode',
|
|
135
|
+
description: 'Axis slot, usually `<ChartAxis position="bottom" />` and `<ChartAxis position="left" />`.',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'legend',
|
|
139
|
+
type: 'boolean | ChartLegendProps',
|
|
140
|
+
description: 'Shows a legend derived from the series (labels + swatches); pass an object for position and alignment.',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: 'tooltip',
|
|
144
|
+
type: 'boolean | Omit<ChartTooltipProps, "series">',
|
|
145
|
+
description: 'Pointer tooltip with every series value at the hovered x. Pointer-only and never focusable.',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: 'yBaseline',
|
|
149
|
+
type: "'auto' | 'zero' | 'data'",
|
|
150
|
+
description: 'How the value domain is derived when `yDomain` is not set: bars/areas pin zero (`auto`), symmetric around zero (`zero`) or tight to the data (`data`).',
|
|
151
|
+
default: "'auto'",
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: 'yDomain',
|
|
155
|
+
type: '[number, number]',
|
|
156
|
+
description: 'Explicit value domain. Authoritative — disables baseline and headroom.',
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: 'xDomain',
|
|
160
|
+
type: '[number, number]',
|
|
161
|
+
description: 'Explicit numeric x domain (streaming windows). Ignored for categorical x.',
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: 'interactions',
|
|
165
|
+
type: 'ReactNode',
|
|
166
|
+
description: 'Slot for interaction layers that read the chart context (`useChart`).',
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: 'children',
|
|
170
|
+
type: 'ReactNode',
|
|
171
|
+
description: 'Escape hatch rendered last inside the plot group.',
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
};
|