@antv/infographic 0.2.7 → 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/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.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/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/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/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/package.json +19 -7
- 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 -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/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
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RelationDagreFlow = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("@antv/infographic/jsx-runtime");
|
|
5
|
+
const layout_1 = require("@antv/layout");
|
|
6
|
+
const jsx_1 = require("../../jsx");
|
|
7
|
+
const components_1 = require("../components");
|
|
8
|
+
const layouts_1 = require("../layouts");
|
|
9
|
+
const utils_1 = require("../utils");
|
|
10
|
+
const registry_1 = require("./registry");
|
|
11
|
+
const DEFAULT_NODE_SEP = 50;
|
|
12
|
+
const DEFAULT_RANK_SEP = 70;
|
|
13
|
+
const DEFAULT_EDGE_SEP = 10;
|
|
14
|
+
const DEFAULT_EDGE_WIDTH = 2;
|
|
15
|
+
const DEFAULT_PADDING = 30;
|
|
16
|
+
const checkUndirectedCycle = (nodeIds, edges) => {
|
|
17
|
+
const adj = new Map();
|
|
18
|
+
nodeIds.forEach((id) => adj.set(id, []));
|
|
19
|
+
for (const edge of edges) {
|
|
20
|
+
if (edge.source === edge.target)
|
|
21
|
+
return true;
|
|
22
|
+
adj.get(edge.source)?.push({ target: edge.target, edgeId: edge.id });
|
|
23
|
+
adj.get(edge.target)?.push({ target: edge.source, edgeId: edge.id });
|
|
24
|
+
}
|
|
25
|
+
const visited = new Set();
|
|
26
|
+
const dfs = (u, parentEdgeId) => {
|
|
27
|
+
visited.add(u);
|
|
28
|
+
const neighbors = adj.get(u) || [];
|
|
29
|
+
for (const { target: v, edgeId } of neighbors) {
|
|
30
|
+
if (edgeId === parentEdgeId)
|
|
31
|
+
continue;
|
|
32
|
+
if (visited.has(v))
|
|
33
|
+
return true;
|
|
34
|
+
if (dfs(v, edgeId))
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
};
|
|
39
|
+
for (const node of nodeIds) {
|
|
40
|
+
if (!visited.has(node)) {
|
|
41
|
+
if (dfs(node, null))
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
};
|
|
47
|
+
const RelationDagreFlow = (props) => {
|
|
48
|
+
const { Title, Item, data, rankdir = 'TB', nodesep = DEFAULT_NODE_SEP, ranksep = DEFAULT_RANK_SEP, edgesep = DEFAULT_EDGE_SEP, edgeWidth = DEFAULT_EDGE_WIDTH, showConnections = true, edgeColorMode = 'gradient', edgeStyle = 'solid', edgeDashPattern = '5,5', edgeCornerRadius = 12, edgeRouting = 'orth', showArrow = true, arrowType = 'triangle', padding = DEFAULT_PADDING, edgeAnimation = 'none', edgeAnimationSpeed = 1, options, } = props;
|
|
49
|
+
const { title, desc, items = [] } = data;
|
|
50
|
+
const titleContent = Title ? (0, jsx_runtime_1.jsx)(Title, { title: title, desc: desc }) : null;
|
|
51
|
+
if (!Item || items.length === 0) {
|
|
52
|
+
return ((0, jsx_runtime_1.jsxs)(layouts_1.FlexLayout, { id: "infographic-container", flexDirection: "column", justifyContent: "center", alignItems: "center", children: [titleContent, (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: (0, jsx_runtime_1.jsx)(components_1.BtnAdd, { indexes: [0], x: 0, y: 0 }) })] }));
|
|
53
|
+
}
|
|
54
|
+
const nodeMetaMap = new Map();
|
|
55
|
+
const nodeSizeMap = new Map();
|
|
56
|
+
const nodeColorMap = new Map();
|
|
57
|
+
const nodeIdsByIndex = new Map();
|
|
58
|
+
const nodeIdSet = new Set();
|
|
59
|
+
const colorGroupIndexMap = new Map();
|
|
60
|
+
let nextColorGroupIndex = 0;
|
|
61
|
+
const nodes = items.map((item, index) => {
|
|
62
|
+
const datum = item;
|
|
63
|
+
const id = String(datum.id ?? index);
|
|
64
|
+
const indexes = [index];
|
|
65
|
+
let primary;
|
|
66
|
+
const groupKey = String(datum.group ?? '');
|
|
67
|
+
if (groupKey) {
|
|
68
|
+
let groupIndex = colorGroupIndexMap.get(groupKey);
|
|
69
|
+
if (groupIndex == null) {
|
|
70
|
+
groupIndex = nextColorGroupIndex;
|
|
71
|
+
colorGroupIndexMap.set(groupKey, groupIndex);
|
|
72
|
+
nextColorGroupIndex += 1;
|
|
73
|
+
}
|
|
74
|
+
primary = (0, utils_1.getPaletteColor)(options, [groupIndex]);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
primary = (0, utils_1.getPaletteColor)(options, indexes);
|
|
78
|
+
}
|
|
79
|
+
const themeColors = primary
|
|
80
|
+
? (0, utils_1.getThemeColors)({ colorPrimary: primary }, options)
|
|
81
|
+
: undefined;
|
|
82
|
+
if (primary) {
|
|
83
|
+
nodeColorMap.set(id, primary);
|
|
84
|
+
}
|
|
85
|
+
const bounds = (0, jsx_1.getElementBounds)((0, jsx_runtime_1.jsx)(Item, { indexes: indexes, data: data, datum: datum, positionH: "center", positionV: "middle", themeColors: themeColors }));
|
|
86
|
+
nodeSizeMap.set(id, bounds);
|
|
87
|
+
nodeMetaMap.set(id, { id, indexes, datum, themeColors });
|
|
88
|
+
nodeIdsByIndex.set(index, id);
|
|
89
|
+
nodeIdSet.add(id);
|
|
90
|
+
return { id, parentId: datum.parentId };
|
|
91
|
+
});
|
|
92
|
+
const relations = data.relations ?? [];
|
|
93
|
+
const resolveNodeId = (value) => {
|
|
94
|
+
if (value == null)
|
|
95
|
+
return null;
|
|
96
|
+
const direct = String(value);
|
|
97
|
+
if (nodeIdSet.has(direct))
|
|
98
|
+
return direct;
|
|
99
|
+
const asIndex = Number(value);
|
|
100
|
+
if (!Number.isNaN(asIndex)) {
|
|
101
|
+
const mapped = nodeIdsByIndex.get(asIndex);
|
|
102
|
+
if (mapped)
|
|
103
|
+
return mapped;
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
};
|
|
107
|
+
const edges = relations
|
|
108
|
+
.map((relation, index) => {
|
|
109
|
+
const source = resolveNodeId(relation.from);
|
|
110
|
+
const target = resolveNodeId(relation.to);
|
|
111
|
+
if (!source || !target)
|
|
112
|
+
return null;
|
|
113
|
+
return {
|
|
114
|
+
id: relation.id ? String(relation.id) : `edge-${index}`,
|
|
115
|
+
source,
|
|
116
|
+
target,
|
|
117
|
+
relation,
|
|
118
|
+
};
|
|
119
|
+
})
|
|
120
|
+
.filter(Boolean);
|
|
121
|
+
const hasCycle = checkUndirectedCycle(Array.from(nodeIdSet), edges);
|
|
122
|
+
const finalEdgeRouting = hasCycle ? 'dagre' : edgeRouting;
|
|
123
|
+
const layout = new layout_1.DagreLayout({
|
|
124
|
+
rankdir,
|
|
125
|
+
nodesep,
|
|
126
|
+
ranksep,
|
|
127
|
+
edgesep,
|
|
128
|
+
controlPoints: true,
|
|
129
|
+
nodeSize: (node) => {
|
|
130
|
+
const id = String(node.id ?? '');
|
|
131
|
+
const bounds = nodeSizeMap.get(id);
|
|
132
|
+
return bounds ? [bounds.width, bounds.height] : [0, 0];
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
layout.execute({ nodes, edges });
|
|
136
|
+
const nodeLayouts = [];
|
|
137
|
+
layout.forEachNode((node) => {
|
|
138
|
+
const id = String(node.id);
|
|
139
|
+
const meta = nodeMetaMap.get(id);
|
|
140
|
+
if (!meta)
|
|
141
|
+
return;
|
|
142
|
+
const bounds = nodeSizeMap.get(id);
|
|
143
|
+
const width = bounds?.width ?? 0;
|
|
144
|
+
const height = bounds?.height ?? 0;
|
|
145
|
+
const x = (node.x ?? 0) - width / 2;
|
|
146
|
+
const y = (node.y ?? 0) - height / 2;
|
|
147
|
+
nodeLayouts.push({
|
|
148
|
+
...meta,
|
|
149
|
+
x,
|
|
150
|
+
y,
|
|
151
|
+
width,
|
|
152
|
+
height,
|
|
153
|
+
centerX: x + width / 2,
|
|
154
|
+
centerY: y + height / 2,
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
if (nodeLayouts.length === 0) {
|
|
158
|
+
return ((0, jsx_runtime_1.jsxs)(layouts_1.FlexLayout, { id: "infographic-container", flexDirection: "column", justifyContent: "center", alignItems: "center", children: [titleContent, (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: (0, jsx_runtime_1.jsx)(components_1.BtnAdd, { indexes: [0], x: 0, y: 0 }) })] }));
|
|
159
|
+
}
|
|
160
|
+
const minX = Math.min(...nodeLayouts.map((node) => node.x));
|
|
161
|
+
const minY = Math.min(...nodeLayouts.map((node) => node.y));
|
|
162
|
+
const offsetX = padding - minX;
|
|
163
|
+
const offsetY = padding - minY;
|
|
164
|
+
const nodeLayoutById = new Map();
|
|
165
|
+
const itemElements = [];
|
|
166
|
+
nodeLayouts.forEach((node) => {
|
|
167
|
+
const displayX = node.x + offsetX;
|
|
168
|
+
const displayY = node.y + offsetY;
|
|
169
|
+
const positionH = rankdir === 'LR' ? 'normal' : rankdir === 'RL' ? 'flipped' : 'center';
|
|
170
|
+
const positionV = rankdir === 'TB' ? 'normal' : rankdir === 'BT' ? 'flipped' : 'middle';
|
|
171
|
+
itemElements.push((0, jsx_runtime_1.jsx)(Item, { indexes: node.indexes, datum: node.datum, data: data, x: displayX, y: displayY, positionH: positionH, positionV: positionV, themeColors: node.themeColors }));
|
|
172
|
+
nodeLayoutById.set(node.id, {
|
|
173
|
+
...node,
|
|
174
|
+
x: displayX,
|
|
175
|
+
y: displayY,
|
|
176
|
+
centerX: displayX + node.width / 2,
|
|
177
|
+
centerY: displayY + node.height / 2,
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
const defsElements = [];
|
|
181
|
+
const decorElements = [];
|
|
182
|
+
if (showConnections) {
|
|
183
|
+
const defaultStroke = (0, utils_1.getColorPrimary)(options);
|
|
184
|
+
const themeColors = (0, utils_1.getThemeColors)(options.themeConfig, options);
|
|
185
|
+
const labelBackground = themeColors?.colorBg ?? '#ffffff';
|
|
186
|
+
const labelTextColor = themeColors?.colorText ?? defaultStroke;
|
|
187
|
+
const arrowSize = Math.max(10, edgeWidth * 4);
|
|
188
|
+
const isVertical = rankdir === 'TB' || rankdir === 'BT';
|
|
189
|
+
const enableAnimation = edgeAnimation === 'ant-line';
|
|
190
|
+
const animationDashArray = enableAnimation ? edgeDashPattern : '';
|
|
191
|
+
const staticDashArray = !enableAnimation && edgeStyle === 'dashed' ? edgeDashPattern : '';
|
|
192
|
+
const actualDashArray = enableAnimation
|
|
193
|
+
? animationDashArray
|
|
194
|
+
: staticDashArray;
|
|
195
|
+
const dashPatternLength = enableAnimation
|
|
196
|
+
? animationDashArray
|
|
197
|
+
.split(',')
|
|
198
|
+
.reduce((sum, val) => sum + parseFloat(val.trim() || '0'), 0)
|
|
199
|
+
: 0;
|
|
200
|
+
const animationDuration = enableAnimation && dashPatternLength > 0
|
|
201
|
+
? `${dashPatternLength / (edgeAnimationSpeed * 10)}s`
|
|
202
|
+
: '1s';
|
|
203
|
+
const straightCornerRadius = edgeCornerRadius;
|
|
204
|
+
const createStraightPath = (points, dx, dy) => points
|
|
205
|
+
.map(([x, y], index) => {
|
|
206
|
+
const prefix = index === 0 ? 'M' : 'L';
|
|
207
|
+
return `${prefix} ${x + dx} ${y + dy}`;
|
|
208
|
+
})
|
|
209
|
+
.join(' ');
|
|
210
|
+
const createRoundedPath = (points, radius, dx, dy) => {
|
|
211
|
+
if (points.length < 2)
|
|
212
|
+
return '';
|
|
213
|
+
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
214
|
+
const toPoint = ([x, y]) => ({
|
|
215
|
+
x: x + dx,
|
|
216
|
+
y: y + dy,
|
|
217
|
+
});
|
|
218
|
+
const output = [];
|
|
219
|
+
const first = toPoint(points[0]);
|
|
220
|
+
output.push(`M ${first.x} ${first.y}`);
|
|
221
|
+
if (points.length === 2) {
|
|
222
|
+
const last = toPoint(points[1]);
|
|
223
|
+
output.push(`L ${last.x} ${last.y}`);
|
|
224
|
+
return output.join(' ');
|
|
225
|
+
}
|
|
226
|
+
for (let i = 1; i < points.length - 1; i += 1) {
|
|
227
|
+
const prev = points[i - 1];
|
|
228
|
+
const curr = points[i];
|
|
229
|
+
const next = points[i + 1];
|
|
230
|
+
const v0x = curr[0] - prev[0];
|
|
231
|
+
const v0y = curr[1] - prev[1];
|
|
232
|
+
const v1x = next[0] - curr[0];
|
|
233
|
+
const v1y = next[1] - curr[1];
|
|
234
|
+
const d0 = Math.hypot(v0x, v0y);
|
|
235
|
+
const d1 = Math.hypot(v1x, v1y);
|
|
236
|
+
if (d0 === 0 || d1 === 0) {
|
|
237
|
+
const currPoint = toPoint(curr);
|
|
238
|
+
output.push(`L ${currPoint.x} ${currPoint.y}`);
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
const r = clamp(radius, 0, Math.min(d0, d1) / 2);
|
|
242
|
+
if (r === 0) {
|
|
243
|
+
const currPoint = toPoint(curr);
|
|
244
|
+
output.push(`L ${currPoint.x} ${currPoint.y}`);
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
const u0x = v0x / d0;
|
|
248
|
+
const u0y = v0y / d0;
|
|
249
|
+
const u1x = v1x / d1;
|
|
250
|
+
const u1y = v1y / d1;
|
|
251
|
+
const start = toPoint([curr[0] - u0x * r, curr[1] - u0y * r]);
|
|
252
|
+
const end = toPoint([curr[0] + u1x * r, curr[1] + u1y * r]);
|
|
253
|
+
output.push(`L ${start.x} ${start.y}`);
|
|
254
|
+
const currPoint = toPoint(curr);
|
|
255
|
+
output.push(`Q ${currPoint.x} ${currPoint.y} ${end.x} ${end.y}`);
|
|
256
|
+
}
|
|
257
|
+
const last = toPoint(points[points.length - 1]);
|
|
258
|
+
output.push(`L ${last.x} ${last.y}`);
|
|
259
|
+
return output.join(' ');
|
|
260
|
+
};
|
|
261
|
+
const createArrowElements = (x, y, angle, type, fillColor) => {
|
|
262
|
+
const ux = Math.cos(angle);
|
|
263
|
+
const uy = Math.sin(angle);
|
|
264
|
+
const px = -uy;
|
|
265
|
+
const py = ux;
|
|
266
|
+
const length = arrowSize;
|
|
267
|
+
const halfWidth = arrowSize * 0.55;
|
|
268
|
+
if (type === 'arrow') {
|
|
269
|
+
const leftX = x - ux * length + px * halfWidth;
|
|
270
|
+
const leftY = y - uy * length + py * halfWidth;
|
|
271
|
+
const rightX = x - ux * length - px * halfWidth;
|
|
272
|
+
const rightY = y - uy * length - py * halfWidth;
|
|
273
|
+
return [
|
|
274
|
+
(0, jsx_runtime_1.jsx)(jsx_1.Path, { d: `M ${leftX} ${leftY} L ${x} ${y} L ${rightX} ${rightY}`, stroke: fillColor, strokeWidth: Math.max(1.5, edgeWidth), strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }),
|
|
275
|
+
];
|
|
276
|
+
}
|
|
277
|
+
if (type === 'diamond') {
|
|
278
|
+
const diamondLength = length * 1.25;
|
|
279
|
+
const diamondWidth = halfWidth * 0.75;
|
|
280
|
+
const midX = x - ux * diamondLength * 0.5;
|
|
281
|
+
const midY = y - uy * diamondLength * 0.5;
|
|
282
|
+
const diamondPoints = [
|
|
283
|
+
{ x, y },
|
|
284
|
+
{ x: midX + px * diamondWidth, y: midY + py * diamondWidth },
|
|
285
|
+
{ x: x - ux * diamondLength, y: y - uy * diamondLength },
|
|
286
|
+
{ x: midX - px * diamondWidth, y: midY - py * diamondWidth },
|
|
287
|
+
];
|
|
288
|
+
return [
|
|
289
|
+
(0, jsx_runtime_1.jsx)(jsx_1.Polygon, { points: diamondPoints, fill: fillColor, stroke: fillColor, strokeWidth: Math.max(1, edgeWidth * 0.8) }),
|
|
290
|
+
];
|
|
291
|
+
}
|
|
292
|
+
const trianglePoints = [
|
|
293
|
+
{ x, y },
|
|
294
|
+
{
|
|
295
|
+
x: x - ux * length + px * halfWidth,
|
|
296
|
+
y: y - uy * length + py * halfWidth,
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
x: x - ux * length - px * halfWidth,
|
|
300
|
+
y: y - uy * length - py * halfWidth,
|
|
301
|
+
},
|
|
302
|
+
];
|
|
303
|
+
return [
|
|
304
|
+
(0, jsx_runtime_1.jsx)(jsx_1.Polygon, { points: trianglePoints, fill: fillColor, stroke: fillColor, strokeWidth: Math.max(1, edgeWidth * 0.8) }),
|
|
305
|
+
];
|
|
306
|
+
};
|
|
307
|
+
const getMidPoint = (points) => {
|
|
308
|
+
if (points.length === 0)
|
|
309
|
+
return null;
|
|
310
|
+
if (points.length === 1)
|
|
311
|
+
return points[0];
|
|
312
|
+
let total = 0;
|
|
313
|
+
const segments = [];
|
|
314
|
+
for (let i = 0; i < points.length - 1; i += 1) {
|
|
315
|
+
const start = points[i];
|
|
316
|
+
const end = points[i + 1];
|
|
317
|
+
const length = Math.hypot(end[0] - start[0], end[1] - start[1]);
|
|
318
|
+
segments.push({ length, start, end });
|
|
319
|
+
total += length;
|
|
320
|
+
}
|
|
321
|
+
if (total === 0)
|
|
322
|
+
return points[0];
|
|
323
|
+
let target = total / 2;
|
|
324
|
+
for (let i = 0; i < segments.length; i += 1) {
|
|
325
|
+
const segment = segments[i];
|
|
326
|
+
if (target <= segment.length || i === segments.length - 1) {
|
|
327
|
+
const ratio = segment.length === 0
|
|
328
|
+
? 0
|
|
329
|
+
: Math.max(0, Math.min(1, target / segment.length));
|
|
330
|
+
return [
|
|
331
|
+
segment.start[0] + (segment.end[0] - segment.start[0]) * ratio,
|
|
332
|
+
segment.start[1] + (segment.end[1] - segment.start[1]) * ratio,
|
|
333
|
+
];
|
|
334
|
+
}
|
|
335
|
+
target -= segment.length;
|
|
336
|
+
}
|
|
337
|
+
return points[Math.floor(points.length / 2)];
|
|
338
|
+
};
|
|
339
|
+
const getOrthEdgeEndpoints = (sourceId, targetId) => {
|
|
340
|
+
const source = nodeLayoutById.get(sourceId);
|
|
341
|
+
const target = nodeLayoutById.get(targetId);
|
|
342
|
+
if (!source || !target)
|
|
343
|
+
return null;
|
|
344
|
+
if (rankdir === 'TB') {
|
|
345
|
+
return {
|
|
346
|
+
start: [source.centerX, source.y + source.height],
|
|
347
|
+
end: [target.centerX, target.y],
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
if (rankdir === 'BT') {
|
|
351
|
+
return {
|
|
352
|
+
start: [source.centerX, source.y],
|
|
353
|
+
end: [target.centerX, target.y + target.height],
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
if (rankdir === 'LR') {
|
|
357
|
+
return {
|
|
358
|
+
start: [source.x + source.width, source.centerY],
|
|
359
|
+
end: [target.x, target.centerY],
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
return {
|
|
363
|
+
start: [source.x, source.centerY],
|
|
364
|
+
end: [target.x + target.width, target.centerY],
|
|
365
|
+
};
|
|
366
|
+
};
|
|
367
|
+
const getOrthEdgePoints = (sourceId, targetId) => {
|
|
368
|
+
const endpoints = getOrthEdgeEndpoints(sourceId, targetId);
|
|
369
|
+
if (!endpoints)
|
|
370
|
+
return null;
|
|
371
|
+
const { start, end } = endpoints;
|
|
372
|
+
if (isVertical) {
|
|
373
|
+
const midY = start[1] + (end[1] - start[1]) / 2;
|
|
374
|
+
return {
|
|
375
|
+
start,
|
|
376
|
+
end,
|
|
377
|
+
points: [start, [start[0], midY], [end[0], midY], end],
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
const midX = start[0] + (end[0] - start[0]) / 2;
|
|
381
|
+
return {
|
|
382
|
+
start,
|
|
383
|
+
end,
|
|
384
|
+
points: [start, [midX, start[1]], [midX, end[1]], end],
|
|
385
|
+
};
|
|
386
|
+
};
|
|
387
|
+
layout.forEachEdge((edge) => {
|
|
388
|
+
const normalizePoints = (rawPoints) => {
|
|
389
|
+
if (!Array.isArray(rawPoints))
|
|
390
|
+
return [];
|
|
391
|
+
return rawPoints
|
|
392
|
+
.map((point) => {
|
|
393
|
+
if (!point)
|
|
394
|
+
return null;
|
|
395
|
+
if (Array.isArray(point) && point.length >= 2) {
|
|
396
|
+
return [Number(point[0]), Number(point[1])];
|
|
397
|
+
}
|
|
398
|
+
return null;
|
|
399
|
+
})
|
|
400
|
+
.filter((point) => !!point && Number.isFinite(point[0]) && Number.isFinite(point[1]));
|
|
401
|
+
};
|
|
402
|
+
const fallbackPoints = () => {
|
|
403
|
+
const source = nodeLayoutById.get(String(edge.source));
|
|
404
|
+
const target = nodeLayoutById.get(String(edge.target));
|
|
405
|
+
if (!source || !target)
|
|
406
|
+
return [];
|
|
407
|
+
return [
|
|
408
|
+
[source.centerX - offsetX, source.centerY - offsetY],
|
|
409
|
+
[target.centerX - offsetX, target.centerY - offsetY],
|
|
410
|
+
];
|
|
411
|
+
};
|
|
412
|
+
const useOrthRouting = finalEdgeRouting === 'orth';
|
|
413
|
+
const orthEdge = useOrthRouting
|
|
414
|
+
? getOrthEdgePoints(String(edge.source), String(edge.target))
|
|
415
|
+
: null;
|
|
416
|
+
const normalized = useOrthRouting ? [] : normalizePoints(edge.points);
|
|
417
|
+
const points = useOrthRouting
|
|
418
|
+
? (orthEdge?.points ?? [])
|
|
419
|
+
: normalized.length
|
|
420
|
+
? normalized
|
|
421
|
+
: fallbackPoints();
|
|
422
|
+
if (!points.length)
|
|
423
|
+
return;
|
|
424
|
+
const pointsOffsetX = useOrthRouting ? 0 : offsetX;
|
|
425
|
+
const pointsOffsetY = useOrthRouting ? 0 : offsetY;
|
|
426
|
+
const startPoint = useOrthRouting
|
|
427
|
+
? (orthEdge?.start ?? points[0])
|
|
428
|
+
: points[0];
|
|
429
|
+
const endPoint = useOrthRouting
|
|
430
|
+
? (orthEdge?.end ?? points[points.length - 1])
|
|
431
|
+
: points[points.length - 1];
|
|
432
|
+
const relation = edge
|
|
433
|
+
._original?.relation;
|
|
434
|
+
const sourceColor = nodeColorMap.get(String(edge.source)) ?? defaultStroke;
|
|
435
|
+
const targetColor = nodeColorMap.get(String(edge.target)) ?? defaultStroke;
|
|
436
|
+
const gradientKey = `edge-gradient-${String(sourceColor)}-${String(targetColor)}`.replace(/[^a-zA-Z0-9_-]/g, '');
|
|
437
|
+
const edgeStroke = edgeColorMode === 'gradient' ? `url(#${gradientKey})` : defaultStroke;
|
|
438
|
+
let pathD = '';
|
|
439
|
+
if (straightCornerRadius > 0) {
|
|
440
|
+
pathD = createRoundedPath(points, straightCornerRadius, pointsOffsetX, pointsOffsetY);
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
pathD = createStraightPath(points, pointsOffsetX, pointsOffsetY);
|
|
444
|
+
}
|
|
445
|
+
if (!pathD)
|
|
446
|
+
return;
|
|
447
|
+
const pathElement = ((0, jsx_runtime_1.jsx)(jsx_1.Path, { d: pathD, stroke: edgeStroke, strokeWidth: edgeWidth, strokeDasharray: actualDashArray, fill: "none", "data-element-type": "shape", children: enableAnimation && ((0, jsx_runtime_1.jsx)("animate", { attributeName: "stroke-dashoffset", from: String(dashPatternLength), to: "0", dur: animationDuration, repeatCount: "indefinite" })) }));
|
|
448
|
+
decorElements.push(pathElement);
|
|
449
|
+
if (edgeColorMode === 'gradient') {
|
|
450
|
+
const start = startPoint;
|
|
451
|
+
const end = endPoint;
|
|
452
|
+
defsElements.push((0, jsx_runtime_1.jsxs)("linearGradient", { id: gradientKey, gradientUnits: "userSpaceOnUse", x1: start[0] + pointsOffsetX, y1: start[1] + pointsOffsetY, x2: end[0] + pointsOffsetX, y2: end[1] + pointsOffsetY, children: [(0, jsx_runtime_1.jsx)("stop", { offset: "0%", stopColor: sourceColor }), (0, jsx_runtime_1.jsx)("stop", { offset: "100%", stopColor: targetColor })] }));
|
|
453
|
+
}
|
|
454
|
+
if (relation?.label) {
|
|
455
|
+
let labelPoint = null;
|
|
456
|
+
const midPoint = getMidPoint(points);
|
|
457
|
+
if (midPoint) {
|
|
458
|
+
labelPoint = [
|
|
459
|
+
midPoint[0] + pointsOffsetX,
|
|
460
|
+
midPoint[1] + pointsOffsetY,
|
|
461
|
+
];
|
|
462
|
+
}
|
|
463
|
+
if (labelPoint) {
|
|
464
|
+
const labelText = String(relation.label);
|
|
465
|
+
const labelBounds = (0, jsx_1.getElementBounds)((0, jsx_runtime_1.jsx)(jsx_1.Text, { fontSize: 14, fontWeight: "normal", children: labelText }));
|
|
466
|
+
const labelX = labelPoint[0] - labelBounds.width / 2;
|
|
467
|
+
const labelY = labelPoint[1] - labelBounds.height / 2;
|
|
468
|
+
decorElements.push((0, jsx_runtime_1.jsx)(jsx_1.Text, { x: labelX, y: labelY, width: labelBounds.width, height: labelBounds.height, fontSize: 14, fontWeight: "normal", alignHorizontal: "center", alignVertical: "middle", fill: labelTextColor, backgroundColor: labelBackground, children: labelText }));
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
const effectiveShowArrow = relation?.showArrow ?? showArrow;
|
|
472
|
+
const direction = relation?.direction ?? 'forward';
|
|
473
|
+
const edgeArrowType = relation?.arrowType ?? arrowType;
|
|
474
|
+
const lastIndex = points.length - 1;
|
|
475
|
+
if (effectiveShowArrow && points.length > 1) {
|
|
476
|
+
if (direction === 'forward' || direction === 'both') {
|
|
477
|
+
const head = points[lastIndex];
|
|
478
|
+
const tail = points[lastIndex - 1];
|
|
479
|
+
const angle = Math.atan2(head[1] - tail[1], head[0] - tail[0]);
|
|
480
|
+
const arrowFill = edgeColorMode === 'gradient' ? targetColor : defaultStroke;
|
|
481
|
+
const arrowElements = createArrowElements(head[0] + pointsOffsetX, head[1] + pointsOffsetY, angle, edgeArrowType, arrowFill);
|
|
482
|
+
decorElements.push(...arrowElements);
|
|
483
|
+
}
|
|
484
|
+
if (direction === 'both') {
|
|
485
|
+
const head = points[0];
|
|
486
|
+
const tail = points[1];
|
|
487
|
+
const angle = Math.atan2(head[1] - tail[1], head[0] - tail[0]);
|
|
488
|
+
const arrowFill = edgeColorMode === 'gradient' ? sourceColor : defaultStroke;
|
|
489
|
+
const arrowElements = createArrowElements(head[0] + pointsOffsetX, head[1] + pointsOffsetY, angle, edgeArrowType, arrowFill);
|
|
490
|
+
decorElements.push(...arrowElements);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
return ((0, jsx_runtime_1.jsxs)(layouts_1.FlexLayout, { id: "infographic-container", flexDirection: "column", justifyContent: "center", alignItems: "center", children: [titleContent, (0, jsx_runtime_1.jsxs)(jsx_1.Group, { children: [(0, jsx_runtime_1.jsx)(jsx_1.Defs, { children: defsElements }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { width: 0, height: 0, children: decorElements }), (0, jsx_runtime_1.jsx)(components_1.ItemsGroup, { children: itemElements }), (0, jsx_runtime_1.jsx)(components_1.BtnsGroup, {})] })] }));
|
|
496
|
+
};
|
|
497
|
+
exports.RelationDagreFlow = RelationDagreFlow;
|
|
498
|
+
(0, registry_1.registerStructure)('relation-dagre-flow', {
|
|
499
|
+
component: exports.RelationDagreFlow,
|
|
500
|
+
composites: ['title', 'item'],
|
|
501
|
+
});
|
|
@@ -4,7 +4,6 @@ exports.EditBar = void 0;
|
|
|
4
4
|
const constants_1 = require("../../../constants");
|
|
5
5
|
const jsx_1 = require("../../../jsx");
|
|
6
6
|
const utils_1 = require("../../../utils");
|
|
7
|
-
const utils_2 = require("../../utils");
|
|
8
7
|
const base_1 = require("../base");
|
|
9
8
|
const edit_items_1 = require("./edit-items");
|
|
10
9
|
class EditBar extends base_1.Plugin {
|
|
@@ -174,24 +173,43 @@ class EditBar extends base_1.Plugin {
|
|
|
174
173
|
placeEditBar(container, selection) {
|
|
175
174
|
if (selection.length === 0)
|
|
176
175
|
return;
|
|
177
|
-
const
|
|
178
|
-
const combinedBounds = (0, jsx_1.getCombinedBounds)(selection.map((element) => (0, utils_2.getElementViewportBounds)(svg, element)));
|
|
176
|
+
const combinedBounds = (0, jsx_1.getCombinedBounds)(selection.map((element) => element.getBoundingClientRect()));
|
|
179
177
|
const offsetParent = container.offsetParent ??
|
|
180
178
|
document.documentElement;
|
|
181
|
-
const parentRect = offsetParent.getBoundingClientRect();
|
|
182
179
|
const viewportHeight = document.documentElement.clientHeight;
|
|
180
|
+
const viewportWidth = document.documentElement.clientWidth;
|
|
183
181
|
const containerRect = container.getBoundingClientRect();
|
|
184
182
|
const offset = 8;
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
183
|
+
const anchorTop = {
|
|
184
|
+
x: combinedBounds.x + combinedBounds.width / 2,
|
|
185
|
+
y: combinedBounds.y,
|
|
186
|
+
};
|
|
187
|
+
const anchorBottom = {
|
|
188
|
+
x: anchorTop.x,
|
|
189
|
+
y: combinedBounds.y + combinedBounds.height,
|
|
190
|
+
};
|
|
188
191
|
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
189
|
-
let left = anchorTop.x - parentRect.left - containerRect.width / 2;
|
|
190
|
-
left = clamp(left, 0, Math.max(parentRect.width - containerRect.width, 0));
|
|
191
192
|
// Use viewport space, not container space, to decide whether we have enough room above.
|
|
192
193
|
const spaceAbove = anchorTop.y - offset;
|
|
193
194
|
const spaceBelow = viewportHeight - anchorBottom.y - offset;
|
|
194
195
|
const shouldPlaceAbove = spaceAbove >= containerRect.height || spaceAbove >= spaceBelow;
|
|
196
|
+
if (offsetParent === document.body ||
|
|
197
|
+
offsetParent === document.documentElement) {
|
|
198
|
+
const scrollX = window.scrollX || document.documentElement.scrollLeft;
|
|
199
|
+
const scrollY = window.scrollY || document.documentElement.scrollTop;
|
|
200
|
+
let left = scrollX + anchorTop.x - containerRect.width / 2;
|
|
201
|
+
left = clamp(left, scrollX, scrollX + Math.max(viewportWidth - containerRect.width, 0));
|
|
202
|
+
let top = shouldPlaceAbove
|
|
203
|
+
? scrollY + anchorTop.y - containerRect.height - offset
|
|
204
|
+
: scrollY + anchorBottom.y + offset;
|
|
205
|
+
top = clamp(top, scrollY, scrollY + Math.max(viewportHeight - containerRect.height, 0));
|
|
206
|
+
container.style.left = `${left}px`;
|
|
207
|
+
container.style.top = `${top}px`;
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const parentRect = offsetParent.getBoundingClientRect();
|
|
211
|
+
let left = anchorTop.x - parentRect.left - containerRect.width / 2;
|
|
212
|
+
left = clamp(left, 0, Math.max(parentRect.width - containerRect.width, 0));
|
|
195
213
|
let top = shouldPlaceAbove
|
|
196
214
|
? anchorTop.y - parentRect.top - containerRect.height - offset
|
|
197
215
|
: anchorBottom.y - parentRect.top + offset;
|
package/lib/jsx/global.d.ts
CHANGED
|
@@ -65,6 +65,7 @@ declare global {
|
|
|
65
65
|
symbol: SVGAttributes<SVGSymbolElement>;
|
|
66
66
|
text: SVGAttributes<SVGTextElement>;
|
|
67
67
|
textPath: SVGAttributes<SVGTextPathElement>;
|
|
68
|
+
title: SVGAttributes<SVGTitleElement>;
|
|
68
69
|
tspan: SVGAttributes<SVGTSpanElement>;
|
|
69
70
|
use: SVGAttributes<SVGUseElement>;
|
|
70
71
|
view: SVGAttributes<SVGViewElement>;
|
|
@@ -21,8 +21,10 @@ export interface GroupProps extends BaseGeometryProps {
|
|
|
21
21
|
children?: JSXNode;
|
|
22
22
|
}
|
|
23
23
|
export interface RectProps extends BaseGeometryProps {
|
|
24
|
+
children?: JSXNode;
|
|
24
25
|
}
|
|
25
26
|
export interface EllipseProps extends BaseGeometryProps {
|
|
27
|
+
children?: JSXNode;
|
|
26
28
|
}
|
|
27
29
|
export interface TextProps extends BaseGeometryProps {
|
|
28
30
|
lineHeight?: number;
|
|
@@ -32,10 +34,12 @@ export interface TextProps extends BaseGeometryProps {
|
|
|
32
34
|
backgroundColor?: string;
|
|
33
35
|
backgroundOpacity?: number;
|
|
34
36
|
backgroundRadius?: number;
|
|
35
|
-
children?: string | number;
|
|
37
|
+
children?: string | number | JSXNode;
|
|
36
38
|
}
|
|
37
39
|
export interface PathProps extends BaseGeometryProps {
|
|
40
|
+
children?: JSXNode;
|
|
38
41
|
}
|
|
39
42
|
export interface PolygonProps extends Omit<BaseGeometryProps, 'points'> {
|
|
40
43
|
points?: Point[];
|
|
44
|
+
children?: JSXNode;
|
|
41
45
|
}
|
package/lib/jsx/utils/svg.js
CHANGED
|
@@ -9,8 +9,10 @@ function renderItemIcon(svg, node, datum, options) {
|
|
|
9
9
|
if (!value)
|
|
10
10
|
return null;
|
|
11
11
|
const { themeConfig } = options;
|
|
12
|
+
const dataAttrs = datum.attributes?.icon;
|
|
12
13
|
const attrs = {
|
|
13
14
|
...themeConfig.item?.icon,
|
|
15
|
+
...dataAttrs,
|
|
14
16
|
};
|
|
15
17
|
const parsedAttrs = (0, utils_2.parseDynamicAttributes)(node, attrs);
|
|
16
18
|
return createIcon(svg, node, value, parsedAttrs, datum);
|
|
@@ -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)()}`;
|