@antv/infographic 0.2.7 → 0.2.9
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/infographic.min.js +191 -191
- package/dist/infographic.min.js.map +1 -1
- package/esm/designs/items/BadgeCard.js +6 -1
- package/esm/designs/items/SimpleCircleNode.d.ts +8 -0
- package/esm/designs/items/SimpleCircleNode.js +14 -0
- package/esm/designs/items/index.d.ts +1 -0
- package/esm/designs/items/index.js +1 -0
- package/esm/designs/structures/hierarchy-mindmap.js +19 -5
- package/esm/designs/structures/hierarchy-tree.d.ts +2 -1
- package/esm/designs/structures/hierarchy-tree.js +23 -20
- package/esm/designs/structures/index.d.ts +1 -0
- package/esm/designs/structures/index.js +1 -0
- package/esm/designs/structures/relation-dagre-flow.d.ts +21 -0
- package/esm/designs/structures/relation-dagre-flow.js +497 -0
- package/esm/designs/utils/hierarchy-color.d.ts +1 -1
- package/esm/editor/plugins/edit-bar/edit-bar.js +27 -9
- package/esm/index.d.ts +1 -1
- package/esm/index.js +1 -2
- package/esm/jsx/global.d.ts +1 -0
- package/esm/jsx/types/element.d.ts +5 -1
- package/esm/jsx/utils/svg.js +2 -0
- package/esm/renderer/composites/icon.js +2 -0
- package/esm/renderer/composites/illus.d.ts +1 -1
- package/esm/renderer/composites/illus.js +9 -4
- package/esm/renderer/composites/text.js +4 -2
- package/esm/renderer/fonts/loader.js +3 -1
- package/esm/renderer/fonts/registry.js +1 -1
- package/esm/renderer/renderer.js +28 -25
- package/esm/resource/loader.js +3 -1
- package/esm/runtime/Infographic.js +1 -1
- package/esm/ssr/dom-shim.d.ts +4 -0
- package/esm/ssr/dom-shim.js +107 -0
- package/esm/ssr/index.d.ts +1 -0
- package/esm/ssr/index.js +1 -0
- package/esm/ssr/renderer.d.ts +2 -0
- package/esm/ssr/renderer.js +60 -0
- package/esm/syntax/index.js +57 -1
- package/esm/syntax/parser.js +44 -0
- package/esm/syntax/relations.d.ts +6 -0
- package/esm/syntax/relations.js +251 -0
- package/esm/syntax/schema.d.ts +1 -0
- package/esm/syntax/schema.js +12 -0
- package/esm/templates/built-in.js +2 -0
- package/esm/templates/relation-dagre-flow.d.ts +2 -0
- package/esm/templates/relation-dagre-flow.js +68 -0
- package/esm/types/data.d.ts +24 -3
- package/esm/utils/data.js +1 -1
- package/esm/utils/index.d.ts +1 -0
- package/esm/utils/index.js +1 -0
- package/esm/utils/is-browser.js +5 -9
- package/esm/utils/measure-text.d.ts +2 -2
- package/esm/utils/measure-text.js +4 -4
- package/esm/utils/recognizer.js +8 -5
- package/esm/utils/text.js +27 -19
- package/esm/version.d.ts +1 -0
- package/esm/version.js +1 -0
- package/lib/designs/items/BadgeCard.js +6 -1
- package/lib/designs/items/SimpleCircleNode.d.ts +8 -0
- package/lib/designs/items/SimpleCircleNode.js +18 -0
- package/lib/designs/items/index.d.ts +1 -0
- package/lib/designs/items/index.js +1 -0
- package/lib/designs/structures/hierarchy-mindmap.js +19 -5
- package/lib/designs/structures/hierarchy-tree.d.ts +2 -1
- package/lib/designs/structures/hierarchy-tree.js +23 -20
- package/lib/designs/structures/index.d.ts +1 -0
- package/lib/designs/structures/index.js +1 -0
- package/lib/designs/structures/relation-dagre-flow.d.ts +21 -0
- package/lib/designs/structures/relation-dagre-flow.js +501 -0
- package/lib/designs/utils/hierarchy-color.d.ts +1 -1
- package/lib/editor/plugins/edit-bar/edit-bar.js +27 -9
- package/lib/index.d.ts +1 -1
- package/lib/index.js +4 -7
- package/lib/jsx/global.d.ts +1 -0
- package/lib/jsx/types/element.d.ts +5 -1
- package/lib/jsx/utils/svg.js +2 -0
- package/lib/renderer/composites/icon.js +2 -0
- package/lib/renderer/composites/illus.d.ts +1 -1
- package/lib/renderer/composites/illus.js +8 -3
- package/lib/renderer/composites/text.js +4 -2
- package/lib/renderer/fonts/loader.js +2 -0
- package/lib/renderer/fonts/registry.js +6 -6
- package/lib/renderer/renderer.js +27 -24
- package/lib/resource/loader.js +3 -1
- package/lib/runtime/Infographic.js +1 -1
- package/lib/ssr/dom-shim.d.ts +4 -0
- package/lib/ssr/dom-shim.js +110 -0
- package/lib/ssr/index.d.ts +1 -0
- package/lib/ssr/index.js +5 -0
- package/lib/ssr/renderer.d.ts +2 -0
- package/lib/ssr/renderer.js +63 -0
- package/lib/syntax/index.js +57 -1
- package/lib/syntax/parser.js +44 -0
- package/lib/syntax/relations.d.ts +6 -0
- package/lib/syntax/relations.js +254 -0
- package/lib/syntax/schema.d.ts +1 -0
- package/lib/syntax/schema.js +13 -1
- package/lib/templates/built-in.js +2 -0
- package/lib/templates/relation-dagre-flow.d.ts +2 -0
- package/lib/templates/relation-dagre-flow.js +71 -0
- package/lib/types/data.d.ts +24 -3
- package/lib/utils/data.js +2 -5
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +1 -0
- package/lib/utils/is-browser.js +5 -9
- package/lib/utils/measure-text.d.ts +2 -2
- package/lib/utils/measure-text.js +4 -4
- package/lib/utils/recognizer.js +8 -5
- package/lib/utils/text.js +28 -23
- package/lib/version.d.ts +1 -0
- package/lib/version.js +4 -0
- package/package.json +21 -8
- package/src/designs/items/BadgeCard.tsx +9 -2
- package/src/designs/items/SimpleCircleNode.tsx +46 -0
- package/src/designs/items/index.ts +1 -0
- package/src/designs/structures/hierarchy-mindmap.tsx +15 -2
- package/src/designs/structures/hierarchy-tree.tsx +33 -31
- package/src/designs/structures/index.ts +1 -0
- package/src/designs/structures/relation-dagre-flow.tsx +782 -0
- package/src/designs/utils/hierarchy-color.ts +6 -1
- package/src/editor/plugins/edit-bar/edit-bar.ts +41 -17
- package/src/index.ts +1 -3
- package/src/jsx/global.ts +1 -0
- package/src/jsx/types/element.ts +15 -6
- package/src/jsx/utils/svg.ts +2 -0
- package/src/renderer/composites/icon.ts +2 -0
- package/src/renderer/composites/illus.ts +16 -3
- package/src/renderer/composites/text.ts +7 -2
- package/src/renderer/fonts/loader.ts +7 -1
- package/src/renderer/fonts/registry.ts +1 -1
- package/src/renderer/renderer.ts +42 -24
- package/src/resource/loader.ts +3 -1
- package/src/runtime/Infographic.tsx +1 -1
- package/src/ssr/dom-shim.ts +120 -0
- package/src/ssr/index.ts +1 -0
- package/src/ssr/renderer.ts +72 -0
- package/src/syntax/index.ts +58 -1
- package/src/syntax/parser.ts +49 -0
- package/src/syntax/relations.ts +291 -0
- package/src/syntax/schema.ts +16 -0
- package/src/templates/built-in.ts +4 -2
- package/src/templates/relation-dagre-flow.ts +73 -0
- package/src/types/data.ts +26 -3
- package/src/utils/data.ts +1 -1
- package/src/utils/index.ts +1 -0
- package/src/utils/is-browser.ts +3 -9
- package/src/utils/measure-text.ts +6 -7
- package/src/utils/recognizer.ts +9 -5
- package/src/utils/svg.ts +0 -1
- package/src/utils/text.ts +25 -19
- package/src/version.ts +1 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ResourceConfig } from '../../resource';
|
|
2
2
|
import type { IllusElement, ItemDatum } from '../../types';
|
|
3
|
-
export declare function renderIllus(svg: SVGSVGElement, node: SVGElement, value: string | ResourceConfig | undefined, datum?: ItemDatum): IllusElement | null;
|
|
3
|
+
export declare function renderIllus(svg: SVGSVGElement, node: SVGElement, value: string | ResourceConfig | undefined, datum?: ItemDatum, attrs?: Record<string, any>): IllusElement | null;
|
|
4
4
|
export declare function renderItemIllus(svg: SVGSVGElement, node: SVGElement, datum: ItemDatum): SVGGElement | null;
|
|
@@ -4,25 +4,30 @@ exports.renderIllus = renderIllus;
|
|
|
4
4
|
exports.renderItemIllus = renderItemIllus;
|
|
5
5
|
const resource_1 = require("../../resource");
|
|
6
6
|
const utils_1 = require("../../utils");
|
|
7
|
-
function renderIllus(svg, node, value, datum) {
|
|
7
|
+
function renderIllus(svg, node, value, datum, attrs = {}) {
|
|
8
8
|
if (!value)
|
|
9
9
|
return null;
|
|
10
10
|
const config = (0, resource_1.parseResourceConfig)(value);
|
|
11
11
|
if (!config)
|
|
12
12
|
return null;
|
|
13
13
|
const id = (0, resource_1.getResourceId)(config);
|
|
14
|
+
if (attrs && Object.keys(attrs).length > 0) {
|
|
15
|
+
(0, utils_1.setAttributes)(node, attrs);
|
|
16
|
+
}
|
|
14
17
|
const clipPathId = createClipPath(svg, node, id);
|
|
15
18
|
(0, resource_1.loadResource)(svg, 'illus', config, datum);
|
|
16
19
|
const { data, color } = config;
|
|
17
20
|
return createIllusElement(id, {
|
|
18
21
|
...parseIllusBounds(node),
|
|
19
|
-
'clip-path': `url(#${clipPathId})`,
|
|
20
22
|
...(color ? { color } : {}),
|
|
23
|
+
...attrs,
|
|
24
|
+
'clip-path': `url(#${clipPathId})`,
|
|
21
25
|
}, data);
|
|
22
26
|
}
|
|
23
27
|
function renderItemIllus(svg, node, datum) {
|
|
24
28
|
const value = datum.illus;
|
|
25
|
-
|
|
29
|
+
const attrs = datum.attributes?.illus;
|
|
30
|
+
return renderIllus(svg, node, value, datum, attrs);
|
|
26
31
|
}
|
|
27
32
|
function createClipPath(svg, node, id) {
|
|
28
33
|
const clipPathId = `clip-${id}-${(0, utils_1.uuid)()}`;
|
|
@@ -24,8 +24,10 @@ function renderItemText(type, node, options) {
|
|
|
24
24
|
return null;
|
|
25
25
|
const { data, themeConfig } = options;
|
|
26
26
|
const indexes = (0, utils_1.getItemIndexes)(node.dataset.indexes || '0');
|
|
27
|
-
const
|
|
28
|
-
const
|
|
27
|
+
const datum = (0, utils_1.getDatumByIndexes)(data, indexes);
|
|
28
|
+
const text = String((0, lodash_es_1.get)(datum, type, ''));
|
|
29
|
+
const dataAttrs = datum?.attributes?.[type];
|
|
30
|
+
const attrs = Object.assign({}, themeConfig.base?.text, themeConfig.item?.[type], dataAttrs);
|
|
29
31
|
const staticAttrs = (0, utils_2.parseDynamicAttributes)(textShape, attrs);
|
|
30
32
|
return renderText(node, node.textContent || text, staticAttrs);
|
|
31
33
|
}
|
|
@@ -6,13 +6,13 @@ exports.getFonts = getFonts;
|
|
|
6
6
|
exports.setDefaultFont = setDefaultFont;
|
|
7
7
|
exports.registerFont = registerFont;
|
|
8
8
|
exports.unregisterFont = unregisterFont;
|
|
9
|
-
const
|
|
9
|
+
const font_1 = require("../../utils/font");
|
|
10
10
|
const FONT_REGISTRY = new Map();
|
|
11
11
|
exports.DEFAULT_FONT = 'Alibaba PuHuiTi';
|
|
12
12
|
function getFont(font) {
|
|
13
|
-
const families = (0,
|
|
13
|
+
const families = (0, font_1.splitFontFamily)(font);
|
|
14
14
|
for (const family of families) {
|
|
15
|
-
const fontObj = FONT_REGISTRY.get((0,
|
|
15
|
+
const fontObj = FONT_REGISTRY.get((0, font_1.decodeFontFamily)(family));
|
|
16
16
|
if (fontObj)
|
|
17
17
|
return fontObj;
|
|
18
18
|
}
|
|
@@ -22,7 +22,7 @@ function getFonts() {
|
|
|
22
22
|
return Array.from(FONT_REGISTRY.values());
|
|
23
23
|
}
|
|
24
24
|
function setDefaultFont(font) {
|
|
25
|
-
exports.DEFAULT_FONT = (0,
|
|
25
|
+
exports.DEFAULT_FONT = (0, font_1.encodeFontFamily)(font);
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* 注册自定义字体
|
|
@@ -44,13 +44,13 @@ function setDefaultFont(font) {
|
|
|
44
44
|
function registerFont(font) {
|
|
45
45
|
const f = { ...font };
|
|
46
46
|
FONT_REGISTRY.set(f.fontFamily, f);
|
|
47
|
-
f.fontFamily = (0,
|
|
47
|
+
f.fontFamily = (0, font_1.encodeFontFamily)(f.fontFamily);
|
|
48
48
|
return f;
|
|
49
49
|
}
|
|
50
50
|
function unregisterFont(font) {
|
|
51
51
|
const fontObj = getFont(font);
|
|
52
52
|
if (!fontObj)
|
|
53
53
|
return null;
|
|
54
|
-
FONT_REGISTRY.delete((0,
|
|
54
|
+
FONT_REGISTRY.delete((0, font_1.decodeFontFamily)(fontObj.fontFamily));
|
|
55
55
|
return fontObj;
|
|
56
56
|
}
|
package/lib/renderer/renderer.js
CHANGED
|
@@ -33,30 +33,33 @@ class Renderer {
|
|
|
33
33
|
const postRender = () => {
|
|
34
34
|
setView(this.template, this.options);
|
|
35
35
|
(0, fonts_1.loadFonts)(this.template);
|
|
36
|
-
svg.style.visibility
|
|
36
|
+
svg.style.removeProperty('visibility');
|
|
37
37
|
};
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
if (utils_1.isNode) {
|
|
39
|
+
postRender();
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const observer = new MutationObserver((mutations) => {
|
|
43
|
+
mutations.forEach((mutation) => {
|
|
44
|
+
mutation.addedNodes.forEach((node) => {
|
|
45
|
+
if (node === svg || node.contains(svg)) {
|
|
46
|
+
postRender();
|
|
47
|
+
observer.disconnect();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
47
50
|
});
|
|
48
51
|
});
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
try {
|
|
53
|
+
observer.observe(document, {
|
|
54
|
+
childList: true,
|
|
55
|
+
subtree: true,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
// Fallback for micro-app environments that proxy document.
|
|
60
|
+
postRender();
|
|
61
|
+
console.error(error);
|
|
62
|
+
}
|
|
60
63
|
}
|
|
61
64
|
this.rendered = true;
|
|
62
65
|
return svg;
|
|
@@ -75,15 +78,15 @@ function fill(svg, options) {
|
|
|
75
78
|
elements.forEach((element) => {
|
|
76
79
|
const id = element.id || '';
|
|
77
80
|
if ((0, utils_1.isTitle)(element)) {
|
|
78
|
-
const modified = (0, composites_1.renderText)(element, data.title || '', Object.assign({}, themeConfig.base?.text, themeConfig.title));
|
|
81
|
+
const modified = (0, composites_1.renderText)(element, data.title || '', Object.assign({}, themeConfig.base?.text, themeConfig.title, data.attributes?.title));
|
|
79
82
|
return upsert(element, modified);
|
|
80
83
|
}
|
|
81
84
|
if ((0, utils_1.isDesc)(element)) {
|
|
82
|
-
const modified = (0, composites_1.renderText)(element, data.desc || '', Object.assign({}, themeConfig.base?.text, themeConfig.desc));
|
|
85
|
+
const modified = (0, composites_1.renderText)(element, data.desc || '', Object.assign({}, themeConfig.base?.text, themeConfig.desc, data.attributes?.desc));
|
|
83
86
|
return upsert(element, modified);
|
|
84
87
|
}
|
|
85
88
|
if ((0, utils_1.isIllus)(element)) {
|
|
86
|
-
const modified = (0, composites_1.renderIllus)(svg, element, data.illus?.[id]);
|
|
89
|
+
const modified = (0, composites_1.renderIllus)(svg, element, data.illus?.[id], undefined, data.attributes?.illus);
|
|
87
90
|
return upsert(element, modified);
|
|
88
91
|
}
|
|
89
92
|
if ((0, utils_1.isShapesGroup)(element)) {
|
package/lib/resource/loader.js
CHANGED
|
@@ -94,7 +94,9 @@ Object.defineProperty(exports, "getSvgLoadPromises", { enumerable: true, get: fu
|
|
|
94
94
|
Object.defineProperty(exports, "waitForSvgLoads", { enumerable: true, get: function () { return load_tracker_2.waitForSvgLoads; } });
|
|
95
95
|
function getFallbackQuery(cfg, scene, datum) {
|
|
96
96
|
const defaultQuery = scene === 'illus' ? 'illustration' : 'icon';
|
|
97
|
-
const datumQuery = normalizeQuery(
|
|
97
|
+
const datumQuery = normalizeQuery(cfg.data) ||
|
|
98
|
+
normalizeQuery(datum?.label) ||
|
|
99
|
+
normalizeQuery(datum?.desc);
|
|
98
100
|
if (datumQuery)
|
|
99
101
|
return datumQuery;
|
|
100
102
|
const data = normalizeQuery(cfg.data);
|
|
@@ -30,7 +30,7 @@ class Infographic {
|
|
|
30
30
|
setOptions(options, mode = 'replace', isInitial = false) {
|
|
31
31
|
const { options: parsedOptions, errors, warnings, } = parseSyntaxOptions(options);
|
|
32
32
|
if (isInitial) {
|
|
33
|
-
this.initialOptions =
|
|
33
|
+
this.initialOptions = parsedOptions;
|
|
34
34
|
}
|
|
35
35
|
const base = mode === 'replace'
|
|
36
36
|
? (0, utils_2.mergeOptions)((0, utils_2.cloneOptions)(this.initialOptions || {}), parsedOptions)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupDOM = setupDOM;
|
|
4
|
+
const linkedom_1 = require("linkedom");
|
|
5
|
+
function setupDOM() {
|
|
6
|
+
const { document, window } = (0, linkedom_1.parseHTML)('<!DOCTYPE html><html><body><div id="container"></div></body></html>');
|
|
7
|
+
Object.assign(globalThis, {
|
|
8
|
+
window,
|
|
9
|
+
document,
|
|
10
|
+
DOMParser: linkedom_1.DOMParser,
|
|
11
|
+
});
|
|
12
|
+
const classes = [
|
|
13
|
+
'HTMLElement',
|
|
14
|
+
'HTMLDivElement',
|
|
15
|
+
'HTMLSpanElement',
|
|
16
|
+
'HTMLImageElement',
|
|
17
|
+
'HTMLCanvasElement',
|
|
18
|
+
'HTMLInputElement',
|
|
19
|
+
'HTMLButtonElement',
|
|
20
|
+
'Element',
|
|
21
|
+
'Node',
|
|
22
|
+
'Text',
|
|
23
|
+
'Comment',
|
|
24
|
+
'DocumentFragment',
|
|
25
|
+
'Document',
|
|
26
|
+
'XMLSerializer',
|
|
27
|
+
'MutationObserver',
|
|
28
|
+
// SVG
|
|
29
|
+
'SVGElement',
|
|
30
|
+
'SVGSVGElement',
|
|
31
|
+
'SVGGraphicsElement',
|
|
32
|
+
'SVGGElement',
|
|
33
|
+
'SVGPathElement',
|
|
34
|
+
'SVGRectElement',
|
|
35
|
+
'SVGCircleElement',
|
|
36
|
+
'SVGTextElement',
|
|
37
|
+
'SVGLineElement',
|
|
38
|
+
'SVGPolygonElement',
|
|
39
|
+
'SVGPolylineElement',
|
|
40
|
+
'SVGEllipseElement',
|
|
41
|
+
'SVGImageElement',
|
|
42
|
+
'SVGDefsElement',
|
|
43
|
+
'SVGUseElement',
|
|
44
|
+
'SVGClipPathElement',
|
|
45
|
+
'SVGLinearGradientElement',
|
|
46
|
+
'SVGRadialGradientElement',
|
|
47
|
+
'SVGStopElement',
|
|
48
|
+
'SVGPatternElement',
|
|
49
|
+
'SVGMaskElement',
|
|
50
|
+
'SVGForeignObjectElement',
|
|
51
|
+
'Image',
|
|
52
|
+
];
|
|
53
|
+
classes.forEach((name) => {
|
|
54
|
+
if (window[name])
|
|
55
|
+
globalThis[name] = window[name];
|
|
56
|
+
});
|
|
57
|
+
if (!document.fonts) {
|
|
58
|
+
const fontSet = new Set();
|
|
59
|
+
Object.defineProperty(document, 'fonts', {
|
|
60
|
+
value: {
|
|
61
|
+
add: (font) => fontSet.add(font),
|
|
62
|
+
delete: (font) => fontSet.delete(font),
|
|
63
|
+
has: (font) => fontSet.has(font),
|
|
64
|
+
clear: () => fontSet.clear(),
|
|
65
|
+
forEach: (callback) => fontSet.forEach(callback),
|
|
66
|
+
entries: () => fontSet.entries(),
|
|
67
|
+
keys: () => fontSet.keys(),
|
|
68
|
+
values: () => fontSet.values(),
|
|
69
|
+
[Symbol.iterator]: () => fontSet[Symbol.iterator](),
|
|
70
|
+
get size() {
|
|
71
|
+
return fontSet.size;
|
|
72
|
+
},
|
|
73
|
+
get ready() {
|
|
74
|
+
return Promise.resolve(this);
|
|
75
|
+
},
|
|
76
|
+
check: () => true,
|
|
77
|
+
load: () => Promise.resolve([]),
|
|
78
|
+
get status() {
|
|
79
|
+
return 'loaded';
|
|
80
|
+
},
|
|
81
|
+
onloading: null,
|
|
82
|
+
onloadingdone: null,
|
|
83
|
+
onloadingerror: null,
|
|
84
|
+
addEventListener: () => { },
|
|
85
|
+
removeEventListener: () => { },
|
|
86
|
+
dispatchEvent: () => true,
|
|
87
|
+
},
|
|
88
|
+
configurable: true,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
const rafIds = new Map();
|
|
92
|
+
let nextRafId = 0;
|
|
93
|
+
globalThis.requestAnimationFrame = (cb) => {
|
|
94
|
+
const id = ++nextRafId;
|
|
95
|
+
const immediate = setImmediate(() => {
|
|
96
|
+
rafIds.delete(id);
|
|
97
|
+
cb(performance.now());
|
|
98
|
+
});
|
|
99
|
+
rafIds.set(id, immediate);
|
|
100
|
+
return id;
|
|
101
|
+
};
|
|
102
|
+
globalThis.cancelAnimationFrame = (id) => {
|
|
103
|
+
const immediate = rafIds.get(id);
|
|
104
|
+
if (immediate) {
|
|
105
|
+
clearImmediate(immediate);
|
|
106
|
+
rafIds.delete(id);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
return { window, document };
|
|
110
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { renderToString } from './renderer';
|
package/lib/ssr/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderToString = void 0;
|
|
4
|
+
var renderer_1 = require("./renderer");
|
|
5
|
+
Object.defineProperty(exports, "renderToString", { enumerable: true, get: function () { return renderer_1.renderToString; } });
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderToString = renderToString;
|
|
4
|
+
const exporter_1 = require("../exporter");
|
|
5
|
+
const renderer_1 = require("../renderer");
|
|
6
|
+
const runtime_1 = require("../runtime");
|
|
7
|
+
const utils_1 = require("../utils");
|
|
8
|
+
const dom_shim_1 = require("./dom-shim");
|
|
9
|
+
async function renderToString(options, init) {
|
|
10
|
+
const { document } = (0, dom_shim_1.setupDOM)();
|
|
11
|
+
const container = document.getElementById('container');
|
|
12
|
+
let infographic;
|
|
13
|
+
let timeoutId;
|
|
14
|
+
try {
|
|
15
|
+
infographic = new runtime_1.Infographic({
|
|
16
|
+
...init,
|
|
17
|
+
container,
|
|
18
|
+
editable: false,
|
|
19
|
+
});
|
|
20
|
+
const renderPromise = new Promise((resolve, reject) => {
|
|
21
|
+
infographic.on('loaded', async ({ node }) => {
|
|
22
|
+
try {
|
|
23
|
+
const svg = await (0, exporter_1.exportToSVG)(node, { embedResources: true });
|
|
24
|
+
resolve(svg.outerHTML);
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
reject(e);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
32
|
+
timeoutId = setTimeout(() => {
|
|
33
|
+
reject(new Error('SSR render timeout'));
|
|
34
|
+
}, 10000);
|
|
35
|
+
});
|
|
36
|
+
infographic.render(options);
|
|
37
|
+
const svg = await Promise.race([renderPromise, timeoutPromise]);
|
|
38
|
+
return injectXMLStylesheet(svg);
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
clearTimeout(timeoutId);
|
|
42
|
+
if (infographic) {
|
|
43
|
+
infographic.destroy();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function injectXMLStylesheet(svg) {
|
|
48
|
+
const matched = svg.matchAll(/font-family="([\S ]+?)"/g);
|
|
49
|
+
const fonts = Array.from(matched, (match) => match[1]);
|
|
50
|
+
const set = new Set();
|
|
51
|
+
fonts.forEach((font) => {
|
|
52
|
+
const decoded = (0, utils_1.decodeFontFamily)(font);
|
|
53
|
+
decoded.split(',').forEach((f) => set.add(f.trim()));
|
|
54
|
+
});
|
|
55
|
+
const urls = Array.from(set)
|
|
56
|
+
.map((font) => (0, renderer_1.getFontURLs)(font))
|
|
57
|
+
.flat();
|
|
58
|
+
if (urls.length === 0)
|
|
59
|
+
return svg;
|
|
60
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
61
|
+
${urls.map((url) => `<?xml-stylesheet href="${url}" type="text/css"?>`).join('\n')}
|
|
62
|
+
${svg}`;
|
|
63
|
+
}
|
package/lib/syntax/index.js
CHANGED
|
@@ -3,7 +3,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseSyntax = parseSyntax;
|
|
4
4
|
const mapper_1 = require("./mapper");
|
|
5
5
|
const parser_1 = require("./parser");
|
|
6
|
+
const relations_1 = require("./relations");
|
|
6
7
|
const schema_1 = require("./schema");
|
|
8
|
+
function normalizeItems(items) {
|
|
9
|
+
const seen = new Set();
|
|
10
|
+
const normalized = [];
|
|
11
|
+
for (let index = items.length - 1; index >= 0; index -= 1) {
|
|
12
|
+
const item = items[index];
|
|
13
|
+
const id = item.id ?? item.label;
|
|
14
|
+
if (!id) {
|
|
15
|
+
normalized.push(item);
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (seen.has(id))
|
|
19
|
+
continue;
|
|
20
|
+
seen.add(id);
|
|
21
|
+
if (!item.id)
|
|
22
|
+
item.id = id;
|
|
23
|
+
normalized.push(item);
|
|
24
|
+
}
|
|
25
|
+
return normalized.reverse();
|
|
26
|
+
}
|
|
7
27
|
function resolveTemplate(node, errors) {
|
|
8
28
|
if (!node)
|
|
9
29
|
return undefined;
|
|
@@ -67,9 +87,45 @@ function parseSyntax(input) {
|
|
|
67
87
|
}
|
|
68
88
|
const dataNode = mergedEntries.data;
|
|
69
89
|
if (dataNode) {
|
|
70
|
-
|
|
90
|
+
let relationsNode;
|
|
91
|
+
let dataNodeForMapping = dataNode;
|
|
92
|
+
if (dataNode.kind === 'object') {
|
|
93
|
+
const { relations, ...rest } = dataNode.entries;
|
|
94
|
+
relationsNode = relations;
|
|
95
|
+
dataNodeForMapping = { ...dataNode, entries: rest };
|
|
96
|
+
}
|
|
97
|
+
const data = (0, mapper_1.mapWithSchema)(dataNodeForMapping, schema_1.DataSchema, 'data', errors);
|
|
71
98
|
if (data)
|
|
72
99
|
options.data = data;
|
|
100
|
+
if (relationsNode) {
|
|
101
|
+
const parsed = (0, relations_1.parseRelationsNode)(relationsNode, errors, 'data.relations');
|
|
102
|
+
if (parsed.relations.length > 0 || parsed.items.length > 0) {
|
|
103
|
+
const current = (options.data ?? {});
|
|
104
|
+
const existingItems = Array.isArray(current.items)
|
|
105
|
+
? current.items
|
|
106
|
+
: [];
|
|
107
|
+
const normalizedItems = normalizeItems(existingItems);
|
|
108
|
+
const itemMap = new Map();
|
|
109
|
+
normalizedItems.forEach((item) => {
|
|
110
|
+
if (item.id)
|
|
111
|
+
itemMap.set(item.id, item);
|
|
112
|
+
});
|
|
113
|
+
parsed.items.forEach((item) => {
|
|
114
|
+
const existing = itemMap.get(item.id);
|
|
115
|
+
if (existing) {
|
|
116
|
+
if (!existing.label && item.label)
|
|
117
|
+
existing.label = item.label;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
normalizedItems.push(item);
|
|
121
|
+
itemMap.set(item.id, item);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
current.items = normalizedItems;
|
|
125
|
+
current.relations = parsed.relations;
|
|
126
|
+
options.data = current;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
73
129
|
}
|
|
74
130
|
const themeNode = mergedEntries.theme;
|
|
75
131
|
if (themeNode) {
|
package/lib/syntax/parser.js
CHANGED
|
@@ -27,6 +27,9 @@ function getIndentInfo(line) {
|
|
|
27
27
|
function stripComments(content) {
|
|
28
28
|
return content.trimEnd();
|
|
29
29
|
}
|
|
30
|
+
function looksLikeRelationExpression(text) {
|
|
31
|
+
return /[<>=o.x-]{2,}/.test(text);
|
|
32
|
+
}
|
|
30
33
|
function parseKeyValue(raw) {
|
|
31
34
|
const text = raw.trim();
|
|
32
35
|
if (!text)
|
|
@@ -109,6 +112,47 @@ function parseSyntaxToAst(input) {
|
|
|
109
112
|
});
|
|
110
113
|
return;
|
|
111
114
|
}
|
|
115
|
+
if (parentFrame.key === 'relations' &&
|
|
116
|
+
!trimmed.startsWith('-') &&
|
|
117
|
+
looksLikeRelationExpression(trimmed)) {
|
|
118
|
+
if (parentNode.kind !== 'array') {
|
|
119
|
+
if (parentNode.kind === 'object' &&
|
|
120
|
+
Object.keys(parentNode.entries).length === 0 &&
|
|
121
|
+
parentNode.value === undefined &&
|
|
122
|
+
parentFrame.parent &&
|
|
123
|
+
parentFrame.key) {
|
|
124
|
+
const arrayNode = createArrayNode(parentNode.line);
|
|
125
|
+
if (parentFrame.parent.kind === 'object') {
|
|
126
|
+
parentFrame.parent.entries[parentFrame.key] = arrayNode;
|
|
127
|
+
}
|
|
128
|
+
else if (parentFrame.parent.kind === 'array') {
|
|
129
|
+
const indexInParent = parentFrame.parent.items.indexOf(parentNode);
|
|
130
|
+
if (indexInParent >= 0)
|
|
131
|
+
parentFrame.parent.items[indexInParent] = arrayNode;
|
|
132
|
+
}
|
|
133
|
+
parentFrame.node = arrayNode;
|
|
134
|
+
parentNode = arrayNode;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
errors.push({
|
|
138
|
+
path: '',
|
|
139
|
+
line: lineNumber,
|
|
140
|
+
code: 'bad_list',
|
|
141
|
+
message: 'List item is not under an array container.',
|
|
142
|
+
raw: trimmed,
|
|
143
|
+
});
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const itemNode = createObjectNode(lineNumber, trimmed);
|
|
148
|
+
parentNode.items.push(itemNode);
|
|
149
|
+
stack.push({
|
|
150
|
+
indent,
|
|
151
|
+
node: itemNode,
|
|
152
|
+
parent: parentNode,
|
|
153
|
+
});
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
112
156
|
const parsed = parseKeyValue(trimmed);
|
|
113
157
|
if (!parsed) {
|
|
114
158
|
errors.push({
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ItemDatum, RelationDatum } from '../types';
|
|
2
|
+
import type { SyntaxError, SyntaxNode } from './types';
|
|
3
|
+
export declare function parseRelationsNode(node: SyntaxNode, errors: SyntaxError[], path: string): {
|
|
4
|
+
relations: RelationDatum[];
|
|
5
|
+
items: ItemDatum[];
|
|
6
|
+
};
|