@antv/infographic 0.2.6 → 0.2.8
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/HorizontalIconArrow.js +2 -2
- 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 +2 -0
- package/esm/designs/structures/index.js +2 -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/structures/sequence-funnel.d.ts +10 -0
- package/esm/designs/structures/sequence-funnel.js +110 -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.js +1 -1
- 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/options/types.d.ts +2 -0
- package/esm/renderer/composites/background.d.ts +2 -1
- package/esm/renderer/composites/background.js +6 -4
- 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 +5 -3
- package/esm/renderer/fonts/registry.js +1 -1
- package/esm/renderer/renderer.js +34 -22
- package/esm/resource/loader.js +3 -1
- package/esm/resource/loaders/svg.js +6 -4
- 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 +12 -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/padding.js +19 -14
- package/esm/utils/recognizer.js +8 -5
- package/esm/utils/text.js +27 -19
- package/lib/designs/items/BadgeCard.js +6 -1
- package/lib/designs/items/HorizontalIconArrow.js +1 -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 +2 -0
- package/lib/designs/structures/index.js +2 -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/structures/sequence-funnel.d.ts +10 -0
- package/lib/designs/structures/sequence-funnel.js +150 -0
- package/lib/designs/utils/hierarchy-color.d.ts +1 -1
- package/lib/editor/plugins/edit-bar/edit-bar.js +27 -9
- 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/options/types.d.ts +2 -0
- package/lib/renderer/composites/background.d.ts +2 -1
- package/lib/renderer/composites/background.js +6 -4
- 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 +4 -2
- package/lib/renderer/fonts/registry.js +6 -6
- package/lib/renderer/renderer.js +33 -21
- package/lib/resource/loader.js +3 -1
- package/lib/resource/loaders/svg.js +6 -4
- 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 +12 -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/padding.js +19 -14
- package/lib/utils/recognizer.js +8 -5
- package/lib/utils/text.js +28 -23
- package/package.json +20 -8
- package/src/designs/items/BadgeCard.tsx +9 -2
- package/src/designs/items/HorizontalIconArrow.tsx +10 -5
- 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 +2 -0
- package/src/designs/structures/relation-dagre-flow.tsx +782 -0
- package/src/designs/structures/sequence-funnel.tsx +260 -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 -1
- 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/options/types.ts +2 -0
- package/src/renderer/composites/background.ts +8 -5
- 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 +9 -3
- package/src/renderer/fonts/registry.ts +1 -1
- package/src/renderer/renderer.ts +49 -22
- package/src/resource/loader.ts +3 -1
- package/src/resource/loaders/svg.ts +8 -4
- 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 +12 -0
- 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/padding.ts +18 -14
- package/src/utils/recognizer.ts +9 -5
- package/src/utils/svg.ts +0 -1
- package/src/utils/text.ts +25 -19
package/esm/syntax/parser.js
CHANGED
|
@@ -23,6 +23,9 @@ function getIndentInfo(line) {
|
|
|
23
23
|
function stripComments(content) {
|
|
24
24
|
return content.trimEnd();
|
|
25
25
|
}
|
|
26
|
+
function looksLikeRelationExpression(text) {
|
|
27
|
+
return /[<>=o.x-]{2,}/.test(text);
|
|
28
|
+
}
|
|
26
29
|
function parseKeyValue(raw) {
|
|
27
30
|
const text = raw.trim();
|
|
28
31
|
if (!text)
|
|
@@ -105,6 +108,47 @@ export function parseSyntaxToAst(input) {
|
|
|
105
108
|
});
|
|
106
109
|
return;
|
|
107
110
|
}
|
|
111
|
+
if (parentFrame.key === 'relations' &&
|
|
112
|
+
!trimmed.startsWith('-') &&
|
|
113
|
+
looksLikeRelationExpression(trimmed)) {
|
|
114
|
+
if (parentNode.kind !== 'array') {
|
|
115
|
+
if (parentNode.kind === 'object' &&
|
|
116
|
+
Object.keys(parentNode.entries).length === 0 &&
|
|
117
|
+
parentNode.value === undefined &&
|
|
118
|
+
parentFrame.parent &&
|
|
119
|
+
parentFrame.key) {
|
|
120
|
+
const arrayNode = createArrayNode(parentNode.line);
|
|
121
|
+
if (parentFrame.parent.kind === 'object') {
|
|
122
|
+
parentFrame.parent.entries[parentFrame.key] = arrayNode;
|
|
123
|
+
}
|
|
124
|
+
else if (parentFrame.parent.kind === 'array') {
|
|
125
|
+
const indexInParent = parentFrame.parent.items.indexOf(parentNode);
|
|
126
|
+
if (indexInParent >= 0)
|
|
127
|
+
parentFrame.parent.items[indexInParent] = arrayNode;
|
|
128
|
+
}
|
|
129
|
+
parentFrame.node = arrayNode;
|
|
130
|
+
parentNode = arrayNode;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
errors.push({
|
|
134
|
+
path: '',
|
|
135
|
+
line: lineNumber,
|
|
136
|
+
code: 'bad_list',
|
|
137
|
+
message: 'List item is not under an array container.',
|
|
138
|
+
raw: trimmed,
|
|
139
|
+
});
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const itemNode = createObjectNode(lineNumber, trimmed);
|
|
144
|
+
parentNode.items.push(itemNode);
|
|
145
|
+
stack.push({
|
|
146
|
+
indent,
|
|
147
|
+
node: itemNode,
|
|
148
|
+
parent: parentNode,
|
|
149
|
+
});
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
108
152
|
const parsed = parseKeyValue(trimmed);
|
|
109
153
|
if (!parsed) {
|
|
110
154
|
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
|
+
};
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { mapWithSchema } from './mapper';
|
|
2
|
+
import { RelationSchema } from './schema';
|
|
3
|
+
const RELATION_TOKEN = /[<>=o.x-]{2,}/;
|
|
4
|
+
const ARROW_TOKEN = /[<>=o.x-]{2,}/g;
|
|
5
|
+
function normalizeLabel(text) {
|
|
6
|
+
let label = text.trim();
|
|
7
|
+
if (!label)
|
|
8
|
+
return '';
|
|
9
|
+
const first = label[0];
|
|
10
|
+
const last = label[label.length - 1];
|
|
11
|
+
if ((first === '"' && last === '"') || (first === "'" && last === "'")) {
|
|
12
|
+
label = label.slice(1, -1);
|
|
13
|
+
}
|
|
14
|
+
label = label
|
|
15
|
+
.replace(/\\(["'])/g, '$1')
|
|
16
|
+
.replace(/("|&#quot;|#quot;)/g, '"')
|
|
17
|
+
.replace(/('|'|#apos;)/g, "'");
|
|
18
|
+
return label.trim();
|
|
19
|
+
}
|
|
20
|
+
function stripEdgeLabelPrefix(text) {
|
|
21
|
+
const trimmed = text
|
|
22
|
+
.trim()
|
|
23
|
+
.replace(/^[-=.ox]+/, '')
|
|
24
|
+
.trim();
|
|
25
|
+
return normalizeLabel(trimmed);
|
|
26
|
+
}
|
|
27
|
+
function skipSpaces(text, index) {
|
|
28
|
+
let cursor = index;
|
|
29
|
+
while (cursor < text.length && /\s/.test(text[cursor])) {
|
|
30
|
+
cursor += 1;
|
|
31
|
+
}
|
|
32
|
+
return cursor;
|
|
33
|
+
}
|
|
34
|
+
function readNode(text, startIndex) {
|
|
35
|
+
let index = skipSpaces(text, startIndex);
|
|
36
|
+
if (index >= text.length)
|
|
37
|
+
return null;
|
|
38
|
+
const idStart = index;
|
|
39
|
+
while (index < text.length) {
|
|
40
|
+
const char = text[index];
|
|
41
|
+
if (/\s/.test(char) ||
|
|
42
|
+
char === '[' ||
|
|
43
|
+
char === '(' ||
|
|
44
|
+
char === '@' ||
|
|
45
|
+
char === '|' ||
|
|
46
|
+
char === '<' ||
|
|
47
|
+
char === '>') {
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
if (char === '-' &&
|
|
51
|
+
(text[index + 1] === '-' ||
|
|
52
|
+
text[index + 1] === '>' ||
|
|
53
|
+
text[index + 1] === '<')) {
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
index += 1;
|
|
57
|
+
}
|
|
58
|
+
if (index === idStart)
|
|
59
|
+
return null;
|
|
60
|
+
const id = text.slice(idStart, index).trim();
|
|
61
|
+
if (!id)
|
|
62
|
+
return null;
|
|
63
|
+
if (text.startsWith('@{', index)) {
|
|
64
|
+
const braceEnd = text.indexOf('}', index + 2);
|
|
65
|
+
if (braceEnd !== -1) {
|
|
66
|
+
index = braceEnd + 1;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
index = skipSpaces(text, index);
|
|
70
|
+
let label;
|
|
71
|
+
if (text[index] === '[') {
|
|
72
|
+
const end = text.indexOf(']', index + 1);
|
|
73
|
+
if (end !== -1) {
|
|
74
|
+
label = normalizeLabel(text.slice(index + 1, end));
|
|
75
|
+
index = end + 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else if (text[index] === '(') {
|
|
79
|
+
const end = text.indexOf(')', index + 1);
|
|
80
|
+
if (end !== -1) {
|
|
81
|
+
let content = text.slice(index + 1, end).trim();
|
|
82
|
+
if (content.startsWith('[') && content.endsWith(']')) {
|
|
83
|
+
content = content.slice(1, -1).trim();
|
|
84
|
+
}
|
|
85
|
+
label = normalizeLabel(content);
|
|
86
|
+
index = end + 1;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
node: { id, label },
|
|
91
|
+
nextIndex: index,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function readEdge(text, startIndex) {
|
|
95
|
+
ARROW_TOKEN.lastIndex = startIndex;
|
|
96
|
+
const match = ARROW_TOKEN.exec(text);
|
|
97
|
+
if (!match)
|
|
98
|
+
return null;
|
|
99
|
+
const arrowToken = match[0];
|
|
100
|
+
const arrowStart = match.index;
|
|
101
|
+
const arrowEnd = arrowStart + arrowToken.length;
|
|
102
|
+
const labelPrefix = stripEdgeLabelPrefix(text.slice(startIndex, arrowStart));
|
|
103
|
+
let label = labelPrefix || undefined;
|
|
104
|
+
let directionToken = arrowToken;
|
|
105
|
+
let index = arrowEnd;
|
|
106
|
+
index = skipSpaces(text, index);
|
|
107
|
+
if (text[index] === '|') {
|
|
108
|
+
const pipeEnd = text.indexOf('|', index + 1);
|
|
109
|
+
if (pipeEnd !== -1) {
|
|
110
|
+
const pipeLabel = normalizeLabel(text.slice(index + 1, pipeEnd));
|
|
111
|
+
label = pipeLabel || label;
|
|
112
|
+
index = pipeEnd + 1;
|
|
113
|
+
const afterLabel = skipSpaces(text, index);
|
|
114
|
+
ARROW_TOKEN.lastIndex = afterLabel;
|
|
115
|
+
const tail = ARROW_TOKEN.exec(text);
|
|
116
|
+
if (tail && tail.index === afterLabel) {
|
|
117
|
+
directionToken += tail[0];
|
|
118
|
+
index = tail.index + tail[0].length;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
index = afterLabel;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const hasLeft = directionToken.includes('<');
|
|
126
|
+
const hasRight = directionToken.includes('>');
|
|
127
|
+
const markerMatch = directionToken.match(/[xo]/gi) || [];
|
|
128
|
+
const markerLeft = /^[xo]/i.test(directionToken);
|
|
129
|
+
const markerRight = /[xo]$/i.test(directionToken);
|
|
130
|
+
let direction = 'none';
|
|
131
|
+
let reverse = false;
|
|
132
|
+
if ((hasLeft && hasRight) ||
|
|
133
|
+
(hasLeft && markerRight) ||
|
|
134
|
+
(hasRight && markerLeft) ||
|
|
135
|
+
(markerLeft && markerRight)) {
|
|
136
|
+
direction = 'both';
|
|
137
|
+
}
|
|
138
|
+
else if (hasLeft || hasRight || markerMatch.length > 0) {
|
|
139
|
+
direction = 'forward';
|
|
140
|
+
reverse = hasLeft && !hasRight;
|
|
141
|
+
}
|
|
142
|
+
return { label, direction, reverse, nextIndex: index };
|
|
143
|
+
}
|
|
144
|
+
function parseRelationLine(text) {
|
|
145
|
+
const relations = [];
|
|
146
|
+
const nodes = [];
|
|
147
|
+
const nodeMap = new Map();
|
|
148
|
+
let index = 0;
|
|
149
|
+
const first = readNode(text, index);
|
|
150
|
+
if (!first)
|
|
151
|
+
return { relations, nodes };
|
|
152
|
+
let current = first.node;
|
|
153
|
+
if (!nodeMap.has(current.id)) {
|
|
154
|
+
nodeMap.set(current.id, current);
|
|
155
|
+
nodes.push(current);
|
|
156
|
+
}
|
|
157
|
+
index = first.nextIndex;
|
|
158
|
+
while (index < text.length) {
|
|
159
|
+
const edge = readEdge(text, index);
|
|
160
|
+
if (!edge)
|
|
161
|
+
break;
|
|
162
|
+
index = edge.nextIndex;
|
|
163
|
+
const nextNode = readNode(text, index);
|
|
164
|
+
if (!nextNode)
|
|
165
|
+
break;
|
|
166
|
+
index = nextNode.nextIndex;
|
|
167
|
+
let from = current.id;
|
|
168
|
+
let to = nextNode.node.id;
|
|
169
|
+
const direction = edge.direction;
|
|
170
|
+
if (edge.reverse) {
|
|
171
|
+
from = nextNode.node.id;
|
|
172
|
+
to = current.id;
|
|
173
|
+
}
|
|
174
|
+
const relation = {
|
|
175
|
+
from,
|
|
176
|
+
to,
|
|
177
|
+
};
|
|
178
|
+
if (edge.label)
|
|
179
|
+
relation.label = edge.label;
|
|
180
|
+
if (direction === 'both')
|
|
181
|
+
relation.direction = 'both';
|
|
182
|
+
if (direction === 'none')
|
|
183
|
+
relation.direction = 'none';
|
|
184
|
+
relations.push(relation);
|
|
185
|
+
if (!nodeMap.has(current.id)) {
|
|
186
|
+
nodeMap.set(current.id, current);
|
|
187
|
+
nodes.push(current);
|
|
188
|
+
}
|
|
189
|
+
if (!nodeMap.has(nextNode.node.id)) {
|
|
190
|
+
nodeMap.set(nextNode.node.id, nextNode.node);
|
|
191
|
+
nodes.push(nextNode.node);
|
|
192
|
+
}
|
|
193
|
+
current = nextNode.node;
|
|
194
|
+
}
|
|
195
|
+
return { relations, nodes };
|
|
196
|
+
}
|
|
197
|
+
function ensureItemLabel(items, list, id, label) {
|
|
198
|
+
if (!id)
|
|
199
|
+
return;
|
|
200
|
+
const existing = items.get(id);
|
|
201
|
+
if (existing) {
|
|
202
|
+
if (!existing.label && label)
|
|
203
|
+
existing.label = label;
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const item = { id, label: label || id };
|
|
207
|
+
items.set(id, item);
|
|
208
|
+
list.push(item);
|
|
209
|
+
}
|
|
210
|
+
function parseExplicitRelation(node, path, errors) {
|
|
211
|
+
const value = mapWithSchema(node, RelationSchema, path, errors);
|
|
212
|
+
if (!value || typeof value !== 'object')
|
|
213
|
+
return null;
|
|
214
|
+
if (typeof value.from !== 'string' || typeof value.to !== 'string') {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
return value;
|
|
218
|
+
}
|
|
219
|
+
export function parseRelationsNode(node, errors, path) {
|
|
220
|
+
const relations = [];
|
|
221
|
+
const items = [];
|
|
222
|
+
const itemMap = new Map();
|
|
223
|
+
const parseLine = (line) => {
|
|
224
|
+
if (!RELATION_TOKEN.test(line))
|
|
225
|
+
return;
|
|
226
|
+
const parsed = parseRelationLine(line);
|
|
227
|
+
parsed.nodes.forEach((nodeItem) => {
|
|
228
|
+
ensureItemLabel(itemMap, items, nodeItem.id, nodeItem.label);
|
|
229
|
+
});
|
|
230
|
+
relations.push(...parsed.relations);
|
|
231
|
+
};
|
|
232
|
+
if (node.kind === 'array') {
|
|
233
|
+
node.items.forEach((item, index) => {
|
|
234
|
+
if (item.kind === 'object' &&
|
|
235
|
+
item.value &&
|
|
236
|
+
Object.keys(item.entries).length === 0 &&
|
|
237
|
+
RELATION_TOKEN.test(item.value)) {
|
|
238
|
+
parseLine(item.value);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const relation = parseExplicitRelation(item, `${path}[${index}]`, errors);
|
|
242
|
+
if (relation) {
|
|
243
|
+
relations.push(relation);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
else if (node.kind === 'object' && node.value) {
|
|
248
|
+
parseLine(node.value);
|
|
249
|
+
}
|
|
250
|
+
return { relations, items };
|
|
251
|
+
}
|
package/esm/syntax/schema.d.ts
CHANGED
package/esm/syntax/schema.js
CHANGED
|
@@ -30,12 +30,23 @@ const textStyleSchema = object(nullableColorFields, { allowUnknown: true });
|
|
|
30
30
|
const shapeStyleSchema = object(nullableColorFields, { allowUnknown: true });
|
|
31
31
|
const itemDatumSchema = object({}, { allowUnknown: true });
|
|
32
32
|
itemDatumSchema.fields = {
|
|
33
|
+
id: string(),
|
|
33
34
|
label: string(),
|
|
34
35
|
value: union(number(), string()),
|
|
35
36
|
desc: string(),
|
|
36
37
|
icon: string(),
|
|
38
|
+
group: string(),
|
|
37
39
|
children: array(itemDatumSchema),
|
|
38
40
|
};
|
|
41
|
+
export const RelationSchema = object({
|
|
42
|
+
id: string(),
|
|
43
|
+
from: string(),
|
|
44
|
+
to: string(),
|
|
45
|
+
label: string(),
|
|
46
|
+
direction: enumOf(['forward', 'both', 'none']),
|
|
47
|
+
showArrow: enumOf(['true', 'false']),
|
|
48
|
+
arrowType: enumOf(['arrow', 'triangle', 'diamond']),
|
|
49
|
+
}, { allowUnknown: true });
|
|
39
50
|
export const ThemeSchema = object({
|
|
40
51
|
type: string(),
|
|
41
52
|
colorBg: color(),
|
|
@@ -80,6 +91,7 @@ export const DataSchema = object({
|
|
|
80
91
|
title: string(),
|
|
81
92
|
desc: string(),
|
|
82
93
|
items: array(itemDatumSchema),
|
|
94
|
+
relations: array(RelationSchema),
|
|
83
95
|
});
|
|
84
96
|
export const TemplateSchema = object({
|
|
85
97
|
type: string(),
|
|
@@ -3,6 +3,7 @@ import { hierarchyStructureTemplates } from './hierarchy-structure';
|
|
|
3
3
|
import { hierarchyTreeTemplates } from './hierarchy-tree';
|
|
4
4
|
import { listZigzagTemplates } from './list-zigzag';
|
|
5
5
|
import { registerTemplate } from './registry';
|
|
6
|
+
import { relationDagreFlowTemplates } from './relation-dagre-flow';
|
|
6
7
|
import { sequenceStairsTemplates } from './sequence-stairs';
|
|
7
8
|
import { wordCloudTemplate } from './word-cloud';
|
|
8
9
|
const BUILT_IN_TEMPLATES = {
|
|
@@ -308,6 +309,16 @@ const BUILT_IN_TEMPLATES = {
|
|
|
308
309
|
colorPrimary: '#1677ff',
|
|
309
310
|
},
|
|
310
311
|
},
|
|
312
|
+
'sequence-funnel-simple': {
|
|
313
|
+
design: {
|
|
314
|
+
title: 'default',
|
|
315
|
+
structure: { type: 'sequence-funnel' },
|
|
316
|
+
items: [{ type: 'simple', showIcon: false, usePaletteColor: true }],
|
|
317
|
+
},
|
|
318
|
+
themeConfig: {
|
|
319
|
+
palette: '#1677ff',
|
|
320
|
+
},
|
|
321
|
+
},
|
|
311
322
|
'list-row-horizontal-icon-line': {
|
|
312
323
|
design: {
|
|
313
324
|
title: 'default',
|
|
@@ -808,6 +819,7 @@ const BUILT_IN_TEMPLATES = {
|
|
|
808
819
|
...sequenceStairsTemplates,
|
|
809
820
|
...wordCloudTemplate,
|
|
810
821
|
...listZigzagTemplates,
|
|
822
|
+
...relationDagreFlowTemplates,
|
|
811
823
|
...hierarchyStructureTemplates,
|
|
812
824
|
};
|
|
813
825
|
Object.entries(BUILT_IN_TEMPLATES).forEach(([name, options]) => {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const items = {
|
|
2
|
+
'simple-circle-node': {
|
|
3
|
+
type: 'simple-circle-node',
|
|
4
|
+
},
|
|
5
|
+
'badge-card': {
|
|
6
|
+
type: 'badge-card',
|
|
7
|
+
},
|
|
8
|
+
capsule: {
|
|
9
|
+
type: 'capsule-item',
|
|
10
|
+
},
|
|
11
|
+
'compact-card': {
|
|
12
|
+
type: 'compact-card',
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
const baseStructureAttrs = {
|
|
16
|
+
type: 'relation-dagre-flow',
|
|
17
|
+
edgeColorMode: 'gradient',
|
|
18
|
+
showArrow: true,
|
|
19
|
+
arrowType: 'triangle',
|
|
20
|
+
colorMode: 'node',
|
|
21
|
+
};
|
|
22
|
+
const structures = {
|
|
23
|
+
tb: {
|
|
24
|
+
...baseStructureAttrs,
|
|
25
|
+
rankdir: 'TB',
|
|
26
|
+
edgeRouting: 'orth',
|
|
27
|
+
},
|
|
28
|
+
lr: {
|
|
29
|
+
...baseStructureAttrs,
|
|
30
|
+
rankdir: 'LR',
|
|
31
|
+
edgeRouting: 'orth',
|
|
32
|
+
},
|
|
33
|
+
'tb-animated': {
|
|
34
|
+
...baseStructureAttrs,
|
|
35
|
+
rankdir: 'TB',
|
|
36
|
+
edgeCornerRadius: 12,
|
|
37
|
+
edgeRouting: 'orth',
|
|
38
|
+
edgeAnimation: 'ant-line',
|
|
39
|
+
edgeDashPattern: '8,4',
|
|
40
|
+
edgeAnimationSpeed: 1,
|
|
41
|
+
},
|
|
42
|
+
'lr-animated': {
|
|
43
|
+
...baseStructureAttrs,
|
|
44
|
+
rankdir: 'LR',
|
|
45
|
+
edgeCornerRadius: 12,
|
|
46
|
+
edgeRouting: 'orth',
|
|
47
|
+
edgeAnimation: 'ant-line',
|
|
48
|
+
edgeDashPattern: '8,4',
|
|
49
|
+
edgeAnimationSpeed: 1,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
export const relationDagreFlowTemplates = {};
|
|
53
|
+
const omit = ['lr-capsule', 'tb-capsule'];
|
|
54
|
+
Object.entries(structures).forEach(([strKey, strAttrs]) => {
|
|
55
|
+
Object.entries(items).forEach(([itemKey, itemAttrs]) => {
|
|
56
|
+
const appendix = `${strKey}-${itemKey}`;
|
|
57
|
+
if (omit.includes(appendix))
|
|
58
|
+
return;
|
|
59
|
+
const templateKey = `relation-dagre-flow-${appendix}`;
|
|
60
|
+
relationDagreFlowTemplates[templateKey] = {
|
|
61
|
+
design: {
|
|
62
|
+
title: 'default',
|
|
63
|
+
structure: strAttrs,
|
|
64
|
+
item: itemAttrs,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
});
|
package/esm/types/data.d.ts
CHANGED
|
@@ -1,18 +1,39 @@
|
|
|
1
1
|
import type { ResourceConfig } from '../resource';
|
|
2
|
-
export interface
|
|
2
|
+
export interface BaseDatum {
|
|
3
|
+
id?: string;
|
|
3
4
|
icon?: string | ResourceConfig;
|
|
4
5
|
label?: string;
|
|
5
6
|
desc?: string;
|
|
6
7
|
value?: number;
|
|
7
|
-
illus?: string | ResourceConfig;
|
|
8
|
-
children?: ItemDatum[];
|
|
9
8
|
attributes?: Record<string, object>;
|
|
10
9
|
[key: string]: any;
|
|
11
10
|
}
|
|
11
|
+
export interface ItemDatum extends BaseDatum {
|
|
12
|
+
illus?: string | ResourceConfig;
|
|
13
|
+
/** for hierarchical structure */
|
|
14
|
+
children?: ItemDatum[];
|
|
15
|
+
/** 图布局中用于分组,相同的 group 会使用同样的颜色 */
|
|
16
|
+
group?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface RelationDatum extends BaseDatum {
|
|
19
|
+
id?: string;
|
|
20
|
+
from: string;
|
|
21
|
+
to: string;
|
|
22
|
+
/**
|
|
23
|
+
* 表示连线的方向,默认 'forward'
|
|
24
|
+
* - 'forward':单向,从 from 指向 to
|
|
25
|
+
* - 'both':双向
|
|
26
|
+
* - 'none':无方向
|
|
27
|
+
*/
|
|
28
|
+
direction?: 'forward' | 'both' | 'none';
|
|
29
|
+
showArrow?: boolean;
|
|
30
|
+
arrowType?: 'arrow' | 'triangle' | 'diamond';
|
|
31
|
+
}
|
|
12
32
|
export interface Data {
|
|
13
33
|
title?: string;
|
|
14
34
|
desc?: string;
|
|
15
35
|
items: ItemDatum[];
|
|
36
|
+
relations?: RelationDatum[];
|
|
16
37
|
illus?: Record<string, string | ResourceConfig>;
|
|
17
38
|
attributes?: Record<string, object>;
|
|
18
39
|
[key: string]: any;
|
package/esm/utils/data.js
CHANGED
package/esm/utils/index.d.ts
CHANGED
package/esm/utils/index.js
CHANGED
package/esm/utils/is-browser.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
let
|
|
1
|
+
let IS_BROWSER;
|
|
2
2
|
export function isBrowser() {
|
|
3
|
-
if (
|
|
4
|
-
return
|
|
5
|
-
}
|
|
3
|
+
if (IS_BROWSER)
|
|
4
|
+
return true;
|
|
6
5
|
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
7
|
-
_isBrowser = false;
|
|
8
6
|
return false;
|
|
9
7
|
}
|
|
10
8
|
const body = document.body;
|
|
11
9
|
if (!body) {
|
|
12
|
-
_isBrowser = false;
|
|
13
10
|
return false;
|
|
14
11
|
}
|
|
15
12
|
let hasRealLayout = false;
|
|
@@ -40,7 +37,6 @@ export function isBrowser() {
|
|
|
40
37
|
hasRealLayout = false;
|
|
41
38
|
}
|
|
42
39
|
if (!hasRealLayout) {
|
|
43
|
-
_isBrowser = false;
|
|
44
40
|
return false;
|
|
45
41
|
}
|
|
46
42
|
let hasRealCanvas = false;
|
|
@@ -50,7 +46,6 @@ export function isBrowser() {
|
|
|
50
46
|
canvas.height = 50;
|
|
51
47
|
const ctx = canvas.getContext('2d');
|
|
52
48
|
if (!ctx) {
|
|
53
|
-
_isBrowser = false;
|
|
54
49
|
return false;
|
|
55
50
|
}
|
|
56
51
|
ctx.font = '20px sans-serif';
|
|
@@ -63,6 +58,7 @@ export function isBrowser() {
|
|
|
63
58
|
catch {
|
|
64
59
|
hasRealCanvas = false;
|
|
65
60
|
}
|
|
66
|
-
|
|
61
|
+
if (hasRealCanvas)
|
|
62
|
+
IS_BROWSER = hasRealCanvas;
|
|
67
63
|
return hasRealCanvas;
|
|
68
64
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { TextProps } from '../jsx';
|
|
1
|
+
import { JSXNode, TextProps } from '../jsx';
|
|
2
2
|
export declare const setFontExtendFactor: (factor: number) => void;
|
|
3
|
-
export declare function measureText(text:
|
|
3
|
+
export declare function measureText(text: JSXNode, attrs: TextProps): {
|
|
4
4
|
width: number;
|
|
5
5
|
height: number;
|
|
6
6
|
};
|
|
@@ -3,14 +3,11 @@ import AlibabaPuHuiTi from 'measury/fonts/AlibabaPuHuiTi-Regular';
|
|
|
3
3
|
import { DEFAULT_FONT } from '../renderer';
|
|
4
4
|
import { encodeFontFamily } from './font';
|
|
5
5
|
import { isBrowser } from './is-browser';
|
|
6
|
-
import { isNode } from './is-node';
|
|
7
6
|
let FONT_EXTEND_FACTOR = 1.01;
|
|
8
7
|
export const setFontExtendFactor = (factor) => {
|
|
9
8
|
FONT_EXTEND_FACTOR = factor;
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
registerFont(AlibabaPuHuiTi);
|
|
13
|
-
}
|
|
10
|
+
registerFont(AlibabaPuHuiTi);
|
|
14
11
|
let canvasContext = null;
|
|
15
12
|
let measureSpan = null;
|
|
16
13
|
function getCanvasContext() {
|
|
@@ -84,6 +81,9 @@ export function measureText(text = '', attrs) {
|
|
|
84
81
|
if (attrs.width && attrs.height) {
|
|
85
82
|
return { width: attrs.width, height: attrs.height };
|
|
86
83
|
}
|
|
84
|
+
if (typeof text !== 'string' && typeof text !== 'number') {
|
|
85
|
+
return { width: 0, height: 0 };
|
|
86
|
+
}
|
|
87
87
|
const { fontFamily = DEFAULT_FONT, fontSize = 14, fontWeight = 'normal', lineHeight = 1.4, } = attrs;
|
|
88
88
|
const content = text.toString();
|
|
89
89
|
const options = {
|
package/esm/utils/padding.js
CHANGED
|
@@ -30,22 +30,27 @@ export function setSVGPadding(svg, padding) {
|
|
|
30
30
|
setSVGPaddingInBrowser(svg, padding);
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
try {
|
|
34
|
+
const observer = new MutationObserver((mutations) => {
|
|
35
|
+
mutations.forEach((mutation) => {
|
|
36
|
+
mutation.addedNodes.forEach((node) => {
|
|
37
|
+
if (node === svg || node.contains(svg)) {
|
|
38
|
+
waitForLayout(svg, () => {
|
|
39
|
+
setSVGPaddingInBrowser(svg, padding);
|
|
40
|
+
});
|
|
41
|
+
observer.disconnect();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
42
44
|
});
|
|
43
45
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
46
|
+
observer.observe(document, {
|
|
47
|
+
childList: true,
|
|
48
|
+
subtree: true,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
setSVGPaddingInNode(svg, padding);
|
|
53
|
+
}
|
|
49
54
|
}
|
|
50
55
|
}
|
|
51
56
|
}
|