@antv/infographic 0.2.14 → 0.2.16
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/README.md +39 -5
- package/README.zh-CN.md +39 -5
- package/dist/infographic.min.js +168 -166
- package/dist/infographic.min.js.map +1 -1
- package/esm/designs/structures/index.d.ts +1 -0
- package/esm/designs/structures/index.js +1 -0
- package/esm/designs/structures/relation-dagre-flow.js +4 -139
- package/esm/designs/structures/sequence-interaction.d.ts +54 -0
- package/esm/designs/structures/sequence-interaction.js +461 -0
- package/esm/designs/structures/sequence-timeline.d.ts +1 -0
- package/esm/designs/structures/sequence-timeline.js +4 -2
- package/esm/designs/utils/geometry.d.ts +44 -0
- package/esm/designs/utils/geometry.js +244 -0
- package/esm/designs/utils/index.d.ts +1 -0
- package/esm/designs/utils/index.js +1 -0
- package/esm/editor/managers/sync-registry.d.ts +2 -1
- package/esm/editor/types/editor.d.ts +2 -1
- package/esm/editor/types/sync.d.ts +2 -1
- package/esm/editor/utils/object.js +46 -39
- package/esm/exporter/png.js +2 -2
- package/esm/exporter/svg.js +9 -1
- package/esm/exporter/types.d.ts +10 -0
- package/esm/options/types.d.ts +6 -0
- package/esm/runtime/Infographic.js +20 -7
- package/esm/syntax/index.js +40 -20
- package/esm/syntax/parser.js +80 -3
- package/esm/syntax/relations.js +26 -2
- package/esm/syntax/schema.js +1 -0
- package/esm/templates/built-in.js +5 -4
- package/esm/templates/sequence-interaction.d.ts +2 -0
- package/esm/templates/sequence-interaction.js +76 -0
- package/esm/types/data.d.ts +1 -0
- package/esm/utils/index.d.ts +1 -0
- package/esm/utils/index.js +1 -0
- package/esm/utils/measure-text.js +31 -3
- package/esm/utils/types.d.ts +16 -0
- package/esm/utils/types.js +12 -0
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/lib/designs/structures/index.d.ts +1 -0
- package/lib/designs/structures/index.js +1 -0
- package/lib/designs/structures/relation-dagre-flow.js +5 -140
- package/lib/designs/structures/sequence-interaction.d.ts +54 -0
- package/lib/designs/structures/sequence-interaction.js +465 -0
- package/lib/designs/structures/sequence-timeline.d.ts +1 -0
- package/lib/designs/structures/sequence-timeline.js +4 -2
- package/lib/designs/utils/geometry.d.ts +44 -0
- package/lib/designs/utils/geometry.js +256 -0
- package/lib/designs/utils/index.d.ts +1 -0
- package/lib/designs/utils/index.js +1 -0
- package/lib/editor/managers/sync-registry.d.ts +2 -1
- package/lib/editor/types/editor.d.ts +2 -1
- package/lib/editor/types/sync.d.ts +2 -1
- package/lib/editor/utils/object.js +45 -38
- package/lib/exporter/png.js +2 -2
- package/lib/exporter/svg.js +9 -1
- package/lib/exporter/types.d.ts +10 -0
- package/lib/options/types.d.ts +6 -0
- package/lib/runtime/Infographic.js +19 -6
- package/lib/syntax/index.js +40 -20
- package/lib/syntax/parser.js +80 -3
- package/lib/syntax/relations.js +26 -2
- package/lib/syntax/schema.js +1 -0
- package/lib/templates/built-in.js +5 -4
- package/lib/templates/sequence-interaction.d.ts +2 -0
- package/lib/templates/sequence-interaction.js +79 -0
- package/lib/types/data.d.ts +1 -0
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +1 -0
- package/lib/utils/measure-text.js +30 -2
- package/lib/utils/types.d.ts +16 -0
- package/lib/utils/types.js +13 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/designs/structures/index.ts +1 -0
- package/src/designs/structures/relation-dagre-flow.tsx +14 -178
- package/src/designs/structures/sequence-interaction.tsx +931 -0
- package/src/designs/structures/sequence-timeline.tsx +18 -15
- package/src/designs/utils/geometry.tsx +315 -0
- package/src/designs/utils/index.ts +1 -0
- package/src/editor/managers/sync-registry.ts +2 -1
- package/src/editor/types/editor.ts +2 -1
- package/src/editor/types/sync.ts +3 -1
- package/src/editor/utils/object.ts +50 -40
- package/src/exporter/png.ts +3 -2
- package/src/exporter/svg.ts +14 -1
- package/src/exporter/types.ts +10 -0
- package/src/options/types.ts +7 -0
- package/src/runtime/Infographic.tsx +27 -17
- package/src/syntax/index.ts +51 -18
- package/src/syntax/parser.ts +101 -3
- package/src/syntax/relations.ts +29 -2
- package/src/syntax/schema.ts +1 -0
- package/src/templates/built-in.ts +4 -2
- package/src/templates/sequence-interaction.ts +101 -0
- package/src/types/data.ts +1 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/measure-text.ts +35 -3
- package/src/utils/types.ts +61 -0
- package/src/version.ts +1 -1
package/lib/syntax/parser.js
CHANGED
|
@@ -44,6 +44,81 @@ function parseKeyValue(raw) {
|
|
|
44
44
|
}
|
|
45
45
|
return { key: text, value: undefined };
|
|
46
46
|
}
|
|
47
|
+
function isUnsafeObjectKey(key) {
|
|
48
|
+
return key === '__proto__' || key === 'constructor' || key === 'prototype';
|
|
49
|
+
}
|
|
50
|
+
function assignObjectEntry(parent, rawKey, node, line, errors) {
|
|
51
|
+
if (!rawKey.includes('.')) {
|
|
52
|
+
if (isUnsafeObjectKey(rawKey)) {
|
|
53
|
+
errors.push({
|
|
54
|
+
path: rawKey,
|
|
55
|
+
line,
|
|
56
|
+
code: 'bad_syntax',
|
|
57
|
+
message: `Invalid key part: ${rawKey}`,
|
|
58
|
+
raw: rawKey,
|
|
59
|
+
});
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
parent.entries[rawKey] = node;
|
|
63
|
+
return { parent, key: rawKey };
|
|
64
|
+
}
|
|
65
|
+
const parts = rawKey.split('.');
|
|
66
|
+
if (parts.some((part) => !part)) {
|
|
67
|
+
errors.push({
|
|
68
|
+
path: rawKey,
|
|
69
|
+
line,
|
|
70
|
+
code: 'bad_syntax',
|
|
71
|
+
message: 'Invalid dotted key path.',
|
|
72
|
+
raw: rawKey,
|
|
73
|
+
});
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
let current = parent;
|
|
77
|
+
for (let index = 0; index < parts.length - 1; index += 1) {
|
|
78
|
+
const part = parts[index];
|
|
79
|
+
if (isUnsafeObjectKey(part)) {
|
|
80
|
+
errors.push({
|
|
81
|
+
path: rawKey,
|
|
82
|
+
line,
|
|
83
|
+
code: 'bad_syntax',
|
|
84
|
+
message: `Invalid key part in dotted path: ${part}`,
|
|
85
|
+
raw: rawKey,
|
|
86
|
+
});
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
const existing = current.entries[part];
|
|
90
|
+
if (!existing) {
|
|
91
|
+
const container = createObjectNode(line);
|
|
92
|
+
current.entries[part] = container;
|
|
93
|
+
current = container;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (existing.kind !== 'object') {
|
|
97
|
+
errors.push({
|
|
98
|
+
path: parts.slice(0, index + 1).join('.'),
|
|
99
|
+
line,
|
|
100
|
+
code: 'bad_syntax',
|
|
101
|
+
message: 'Cannot assign dotted key under a list value.',
|
|
102
|
+
raw: rawKey,
|
|
103
|
+
});
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
current = existing;
|
|
107
|
+
}
|
|
108
|
+
const finalKey = parts[parts.length - 1];
|
|
109
|
+
if (isUnsafeObjectKey(finalKey)) {
|
|
110
|
+
errors.push({
|
|
111
|
+
path: rawKey,
|
|
112
|
+
line,
|
|
113
|
+
code: 'bad_syntax',
|
|
114
|
+
message: `Invalid key part in dotted path: ${finalKey}`,
|
|
115
|
+
raw: rawKey,
|
|
116
|
+
});
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
current.entries[finalKey] = node;
|
|
120
|
+
return { parent: current, key: finalKey };
|
|
121
|
+
}
|
|
47
122
|
function createObjectNode(line, value) {
|
|
48
123
|
return { kind: 'object', line, value, entries: {} };
|
|
49
124
|
}
|
|
@@ -175,12 +250,14 @@ function parseSyntaxToAst(input) {
|
|
|
175
250
|
return;
|
|
176
251
|
}
|
|
177
252
|
const node = createObjectNode(lineNumber, parsed.value);
|
|
178
|
-
parentNode
|
|
253
|
+
const assigned = assignObjectEntry(parentNode, parsed.key, node, lineNumber, errors);
|
|
254
|
+
if (!assigned)
|
|
255
|
+
return;
|
|
179
256
|
stack.push({
|
|
180
257
|
indent,
|
|
181
258
|
node,
|
|
182
|
-
parent:
|
|
183
|
-
key:
|
|
259
|
+
parent: assigned.parent,
|
|
260
|
+
key: assigned.key,
|
|
184
261
|
});
|
|
185
262
|
});
|
|
186
263
|
return { ast: root, errors };
|
package/lib/syntax/relations.js
CHANGED
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseRelationsNode = parseRelationsNode;
|
|
4
4
|
const mapper_1 = require("./mapper");
|
|
5
5
|
const schema_1 = require("./schema");
|
|
6
|
-
const RELATION_TOKEN = /[
|
|
7
|
-
const ARROW_TOKEN = /[
|
|
6
|
+
const RELATION_TOKEN = /(?:[<>o.x-]{2,}|[<>=]{2,})/;
|
|
7
|
+
const ARROW_TOKEN = /(?:[<>o.x-]{2,}|[<>=]{2,})/g;
|
|
8
8
|
function normalizeLabel(text) {
|
|
9
9
|
let label = text.trim();
|
|
10
10
|
if (!label)
|
|
@@ -106,6 +106,30 @@ function readEdge(text, startIndex) {
|
|
|
106
106
|
let label = labelPrefix || undefined;
|
|
107
107
|
let directionToken = arrowToken;
|
|
108
108
|
let index = arrowEnd;
|
|
109
|
+
// Detect split bidirectional arrow pattern: <- label ->
|
|
110
|
+
{
|
|
111
|
+
const leftHasLeft = directionToken.includes('<');
|
|
112
|
+
const leftHasRight = directionToken.includes('>');
|
|
113
|
+
if (leftHasLeft && !leftHasRight) {
|
|
114
|
+
const lookahead = new RegExp(ARROW_TOKEN.source, 'g');
|
|
115
|
+
lookahead.lastIndex = arrowEnd;
|
|
116
|
+
const rightMatch = lookahead.exec(text);
|
|
117
|
+
if (rightMatch &&
|
|
118
|
+
rightMatch[0].includes('>') &&
|
|
119
|
+
!rightMatch[0].includes('<')) {
|
|
120
|
+
const middleText = text.slice(arrowEnd, rightMatch.index).trim();
|
|
121
|
+
if (middleText) {
|
|
122
|
+
const splitLabel = normalizeLabel(middleText);
|
|
123
|
+
return {
|
|
124
|
+
label: splitLabel || label,
|
|
125
|
+
direction: 'both',
|
|
126
|
+
reverse: false,
|
|
127
|
+
nextIndex: rightMatch.index + rightMatch[0].length,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
109
133
|
index = skipSpaces(text, index);
|
|
110
134
|
if (text[index] === '|') {
|
|
111
135
|
const pipeEnd = text.indexOf('|', index + 1);
|
package/lib/syntax/schema.js
CHANGED
|
@@ -53,6 +53,7 @@ exports.RelationSchema = object({
|
|
|
53
53
|
direction: enumOf(['forward', 'both', 'none']),
|
|
54
54
|
showArrow: enumOf(['true', 'false']),
|
|
55
55
|
arrowType: enumOf(['arrow', 'triangle', 'diamond']),
|
|
56
|
+
lineStyle: enumOf(['solid', 'dashed']),
|
|
56
57
|
}, { allowUnknown: true });
|
|
57
58
|
exports.ThemeSchema = object({
|
|
58
59
|
type: string(),
|
|
@@ -8,9 +8,10 @@ const hierarchy_tree_1 = require("./hierarchy-tree");
|
|
|
8
8
|
const list_zigzag_1 = require("./list-zigzag");
|
|
9
9
|
const registry_1 = require("./registry");
|
|
10
10
|
const relation_dagre_flow_1 = require("./relation-dagre-flow");
|
|
11
|
+
const sequence_interaction_1 = require("./sequence-interaction");
|
|
11
12
|
const sequence_stairs_1 = require("./sequence-stairs");
|
|
12
13
|
const word_cloud_1 = require("./word-cloud");
|
|
13
|
-
const BUILT_IN_TEMPLATES = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ 'compare-hierarchy-left-right-circle-node-pill-badge': {
|
|
14
|
+
const BUILT_IN_TEMPLATES = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ 'compare-hierarchy-left-right-circle-node-pill-badge': {
|
|
14
15
|
design: {
|
|
15
16
|
structure: {
|
|
16
17
|
type: 'compare-hierarchy-left-right',
|
|
@@ -182,7 +183,7 @@ const BUILT_IN_TEMPLATES = Object.assign(Object.assign(Object.assign(Object.assi
|
|
|
182
183
|
}, 'sequence-timeline-plain-text': {
|
|
183
184
|
design: {
|
|
184
185
|
title: 'default',
|
|
185
|
-
structure: { type: 'sequence-timeline' },
|
|
186
|
+
structure: { type: 'sequence-timeline', showStepLabels: false },
|
|
186
187
|
items: [{ type: 'plain-text' }],
|
|
187
188
|
},
|
|
188
189
|
}, 'sequence-timeline-rounded-rect-node': {
|
|
@@ -200,7 +201,7 @@ const BUILT_IN_TEMPLATES = Object.assign(Object.assign(Object.assign(Object.assi
|
|
|
200
201
|
}, 'sequence-timeline-simple': {
|
|
201
202
|
design: {
|
|
202
203
|
title: 'default',
|
|
203
|
-
structure: { type: 'sequence-timeline', gap: 20 },
|
|
204
|
+
structure: { type: 'sequence-timeline', gap: 20, showStepLabels: false },
|
|
204
205
|
items: [{ type: 'simple', positionV: 'middle' }],
|
|
205
206
|
},
|
|
206
207
|
}, 'sequence-cylinders-3d-simple': {
|
|
@@ -650,7 +651,7 @@ const BUILT_IN_TEMPLATES = Object.assign(Object.assign(Object.assign(Object.assi
|
|
|
650
651
|
},
|
|
651
652
|
],
|
|
652
653
|
},
|
|
653
|
-
} }, chart_pie_1.chartPieTemplates), compare_quadrant_1.compareQuadrantTemplates), hierarchy_tree_1.hierarchyTreeTemplates), hierarchy_mindmap_1.hierarchyMindmapTemplates), sequence_stairs_1.sequenceStairsTemplates), word_cloud_1.wordCloudTemplate), list_zigzag_1.listZigzagTemplates), relation_dagre_flow_1.relationDagreFlowTemplates), hierarchy_structure_1.hierarchyStructureTemplates);
|
|
654
|
+
} }, chart_pie_1.chartPieTemplates), compare_quadrant_1.compareQuadrantTemplates), hierarchy_tree_1.hierarchyTreeTemplates), hierarchy_mindmap_1.hierarchyMindmapTemplates), sequence_stairs_1.sequenceStairsTemplates), word_cloud_1.wordCloudTemplate), list_zigzag_1.listZigzagTemplates), relation_dagre_flow_1.relationDagreFlowTemplates), sequence_interaction_1.sequenceInteractionTemplates), hierarchy_structure_1.hierarchyStructureTemplates);
|
|
654
655
|
Object.entries(BUILT_IN_TEMPLATES).forEach(([name, options]) => {
|
|
655
656
|
(0, registry_1.registerTemplate)(name, options);
|
|
656
657
|
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sequenceInteractionTemplates = void 0;
|
|
4
|
+
// 多样化的节点样式
|
|
5
|
+
const items = {
|
|
6
|
+
'badge-card': {
|
|
7
|
+
type: 'badge-card',
|
|
8
|
+
width: 160,
|
|
9
|
+
height: 60,
|
|
10
|
+
},
|
|
11
|
+
'compact-card': {
|
|
12
|
+
type: 'compact-card',
|
|
13
|
+
width: 180,
|
|
14
|
+
height: 60,
|
|
15
|
+
},
|
|
16
|
+
'capsule-item': {
|
|
17
|
+
type: 'capsule-item',
|
|
18
|
+
width: 150,
|
|
19
|
+
height: 60,
|
|
20
|
+
},
|
|
21
|
+
'rounded-rect-node': {
|
|
22
|
+
type: 'rounded-rect-node',
|
|
23
|
+
width: 140,
|
|
24
|
+
height: 60,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
// 基础结构属性
|
|
28
|
+
const baseStructureAttrs = {
|
|
29
|
+
type: 'sequence-interaction',
|
|
30
|
+
showLaneHeader: true,
|
|
31
|
+
arrowType: 'triangle',
|
|
32
|
+
};
|
|
33
|
+
// 箭头样式配置
|
|
34
|
+
const arrowStyles = {
|
|
35
|
+
default: {},
|
|
36
|
+
dashed: {
|
|
37
|
+
edgeStyle: 'dashed',
|
|
38
|
+
},
|
|
39
|
+
animated: {
|
|
40
|
+
edgeStyle: 'dashed',
|
|
41
|
+
animated: true,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
// 结构布局配置
|
|
45
|
+
const structures = {
|
|
46
|
+
// 默认:带生命线
|
|
47
|
+
default: Object.assign(Object.assign({}, baseStructureAttrs), { showLifeline: true, nodeGap: 40 }),
|
|
48
|
+
// 紧凑:更小间距
|
|
49
|
+
compact: Object.assign(Object.assign({}, baseStructureAttrs), { showLifeline: true, nodeGap: 20 }),
|
|
50
|
+
// 宽松:更大间距
|
|
51
|
+
wide: Object.assign(Object.assign({}, baseStructureAttrs), { showLifeline: true, nodeGap: 60 }),
|
|
52
|
+
};
|
|
53
|
+
exports.sequenceInteractionTemplates = {};
|
|
54
|
+
// 排除某些不合适的组合
|
|
55
|
+
const omit = [
|
|
56
|
+
// 后续如果有不合适的可以排除掉
|
|
57
|
+
];
|
|
58
|
+
Object.entries(structures).forEach(([strKey, strAttrs]) => {
|
|
59
|
+
Object.entries(arrowStyles).forEach(([arrowKey, arrowAttrs]) => {
|
|
60
|
+
Object.entries(items).forEach(([itemKey, itemAttrs]) => {
|
|
61
|
+
const parts = [strKey];
|
|
62
|
+
if (arrowKey !== 'default') {
|
|
63
|
+
parts.push(arrowKey);
|
|
64
|
+
}
|
|
65
|
+
parts.push(itemKey);
|
|
66
|
+
const appendix = parts.join('-');
|
|
67
|
+
if (omit.includes(appendix))
|
|
68
|
+
return;
|
|
69
|
+
const templateKey = `sequence-interaction-${appendix}`;
|
|
70
|
+
exports.sequenceInteractionTemplates[templateKey] = {
|
|
71
|
+
design: {
|
|
72
|
+
title: 'default',
|
|
73
|
+
structure: Object.assign(Object.assign({}, strAttrs), arrowAttrs),
|
|
74
|
+
item: itemAttrs,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
});
|
package/lib/types/data.d.ts
CHANGED
package/lib/utils/index.d.ts
CHANGED
package/lib/utils/index.js
CHANGED
|
@@ -33,5 +33,6 @@ __exportStar(require("./recognizer"), exports);
|
|
|
33
33
|
__exportStar(require("./style"), exports);
|
|
34
34
|
__exportStar(require("./svg"), exports);
|
|
35
35
|
__exportStar(require("./text"), exports);
|
|
36
|
+
__exportStar(require("./types"), exports);
|
|
36
37
|
__exportStar(require("./uuid"), exports);
|
|
37
38
|
__exportStar(require("./viewbox"), exports);
|
|
@@ -6,15 +6,42 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.setFontExtendFactor = void 0;
|
|
7
7
|
exports.measureText = measureText;
|
|
8
8
|
const measury_1 = require("measury");
|
|
9
|
+
const _851tegakizatsu_Regular_1 = __importDefault(require("measury/fonts/851tegakizatsu-Regular"));
|
|
9
10
|
const AlibabaPuHuiTi_Regular_1 = __importDefault(require("measury/fonts/AlibabaPuHuiTi-Regular"));
|
|
11
|
+
const Arial_Regular_1 = __importDefault(require("measury/fonts/Arial-Regular"));
|
|
12
|
+
const LXGWWenKai_Regular_1 = __importDefault(require("measury/fonts/LXGWWenKai-Regular"));
|
|
13
|
+
const SourceHanSans_Regular_1 = __importDefault(require("measury/fonts/SourceHanSans-Regular"));
|
|
14
|
+
const SourceHanSerif_Regular_1 = __importDefault(require("measury/fonts/SourceHanSerif-Regular"));
|
|
10
15
|
const renderer_1 = require("../renderer");
|
|
11
16
|
const font_1 = require("./font");
|
|
12
|
-
let FONT_EXTEND_FACTOR = 1.
|
|
17
|
+
let FONT_EXTEND_FACTOR = 1.015;
|
|
13
18
|
const setFontExtendFactor = (factor) => {
|
|
14
19
|
FONT_EXTEND_FACTOR = factor;
|
|
15
20
|
};
|
|
16
21
|
exports.setFontExtendFactor = setFontExtendFactor;
|
|
17
22
|
(0, measury_1.registerFont)(AlibabaPuHuiTi_Regular_1.default);
|
|
23
|
+
// Lazy-register extra measury fonts on first use (SSR only needs glyph data).
|
|
24
|
+
const EXTRA_MEASURY_FONTS = {
|
|
25
|
+
'851tegakizatsu': _851tegakizatsu_Regular_1.default,
|
|
26
|
+
Arial: Arial_Regular_1.default,
|
|
27
|
+
'LXGW WenKai': LXGWWenKai_Regular_1.default,
|
|
28
|
+
'Source Han Sans': SourceHanSans_Regular_1.default,
|
|
29
|
+
'Source Han Serif': SourceHanSerif_Regular_1.default,
|
|
30
|
+
};
|
|
31
|
+
const registeredMeasuryFonts = new Set();
|
|
32
|
+
function ensureMeasuryFont(fontFamily) {
|
|
33
|
+
var _a, _b;
|
|
34
|
+
// decodeFontFamily: '"851tegakizatsu", sans-serif' → '851tegakizatsu, sans-serif'
|
|
35
|
+
// split by comma and take the first family name
|
|
36
|
+
const primary = (_b = (_a = (0, font_1.decodeFontFamily)(fontFamily)) === null || _a === void 0 ? void 0 : _a.split(',')[0]) === null || _b === void 0 ? void 0 : _b.trim();
|
|
37
|
+
if (!primary || registeredMeasuryFonts.has(primary))
|
|
38
|
+
return;
|
|
39
|
+
const data = EXTRA_MEASURY_FONTS[primary];
|
|
40
|
+
if (!data)
|
|
41
|
+
return;
|
|
42
|
+
(0, measury_1.registerFont)(data);
|
|
43
|
+
registeredMeasuryFonts.add(primary);
|
|
44
|
+
}
|
|
18
45
|
let canvasContext = undefined;
|
|
19
46
|
let measureSpan = null;
|
|
20
47
|
function getCanvasContext() {
|
|
@@ -100,13 +127,14 @@ function measureText(text = '', attrs) {
|
|
|
100
127
|
}
|
|
101
128
|
const { fontFamily = renderer_1.DEFAULT_FONT, fontSize = 14, fontWeight = 'normal', lineHeight = 1.4, } = attrs;
|
|
102
129
|
const content = text.toString();
|
|
130
|
+
ensureMeasuryFont(fontFamily);
|
|
103
131
|
const options = {
|
|
104
132
|
fontFamily,
|
|
105
133
|
fontSize: parseFloat(fontSize.toString()),
|
|
106
134
|
fontWeight,
|
|
107
135
|
lineHeight,
|
|
108
136
|
};
|
|
109
|
-
const fallback = () => (0, measury_1.measureText)(content, options);
|
|
137
|
+
const fallback = () => (0, measury_1.measureText)(content, Object.assign(Object.assign({}, options), { fontFamily: (0, font_1.decodeFontFamily)(fontFamily) }));
|
|
110
138
|
const metrics = (_a = measureTextInBrowser(content, options)) !== null && _a !== void 0 ? _a : fallback();
|
|
111
139
|
// 额外添加 1% 宽高
|
|
112
140
|
return {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
2
|
+
type StopType = string | number | boolean | symbol | undefined | null | ((...args: any[]) => any) | Array<any>;
|
|
3
|
+
type Join<K, P> = K extends string | number ? P extends string | number ? `${K}${'' extends P ? '' : '.'}${P}` : never : never;
|
|
4
|
+
type ValidKey<T> = keyof {
|
|
5
|
+
[K in keyof T as string extends K ? never : number extends K ? never : K]: any;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* 递归生成 T 的所有点语法路径 (例如 "design.structure" 或 "data.items")
|
|
9
|
+
* @template T 目标对象类型
|
|
10
|
+
* @template D 递归深度限制,默认 3 层 (足以覆盖大多数配置嵌套)
|
|
11
|
+
*/
|
|
12
|
+
export type Path<T, D extends number = 3> = [D] extends [never] ? never : T extends StopType ? never : {
|
|
13
|
+
[K in ValidKey<T>]-?: K extends string | number ? // 生成: 当前路径 K 或 "K + 子路径"
|
|
14
|
+
K | Join<K, Path<NonNullable<T[K]>, Prev[D]>> : never;
|
|
15
|
+
}[ValidKey<T>];
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Path Helper Types (路径生成工具类型)
|
|
4
|
+
//
|
|
5
|
+
// 作用:递归提取对象的所有可选路径(点语法),用于 SyncRegistry 等场景的类型安全与补全。
|
|
6
|
+
//
|
|
7
|
+
// [Input]:
|
|
8
|
+
// type Obj = { a: { b: { c: string } }, d: number };
|
|
9
|
+
//
|
|
10
|
+
// [Output]:
|
|
11
|
+
// "a" | "a.b" | "a.b.c" | "d"
|
|
12
|
+
// =============================================================================
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/lib/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.2.
|
|
1
|
+
export declare const VERSION = "0.2.16";
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -31,6 +31,7 @@ export * from './sequence-cylinders-3d';
|
|
|
31
31
|
export * from './sequence-filter-mesh';
|
|
32
32
|
export * from './sequence-funnel';
|
|
33
33
|
export * from './sequence-horizontal-zigzag';
|
|
34
|
+
export * from './sequence-interaction';
|
|
34
35
|
export * from './sequence-mountain';
|
|
35
36
|
export * from './sequence-pyramid';
|
|
36
37
|
export * from './sequence-roadmap-vertical';
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { DagreLayout } from '@antv/layout';
|
|
2
2
|
import type { ComponentType, JSXElement } from '../../jsx';
|
|
3
|
-
import { Defs, getElementBounds, Group, Path,
|
|
3
|
+
import { Defs, getElementBounds, Group, Path, Text } from '../../jsx';
|
|
4
4
|
import type { ItemDatum, RelationData, RelationEdgeDatum } from '../../types';
|
|
5
5
|
import { BtnAdd, BtnsGroup, ItemsGroup } from '../components';
|
|
6
6
|
import { FlexLayout } from '../layouts';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
createArrowElements,
|
|
9
|
+
createRoundedPath,
|
|
10
|
+
createStraightPath,
|
|
11
|
+
getColorPrimary,
|
|
12
|
+
getMidPoint,
|
|
13
|
+
getPaletteColor,
|
|
14
|
+
getThemeColors,
|
|
15
|
+
} from '../utils';
|
|
8
16
|
import { registerStructure } from './registry';
|
|
9
17
|
import type { BaseStructureProps } from './types';
|
|
10
18
|
|
|
@@ -332,183 +340,7 @@ export const RelationDagreFlow: ComponentType<RelationDagreFlowProps> = (
|
|
|
332
340
|
: '1s';
|
|
333
341
|
|
|
334
342
|
const straightCornerRadius = edgeCornerRadius;
|
|
335
|
-
const createStraightPath = (
|
|
336
|
-
points: [number, number][],
|
|
337
|
-
dx: number,
|
|
338
|
-
dy: number,
|
|
339
|
-
) =>
|
|
340
|
-
points
|
|
341
|
-
.map(([x, y], index) => {
|
|
342
|
-
const prefix = index === 0 ? 'M' : 'L';
|
|
343
|
-
return `${prefix} ${x + dx} ${y + dy}`;
|
|
344
|
-
})
|
|
345
|
-
.join(' ');
|
|
346
|
-
|
|
347
|
-
const createRoundedPath = (
|
|
348
|
-
points: [number, number][],
|
|
349
|
-
radius: number,
|
|
350
|
-
dx: number,
|
|
351
|
-
dy: number,
|
|
352
|
-
) => {
|
|
353
|
-
if (points.length < 2) return '';
|
|
354
|
-
const clamp = (value: number, min: number, max: number) =>
|
|
355
|
-
Math.min(max, Math.max(min, value));
|
|
356
|
-
const toPoint = ([x, y]: [number, number]) => ({
|
|
357
|
-
x: x + dx,
|
|
358
|
-
y: y + dy,
|
|
359
|
-
});
|
|
360
|
-
const output: string[] = [];
|
|
361
|
-
const first = toPoint(points[0]);
|
|
362
|
-
output.push(`M ${first.x} ${first.y}`);
|
|
363
|
-
|
|
364
|
-
if (points.length === 2) {
|
|
365
|
-
const last = toPoint(points[1]);
|
|
366
|
-
output.push(`L ${last.x} ${last.y}`);
|
|
367
|
-
return output.join(' ');
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
for (let i = 1; i < points.length - 1; i += 1) {
|
|
371
|
-
const prev = points[i - 1];
|
|
372
|
-
const curr = points[i];
|
|
373
|
-
const next = points[i + 1];
|
|
374
|
-
const v0x = curr[0] - prev[0];
|
|
375
|
-
const v0y = curr[1] - prev[1];
|
|
376
|
-
const v1x = next[0] - curr[0];
|
|
377
|
-
const v1y = next[1] - curr[1];
|
|
378
|
-
const d0 = Math.hypot(v0x, v0y);
|
|
379
|
-
const d1 = Math.hypot(v1x, v1y);
|
|
380
|
-
if (d0 === 0 || d1 === 0) {
|
|
381
|
-
const currPoint = toPoint(curr);
|
|
382
|
-
output.push(`L ${currPoint.x} ${currPoint.y}`);
|
|
383
|
-
continue;
|
|
384
|
-
}
|
|
385
|
-
const r = clamp(radius, 0, Math.min(d0, d1) / 2);
|
|
386
|
-
if (r === 0) {
|
|
387
|
-
const currPoint = toPoint(curr);
|
|
388
|
-
output.push(`L ${currPoint.x} ${currPoint.y}`);
|
|
389
|
-
continue;
|
|
390
|
-
}
|
|
391
|
-
const u0x = v0x / d0;
|
|
392
|
-
const u0y = v0y / d0;
|
|
393
|
-
const u1x = v1x / d1;
|
|
394
|
-
const u1y = v1y / d1;
|
|
395
|
-
const start = toPoint([curr[0] - u0x * r, curr[1] - u0y * r]);
|
|
396
|
-
const end = toPoint([curr[0] + u1x * r, curr[1] + u1y * r]);
|
|
397
|
-
output.push(`L ${start.x} ${start.y}`);
|
|
398
|
-
const currPoint = toPoint(curr);
|
|
399
|
-
output.push(`Q ${currPoint.x} ${currPoint.y} ${end.x} ${end.y}`);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
const last = toPoint(points[points.length - 1]);
|
|
403
|
-
output.push(`L ${last.x} ${last.y}`);
|
|
404
|
-
return output.join(' ');
|
|
405
|
-
};
|
|
406
|
-
const createArrowElements = (
|
|
407
|
-
x: number,
|
|
408
|
-
y: number,
|
|
409
|
-
angle: number,
|
|
410
|
-
type: 'arrow' | 'triangle' | 'diamond',
|
|
411
|
-
fillColor: string,
|
|
412
|
-
): JSXElement[] => {
|
|
413
|
-
const ux = Math.cos(angle);
|
|
414
|
-
const uy = Math.sin(angle);
|
|
415
|
-
const px = -uy;
|
|
416
|
-
const py = ux;
|
|
417
|
-
const length = arrowSize;
|
|
418
|
-
const halfWidth = arrowSize * 0.55;
|
|
419
|
-
|
|
420
|
-
if (type === 'arrow') {
|
|
421
|
-
const leftX = x - ux * length + px * halfWidth;
|
|
422
|
-
const leftY = y - uy * length + py * halfWidth;
|
|
423
|
-
const rightX = x - ux * length - px * halfWidth;
|
|
424
|
-
const rightY = y - uy * length - py * halfWidth;
|
|
425
|
-
return [
|
|
426
|
-
<Path
|
|
427
|
-
d={`M ${leftX} ${leftY} L ${x} ${y} L ${rightX} ${rightY}`}
|
|
428
|
-
stroke={fillColor}
|
|
429
|
-
strokeWidth={Math.max(1.5, edgeWidth)}
|
|
430
|
-
strokeLinecap="round"
|
|
431
|
-
strokeLinejoin="round"
|
|
432
|
-
fill="none"
|
|
433
|
-
/>,
|
|
434
|
-
];
|
|
435
|
-
}
|
|
436
343
|
|
|
437
|
-
if (type === 'diamond') {
|
|
438
|
-
const diamondLength = length * 1.25;
|
|
439
|
-
const diamondWidth = halfWidth * 0.75;
|
|
440
|
-
const midX = x - ux * diamondLength * 0.5;
|
|
441
|
-
const midY = y - uy * diamondLength * 0.5;
|
|
442
|
-
const diamondPoints = [
|
|
443
|
-
{ x, y },
|
|
444
|
-
{ x: midX + px * diamondWidth, y: midY + py * diamondWidth },
|
|
445
|
-
{ x: x - ux * diamondLength, y: y - uy * diamondLength },
|
|
446
|
-
{ x: midX - px * diamondWidth, y: midY - py * diamondWidth },
|
|
447
|
-
];
|
|
448
|
-
return [
|
|
449
|
-
<Polygon
|
|
450
|
-
points={diamondPoints}
|
|
451
|
-
fill={fillColor}
|
|
452
|
-
stroke={fillColor}
|
|
453
|
-
strokeWidth={Math.max(1, edgeWidth * 0.8)}
|
|
454
|
-
/>,
|
|
455
|
-
];
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
const trianglePoints = [
|
|
459
|
-
{ x, y },
|
|
460
|
-
{
|
|
461
|
-
x: x - ux * length + px * halfWidth,
|
|
462
|
-
y: y - uy * length + py * halfWidth,
|
|
463
|
-
},
|
|
464
|
-
{
|
|
465
|
-
x: x - ux * length - px * halfWidth,
|
|
466
|
-
y: y - uy * length - py * halfWidth,
|
|
467
|
-
},
|
|
468
|
-
];
|
|
469
|
-
return [
|
|
470
|
-
<Polygon
|
|
471
|
-
points={trianglePoints}
|
|
472
|
-
fill={fillColor}
|
|
473
|
-
stroke={fillColor}
|
|
474
|
-
strokeWidth={Math.max(1, edgeWidth * 0.8)}
|
|
475
|
-
/>,
|
|
476
|
-
];
|
|
477
|
-
};
|
|
478
|
-
const getMidPoint = (points: [number, number][]) => {
|
|
479
|
-
if (points.length === 0) return null;
|
|
480
|
-
if (points.length === 1) return points[0];
|
|
481
|
-
let total = 0;
|
|
482
|
-
const segments: {
|
|
483
|
-
length: number;
|
|
484
|
-
start: [number, number];
|
|
485
|
-
end: [number, number];
|
|
486
|
-
}[] = [];
|
|
487
|
-
for (let i = 0; i < points.length - 1; i += 1) {
|
|
488
|
-
const start = points[i];
|
|
489
|
-
const end = points[i + 1];
|
|
490
|
-
const length = Math.hypot(end[0] - start[0], end[1] - start[1]);
|
|
491
|
-
segments.push({ length, start, end });
|
|
492
|
-
total += length;
|
|
493
|
-
}
|
|
494
|
-
if (total === 0) return points[0];
|
|
495
|
-
let target = total / 2;
|
|
496
|
-
for (let i = 0; i < segments.length; i += 1) {
|
|
497
|
-
const segment = segments[i];
|
|
498
|
-
if (target <= segment.length || i === segments.length - 1) {
|
|
499
|
-
const ratio =
|
|
500
|
-
segment.length === 0
|
|
501
|
-
? 0
|
|
502
|
-
: Math.max(0, Math.min(1, target / segment.length));
|
|
503
|
-
return [
|
|
504
|
-
segment.start[0] + (segment.end[0] - segment.start[0]) * ratio,
|
|
505
|
-
segment.start[1] + (segment.end[1] - segment.start[1]) * ratio,
|
|
506
|
-
] as [number, number];
|
|
507
|
-
}
|
|
508
|
-
target -= segment.length;
|
|
509
|
-
}
|
|
510
|
-
return points[Math.floor(points.length / 2)];
|
|
511
|
-
};
|
|
512
344
|
const getOrthEdgeEndpoints = (sourceId: string, targetId: string) => {
|
|
513
345
|
const source = nodeLayoutById.get(sourceId);
|
|
514
346
|
const target = nodeLayoutById.get(targetId);
|
|
@@ -733,6 +565,8 @@ export const RelationDagreFlow: ComponentType<RelationDagreFlowProps> = (
|
|
|
733
565
|
angle,
|
|
734
566
|
edgeArrowType,
|
|
735
567
|
arrowFill,
|
|
568
|
+
edgeWidth,
|
|
569
|
+
arrowSize,
|
|
736
570
|
);
|
|
737
571
|
decorElements.push(...arrowElements);
|
|
738
572
|
}
|
|
@@ -748,6 +582,8 @@ export const RelationDagreFlow: ComponentType<RelationDagreFlowProps> = (
|
|
|
748
582
|
angle,
|
|
749
583
|
edgeArrowType,
|
|
750
584
|
arrowFill,
|
|
585
|
+
edgeWidth,
|
|
586
|
+
arrowSize,
|
|
751
587
|
);
|
|
752
588
|
decorElements.push(...arrowElements);
|
|
753
589
|
}
|