@kanaries/graphic-walker 0.3.8 → 0.3.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/dist/components/appRoot.d.ts +7 -0
- package/dist/graphic-walker.es.js +16909 -16800
- package/dist/graphic-walker.es.js.map +1 -1
- package/dist/graphic-walker.umd.js +123 -123
- package/dist/graphic-walker.umd.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/interfaces.d.ts +21 -0
- package/dist/main.d.ts +1 -1
- package/dist/renderer/pureRenderer.d.ts +1 -0
- package/dist/renderer/specRenderer.d.ts +1 -0
- package/dist/shadow-dom.d.ts +10 -0
- package/dist/style.css +1 -0
- package/dist/utils/vegaApiExport.d.ts +10 -0
- package/dist/vanilla.d.ts +3 -0
- package/dist/vis/react-vega.d.ts +1 -0
- package/package.json +3 -2
- package/src/components/appRoot.tsx +32 -0
- package/src/components/callout.tsx +1 -1
- package/src/components/tooltip.tsx +1 -1
- package/src/index.tsx +23 -36
- package/src/interfaces.ts +24 -1
- package/src/main.tsx +2 -24
- package/src/renderer/hooks.ts +9 -1
- package/src/renderer/index.tsx +3 -1
- package/src/renderer/pureRenderer.tsx +20 -9
- package/src/renderer/specRenderer.tsx +3 -1
- package/src/shadow-dom.tsx +48 -0
- package/src/utils/vegaApiExport.ts +102 -0
- package/src/vanilla.tsx +31 -0
- package/src/vis/react-vega.tsx +22 -43
package/src/vis/react-vega.tsx
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import React, { useEffect, useState, useMemo, forwardRef,
|
|
1
|
+
import React, { useEffect, useState, useMemo, forwardRef, useRef } from 'react';
|
|
2
2
|
import embed from 'vega-embed';
|
|
3
3
|
import { Subject, Subscription } from 'rxjs'
|
|
4
4
|
import * as op from 'rxjs/operators';
|
|
5
5
|
import type { ScenegraphEvent, View } from 'vega';
|
|
6
6
|
import styled from 'styled-components';
|
|
7
7
|
|
|
8
|
+
import { useVegaExportApi } from '../utils/vegaApiExport';
|
|
8
9
|
import { IViewField, IRow, IStackMode, VegaGlobalConfig } from '../interfaces';
|
|
9
10
|
import { useTranslation } from 'react-i18next';
|
|
10
11
|
import { getVegaTimeFormatRules } from './temporalFormat';
|
|
@@ -25,6 +26,7 @@ export interface IReactVegaHandler {
|
|
|
25
26
|
downloadPNG: (filename?: string) => Promise<string[]>;
|
|
26
27
|
}
|
|
27
28
|
interface ReactVegaProps {
|
|
29
|
+
name?: string;
|
|
28
30
|
rows: Readonly<IViewField[]>;
|
|
29
31
|
columns: Readonly<IViewField[]>;
|
|
30
32
|
dataSource: IRow[];
|
|
@@ -73,6 +75,7 @@ interface ParamStoreEntry {
|
|
|
73
75
|
|
|
74
76
|
const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVega (props, ref) {
|
|
75
77
|
const {
|
|
78
|
+
name,
|
|
76
79
|
dataSource = [],
|
|
77
80
|
rows = [],
|
|
78
81
|
columns = [],
|
|
@@ -150,7 +153,7 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
150
153
|
})
|
|
151
154
|
}, [rowRepeatFields, colRepeatFields])
|
|
152
155
|
|
|
153
|
-
const vegaRefs = useRef<View[]>([]);
|
|
156
|
+
const vegaRefs = useRef<{ x: number; y: number; w: number; h: number; view: View }[]>([]);
|
|
154
157
|
|
|
155
158
|
useEffect(() => {
|
|
156
159
|
vegaRefs.current = [];
|
|
@@ -218,7 +221,13 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
218
221
|
|
|
219
222
|
if (viewPlaceholders.length > 0 && viewPlaceholders[0].current) {
|
|
220
223
|
embed(viewPlaceholders[0].current, spec, { mode: 'vega-lite', actions: showActions, timeFormatLocale: getVegaTimeFormatRules(i18n.language), config: vegaConfig }).then(res => {
|
|
221
|
-
vegaRefs.current = [
|
|
224
|
+
vegaRefs.current = [{
|
|
225
|
+
w: res.view.container()?.clientWidth ?? res.view.width(),
|
|
226
|
+
h: res.view.container()?.clientHeight ?? res.view.height(),
|
|
227
|
+
x: 0,
|
|
228
|
+
y: 0,
|
|
229
|
+
view: res.view,
|
|
230
|
+
}];
|
|
222
231
|
try {
|
|
223
232
|
res.view.addEventListener('click', (e) => {
|
|
224
233
|
click$.next(e);
|
|
@@ -250,6 +259,7 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
250
259
|
subscriptions.push(throttledParamStore$.subscribe(cb));
|
|
251
260
|
};
|
|
252
261
|
let index = 0;
|
|
262
|
+
vegaRefs.current = new Array(rowRepeatFields.length * colRepeatFields.length);
|
|
253
263
|
for (let i = 0; i < rowRepeatFields.length; i++) {
|
|
254
264
|
for (let j = 0; j < colRepeatFields.length; j++, index++) {
|
|
255
265
|
const sourceId = index;
|
|
@@ -282,8 +292,15 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
282
292
|
ans.params = commonSpec.params;
|
|
283
293
|
}
|
|
284
294
|
if (node) {
|
|
295
|
+
const id = index;
|
|
285
296
|
embed(node, ans, { mode: 'vega-lite', actions: showActions, timeFormatLocale: getVegaTimeFormatRules(i18n.language), config: vegaConfig }).then(res => {
|
|
286
|
-
vegaRefs.current
|
|
297
|
+
vegaRefs.current[id] = {
|
|
298
|
+
w: res.view.container()?.clientWidth ?? res.view.width(),
|
|
299
|
+
h: res.view.container()?.clientHeight ?? res.view.height(),
|
|
300
|
+
x: j,
|
|
301
|
+
y: i,
|
|
302
|
+
view: res.view,
|
|
303
|
+
};
|
|
287
304
|
const paramStores = (res.vgSpec.data?.map(d => d.name) ?? []).filter(
|
|
288
305
|
name => [BRUSH_SIGNAL_NAME, POINT_SIGNAL_NAME].map(p => `${p}_store`).includes(name)
|
|
289
306
|
).map(name => name.replace(/_store$/, ''));
|
|
@@ -374,45 +391,7 @@ const ReactVega = forwardRef<IReactVegaHandler, ReactVegaProps>(function ReactVe
|
|
|
374
391
|
text
|
|
375
392
|
]);
|
|
376
393
|
|
|
377
|
-
|
|
378
|
-
getSVGData() {
|
|
379
|
-
return Promise.all(vegaRefs.current.map(view => view.toSVG()));
|
|
380
|
-
},
|
|
381
|
-
async getCanvasData() {
|
|
382
|
-
const canvases = await Promise.all(vegaRefs.current.map(view => view.toCanvas()));
|
|
383
|
-
return canvases.map(canvas => canvas.toDataURL('image/png'));
|
|
384
|
-
},
|
|
385
|
-
async downloadSVG(filename = `gw chart ${Date.now() % 1_000_000}`.padStart(6, '0')) {
|
|
386
|
-
const data = await Promise.all(vegaRefs.current.map(view => view.toSVG()));
|
|
387
|
-
const files: string[] = [];
|
|
388
|
-
for (let i = 0; i < data.length; i += 1) {
|
|
389
|
-
const d = data[i];
|
|
390
|
-
const file = new File([d], `${filename}${data.length > 1 ? `_${i + 1}` : ''}.svg`);
|
|
391
|
-
const url = URL.createObjectURL(file);
|
|
392
|
-
const a = document.createElement('a');
|
|
393
|
-
a.download = file.name;
|
|
394
|
-
a.href = url;
|
|
395
|
-
a.click();
|
|
396
|
-
requestAnimationFrame(() => {
|
|
397
|
-
URL.revokeObjectURL(url);
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
return files;
|
|
401
|
-
},
|
|
402
|
-
async downloadPNG(filename = `gw chart ${Date.now() % 1_000_000}`.padStart(6, '0')) {
|
|
403
|
-
const canvases = await Promise.all(vegaRefs.current.map(view => view.toCanvas(2)));
|
|
404
|
-
const data = canvases.map(canvas => canvas.toDataURL('image/png', 1));
|
|
405
|
-
const files: string[] = [];
|
|
406
|
-
for (let i = 0; i < data.length; i += 1) {
|
|
407
|
-
const d = data[i];
|
|
408
|
-
const a = document.createElement('a');
|
|
409
|
-
a.download = `${filename}${data.length > 1 ? `_${i + 1}` : ''}.png`;
|
|
410
|
-
a.href = d.replace(/^data:image\/[^;]/, 'data:application/octet-stream');
|
|
411
|
-
a.click();
|
|
412
|
-
}
|
|
413
|
-
return files;
|
|
414
|
-
},
|
|
415
|
-
}));
|
|
394
|
+
useVegaExportApi(name, vegaRefs, ref);
|
|
416
395
|
|
|
417
396
|
return <CanvaContainer rowSize={Math.max(rowRepeatFields.length, 1)} colSize={Math.max(colRepeatFields.length, 1)}>
|
|
418
397
|
{/* <div ref={container}></div> */}
|