@opendata-ai/openchart-vanilla 2.0.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/dist/index.d.ts +327 -0
- package/dist/index.js +4745 -0
- package/dist/index.js.map +1 -0
- package/dist/simulation-worker.js +1196 -0
- package/package.json +58 -0
- package/src/__test-fixtures__/dom.ts +42 -0
- package/src/__test-fixtures__/specs.ts +187 -0
- package/src/__tests__/edit-events.test.ts +747 -0
- package/src/__tests__/events.test.ts +336 -0
- package/src/__tests__/export.test.ts +150 -0
- package/src/__tests__/mount.test.ts +219 -0
- package/src/__tests__/svg-renderer.test.ts +609 -0
- package/src/__tests__/table-mount.test.ts +484 -0
- package/src/__tests__/tooltip.test.ts +201 -0
- package/src/export.ts +105 -0
- package/src/graph/__tests__/canvas-renderer.test.ts +704 -0
- package/src/graph/__tests__/graph-mount.test.ts +213 -0
- package/src/graph/__tests__/interaction.test.ts +205 -0
- package/src/graph/__tests__/keyboard.test.ts +653 -0
- package/src/graph/__tests__/search.test.ts +88 -0
- package/src/graph/__tests__/simulation.test.ts +233 -0
- package/src/graph/__tests__/spatial-index.test.ts +142 -0
- package/src/graph/__tests__/zoom.test.ts +195 -0
- package/src/graph/canvas-renderer.ts +660 -0
- package/src/graph/interaction.ts +359 -0
- package/src/graph/keyboard.ts +208 -0
- package/src/graph/search.ts +50 -0
- package/src/graph/simulation-worker-url.ts +30 -0
- package/src/graph/simulation-worker.ts +265 -0
- package/src/graph/simulation.ts +350 -0
- package/src/graph/spatial-index.ts +121 -0
- package/src/graph/types.ts +44 -0
- package/src/graph/worker-protocol.ts +67 -0
- package/src/graph/zoom.ts +104 -0
- package/src/graph-mount.ts +675 -0
- package/src/index.ts +56 -0
- package/src/mount.ts +1639 -0
- package/src/renderers/table-cells.ts +444 -0
- package/src/resize-observer.ts +46 -0
- package/src/svg-renderer.ts +914 -0
- package/src/table-keyboard.ts +266 -0
- package/src/table-mount.ts +532 -0
- package/src/table-renderer.ts +350 -0
- package/src/tooltip.ts +120 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
export { ChartLayout, ChartSpec, CompileOptions, TableLayout, TableSpec, VizSpec } from '@opendata-ai/openchart-engine';
|
|
2
|
+
import { GraphSpec, ThemeConfig, DarkMode, ChartSpec, ChartLayout, ChartEventHandlers, BarTableCell, CategoryTableCell, TableCell, FlagTableCell, HeatmapTableCell, ImageTableCell, SparklineTableCell, TextTableCell, Mark, TableSpec, SortState, TableLayout, TooltipContent } from '@opendata-ai/openchart-core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Export utilities: serialize charts to SVG, PNG, or CSV.
|
|
6
|
+
*
|
|
7
|
+
* - SVG: serializes the rendered DOM element via XMLSerializer
|
|
8
|
+
* - PNG: renders SVG to canvas, then extracts as Blob
|
|
9
|
+
* - CSV: converts a data array to comma-separated text
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Serialize an SVG element to an XML string.
|
|
13
|
+
*
|
|
14
|
+
* @param svgElement - The rendered SVG element to serialize.
|
|
15
|
+
* @returns The SVG markup as a string.
|
|
16
|
+
*/
|
|
17
|
+
declare function exportSVG(svgElement: SVGElement): string;
|
|
18
|
+
interface PNGExportOptions {
|
|
19
|
+
/** DPI scaling factor. Defaults to 2 for retina-quality output. */
|
|
20
|
+
dpi?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Render an SVG element to a PNG Blob via a canvas.
|
|
24
|
+
*
|
|
25
|
+
* @param svgElement - The rendered SVG element.
|
|
26
|
+
* @param options - Optional DPI scaling.
|
|
27
|
+
* @returns A Promise resolving to the PNG Blob.
|
|
28
|
+
*/
|
|
29
|
+
declare function exportPNG(svgElement: SVGElement, options?: PNGExportOptions): Promise<Blob>;
|
|
30
|
+
/**
|
|
31
|
+
* Convert an array of data objects to a CSV string.
|
|
32
|
+
*
|
|
33
|
+
* Uses the keys from the first row as column headers.
|
|
34
|
+
* Values are quoted if they contain commas, quotes, or newlines.
|
|
35
|
+
*
|
|
36
|
+
* @param data - Array of row objects.
|
|
37
|
+
* @returns CSV-formatted string.
|
|
38
|
+
*/
|
|
39
|
+
declare function exportCSV(data: Record<string, unknown>[]): string;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a Web Worker running the force simulation.
|
|
43
|
+
*
|
|
44
|
+
* Uses the `new URL` + `import.meta.url` pattern recognized by Vite, Webpack 5,
|
|
45
|
+
* Parcel, and esbuild. The bundler resolves the worker file path at build time
|
|
46
|
+
* and handles the asset accordingly.
|
|
47
|
+
*
|
|
48
|
+
* - Vite dev (Ladle): resolves src/graph/simulation-worker.ts directly, serves
|
|
49
|
+
* it as a native ES module worker with on-the-fly TypeScript transform.
|
|
50
|
+
* - Production (tsup + bun build): dist/simulation-worker.js is a self-contained
|
|
51
|
+
* IIFE produced by `bun build`. The consuming app's bundler copies it as an
|
|
52
|
+
* asset and rewrites the URL.
|
|
53
|
+
*
|
|
54
|
+
* Usage:
|
|
55
|
+
* import { createSimulationWorker } from '@opendata-ai/openchart-vanilla';
|
|
56
|
+
* const worker = createSimulationWorker();
|
|
57
|
+
* worker.postMessage({ type: 'init', nodes, links, width: 800, height: 600 });
|
|
58
|
+
* worker.onmessage = (e) => console.log(e.data);
|
|
59
|
+
*/
|
|
60
|
+
declare function createSimulationWorker(): Worker;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Graph mount API: the main entry point for vanilla JS graph usage.
|
|
64
|
+
*
|
|
65
|
+
* createGraph() takes a container, GraphSpec, and options, compiles the graph,
|
|
66
|
+
* creates a force simulation, canvas renderer, spatial index, interaction
|
|
67
|
+
* manager, and search manager, then runs an animation loop driven by
|
|
68
|
+
* simulation ticks. Returns a GraphInstance with update/search/zoom/destroy.
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
interface GraphMountOptions {
|
|
72
|
+
theme?: ThemeConfig;
|
|
73
|
+
darkMode?: DarkMode;
|
|
74
|
+
responsive?: boolean;
|
|
75
|
+
onNodeClick?: (node: Record<string, unknown>) => void;
|
|
76
|
+
onNodeDoubleClick?: (node: Record<string, unknown>) => void;
|
|
77
|
+
onSelectionChange?: (nodeIds: string[]) => void;
|
|
78
|
+
}
|
|
79
|
+
interface GraphInstance {
|
|
80
|
+
update(spec: GraphSpec): void;
|
|
81
|
+
search(query: string): void;
|
|
82
|
+
clearSearch(): void;
|
|
83
|
+
zoomToFit(): void;
|
|
84
|
+
zoomToNode(nodeId: string): void;
|
|
85
|
+
selectNode(nodeId: string): void;
|
|
86
|
+
getSelectedNodes(): string[];
|
|
87
|
+
resize(): void;
|
|
88
|
+
destroy(): void;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create a graph instance from a spec and mount it into a container.
|
|
92
|
+
*
|
|
93
|
+
* @param container - The DOM element to render into.
|
|
94
|
+
* @param spec - The graph spec.
|
|
95
|
+
* @param options - Mount options.
|
|
96
|
+
* @returns A GraphInstance with update/search/zoom/destroy methods.
|
|
97
|
+
*/
|
|
98
|
+
declare function createGraph(container: HTMLElement, spec: GraphSpec, options?: GraphMountOptions): GraphInstance;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Mount API: the main entry point for vanilla JS usage.
|
|
102
|
+
*
|
|
103
|
+
* createChart() takes a container, spec, and options, compiles the chart,
|
|
104
|
+
* renders it as SVG, sets up responsive resizing, tooltip interaction
|
|
105
|
+
* (mouse/touch/keyboard), keyboard navigation between data points,
|
|
106
|
+
* and returns a ChartInstance with update/resize/export/destroy methods.
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
interface MountOptions extends ChartEventHandlers {
|
|
110
|
+
/** Theme overrides. */
|
|
111
|
+
theme?: ThemeConfig;
|
|
112
|
+
/** Dark mode setting: "auto" (system pref), "force", or "off". */
|
|
113
|
+
darkMode?: DarkMode;
|
|
114
|
+
/** Callback when a data point is clicked. @deprecated Use onMarkClick instead. */
|
|
115
|
+
onDataPointClick?: (data: Record<string, unknown>) => void;
|
|
116
|
+
/** Enable responsive resizing. Defaults to true. */
|
|
117
|
+
responsive?: boolean;
|
|
118
|
+
}
|
|
119
|
+
interface ExportOptions extends PNGExportOptions {
|
|
120
|
+
}
|
|
121
|
+
interface ChartInstance {
|
|
122
|
+
/** Re-compile and re-render with a new spec. */
|
|
123
|
+
update(spec: ChartSpec | GraphSpec): void;
|
|
124
|
+
/** Re-compile at current container dimensions. */
|
|
125
|
+
resize(): void;
|
|
126
|
+
/** Export the chart. */
|
|
127
|
+
export(format: 'svg'): string;
|
|
128
|
+
export(format: 'png', options?: ExportOptions): Promise<Blob>;
|
|
129
|
+
export(format: 'csv'): string;
|
|
130
|
+
export(format: 'svg' | 'png' | 'csv', options?: ExportOptions): string | Promise<Blob>;
|
|
131
|
+
/** Remove all DOM elements and disconnect observers. */
|
|
132
|
+
destroy(): void;
|
|
133
|
+
/** The current compiled layout (for hooks / debugging). */
|
|
134
|
+
readonly layout: ChartLayout;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Create a chart instance from a spec and mount it into a container.
|
|
138
|
+
*
|
|
139
|
+
* @param container - The DOM element to render into.
|
|
140
|
+
* @param spec - The visualization spec.
|
|
141
|
+
* @param options - Mount options (theme, darkMode, responsive, etc.).
|
|
142
|
+
* @returns A ChartInstance with update/resize/export/destroy methods.
|
|
143
|
+
*/
|
|
144
|
+
declare function createChart(container: HTMLElement, spec: ChartSpec | GraphSpec, options?: MountOptions): ChartInstance;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Table cell renderers: produce DOM elements for each cell type.
|
|
148
|
+
*
|
|
149
|
+
* Each renderer takes a resolved TableCell and returns an HTMLElement
|
|
150
|
+
* (typically a <td>) with appropriate content, styling, and classes.
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
/** Render a plain text cell. */
|
|
154
|
+
declare function renderTextCell(cell: TextTableCell): HTMLTableCellElement;
|
|
155
|
+
/** Render a heatmap-colored cell. */
|
|
156
|
+
declare function renderHeatmapCell(cell: HeatmapTableCell): HTMLTableCellElement;
|
|
157
|
+
/** Render a category-colored cell. */
|
|
158
|
+
declare function renderCategoryCell(cell: CategoryTableCell): HTMLTableCellElement;
|
|
159
|
+
/** Render a cell with an inline bar visualization. */
|
|
160
|
+
declare function renderBarCell(cell: BarTableCell): HTMLTableCellElement;
|
|
161
|
+
/** Render a cell with an inline sparkline SVG. */
|
|
162
|
+
declare function renderSparklineCell(cell: SparklineTableCell): HTMLTableCellElement;
|
|
163
|
+
/** Render a cell with an image. */
|
|
164
|
+
declare function renderImageCell(cell: ImageTableCell): HTMLTableCellElement;
|
|
165
|
+
/** Render a cell with a country flag emoji. */
|
|
166
|
+
declare function renderFlagCell(cell: FlagTableCell): HTMLTableCellElement;
|
|
167
|
+
/** Render any table cell by dispatching on its cellType. */
|
|
168
|
+
declare function renderCell(cell: TableCell): HTMLTableCellElement;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Resize observer: thin wrapper around ResizeObserver with debounce.
|
|
172
|
+
*
|
|
173
|
+
* Watches a container element for size changes and calls back with
|
|
174
|
+
* the new width and height. Debounced at ~60fps (16ms) to avoid
|
|
175
|
+
* excessive re-renders during drag resizes.
|
|
176
|
+
*/
|
|
177
|
+
/**
|
|
178
|
+
* Observe a container element for size changes.
|
|
179
|
+
*
|
|
180
|
+
* @param container - The element to watch.
|
|
181
|
+
* @param callback - Called with (width, height) when size changes.
|
|
182
|
+
* @returns A cleanup function that disconnects the observer.
|
|
183
|
+
*/
|
|
184
|
+
declare function observeResize(container: HTMLElement, callback: (width: number, height: number) => void): () => void;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* SVG renderer: converts a ChartLayout into SVG DOM elements.
|
|
188
|
+
*
|
|
189
|
+
* Creates an <svg> element with viewBox matching layout dimensions,
|
|
190
|
+
* renders chrome (title/subtitle/source), axes, marks, annotations,
|
|
191
|
+
* and legend. All styling via inline SVG attributes from layout data.
|
|
192
|
+
*
|
|
193
|
+
* Mark rendering dispatches per mark type with dedicated renderers
|
|
194
|
+
* for line, area, rect, arc, and point marks.
|
|
195
|
+
*/
|
|
196
|
+
|
|
197
|
+
type MarkRenderer<T extends Mark> = (mark: T, index: number) => SVGElement;
|
|
198
|
+
/**
|
|
199
|
+
* Register a mark renderer for a specific mark type.
|
|
200
|
+
* Built-in renderers are registered below for all chart types.
|
|
201
|
+
*/
|
|
202
|
+
declare function registerMarkRenderer<T extends Mark>(type: T['type'], renderer: MarkRenderer<T>): void;
|
|
203
|
+
/**
|
|
204
|
+
* Render a compiled ChartLayout into an SVG element and append it to a container.
|
|
205
|
+
*
|
|
206
|
+
* @param layout - Compiled ChartLayout from compileChart().
|
|
207
|
+
* @param container - DOM element to mount the SVG into.
|
|
208
|
+
* @returns The created SVG element.
|
|
209
|
+
*/
|
|
210
|
+
declare function renderChartSVG(layout: ChartLayout, container: HTMLElement): SVGElement;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Table keyboard navigation: arrow-key cell navigation, Enter to sort,
|
|
214
|
+
* Escape to clear search, and aria-activedescendant management.
|
|
215
|
+
*
|
|
216
|
+
* Designed to be wired up by table-mount.ts after render. Returns a
|
|
217
|
+
* cleanup function to remove listeners on re-render or destroy.
|
|
218
|
+
*/
|
|
219
|
+
interface KeyboardNavOptions {
|
|
220
|
+
/** The wrapper element containing the whole table UI. */
|
|
221
|
+
wrapper: HTMLElement;
|
|
222
|
+
/** Callback to trigger sort on a column. */
|
|
223
|
+
onSort: (columnKey: string) => void;
|
|
224
|
+
/** Callback to clear search and return focus to the table body. */
|
|
225
|
+
onClearSearch: () => void;
|
|
226
|
+
/** Callback to announce text to screen readers via the live region. */
|
|
227
|
+
onAnnounce: (message: string) => void;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Attach keyboard navigation to a rendered table.
|
|
231
|
+
*
|
|
232
|
+
* @returns A cleanup function that removes all event listeners.
|
|
233
|
+
*/
|
|
234
|
+
declare function attachKeyboardNav(options: KeyboardNavOptions): () => void;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Table mount API: the main entry point for vanilla JS table usage.
|
|
238
|
+
*
|
|
239
|
+
* createTable() takes a container, spec, and options, compiles the table,
|
|
240
|
+
* renders it as HTML, sets up responsive resizing, sort/search/pagination
|
|
241
|
+
* interactivity, and returns a TableInstance with update/resize/export/destroy.
|
|
242
|
+
*
|
|
243
|
+
* Supports both controlled and uncontrolled modes:
|
|
244
|
+
* - Uncontrolled (default): manages sort/search/page internally
|
|
245
|
+
* - Controlled: reads state from externalState, fires onStateChange
|
|
246
|
+
*/
|
|
247
|
+
|
|
248
|
+
interface TableState {
|
|
249
|
+
sort: SortState | null;
|
|
250
|
+
search: string;
|
|
251
|
+
page: number;
|
|
252
|
+
}
|
|
253
|
+
interface TableMountOptions {
|
|
254
|
+
theme?: ThemeConfig;
|
|
255
|
+
darkMode?: DarkMode;
|
|
256
|
+
responsive?: boolean;
|
|
257
|
+
onRowClick?: (row: Record<string, unknown>) => void;
|
|
258
|
+
onStateChange?: (state: TableState) => void;
|
|
259
|
+
externalState?: {
|
|
260
|
+
sort?: SortState | null;
|
|
261
|
+
search?: string;
|
|
262
|
+
page?: number;
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
interface TableInstance {
|
|
266
|
+
update(spec: TableSpec): void;
|
|
267
|
+
resize(): void;
|
|
268
|
+
export(format: 'csv'): string;
|
|
269
|
+
getState(): TableState;
|
|
270
|
+
setState(partial: Partial<TableState>): void;
|
|
271
|
+
destroy(): void;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Create a table instance from a spec and mount it into a container.
|
|
275
|
+
*
|
|
276
|
+
* @param container - The DOM element to render into.
|
|
277
|
+
* @param spec - The table spec.
|
|
278
|
+
* @param options - Mount options.
|
|
279
|
+
* @returns A TableInstance with update/resize/export/destroy methods.
|
|
280
|
+
*/
|
|
281
|
+
declare function createTable(container: HTMLElement, spec: TableSpec, options?: TableMountOptions): TableInstance;
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Table renderer: produces semantic HTML from a TableLayout.
|
|
285
|
+
*
|
|
286
|
+
* renderTable() creates the full DOM structure: chrome, search bar,
|
|
287
|
+
* scrollable table with sticky column support, pagination, and footer.
|
|
288
|
+
* The returned element replaces or appends to the given container.
|
|
289
|
+
*/
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Render a TableLayout into a full DOM structure.
|
|
293
|
+
*
|
|
294
|
+
* @param layout - The compiled table layout.
|
|
295
|
+
* @param container - The container element to render into.
|
|
296
|
+
* @returns The wrapper element that was created.
|
|
297
|
+
*/
|
|
298
|
+
declare function renderTable(layout: TableLayout, container: HTMLElement): HTMLElement;
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Tooltip manager: creates and positions a floating tooltip element.
|
|
302
|
+
*
|
|
303
|
+
* Shows tooltip content near the mouse/touch position with viewport
|
|
304
|
+
* edge avoidance. Touch support via tap-to-show, tap-outside-to-hide.
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
interface TooltipManager {
|
|
308
|
+
/** Show the tooltip with content at a given position. */
|
|
309
|
+
show(content: TooltipContent, x: number, y: number): void;
|
|
310
|
+
/** Hide the tooltip. */
|
|
311
|
+
hide(): void;
|
|
312
|
+
/** Remove the tooltip element and clean up event listeners. */
|
|
313
|
+
destroy(): void;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Create a tooltip manager attached to a container element.
|
|
317
|
+
*
|
|
318
|
+
* The manager creates a floating div positioned relative to the container.
|
|
319
|
+
* Content is rendered as a title line with optional color indicator,
|
|
320
|
+
* followed by a compact list of field-value pairs.
|
|
321
|
+
*
|
|
322
|
+
* @param container - The parent element for the tooltip.
|
|
323
|
+
* @returns TooltipManager with show/hide/destroy methods.
|
|
324
|
+
*/
|
|
325
|
+
declare function createTooltipManager(container: HTMLElement): TooltipManager;
|
|
326
|
+
|
|
327
|
+
export { type ChartInstance, type ExportOptions, type GraphInstance, type GraphMountOptions, type KeyboardNavOptions, type MountOptions, type PNGExportOptions, type TableInstance, type TableMountOptions, type TableState, type TooltipManager, attachKeyboardNav, createChart, createGraph, createSimulationWorker, createTable, createTooltipManager, exportCSV, exportPNG, exportSVG, observeResize, registerMarkRenderer, renderBarCell, renderCategoryCell, renderCell, renderChartSVG, renderFlagCell, renderHeatmapCell, renderImageCell, renderSparklineCell, renderTable, renderTextCell };
|