@antv/infographic 0.2.13 → 0.2.15
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 +12 -5
- package/README.zh-CN.md +12 -5
- package/dist/infographic.min.js +180 -171
- 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 +440 -0
- 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/commands/UpdateOptions.d.ts +4 -4
- package/esm/editor/commands/UpdateOptions.js +6 -3
- package/esm/editor/editor.d.ts +5 -1
- package/esm/editor/editor.js +16 -5
- package/esm/editor/index.d.ts +1 -0
- package/esm/editor/index.js +1 -0
- package/esm/editor/interactions/brush-select.d.ts +0 -1
- package/esm/editor/interactions/brush-select.js +2 -10
- package/esm/editor/interactions/drag-canvas.d.ts +35 -0
- package/esm/editor/interactions/drag-canvas.js +161 -0
- package/esm/editor/interactions/drag-element.js +4 -3
- package/esm/editor/interactions/index.d.ts +1 -0
- package/esm/editor/interactions/index.js +1 -0
- package/esm/editor/interactions/zoom-wheel.d.ts +9 -0
- package/esm/editor/interactions/zoom-wheel.js +32 -15
- package/esm/editor/managers/index.d.ts +1 -0
- package/esm/editor/managers/index.js +1 -0
- package/esm/editor/managers/state.d.ts +4 -2
- package/esm/editor/managers/state.js +14 -13
- package/esm/editor/managers/sync-registry.d.ts +16 -0
- package/esm/editor/managers/sync-registry.js +51 -0
- package/esm/editor/plugins/{edit-bar/components → components}/button.js +1 -1
- package/esm/editor/plugins/{edit-bar/components → components}/color-picker.js +1 -1
- package/esm/editor/plugins/{edit-bar/components → components}/icons.d.ts +1 -0
- package/esm/editor/plugins/{edit-bar/components → components}/icons.js +1 -0
- package/esm/editor/plugins/{edit-bar/components → components}/popover.js +2 -2
- package/esm/editor/plugins/{edit-bar/components → components}/select.js +1 -1
- package/esm/editor/plugins/core-sync.d.ts +8 -0
- package/esm/editor/plugins/core-sync.js +30 -0
- package/esm/editor/plugins/edit-bar/edit-items/align-elements.js +1 -1
- package/esm/editor/plugins/edit-bar/edit-items/font-align.js +1 -1
- package/esm/editor/plugins/edit-bar/edit-items/font-color.js +1 -1
- package/esm/editor/plugins/edit-bar/edit-items/font-family.js +1 -1
- package/esm/editor/plugins/edit-bar/edit-items/font-size.js +1 -1
- package/esm/editor/plugins/edit-bar/edit-items/icon-color.js +1 -1
- package/esm/editor/plugins/edit-bar/index.d.ts +2 -2
- package/esm/editor/plugins/edit-bar/index.js +1 -1
- package/esm/editor/plugins/index.d.ts +2 -0
- package/esm/editor/plugins/index.js +2 -0
- package/esm/editor/plugins/reset-viewbox.d.ts +33 -0
- package/esm/editor/plugins/reset-viewbox.js +186 -0
- package/esm/editor/types/editor.d.ts +14 -0
- package/esm/editor/types/index.d.ts +1 -0
- package/esm/editor/types/interaction.d.ts +9 -0
- package/esm/editor/types/state.d.ts +4 -2
- package/esm/editor/types/sync.d.ts +27 -0
- package/esm/editor/types/sync.js +1 -0
- package/esm/editor/utils/data.js +3 -1
- package/esm/editor/utils/event.d.ts +1 -0
- package/esm/editor/utils/event.js +8 -0
- package/esm/editor/utils/index.d.ts +1 -0
- package/esm/editor/utils/index.js +1 -0
- package/esm/editor/utils/object.d.ts +15 -0
- package/esm/editor/utils/object.js +77 -0
- package/esm/index.d.ts +4 -3
- package/esm/index.js +3 -2
- package/esm/options/types.d.ts +7 -0
- package/esm/runtime/Infographic.js +20 -7
- package/esm/runtime/options.js +7 -2
- package/esm/syntax/index.js +40 -20
- package/esm/syntax/relations.js +26 -2
- package/esm/syntax/schema.js +1 -0
- package/esm/templates/built-in.js +27 -2
- 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 +40 -9
- package/esm/utils/padding.d.ts +1 -0
- package/esm/utils/padding.js +6 -2
- 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 +444 -0
- 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/commands/UpdateOptions.d.ts +4 -4
- package/lib/editor/commands/UpdateOptions.js +6 -3
- package/lib/editor/editor.d.ts +5 -1
- package/lib/editor/editor.js +16 -5
- package/lib/editor/index.d.ts +1 -0
- package/lib/editor/index.js +1 -0
- package/lib/editor/interactions/brush-select.d.ts +0 -1
- package/lib/editor/interactions/brush-select.js +1 -9
- package/lib/editor/interactions/drag-canvas.d.ts +35 -0
- package/lib/editor/interactions/drag-canvas.js +165 -0
- package/lib/editor/interactions/drag-element.js +4 -3
- package/lib/editor/interactions/index.d.ts +1 -0
- package/lib/editor/interactions/index.js +3 -1
- package/lib/editor/interactions/zoom-wheel.d.ts +9 -0
- package/lib/editor/interactions/zoom-wheel.js +32 -15
- package/lib/editor/managers/index.d.ts +1 -0
- package/lib/editor/managers/index.js +1 -0
- package/lib/editor/managers/state.d.ts +4 -2
- package/lib/editor/managers/state.js +12 -11
- package/lib/editor/managers/sync-registry.d.ts +16 -0
- package/lib/editor/managers/sync-registry.js +55 -0
- package/lib/editor/plugins/{edit-bar/components → components}/button.js +1 -1
- package/lib/editor/plugins/{edit-bar/components → components}/color-picker.js +1 -1
- package/lib/editor/plugins/{edit-bar/components → components}/icons.d.ts +1 -0
- package/lib/editor/plugins/{edit-bar/components → components}/icons.js +2 -1
- package/lib/editor/plugins/{edit-bar/components → components}/popover.js +2 -2
- package/lib/editor/plugins/{edit-bar/components → components}/select.js +1 -1
- package/lib/editor/plugins/core-sync.d.ts +8 -0
- package/lib/editor/plugins/core-sync.js +34 -0
- package/lib/editor/plugins/edit-bar/edit-items/align-elements.js +1 -1
- package/lib/editor/plugins/edit-bar/edit-items/font-align.js +1 -1
- package/lib/editor/plugins/edit-bar/edit-items/font-color.js +1 -1
- package/lib/editor/plugins/edit-bar/edit-items/font-family.js +1 -1
- package/lib/editor/plugins/edit-bar/edit-items/font-size.js +1 -1
- package/lib/editor/plugins/edit-bar/edit-items/icon-color.js +1 -1
- package/lib/editor/plugins/edit-bar/index.d.ts +2 -2
- package/lib/editor/plugins/edit-bar/index.js +1 -1
- package/lib/editor/plugins/index.d.ts +2 -0
- package/lib/editor/plugins/index.js +5 -1
- package/lib/editor/plugins/reset-viewbox.d.ts +33 -0
- package/lib/editor/plugins/reset-viewbox.js +190 -0
- package/lib/editor/types/editor.d.ts +14 -0
- package/lib/editor/types/index.d.ts +1 -0
- package/lib/editor/types/interaction.d.ts +9 -0
- package/lib/editor/types/state.d.ts +4 -2
- package/lib/editor/types/sync.d.ts +27 -0
- package/lib/editor/types/sync.js +2 -0
- package/lib/editor/utils/data.js +3 -1
- package/lib/editor/utils/event.d.ts +1 -0
- package/lib/editor/utils/event.js +9 -0
- package/lib/editor/utils/index.d.ts +1 -0
- package/lib/editor/utils/index.js +1 -0
- package/lib/editor/utils/object.d.ts +15 -0
- package/lib/editor/utils/object.js +80 -0
- package/lib/index.d.ts +4 -3
- package/lib/index.js +9 -2
- package/lib/options/types.d.ts +7 -0
- package/lib/runtime/Infographic.js +19 -6
- package/lib/runtime/options.js +6 -1
- package/lib/syntax/index.js +40 -20
- package/lib/syntax/relations.js +26 -2
- package/lib/syntax/schema.js +1 -0
- package/lib/templates/built-in.js +27 -2
- 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 +39 -8
- package/lib/utils/padding.d.ts +1 -0
- package/lib/utils/padding.js +7 -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 +885 -0
- package/src/designs/utils/geometry.tsx +315 -0
- package/src/designs/utils/index.ts +1 -0
- package/src/editor/commands/UpdateOptions.ts +11 -6
- package/src/editor/editor.ts +26 -5
- package/src/editor/index.ts +1 -0
- package/src/editor/interactions/brush-select.ts +2 -8
- package/src/editor/interactions/drag-canvas.ts +203 -0
- package/src/editor/interactions/drag-element.ts +5 -4
- package/src/editor/interactions/index.ts +1 -0
- package/src/editor/interactions/zoom-wheel.ts +49 -13
- package/src/editor/managers/index.ts +1 -0
- package/src/editor/managers/state.ts +21 -21
- package/src/editor/managers/sync-registry.ts +66 -0
- package/src/editor/plugins/{edit-bar/components → components}/button.ts +1 -1
- package/src/editor/plugins/{edit-bar/components → components}/color-picker.ts +1 -1
- package/src/editor/plugins/{edit-bar/components → components}/icons.ts +4 -0
- package/src/editor/plugins/{edit-bar/components → components}/popover.ts +2 -2
- package/src/editor/plugins/{edit-bar/components → components}/select.ts +1 -1
- package/src/editor/plugins/core-sync.ts +44 -0
- package/src/editor/plugins/edit-bar/edit-items/align-elements.ts +2 -2
- package/src/editor/plugins/edit-bar/edit-items/font-align.ts +1 -1
- package/src/editor/plugins/edit-bar/edit-items/font-color.ts +1 -1
- package/src/editor/plugins/edit-bar/edit-items/font-family.ts +1 -1
- package/src/editor/plugins/edit-bar/edit-items/font-size.ts +3 -3
- package/src/editor/plugins/edit-bar/edit-items/icon-color.ts +1 -1
- package/src/editor/plugins/edit-bar/index.ts +2 -2
- package/src/editor/plugins/index.ts +2 -0
- package/src/editor/plugins/reset-viewbox.ts +258 -0
- package/src/editor/types/editor.ts +18 -0
- package/src/editor/types/index.ts +1 -0
- package/src/editor/types/interaction.ts +31 -0
- package/src/editor/types/state.ts +14 -2
- package/src/editor/types/sync.ts +33 -0
- package/src/editor/utils/data.ts +2 -1
- package/src/editor/utils/event.ts +7 -0
- package/src/editor/utils/index.ts +1 -0
- package/src/editor/utils/object.ts +116 -0
- package/src/index.ts +26 -2
- package/src/options/types.ts +11 -0
- package/src/runtime/Infographic.tsx +27 -17
- package/src/runtime/options.ts +8 -1
- package/src/syntax/index.ts +51 -18
- package/src/syntax/relations.ts +29 -2
- package/src/syntax/schema.ts +1 -0
- package/src/templates/built-in.ts +30 -0
- 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 +41 -9
- package/src/utils/padding.ts +10 -2
- package/src/utils/types.ts +61 -0
- package/src/version.ts +1 -1
- /package/esm/editor/plugins/{edit-bar/components → components}/button.d.ts +0 -0
- /package/esm/editor/plugins/{edit-bar/components → components}/color-picker.d.ts +0 -0
- /package/esm/editor/plugins/{edit-bar/components → components}/index.d.ts +0 -0
- /package/esm/editor/plugins/{edit-bar/components → components}/index.js +0 -0
- /package/esm/editor/plugins/{edit-bar/components → components}/popover.d.ts +0 -0
- /package/esm/editor/plugins/{edit-bar/components → components}/select.d.ts +0 -0
- /package/lib/editor/plugins/{edit-bar/components → components}/button.d.ts +0 -0
- /package/lib/editor/plugins/{edit-bar/components → components}/color-picker.d.ts +0 -0
- /package/lib/editor/plugins/{edit-bar/components → components}/index.d.ts +0 -0
- /package/lib/editor/plugins/{edit-bar/components → components}/index.js +0 -0
- /package/lib/editor/plugins/{edit-bar/components → components}/popover.d.ts +0 -0
- /package/lib/editor/plugins/{edit-bar/components → components}/select.d.ts +0 -0
- /package/src/editor/plugins/{edit-bar/components → components}/index.ts +0 -0
package/src/runtime/options.ts
CHANGED
|
@@ -2,17 +2,24 @@ import {
|
|
|
2
2
|
BrushSelect,
|
|
3
3
|
ClickSelect,
|
|
4
4
|
DblClickEditText,
|
|
5
|
+
DragCanvas,
|
|
5
6
|
DragElement,
|
|
6
7
|
EditBar,
|
|
7
8
|
HotkeyHistory,
|
|
9
|
+
ResetViewBox,
|
|
8
10
|
ResizeElement,
|
|
9
11
|
SelectHighlight,
|
|
10
12
|
ZoomWheel,
|
|
11
13
|
} from '../editor';
|
|
12
14
|
import { InfographicOptions } from '../options';
|
|
13
15
|
|
|
14
|
-
const createDefaultPlugins = () => [
|
|
16
|
+
const createDefaultPlugins = () => [
|
|
17
|
+
new EditBar(),
|
|
18
|
+
new ResizeElement(),
|
|
19
|
+
new ResetViewBox(),
|
|
20
|
+
];
|
|
15
21
|
const createDefaultInteractions = () => [
|
|
22
|
+
new DragCanvas(),
|
|
16
23
|
new DblClickEditText(),
|
|
17
24
|
new BrushSelect(),
|
|
18
25
|
new ClickSelect(),
|
package/src/syntax/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
TemplateSchema,
|
|
11
11
|
ThemeSchema,
|
|
12
12
|
} from './schema';
|
|
13
|
-
import type { SyntaxNode, SyntaxParseResult } from './types';
|
|
13
|
+
import type { ObjectSchema, SyntaxNode, SyntaxParseResult } from './types';
|
|
14
14
|
|
|
15
15
|
function normalizeItems(items: ItemDatum[]) {
|
|
16
16
|
const seen = new Set<string>();
|
|
@@ -112,24 +112,57 @@ export function parseSyntax(input: string): SyntaxParseResult {
|
|
|
112
112
|
);
|
|
113
113
|
if (parsed.relations.length > 0 || parsed.items.length > 0) {
|
|
114
114
|
const current = (options.data ?? {}) as Record<string, any>;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
} else {
|
|
128
|
-
normalizedItems.push(item);
|
|
129
|
-
itemMap.set(item.id as string, item);
|
|
115
|
+
|
|
116
|
+
// 优先使用已存在的数据列表 (sequences, lists, etc.)
|
|
117
|
+
const dataKeys = Object.keys(
|
|
118
|
+
(DataSchema as ObjectSchema).fields,
|
|
119
|
+
).filter((key) => key !== 'items' && key !== 'relations');
|
|
120
|
+
let hasStructuredData = false;
|
|
121
|
+
|
|
122
|
+
// 尝试找到一个非空的数据源
|
|
123
|
+
for (const key of dataKeys) {
|
|
124
|
+
if (Array.isArray(current[key]) && current[key].length > 0) {
|
|
125
|
+
hasStructuredData = true;
|
|
126
|
+
break;
|
|
130
127
|
}
|
|
131
|
-
}
|
|
132
|
-
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// 如果 items 已包含层级结构数据(带 children),也视为结构化数据
|
|
131
|
+
if (
|
|
132
|
+
!hasStructuredData &&
|
|
133
|
+
Array.isArray(current.items) &&
|
|
134
|
+
current.items.length > 0 &&
|
|
135
|
+
current.items.some(
|
|
136
|
+
(item: any) =>
|
|
137
|
+
Array.isArray(item.children) && item.children.length > 0,
|
|
138
|
+
)
|
|
139
|
+
) {
|
|
140
|
+
hasStructuredData = true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 如果没有找到其他数据源,才尝试合并 items
|
|
144
|
+
if (!hasStructuredData) {
|
|
145
|
+
const existingItems = Array.isArray(current.items)
|
|
146
|
+
? (current.items as ItemDatum[])
|
|
147
|
+
: [];
|
|
148
|
+
|
|
149
|
+
const normalizedItems = normalizeItems(existingItems);
|
|
150
|
+
const itemMap = new Map<string, ItemDatum>();
|
|
151
|
+
normalizedItems.forEach((item) => {
|
|
152
|
+
if (item.id) itemMap.set(item.id, item);
|
|
153
|
+
});
|
|
154
|
+
parsed.items.forEach((item) => {
|
|
155
|
+
const existing = itemMap.get(item.id as string);
|
|
156
|
+
if (existing) {
|
|
157
|
+
if (!existing.label && item.label) existing.label = item.label;
|
|
158
|
+
} else {
|
|
159
|
+
normalizedItems.push(item);
|
|
160
|
+
itemMap.set(item.id as string, item);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
current.items = normalizedItems;
|
|
164
|
+
}
|
|
165
|
+
|
|
133
166
|
current.relations = parsed.relations;
|
|
134
167
|
options.data = current as any;
|
|
135
168
|
}
|
package/src/syntax/relations.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { mapWithSchema } from './mapper';
|
|
|
3
3
|
import { RelationSchema } from './schema';
|
|
4
4
|
import type { SyntaxError, SyntaxNode } from './types';
|
|
5
5
|
|
|
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
|
|
|
9
9
|
interface ParsedNode {
|
|
10
10
|
id: string;
|
|
@@ -125,6 +125,33 @@ function readEdge(text: string, startIndex: number): ParsedEdge | null {
|
|
|
125
125
|
let directionToken = arrowToken;
|
|
126
126
|
let index = arrowEnd;
|
|
127
127
|
|
|
128
|
+
// Detect split bidirectional arrow pattern: <- label ->
|
|
129
|
+
{
|
|
130
|
+
const leftHasLeft = directionToken.includes('<');
|
|
131
|
+
const leftHasRight = directionToken.includes('>');
|
|
132
|
+
if (leftHasLeft && !leftHasRight) {
|
|
133
|
+
const lookahead = new RegExp(ARROW_TOKEN.source, 'g');
|
|
134
|
+
lookahead.lastIndex = arrowEnd;
|
|
135
|
+
const rightMatch = lookahead.exec(text);
|
|
136
|
+
if (
|
|
137
|
+
rightMatch &&
|
|
138
|
+
rightMatch[0].includes('>') &&
|
|
139
|
+
!rightMatch[0].includes('<')
|
|
140
|
+
) {
|
|
141
|
+
const middleText = text.slice(arrowEnd, rightMatch.index).trim();
|
|
142
|
+
if (middleText) {
|
|
143
|
+
const splitLabel = normalizeLabel(middleText);
|
|
144
|
+
return {
|
|
145
|
+
label: splitLabel || label,
|
|
146
|
+
direction: 'both',
|
|
147
|
+
reverse: false,
|
|
148
|
+
nextIndex: rightMatch.index + rightMatch[0].length,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
128
155
|
index = skipSpaces(text, index);
|
|
129
156
|
if (text[index] === '|') {
|
|
130
157
|
const pipeEnd = text.indexOf('|', index + 1);
|
package/src/syntax/schema.ts
CHANGED
|
@@ -60,6 +60,7 @@ export const RelationSchema: ObjectSchema = object(
|
|
|
60
60
|
direction: enumOf(['forward', 'both', 'none']),
|
|
61
61
|
showArrow: enumOf(['true', 'false']),
|
|
62
62
|
arrowType: enumOf(['arrow', 'triangle', 'diamond']),
|
|
63
|
+
lineStyle: enumOf(['solid', 'dashed']),
|
|
63
64
|
},
|
|
64
65
|
{ allowUnknown: true },
|
|
65
66
|
);
|
|
@@ -6,6 +6,7 @@ import { hierarchyTreeTemplates } from './hierarchy-tree';
|
|
|
6
6
|
import { listZigzagTemplates } from './list-zigzag';
|
|
7
7
|
import { registerTemplate } from './registry';
|
|
8
8
|
import { relationDagreFlowTemplates } from './relation-dagre-flow';
|
|
9
|
+
import { sequenceInteractionTemplates } from './sequence-interaction';
|
|
9
10
|
import { sequenceStairsTemplates } from './sequence-stairs';
|
|
10
11
|
import type { TemplateOptions } from './types';
|
|
11
12
|
import { wordCloudTemplate } from './word-cloud';
|
|
@@ -171,6 +172,20 @@ const BUILT_IN_TEMPLATES: Record<string, TemplateOptions> = {
|
|
|
171
172
|
items: [{ type: 'icon-badge' }],
|
|
172
173
|
},
|
|
173
174
|
},
|
|
175
|
+
'relation-network-icon-badge': {
|
|
176
|
+
design: {
|
|
177
|
+
title: 'default',
|
|
178
|
+
structure: { type: 'relation-network' },
|
|
179
|
+
items: [{ type: 'icon-badge' }],
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
'relation-network-simple-circle-node': {
|
|
183
|
+
design: {
|
|
184
|
+
title: 'default',
|
|
185
|
+
structure: { type: 'relation-network' },
|
|
186
|
+
items: [{ type: 'simple-circle-node' }],
|
|
187
|
+
},
|
|
188
|
+
},
|
|
174
189
|
'sequence-steps-badge-card': {
|
|
175
190
|
design: {
|
|
176
191
|
title: 'default',
|
|
@@ -351,6 +366,20 @@ const BUILT_IN_TEMPLATES: Record<string, TemplateOptions> = {
|
|
|
351
366
|
items: [{ type: 'plain-text' }],
|
|
352
367
|
},
|
|
353
368
|
},
|
|
369
|
+
'list-waterfall-badge-card': {
|
|
370
|
+
design: {
|
|
371
|
+
title: 'default',
|
|
372
|
+
structure: { type: 'list-waterfall' },
|
|
373
|
+
items: [{ type: 'badge-card' }],
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
'list-waterfall-compact-card': {
|
|
377
|
+
design: {
|
|
378
|
+
title: 'default',
|
|
379
|
+
structure: { type: 'list-waterfall' },
|
|
380
|
+
items: [{ type: 'compact-card' }],
|
|
381
|
+
},
|
|
382
|
+
},
|
|
354
383
|
'sequence-roadmap-vertical-plain-text': {
|
|
355
384
|
design: {
|
|
356
385
|
title: 'default',
|
|
@@ -724,6 +753,7 @@ const BUILT_IN_TEMPLATES: Record<string, TemplateOptions> = {
|
|
|
724
753
|
...wordCloudTemplate,
|
|
725
754
|
...listZigzagTemplates,
|
|
726
755
|
...relationDagreFlowTemplates,
|
|
756
|
+
...sequenceInteractionTemplates,
|
|
727
757
|
...hierarchyStructureTemplates,
|
|
728
758
|
};
|
|
729
759
|
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { TemplateOptions } from './types';
|
|
2
|
+
|
|
3
|
+
// 多样化的节点样式
|
|
4
|
+
const items = {
|
|
5
|
+
'badge-card': {
|
|
6
|
+
type: 'badge-card',
|
|
7
|
+
width: 160,
|
|
8
|
+
height: 60,
|
|
9
|
+
},
|
|
10
|
+
'compact-card': {
|
|
11
|
+
type: 'compact-card',
|
|
12
|
+
width: 180,
|
|
13
|
+
height: 60,
|
|
14
|
+
},
|
|
15
|
+
'capsule-item': {
|
|
16
|
+
type: 'capsule-item',
|
|
17
|
+
width: 150,
|
|
18
|
+
height: 60,
|
|
19
|
+
},
|
|
20
|
+
'rounded-rect-node': {
|
|
21
|
+
type: 'rounded-rect-node',
|
|
22
|
+
width: 140,
|
|
23
|
+
height: 60,
|
|
24
|
+
},
|
|
25
|
+
} as const;
|
|
26
|
+
|
|
27
|
+
// 基础结构属性
|
|
28
|
+
const baseStructureAttrs = {
|
|
29
|
+
type: 'sequence-interaction',
|
|
30
|
+
showLaneHeader: true,
|
|
31
|
+
arrowType: 'triangle',
|
|
32
|
+
} as const;
|
|
33
|
+
|
|
34
|
+
// 箭头样式配置
|
|
35
|
+
const arrowStyles = {
|
|
36
|
+
default: {},
|
|
37
|
+
dashed: {
|
|
38
|
+
edgeStyle: 'dashed',
|
|
39
|
+
},
|
|
40
|
+
animated: {
|
|
41
|
+
edgeStyle: 'dashed',
|
|
42
|
+
animated: true,
|
|
43
|
+
},
|
|
44
|
+
} as const;
|
|
45
|
+
|
|
46
|
+
// 结构布局配置
|
|
47
|
+
const structures = {
|
|
48
|
+
// 默认:带生命线
|
|
49
|
+
default: {
|
|
50
|
+
...baseStructureAttrs,
|
|
51
|
+
showLifeline: true,
|
|
52
|
+
nodeGap: 40,
|
|
53
|
+
},
|
|
54
|
+
// 紧凑:更小间距
|
|
55
|
+
compact: {
|
|
56
|
+
...baseStructureAttrs,
|
|
57
|
+
showLifeline: true,
|
|
58
|
+
nodeGap: 20,
|
|
59
|
+
},
|
|
60
|
+
// 宽松:更大间距
|
|
61
|
+
wide: {
|
|
62
|
+
...baseStructureAttrs,
|
|
63
|
+
showLifeline: true,
|
|
64
|
+
nodeGap: 60,
|
|
65
|
+
},
|
|
66
|
+
} as const;
|
|
67
|
+
|
|
68
|
+
export const sequenceInteractionTemplates: Record<string, TemplateOptions> = {};
|
|
69
|
+
|
|
70
|
+
// 排除某些不合适的组合
|
|
71
|
+
const omit: string[] = [
|
|
72
|
+
// 后续如果有不合适的可以排除掉
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
Object.entries(structures).forEach(([strKey, strAttrs]) => {
|
|
76
|
+
Object.entries(arrowStyles).forEach(([arrowKey, arrowAttrs]) => {
|
|
77
|
+
Object.entries(items).forEach(([itemKey, itemAttrs]) => {
|
|
78
|
+
const parts = [strKey];
|
|
79
|
+
if (arrowKey !== 'default') {
|
|
80
|
+
parts.push(arrowKey);
|
|
81
|
+
}
|
|
82
|
+
parts.push(itemKey);
|
|
83
|
+
|
|
84
|
+
const appendix = parts.join('-');
|
|
85
|
+
if (omit.includes(appendix)) return;
|
|
86
|
+
|
|
87
|
+
const templateKey = `sequence-interaction-${appendix}`;
|
|
88
|
+
|
|
89
|
+
sequenceInteractionTemplates[templateKey] = {
|
|
90
|
+
design: {
|
|
91
|
+
title: 'default',
|
|
92
|
+
structure: {
|
|
93
|
+
...strAttrs,
|
|
94
|
+
...arrowAttrs,
|
|
95
|
+
},
|
|
96
|
+
item: itemAttrs,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
});
|
package/src/types/data.ts
CHANGED
package/src/utils/index.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { measureText as measure, registerFont } from 'measury';
|
|
2
|
+
import Tegakizatsu from 'measury/fonts/851tegakizatsu-Regular';
|
|
2
3
|
import AlibabaPuHuiTi from 'measury/fonts/AlibabaPuHuiTi-Regular';
|
|
4
|
+
import Arial from 'measury/fonts/Arial-Regular';
|
|
5
|
+
import LXGWWenKai from 'measury/fonts/LXGWWenKai-Regular';
|
|
6
|
+
import SourceHanSans from 'measury/fonts/SourceHanSans-Regular';
|
|
7
|
+
import SourceHanSerif from 'measury/fonts/SourceHanSerif-Regular';
|
|
3
8
|
import { JSXNode, TextProps } from '../jsx';
|
|
4
9
|
import { DEFAULT_FONT } from '../renderer';
|
|
5
|
-
import { encodeFontFamily } from './font';
|
|
6
|
-
import { isBrowser } from './is-browser';
|
|
10
|
+
import { decodeFontFamily, encodeFontFamily } from './font';
|
|
7
11
|
|
|
8
|
-
let FONT_EXTEND_FACTOR = 1.
|
|
12
|
+
let FONT_EXTEND_FACTOR = 1.015;
|
|
9
13
|
|
|
10
14
|
export const setFontExtendFactor = (factor: number) => {
|
|
11
15
|
FONT_EXTEND_FACTOR = factor;
|
|
@@ -13,17 +17,41 @@ export const setFontExtendFactor = (factor: number) => {
|
|
|
13
17
|
|
|
14
18
|
registerFont(AlibabaPuHuiTi);
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
// Lazy-register extra measury fonts on first use (SSR only needs glyph data).
|
|
21
|
+
const EXTRA_MEASURY_FONTS: Record<string, Parameters<typeof registerFont>[0]> =
|
|
22
|
+
{
|
|
23
|
+
'851tegakizatsu': Tegakizatsu,
|
|
24
|
+
Arial: Arial,
|
|
25
|
+
'LXGW WenKai': LXGWWenKai,
|
|
26
|
+
'Source Han Sans': SourceHanSans,
|
|
27
|
+
'Source Han Serif': SourceHanSerif,
|
|
28
|
+
};
|
|
29
|
+
const registeredMeasuryFonts = new Set<string>();
|
|
30
|
+
|
|
31
|
+
function ensureMeasuryFont(fontFamily: string) {
|
|
32
|
+
// decodeFontFamily: '"851tegakizatsu", sans-serif' → '851tegakizatsu, sans-serif'
|
|
33
|
+
// split by comma and take the first family name
|
|
34
|
+
const primary = decodeFontFamily(fontFamily)?.split(',')[0]?.trim();
|
|
35
|
+
if (!primary || registeredMeasuryFonts.has(primary)) return;
|
|
36
|
+
const data = EXTRA_MEASURY_FONTS[primary];
|
|
37
|
+
if (!data) return;
|
|
38
|
+
registerFont(data);
|
|
39
|
+
registeredMeasuryFonts.add(primary);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let canvasContext: CanvasRenderingContext2D | null | undefined = undefined;
|
|
17
43
|
let measureSpan: HTMLSpanElement | null = null;
|
|
18
44
|
|
|
19
45
|
function getCanvasContext() {
|
|
20
|
-
if (
|
|
46
|
+
if (typeof document === 'undefined') return null;
|
|
47
|
+
if (canvasContext !== undefined) return canvasContext;
|
|
21
48
|
const canvas = document.createElement('canvas');
|
|
22
49
|
canvasContext = canvas.getContext('2d');
|
|
23
50
|
return canvasContext;
|
|
24
51
|
}
|
|
25
52
|
|
|
26
53
|
function getMeasureSpan() {
|
|
54
|
+
if (typeof document === 'undefined') return null;
|
|
27
55
|
if (!document.body) return null;
|
|
28
56
|
if (measureSpan) return measureSpan;
|
|
29
57
|
measureSpan = document.createElement('span');
|
|
@@ -98,6 +126,7 @@ function measureTextInBrowser(
|
|
|
98
126
|
span.style.lineHeight = `${lineHeightPx}px`;
|
|
99
127
|
span.textContent = content;
|
|
100
128
|
const rect = span.getBoundingClientRect();
|
|
129
|
+
if (content && rect.width <= 0 && rect.height <= 0) return null;
|
|
101
130
|
return { width: rect.width, height: rect.height };
|
|
102
131
|
}
|
|
103
132
|
|
|
@@ -119,16 +148,19 @@ export function measureText(
|
|
|
119
148
|
} = attrs;
|
|
120
149
|
|
|
121
150
|
const content = text.toString();
|
|
151
|
+
ensureMeasuryFont(fontFamily);
|
|
122
152
|
const options = {
|
|
123
153
|
fontFamily,
|
|
124
154
|
fontSize: parseFloat(fontSize.toString()),
|
|
125
155
|
fontWeight,
|
|
126
156
|
lineHeight,
|
|
127
157
|
};
|
|
128
|
-
const fallback = () =>
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
158
|
+
const fallback = () =>
|
|
159
|
+
measure(content, {
|
|
160
|
+
...options,
|
|
161
|
+
fontFamily: decodeFontFamily(fontFamily),
|
|
162
|
+
});
|
|
163
|
+
const metrics = measureTextInBrowser(content, options) ?? fallback();
|
|
132
164
|
|
|
133
165
|
// 额外添加 1% 宽高
|
|
134
166
|
return {
|
package/src/utils/padding.ts
CHANGED
|
@@ -67,7 +67,10 @@ function setSVGPaddingInNode(svg: SVGSVGElement, padding: ParsedPadding) {
|
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
function
|
|
70
|
+
export function getBoundViewBox(
|
|
71
|
+
svg: SVGSVGElement,
|
|
72
|
+
padding: ParsedPadding,
|
|
73
|
+
): string {
|
|
71
74
|
const bbox = svg.getBBox();
|
|
72
75
|
const clientRect = svg.getBoundingClientRect();
|
|
73
76
|
const scaleX = clientRect.width > 0 ? bbox.width / clientRect.width : 1;
|
|
@@ -84,8 +87,13 @@ function setSVGPaddingInBrowser(svg: SVGSVGElement, padding: ParsedPadding) {
|
|
|
84
87
|
const newWidth = bbox.width + leftSvg + rightSvg;
|
|
85
88
|
const newHeight = bbox.height + topSvg + bottomSvg;
|
|
86
89
|
|
|
90
|
+
return `${newX} ${newY} ${newWidth} ${newHeight}`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function setSVGPaddingInBrowser(svg: SVGSVGElement, padding: ParsedPadding) {
|
|
94
|
+
const viewBox = getBoundViewBox(svg, padding);
|
|
87
95
|
setAttributes(svg, {
|
|
88
|
-
viewBox
|
|
96
|
+
viewBox,
|
|
89
97
|
});
|
|
90
98
|
}
|
|
91
99
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Path Helper Types (路径生成工具类型)
|
|
3
|
+
//
|
|
4
|
+
// 作用:递归提取对象的所有可选路径(点语法),用于 SyncRegistry 等场景的类型安全与补全。
|
|
5
|
+
//
|
|
6
|
+
// [Input]:
|
|
7
|
+
// type Obj = { a: { b: { c: string } }, d: number };
|
|
8
|
+
//
|
|
9
|
+
// [Output]:
|
|
10
|
+
// "a" | "a.b" | "a.b.c" | "d"
|
|
11
|
+
// =============================================================================
|
|
12
|
+
|
|
13
|
+
// 1. 递归深度控制:定义一个元组,用于递减深度 (D -> D-1)
|
|
14
|
+
// Prev[3] => 2, Prev[2] => 1, ... Prev[0] => never
|
|
15
|
+
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
16
|
+
|
|
17
|
+
// 2. 终止节点类型:遇到这些类型停止递归
|
|
18
|
+
// 包括基本类型、数组、函数等,只深入遍历普通对象
|
|
19
|
+
type StopType =
|
|
20
|
+
| string
|
|
21
|
+
| number
|
|
22
|
+
| boolean
|
|
23
|
+
| symbol
|
|
24
|
+
| undefined
|
|
25
|
+
| null
|
|
26
|
+
| ((...args: any[]) => any)
|
|
27
|
+
| Array<any>;
|
|
28
|
+
|
|
29
|
+
// 3. 辅助:拼接两个路径片段 (K.P)
|
|
30
|
+
type Join<K, P> = K extends string | number
|
|
31
|
+
? P extends string | number
|
|
32
|
+
? `${K}${'' extends P ? '' : '.'}${P}`
|
|
33
|
+
: never
|
|
34
|
+
: never;
|
|
35
|
+
|
|
36
|
+
// 4. 辅助:提取对象中明确定义的 Key (过滤掉索引签名 [key: string]: any)
|
|
37
|
+
// 使用 Key Remapping (TS 4.1+) 技术
|
|
38
|
+
type ValidKey<T> = keyof {
|
|
39
|
+
[K in keyof T as string extends K
|
|
40
|
+
? never
|
|
41
|
+
: number extends K
|
|
42
|
+
? never
|
|
43
|
+
: K]: any;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 递归生成 T 的所有点语法路径 (例如 "design.structure" 或 "data.items")
|
|
48
|
+
* @template T 目标对象类型
|
|
49
|
+
* @template D 递归深度限制,默认 3 层 (足以覆盖大多数配置嵌套)
|
|
50
|
+
*/
|
|
51
|
+
export type Path<T, D extends number = 3> = [D] extends [never]
|
|
52
|
+
? never // A. 达到最大深度,终止
|
|
53
|
+
: T extends StopType
|
|
54
|
+
? never // B. 遇到终止类型,终止
|
|
55
|
+
: {
|
|
56
|
+
// C. 遍历所有有效的 Key,并移除可选修饰符 (-?) 以处理 undefined
|
|
57
|
+
[K in ValidKey<T>]-?: K extends string | number
|
|
58
|
+
? // 生成: 当前路径 K 或 "K + 子路径"
|
|
59
|
+
K | Join<K, Path<NonNullable<T[K]>, Prev[D]>>
|
|
60
|
+
: never;
|
|
61
|
+
}[ValidKey<T>]; // D. 提取所有生成路径的联合类型
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.2.
|
|
1
|
+
export const VERSION = '0.2.15';
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|