@blueking/flow-canvas 0.0.1-beta.1
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 +725 -0
- package/dist/core/apply-command.d.ts +11 -0
- package/dist/core/editor.d.ts +50 -0
- package/dist/core/errors.d.ts +6 -0
- package/dist/core/history.d.ts +15 -0
- package/dist/core/plugin-manager.d.ts +58 -0
- package/dist/index-BAAMFT_J.js +236 -0
- package/dist/index-CleU3x1v.cjs +1 -0
- package/dist/index-DD3pv5ZZ.cjs +21 -0
- package/dist/index-siYsjzl4.js +181 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.esm.js +2709 -0
- package/dist/plugins/clipboard.d.ts +9 -0
- package/dist/plugins/connection-validator.d.ts +3 -0
- package/dist/plugins/minimap.d.ts +7 -0
- package/dist/plugins/selection.d.ts +7 -0
- package/dist/plugins/snapline.d.ts +6 -0
- package/dist/runtime/canvas-api.d.ts +25 -0
- package/dist/runtime/canvas-runtime-core.vue.d.ts +36 -0
- package/dist/runtime/event-bridge.d.ts +28 -0
- package/dist/runtime/graph-bridge.d.ts +127 -0
- package/dist/runtime/overlay-manager.d.ts +4 -0
- package/dist/runtime/shape-registry.d.ts +8 -0
- package/dist/runtime/use-edge-delete-tool.d.ts +11 -0
- package/dist/runtime/use-node-hover.d.ts +8 -0
- package/dist/runtime/use-port-visibility.d.ts +15 -0
- package/dist/shell/canvas-layout.vue.d.ts +35 -0
- package/dist/shell/canvas-node-palette.vue.d.ts +10 -0
- package/dist/shell/canvas-toolbar.vue.d.ts +11 -0
- package/dist/shell/default-node.vue.d.ts +4 -0
- package/dist/shell/default-schema.d.ts +39 -0
- package/dist/shell/node-actions-toolbar.vue.d.ts +18 -0
- package/dist/shell/node-quick-add-popover.vue.d.ts +36 -0
- package/dist/shell/toolbar-items.d.ts +13 -0
- package/dist/style.css +1 -0
- package/dist/types/api.d.ts +104 -0
- package/dist/types/command.d.ts +160 -0
- package/dist/types/flow-model.d.ts +46 -0
- package/dist/types/history.d.ts +18 -0
- package/dist/types/overlay.d.ts +17 -0
- package/dist/types/plugin.d.ts +64 -0
- package/dist/types/schema.d.ts +77 -0
- package/dist/utils/path.d.ts +7 -0
- package/dist/utils/uuid.d.ts +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FlowModel } from '../types/flow-model';
|
|
2
|
+
import type { CanvasCommand } from '../types/command';
|
|
3
|
+
/**
|
|
4
|
+
* 纯函数 reducer:将一条原子命令应用到 FlowModel 上,返回新 FlowModel(不可变)。
|
|
5
|
+
* 所有 FlowModel 不变量在此处保证:
|
|
6
|
+
* - 节点/边 id 唯一性
|
|
7
|
+
* - 边端点必须指向存在的节点(及可选的 port)
|
|
8
|
+
* - 删除节点时级联清理关联边
|
|
9
|
+
* - label id 在同一条边内唯一
|
|
10
|
+
*/
|
|
11
|
+
export declare function applyCanvasCommand(model: FlowModel, cmd: CanvasCommand): FlowModel;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
import type { FlowModel } from '../types/flow-model';
|
|
3
|
+
import type { CanvasSchema, CanvasMode } from '../types/schema';
|
|
4
|
+
import type { CanvasPlugin } from '../types/plugin';
|
|
5
|
+
import type { CanvasApi, CanvasToolbarItem } from '../types/api';
|
|
6
|
+
import type { CanvasHistory, CanvasHistoryOptions } from '../types/history';
|
|
7
|
+
import type { CommandEnvelope, CommandExecutionResult, FlowModelChangeEvent } from '../types/command';
|
|
8
|
+
import { PluginManager } from './plugin-manager';
|
|
9
|
+
export interface CanvasEditorOptions {
|
|
10
|
+
initialFlowModel: FlowModel;
|
|
11
|
+
schema: CanvasSchema;
|
|
12
|
+
plugins?: CanvasPlugin[];
|
|
13
|
+
mode?: CanvasMode;
|
|
14
|
+
historyOptions?: CanvasHistoryOptions;
|
|
15
|
+
onCommandResult?(result: CommandExecutionResult): void;
|
|
16
|
+
onFlowModelChange?(event: FlowModelChangeEvent): void;
|
|
17
|
+
}
|
|
18
|
+
export interface CanvasEditorContext {
|
|
19
|
+
flowModel: Readonly<Ref<FlowModel>>;
|
|
20
|
+
history: CanvasHistory;
|
|
21
|
+
schema: CanvasSchema;
|
|
22
|
+
mode: Ref<CanvasMode>;
|
|
23
|
+
executeCommand(envelope: CommandEnvelope): CommandExecutionResult;
|
|
24
|
+
replaceFlowModel(model: FlowModel): void;
|
|
25
|
+
setMode(mode: CanvasMode): void;
|
|
26
|
+
/** 框选模式:开启后左键拖拽画布空白区域为框选,关闭时为画布平移 */
|
|
27
|
+
selectionMode: Ref<boolean>;
|
|
28
|
+
setSelectionMode(enabled: boolean): void;
|
|
29
|
+
api: Ref<CanvasApi | null>;
|
|
30
|
+
toolbarItems: Readonly<Ref<CanvasToolbarItem[]>>;
|
|
31
|
+
extendedApi: Record<string, Function>;
|
|
32
|
+
/** @internal used by CanvasRuntime */
|
|
33
|
+
_pluginManager: PluginManager;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 画布编辑引擎的核心 composable。
|
|
37
|
+
*
|
|
38
|
+
* 初始化时完成:
|
|
39
|
+
* 1. 创建 CanvasHistory(快照栈)
|
|
40
|
+
* 2. 安装插件(editor-stage)
|
|
41
|
+
* 3. 暴露 executeCommand / replaceFlowModel / setMode 等 API
|
|
42
|
+
*
|
|
43
|
+
* api(CanvasApi)在 CanvasRuntime mount 后才由 runtime 注入。
|
|
44
|
+
* 在此之前 api.value === null,工具栏等依赖 api 的功能默认禁用。
|
|
45
|
+
*
|
|
46
|
+
* executeCommand 的完整管道:
|
|
47
|
+
* pluginManager.transformCommand → history.execute → applyCanvasCommand
|
|
48
|
+
* → pluginManager.afterCommand → onCommandResult → onFlowModelChange
|
|
49
|
+
*/
|
|
50
|
+
export declare function useCanvasEditor(options: CanvasEditorOptions): CanvasEditorContext;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
import type { FlowModel } from '../types/flow-model';
|
|
3
|
+
import type { CanvasHistory, CanvasHistoryOptions } from '../types/history';
|
|
4
|
+
/**
|
|
5
|
+
* 基于快照栈的历史系统。
|
|
6
|
+
*
|
|
7
|
+
* 每次 execute 时在 undo 栈中保存执行前的 FlowModel 快照,同时清空 redo 栈。
|
|
8
|
+
* undo 弹出上一个快照恢复 FlowModel;redo 重新执行对应 envelope 的命令序列。
|
|
9
|
+
*
|
|
10
|
+
* 注意:当前实现为完整快照,适用于中小规模 FlowModel。
|
|
11
|
+
* 若 payload 增长导致性能问题,后续可引入结构共享或 checkpoint + patch 混合模式。
|
|
12
|
+
*/
|
|
13
|
+
export declare function createCanvasHistory(initialFlowModel: FlowModel, options?: CanvasHistoryOptions): CanvasHistory & {
|
|
14
|
+
currentFlowModel: Ref<FlowModel>;
|
|
15
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { CanvasPlugin, EditorPluginContext, RuntimePluginContext, CanvasSelection, NodeDecoration, EdgeDecoration } from '../types/plugin';
|
|
2
|
+
import type { CommandEnvelope, CanvasUiEvent, ScreenPosition, CommandExecutionError } from '../types/command';
|
|
3
|
+
import type { CanvasToolbarItem } from '../types/api';
|
|
4
|
+
import type { FlowModel, FlowNodeModel, FlowEdgeModel } from '../types/flow-model';
|
|
5
|
+
/**
|
|
6
|
+
* 管理插件的安装、运行时挂载、命令管道和事件分发。
|
|
7
|
+
*
|
|
8
|
+
* 生命周期分两阶段:
|
|
9
|
+
* 1. install(editor 级):在 useCanvasEditor 初始化时调用,此时只有 flowModel/history/schema 可用
|
|
10
|
+
* 2. attachRuntime(runtime 级):在 CanvasRuntime mount 后调用,此时 api/graph/overlay 已就绪
|
|
11
|
+
*
|
|
12
|
+
* 命令管道(transformCommand)为不可变管道:
|
|
13
|
+
* - 插件按 priority 升序执行
|
|
14
|
+
* - 每个插件返回新 envelope 或 null(拒绝)或 CommandRejection
|
|
15
|
+
* - 前一个插件的输出是下一个插件的输入
|
|
16
|
+
*/
|
|
17
|
+
export declare class PluginManager {
|
|
18
|
+
private plugins;
|
|
19
|
+
private editorContext;
|
|
20
|
+
private runtimeCtx;
|
|
21
|
+
/** 每次 attachRuntime 递增,detachRuntime 时旧 generation 的异步调用自动作废 */
|
|
22
|
+
private runtimeVersion;
|
|
23
|
+
install(plugins: CanvasPlugin[], ctx: EditorPluginContext): void;
|
|
24
|
+
/**
|
|
25
|
+
* 挂载运行时上下文并调用各插件的 attachRuntime。
|
|
26
|
+
* 异步插件(如动态 import X6 插件)在 await 返回后会检查 generation,
|
|
27
|
+
* 若 detachRuntime 已被调用(generation 已变),则跳过 graph.use() 等操作。
|
|
28
|
+
*/
|
|
29
|
+
attachRuntime(ctx: RuntimePluginContext): void;
|
|
30
|
+
/** 按安装的逆序 detach,保证后安装的插件先释放运行时资源 */
|
|
31
|
+
detachRuntime(): void;
|
|
32
|
+
/**
|
|
33
|
+
* 为 attachRuntime 创建保护代理:graph.use() 等可能在异步回调中调用,
|
|
34
|
+
* 如果在 await 期间 detachRuntime 已执行,代理会将 graph 操作变为 no-op。
|
|
35
|
+
*/
|
|
36
|
+
private createSafeRuntimeContext;
|
|
37
|
+
dispose(): void;
|
|
38
|
+
transformCommand(envelope: Readonly<CommandEnvelope>): {
|
|
39
|
+
envelope: CommandEnvelope;
|
|
40
|
+
} | {
|
|
41
|
+
rejected: true;
|
|
42
|
+
error: CommandExecutionError;
|
|
43
|
+
};
|
|
44
|
+
afterCommand(envelope: Readonly<CommandEnvelope>, prevModel: Readonly<FlowModel>, newModel: Readonly<FlowModel>): void;
|
|
45
|
+
dispatchUiEvent(event: CanvasUiEvent): void;
|
|
46
|
+
dispatchSelectionChange(selection: CanvasSelection): void;
|
|
47
|
+
dispatchKeyboardShortcut(event: KeyboardEvent): boolean;
|
|
48
|
+
collectContextMenuItems(position: ScreenPosition): import('../types/plugin').ContextMenuItem[];
|
|
49
|
+
/** 汇聚所有插件的工具栏项,相同 id 的后注册覆盖先注册,最终按 order 排序 */
|
|
50
|
+
collectToolbarItems(): CanvasToolbarItem[];
|
|
51
|
+
/** 合并所有插件对某节点的装饰(className / borderColor / badge),后注册覆盖先注册 */
|
|
52
|
+
collectNodeDecorations(node: FlowNodeModel): NodeDecoration | undefined;
|
|
53
|
+
/** 合并所有插件对某边的装饰(className / strokeColor),后注册覆盖先注册 */
|
|
54
|
+
collectEdgeDecorations(edge: FlowEdgeModel): EdgeDecoration | undefined;
|
|
55
|
+
collectExtendedApi(): Record<string, Function>;
|
|
56
|
+
/** 基于当前 FlowModel 和待执行命令序列,生成预览 FlowModel 供 transformCommand 使用 */
|
|
57
|
+
private createPreview;
|
|
58
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { View as x, CssLoader as u, Dom as l, Graph as y, FunctionExt as f, Rectangle as E, GeometryUtil as m } from "@antv/x6";
|
|
2
|
+
const G = `.x6-widget-dnd {
|
|
3
|
+
position: absolute;
|
|
4
|
+
top: -10000px;
|
|
5
|
+
left: -10000px;
|
|
6
|
+
z-index: 999999;
|
|
7
|
+
display: none;
|
|
8
|
+
cursor: move;
|
|
9
|
+
opacity: 0.7;
|
|
10
|
+
pointer-events: 'cursor';
|
|
11
|
+
}
|
|
12
|
+
.x6-widget-dnd.dragging {
|
|
13
|
+
display: inline-block;
|
|
14
|
+
}
|
|
15
|
+
.x6-widget-dnd.dragging * {
|
|
16
|
+
pointer-events: none !important;
|
|
17
|
+
}
|
|
18
|
+
.x6-widget-dnd .x6-graph {
|
|
19
|
+
background: transparent;
|
|
20
|
+
box-shadow: none;
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
var v = function(c, e, n, t) {
|
|
24
|
+
var i = arguments.length, s = i < 3 ? e : t === null ? t = Object.getOwnPropertyDescriptor(e, n) : t, a;
|
|
25
|
+
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") s = Reflect.decorate(c, e, n, t);
|
|
26
|
+
else for (var o = c.length - 1; o >= 0; o--) (a = c[o]) && (s = (i < 3 ? a(s) : i > 3 ? a(e, n, s) : a(e, n)) || s);
|
|
27
|
+
return i > 3 && s && Object.defineProperty(e, n, s), s;
|
|
28
|
+
};
|
|
29
|
+
class p extends x {
|
|
30
|
+
get targetScroller() {
|
|
31
|
+
return this.options.target.getPlugin("scroller");
|
|
32
|
+
}
|
|
33
|
+
get targetGraph() {
|
|
34
|
+
return this.options.target;
|
|
35
|
+
}
|
|
36
|
+
get targetModel() {
|
|
37
|
+
return this.targetGraph.model;
|
|
38
|
+
}
|
|
39
|
+
get snapline() {
|
|
40
|
+
return this.options.target.getPlugin("snapline");
|
|
41
|
+
}
|
|
42
|
+
constructor(e) {
|
|
43
|
+
super(), this.name = "dnd", this.options = Object.assign(Object.assign({}, p.defaults), e), this.init();
|
|
44
|
+
}
|
|
45
|
+
init() {
|
|
46
|
+
u.ensure(this.name, G), this.container = document.createElement("div"), l.addClass(this.container, this.prefixClassName("widget-dnd")), this.draggingGraph = new y(Object.assign(Object.assign({}, this.options.delegateGraphOptions), { container: document.createElement("div"), width: 1, height: 1, async: !1 })), l.append(this.container, this.draggingGraph.container);
|
|
47
|
+
}
|
|
48
|
+
start(e, n) {
|
|
49
|
+
const t = n;
|
|
50
|
+
t.preventDefault(), this.targetModel.startBatch("dnd"), l.addClass(this.container, "dragging"), l.appendTo(this.container, this.options.draggingContainer || document.body), this.sourceNode = e, this.prepareDragging(e, t.clientX, t.clientY);
|
|
51
|
+
const i = this.updateNodePosition(t.clientX, t.clientY);
|
|
52
|
+
this.isSnaplineEnabled() && (this.snapline.captureCursorOffset({
|
|
53
|
+
e: t,
|
|
54
|
+
node: e,
|
|
55
|
+
cell: e,
|
|
56
|
+
view: this.draggingView,
|
|
57
|
+
x: i.x,
|
|
58
|
+
y: i.y
|
|
59
|
+
}), this.draggingNode.on("change:position", this.snap, this)), this.delegateDocumentEvents(p.documentEvents, t.data);
|
|
60
|
+
}
|
|
61
|
+
isSnaplineEnabled() {
|
|
62
|
+
return this.snapline && this.snapline.isEnabled();
|
|
63
|
+
}
|
|
64
|
+
prepareDragging(e, n, t) {
|
|
65
|
+
const i = this.draggingGraph, s = i.model, a = this.options.getDragNode(e, {
|
|
66
|
+
sourceNode: e,
|
|
67
|
+
draggingGraph: i,
|
|
68
|
+
targetGraph: this.targetGraph
|
|
69
|
+
});
|
|
70
|
+
a.position(0, 0);
|
|
71
|
+
let o = 5;
|
|
72
|
+
if (this.isSnaplineEnabled() && (o += this.snapline.options.tolerance || 0), this.isSnaplineEnabled() || this.options.scaled) {
|
|
73
|
+
const g = this.targetGraph.transform.getScale();
|
|
74
|
+
i.scale(g.sx, g.sy), o *= Math.max(g.sx, g.sy);
|
|
75
|
+
} else
|
|
76
|
+
i.scale(1, 1);
|
|
77
|
+
this.clearDragging(), s.resetCells([a]);
|
|
78
|
+
const r = i.findViewByCell(a);
|
|
79
|
+
r.undelegateEvents(), r.cell.off("changed"), i.fitToContent({
|
|
80
|
+
padding: o,
|
|
81
|
+
allowNewOrigin: "any",
|
|
82
|
+
useCellGeometry: !1
|
|
83
|
+
});
|
|
84
|
+
const d = r.getBBox();
|
|
85
|
+
this.geometryBBox = r.getBBox({ useCellGeometry: !0 }), this.delta = this.geometryBBox.getTopLeft().diff(d.getTopLeft()), this.draggingNode = a, this.draggingView = r, this.draggingBBox = a.getBBox(), this.padding = o, this.originOffset = this.updateGraphPosition(n, t);
|
|
86
|
+
}
|
|
87
|
+
updateGraphPosition(e, n) {
|
|
88
|
+
const t = document.body.scrollTop || document.documentElement.scrollTop, i = document.body.scrollLeft || document.documentElement.scrollLeft, s = this.delta, a = this.geometryBBox, o = this.padding || 5, r = {
|
|
89
|
+
left: e - s.x - a.width / 2 - o + i,
|
|
90
|
+
top: n - s.y - a.height / 2 - o + t
|
|
91
|
+
};
|
|
92
|
+
return this.draggingGraph && l.css(this.container, {
|
|
93
|
+
left: `${r.left}px`,
|
|
94
|
+
top: `${r.top}px`
|
|
95
|
+
}), r;
|
|
96
|
+
}
|
|
97
|
+
updateNodePosition(e, n) {
|
|
98
|
+
const t = this.targetGraph.clientToLocal(e, n), i = this.draggingBBox;
|
|
99
|
+
return t.x -= i.width / 2, t.y -= i.height / 2, this.draggingNode.position(t.x, t.y), t;
|
|
100
|
+
}
|
|
101
|
+
snap({ cell: e, current: n, options: t }) {
|
|
102
|
+
const i = e;
|
|
103
|
+
if (t.snapped) {
|
|
104
|
+
const s = this.draggingBBox;
|
|
105
|
+
i.position(s.x + t.tx, s.y + t.ty, { silent: !0 }), this.draggingView.translate(), i.position(n.x, n.y, { silent: !0 }), this.snapOffset = {
|
|
106
|
+
x: t.tx,
|
|
107
|
+
y: t.ty
|
|
108
|
+
};
|
|
109
|
+
} else
|
|
110
|
+
this.snapOffset = null;
|
|
111
|
+
}
|
|
112
|
+
onDragging(e) {
|
|
113
|
+
const n = this.draggingView;
|
|
114
|
+
if (n) {
|
|
115
|
+
e.preventDefault();
|
|
116
|
+
const t = this.normalizeEvent(e), i = t.clientX, s = t.clientY;
|
|
117
|
+
this.updateGraphPosition(i, s);
|
|
118
|
+
const a = this.updateNodePosition(i, s), o = this.targetGraph.options.embedding.enabled, r = (o || this.isSnaplineEnabled()) && this.isInsideValidArea({
|
|
119
|
+
x: i,
|
|
120
|
+
y: s
|
|
121
|
+
});
|
|
122
|
+
if (o) {
|
|
123
|
+
n.setEventData(t, {
|
|
124
|
+
graph: this.targetGraph,
|
|
125
|
+
candidateEmbedView: this.candidateEmbedView
|
|
126
|
+
});
|
|
127
|
+
const d = n.getEventData(t);
|
|
128
|
+
r ? n.processEmbedding(t, d) : n.clearEmbedding(d), this.candidateEmbedView = d.candidateEmbedView;
|
|
129
|
+
}
|
|
130
|
+
this.isSnaplineEnabled() && (r ? this.snapline.snapOnMoving({
|
|
131
|
+
e: t,
|
|
132
|
+
view: n,
|
|
133
|
+
x: a.x,
|
|
134
|
+
y: a.y
|
|
135
|
+
}) : this.snapline.hide());
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
onDragEnd(e) {
|
|
139
|
+
const n = this.draggingNode;
|
|
140
|
+
if (n) {
|
|
141
|
+
const t = this.normalizeEvent(e), i = this.draggingView, s = this.draggingBBox, a = this.snapOffset;
|
|
142
|
+
let o = s.x, r = s.y;
|
|
143
|
+
a && (o += a.x, r += a.y), n.position(o, r, { silent: !0 });
|
|
144
|
+
const d = this.drop(n, { x: t.clientX, y: t.clientY }), g = (h) => {
|
|
145
|
+
h ? (this.onDropped(n), this.targetGraph.options.embedding.enabled && i && (i.setEventData(t, {
|
|
146
|
+
cell: h,
|
|
147
|
+
graph: this.targetGraph,
|
|
148
|
+
candidateEmbedView: this.candidateEmbedView
|
|
149
|
+
}), i.finalizeEmbedding(t, i.getEventData(t)))) : this.onDropInvalid(), this.candidateEmbedView = null, this.targetModel.stopBatch("dnd");
|
|
150
|
+
};
|
|
151
|
+
f.isAsync(d) ? (this.undelegateDocumentEvents(), d.then(g)) : g(d);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
clearDragging() {
|
|
155
|
+
this.draggingNode && (this.sourceNode = null, this.draggingNode.remove(), this.draggingNode = null, this.draggingView = null, this.delta = null, this.padding = null, this.snapOffset = null, this.originOffset = null, this.undelegateDocumentEvents());
|
|
156
|
+
}
|
|
157
|
+
onDropped(e) {
|
|
158
|
+
this.draggingNode === e && (this.clearDragging(), l.removeClass(this.container, "dragging"), l.remove(this.container));
|
|
159
|
+
}
|
|
160
|
+
onDropInvalid() {
|
|
161
|
+
const e = this.draggingNode;
|
|
162
|
+
e && this.onDropped(e);
|
|
163
|
+
}
|
|
164
|
+
isInsideValidArea(e) {
|
|
165
|
+
let n, t = null;
|
|
166
|
+
const i = this.targetGraph, s = this.targetScroller;
|
|
167
|
+
this.options.dndContainer && (t = this.getDropArea(this.options.dndContainer));
|
|
168
|
+
const a = t && t.containsPoint(e);
|
|
169
|
+
if (s)
|
|
170
|
+
if (s.options.autoResize)
|
|
171
|
+
n = this.getDropArea(s.container);
|
|
172
|
+
else {
|
|
173
|
+
const o = this.getDropArea(s.container);
|
|
174
|
+
n = this.getDropArea(i.container).intersectsWithRect(o);
|
|
175
|
+
}
|
|
176
|
+
else
|
|
177
|
+
n = this.getDropArea(i.container);
|
|
178
|
+
return !a && n && n.containsPoint(e);
|
|
179
|
+
}
|
|
180
|
+
getDropArea(e) {
|
|
181
|
+
const n = l.offset(e), t = document.body.scrollTop || document.documentElement.scrollTop, i = document.body.scrollLeft || document.documentElement.scrollLeft;
|
|
182
|
+
return E.create({
|
|
183
|
+
x: n.left + parseInt(l.css(e, "border-left-width"), 10) - i,
|
|
184
|
+
y: n.top + parseInt(l.css(e, "border-top-width"), 10) - t,
|
|
185
|
+
width: e.clientWidth,
|
|
186
|
+
height: e.clientHeight
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
drop(e, n) {
|
|
190
|
+
if (this.isInsideValidArea(n)) {
|
|
191
|
+
const t = this.targetGraph, i = t.model, s = t.clientToLocal(n), a = this.sourceNode, o = this.options.getDropNode(e, {
|
|
192
|
+
sourceNode: a,
|
|
193
|
+
draggingNode: e,
|
|
194
|
+
targetGraph: this.targetGraph,
|
|
195
|
+
draggingGraph: this.draggingGraph
|
|
196
|
+
}), r = o.getBBox();
|
|
197
|
+
s.x += r.x - r.width / 2, s.y += r.y - r.height / 2;
|
|
198
|
+
const d = this.snapOffset ? 1 : t.getGridSize();
|
|
199
|
+
o.position(m.snapToGrid(s.x, d), m.snapToGrid(s.y, d)), o.removeZIndex();
|
|
200
|
+
const g = this.options.validateNode, h = g ? g(o, {
|
|
201
|
+
sourceNode: a,
|
|
202
|
+
draggingNode: e,
|
|
203
|
+
droppingNode: o,
|
|
204
|
+
targetGraph: t,
|
|
205
|
+
draggingGraph: this.draggingGraph
|
|
206
|
+
}) : !0;
|
|
207
|
+
return typeof h == "boolean" ? h ? (i.addCell(o, { stencil: this.cid }), o) : null : f.toDeferredBoolean(h).then((b) => b ? (i.addCell(o, { stencil: this.cid }), o) : null);
|
|
208
|
+
}
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
onRemove() {
|
|
212
|
+
this.draggingGraph && (this.draggingGraph.view.remove(), this.draggingGraph.dispose());
|
|
213
|
+
}
|
|
214
|
+
dispose() {
|
|
215
|
+
this.remove(), u.clean(this.name);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
v([
|
|
219
|
+
x.dispose()
|
|
220
|
+
], p.prototype, "dispose", null);
|
|
221
|
+
(function(c) {
|
|
222
|
+
c.defaults = {
|
|
223
|
+
// animation: false,
|
|
224
|
+
getDragNode: (e) => e.clone(),
|
|
225
|
+
getDropNode: (e) => e.clone()
|
|
226
|
+
}, c.documentEvents = {
|
|
227
|
+
mousemove: "onDragging",
|
|
228
|
+
touchmove: "onDragging",
|
|
229
|
+
mouseup: "onDragEnd",
|
|
230
|
+
touchend: "onDragEnd",
|
|
231
|
+
touchcancel: "onDragEnd"
|
|
232
|
+
};
|
|
233
|
+
})(p || (p = {}));
|
|
234
|
+
export {
|
|
235
|
+
p as Dnd
|
|
236
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("@antv/x6");a.Graph.prototype.toSVG=function(s,e){const t=this.getPlugin("export");t&&t.toSVG(s,e)};a.Graph.prototype.toPNG=function(s,e){const t=this.getPlugin("export");t&&t.toPNG(s,e)};a.Graph.prototype.toJPEG=function(s,e){const t=this.getPlugin("export");t&&t.toJPEG(s,e)};a.Graph.prototype.exportPNG=function(s,e){const t=this.getPlugin("export");t&&t.exportPNG(s,e)};a.Graph.prototype.exportJPEG=function(s,e){const t=this.getPlugin("export");t&&t.exportJPEG(s,e)};a.Graph.prototype.exportSVG=function(s,e){const t=this.getPlugin("export");t&&t.exportSVG(s,e)};var E=function(s,e,t,r){var i=arguments.length,c=i<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")c=Reflect.decorate(s,e,t,r);else for(var h=s.length-1;h>=0;h--)(d=s[h])&&(c=(i<3?d(c):i>3?d(e,t,c):d(e,t))||c);return i>3&&c&&Object.defineProperty(e,t,c),c};class D extends a.Basecoat{constructor(){super(),this.name="export"}get view(){return this.graph.view}init(e){this.graph=e}exportPNG(e="chart",t={}){this.toPNG(r=>{a.DataUri.downloadDataUri(r,e)},t)}exportJPEG(e="chart",t={}){this.toPNG(r=>{a.DataUri.downloadDataUri(r,e)},t)}exportSVG(e="chart",t={}){this.toSVG(r=>{a.DataUri.downloadDataUri(a.DataUri.svgToDataUrl(r),e)},t)}toSVG(e,t={}){this.notify("before:export",t);const r=this.view.svg,i=a.Vector.create(r).clone();let c=i.node;const d=i.findOne(`.${this.view.prefixClassName("graph-svg-stage")}`),h=t.viewBox||this.graph.graphToLocal(this.graph.getContentBBox()),l=t.preserveDimensions;if(l){const o=typeof l=="boolean"?h:l;i.attr({width:o.width,height:o.height})}if(i.removeAttribute("style").attr("viewBox",[h.x,h.y,h.width,h.height].join(" ")),d.removeAttribute("transform"),t.copyStyles!==!1){const o=r.ownerDocument,f=Array.from(r.querySelectorAll("*")),u=Array.from(c.querySelectorAll("*")),p=o.styleSheets.length,G=[];for(let n=p-1;n>=0;n-=1)G[n]=o.styleSheets[n],o.styleSheets[n].disabled=!0;const x={};f.forEach((n,m)=>{const w=window.getComputedStyle(n,null),P={};Object.keys(w).forEach(S=>{P[S]=w.getPropertyValue(S)}),x[m]=P}),p!==o.styleSheets.length&&G.forEach((n,m)=>{o.styleSheets[m]=n});for(let n=0;n<p;n+=1)o.styleSheets[n].disabled=!1;const v={};f.forEach((n,m)=>{const w=window.getComputedStyle(n,null),P=x[m],S={};Object.keys(w).forEach(b=>{!a.NumberExt.isNumber(b)&&w.getPropertyValue(b)!==P[b]&&(S[b]=w.getPropertyValue(b))}),v[m]=S}),u.forEach((n,m)=>{a.Dom.css(n,v[m])})}const y=t.stylesheet;if(typeof y=="string"){const o=r.ownerDocument.implementation.createDocument(null,"xml",null).createCDATASection(y);i.prepend(a.Vector.create("style",{type:"text/css"},[o]))}const g=()=>{const o=t.beforeSerialize;if(typeof o=="function"){const u=a.FunctionExt.call(o,this.graph,c);u instanceof SVGSVGElement&&(c=u)}const f=new XMLSerializer().serializeToString(c).replace(/ /g," ");this.notify("after:export",t),e(f)};if(t.serializeImages){const o=i.find("image").map(f=>new Promise(u=>{const p=f.attr("xlink:href")||f.attr("href");a.DataUri.imageToDataUri(p,(G,x)=>{!G&&x&&f.attr("xlink:href",x),u()})}));Promise.all(o).then(g)}else g()}toDataURL(e,t){let r=t.viewBox||this.graph.getContentBBox();const i=a.NumberExt.normalizeSides(t.padding);t.width&&t.height&&(i.left+i.right>=t.width&&(i.left=i.right=0),i.top+i.bottom>=t.height&&(i.top=i.bottom=0));const c=new a.Rectangle(-i.left,-i.top,i.left+i.right,i.top+i.bottom);if(t.width&&t.height){const g=r.width+i.left+i.right,o=r.height+i.top+i.bottom;c.scale(g/t.width,o/t.height)}r=a.Rectangle.create(r).moveAndExpand(c);const d=typeof t.width=="number"&&typeof t.height=="number"?{width:t.width,height:t.height}:r;let h=t.ratio?parseFloat(t.ratio):1;(!Number.isFinite(h)||h===0)&&(h=1);const l={width:Math.max(Math.round(d.width*h),1),height:Math.max(Math.round(d.height*h),1)};{const g=document.createElement("canvas"),o=g.getContext("2d");g.width=l.width,g.height=l.height;const f=l.width-1,u=l.height-1;o.fillStyle="rgb(1,1,1)",o.fillRect(f,u,1,1);const p=o.getImageData(f,u,1,1).data;if(p[0]!==1||p[1]!==1||p[2]!==1)throw new Error("size exceeded")}const y=new Image;y.onload=()=>{const g=document.createElement("canvas");g.width=l.width,g.height=l.height;const o=g.getContext("2d");o.fillStyle=t.backgroundColor||"white",o.fillRect(0,0,l.width,l.height);try{o.drawImage(y,0,0,l.width,l.height);const f=g.toDataURL(t.type,t.quality);e(f)}catch{}},this.toSVG(g=>{y.src=`data:image/svg+xml,${encodeURIComponent(g)}`},Object.assign(Object.assign({},t),{viewBox:r,serializeImages:!0,preserveDimensions:Object.assign({},l)}))}toPNG(e,t={}){this.toDataURL(e,Object.assign(Object.assign({},t),{type:"image/png"}))}toJPEG(e,t={}){this.toDataURL(e,Object.assign(Object.assign({},t),{type:"image/jpeg"}))}notify(e,t){this.trigger(e,t),this.graph.trigger(e,t)}dispose(){this.off()}}E([a.Basecoat.dispose()],D.prototype,"dispose",null);exports.Export=D;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("@antv/x6"),f=`.x6-widget-dnd {
|
|
2
|
+
position: absolute;
|
|
3
|
+
top: -10000px;
|
|
4
|
+
left: -10000px;
|
|
5
|
+
z-index: 999999;
|
|
6
|
+
display: none;
|
|
7
|
+
cursor: move;
|
|
8
|
+
opacity: 0.7;
|
|
9
|
+
pointer-events: 'cursor';
|
|
10
|
+
}
|
|
11
|
+
.x6-widget-dnd.dragging {
|
|
12
|
+
display: inline-block;
|
|
13
|
+
}
|
|
14
|
+
.x6-widget-dnd.dragging * {
|
|
15
|
+
pointer-events: none !important;
|
|
16
|
+
}
|
|
17
|
+
.x6-widget-dnd .x6-graph {
|
|
18
|
+
background: transparent;
|
|
19
|
+
box-shadow: none;
|
|
20
|
+
}
|
|
21
|
+
`;var m=function(h,e,n,t){var i=arguments.length,s=i<3?e:t===null?t=Object.getOwnPropertyDescriptor(e,n):t,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(h,e,n,t);else for(var o=h.length-1;o>=0;o--)(a=h[o])&&(s=(i<3?a(s):i>3?a(e,n,s):a(e,n))||s);return i>3&&s&&Object.defineProperty(e,n,s),s};class c extends d.View{get targetScroller(){return this.options.target.getPlugin("scroller")}get targetGraph(){return this.options.target}get targetModel(){return this.targetGraph.model}get snapline(){return this.options.target.getPlugin("snapline")}constructor(e){super(),this.name="dnd",this.options=Object.assign(Object.assign({},c.defaults),e),this.init()}init(){d.CssLoader.ensure(this.name,f),this.container=document.createElement("div"),d.Dom.addClass(this.container,this.prefixClassName("widget-dnd")),this.draggingGraph=new d.Graph(Object.assign(Object.assign({},this.options.delegateGraphOptions),{container:document.createElement("div"),width:1,height:1,async:!1})),d.Dom.append(this.container,this.draggingGraph.container)}start(e,n){const t=n;t.preventDefault(),this.targetModel.startBatch("dnd"),d.Dom.addClass(this.container,"dragging"),d.Dom.appendTo(this.container,this.options.draggingContainer||document.body),this.sourceNode=e,this.prepareDragging(e,t.clientX,t.clientY);const i=this.updateNodePosition(t.clientX,t.clientY);this.isSnaplineEnabled()&&(this.snapline.captureCursorOffset({e:t,node:e,cell:e,view:this.draggingView,x:i.x,y:i.y}),this.draggingNode.on("change:position",this.snap,this)),this.delegateDocumentEvents(c.documentEvents,t.data)}isSnaplineEnabled(){return this.snapline&&this.snapline.isEnabled()}prepareDragging(e,n,t){const i=this.draggingGraph,s=i.model,a=this.options.getDragNode(e,{sourceNode:e,draggingGraph:i,targetGraph:this.targetGraph});a.position(0,0);let o=5;if(this.isSnaplineEnabled()&&(o+=this.snapline.options.tolerance||0),this.isSnaplineEnabled()||this.options.scaled){const l=this.targetGraph.transform.getScale();i.scale(l.sx,l.sy),o*=Math.max(l.sx,l.sy)}else i.scale(1,1);this.clearDragging(),s.resetCells([a]);const r=i.findViewByCell(a);r.undelegateEvents(),r.cell.off("changed"),i.fitToContent({padding:o,allowNewOrigin:"any",useCellGeometry:!1});const g=r.getBBox();this.geometryBBox=r.getBBox({useCellGeometry:!0}),this.delta=this.geometryBBox.getTopLeft().diff(g.getTopLeft()),this.draggingNode=a,this.draggingView=r,this.draggingBBox=a.getBBox(),this.padding=o,this.originOffset=this.updateGraphPosition(n,t)}updateGraphPosition(e,n){const t=document.body.scrollTop||document.documentElement.scrollTop,i=document.body.scrollLeft||document.documentElement.scrollLeft,s=this.delta,a=this.geometryBBox,o=this.padding||5,r={left:e-s.x-a.width/2-o+i,top:n-s.y-a.height/2-o+t};return this.draggingGraph&&d.Dom.css(this.container,{left:`${r.left}px`,top:`${r.top}px`}),r}updateNodePosition(e,n){const t=this.targetGraph.clientToLocal(e,n),i=this.draggingBBox;return t.x-=i.width/2,t.y-=i.height/2,this.draggingNode.position(t.x,t.y),t}snap({cell:e,current:n,options:t}){const i=e;if(t.snapped){const s=this.draggingBBox;i.position(s.x+t.tx,s.y+t.ty,{silent:!0}),this.draggingView.translate(),i.position(n.x,n.y,{silent:!0}),this.snapOffset={x:t.tx,y:t.ty}}else this.snapOffset=null}onDragging(e){const n=this.draggingView;if(n){e.preventDefault();const t=this.normalizeEvent(e),i=t.clientX,s=t.clientY;this.updateGraphPosition(i,s);const a=this.updateNodePosition(i,s),o=this.targetGraph.options.embedding.enabled,r=(o||this.isSnaplineEnabled())&&this.isInsideValidArea({x:i,y:s});if(o){n.setEventData(t,{graph:this.targetGraph,candidateEmbedView:this.candidateEmbedView});const g=n.getEventData(t);r?n.processEmbedding(t,g):n.clearEmbedding(g),this.candidateEmbedView=g.candidateEmbedView}this.isSnaplineEnabled()&&(r?this.snapline.snapOnMoving({e:t,view:n,x:a.x,y:a.y}):this.snapline.hide())}}onDragEnd(e){const n=this.draggingNode;if(n){const t=this.normalizeEvent(e),i=this.draggingView,s=this.draggingBBox,a=this.snapOffset;let o=s.x,r=s.y;a&&(o+=a.x,r+=a.y),n.position(o,r,{silent:!0});const g=this.drop(n,{x:t.clientX,y:t.clientY}),l=p=>{p?(this.onDropped(n),this.targetGraph.options.embedding.enabled&&i&&(i.setEventData(t,{cell:p,graph:this.targetGraph,candidateEmbedView:this.candidateEmbedView}),i.finalizeEmbedding(t,i.getEventData(t)))):this.onDropInvalid(),this.candidateEmbedView=null,this.targetModel.stopBatch("dnd")};d.FunctionExt.isAsync(g)?(this.undelegateDocumentEvents(),g.then(l)):l(g)}}clearDragging(){this.draggingNode&&(this.sourceNode=null,this.draggingNode.remove(),this.draggingNode=null,this.draggingView=null,this.delta=null,this.padding=null,this.snapOffset=null,this.originOffset=null,this.undelegateDocumentEvents())}onDropped(e){this.draggingNode===e&&(this.clearDragging(),d.Dom.removeClass(this.container,"dragging"),d.Dom.remove(this.container))}onDropInvalid(){const e=this.draggingNode;e&&this.onDropped(e)}isInsideValidArea(e){let n,t=null;const i=this.targetGraph,s=this.targetScroller;this.options.dndContainer&&(t=this.getDropArea(this.options.dndContainer));const a=t&&t.containsPoint(e);if(s)if(s.options.autoResize)n=this.getDropArea(s.container);else{const o=this.getDropArea(s.container);n=this.getDropArea(i.container).intersectsWithRect(o)}else n=this.getDropArea(i.container);return!a&&n&&n.containsPoint(e)}getDropArea(e){const n=d.Dom.offset(e),t=document.body.scrollTop||document.documentElement.scrollTop,i=document.body.scrollLeft||document.documentElement.scrollLeft;return d.Rectangle.create({x:n.left+parseInt(d.Dom.css(e,"border-left-width"),10)-i,y:n.top+parseInt(d.Dom.css(e,"border-top-width"),10)-t,width:e.clientWidth,height:e.clientHeight})}drop(e,n){if(this.isInsideValidArea(n)){const t=this.targetGraph,i=t.model,s=t.clientToLocal(n),a=this.sourceNode,o=this.options.getDropNode(e,{sourceNode:a,draggingNode:e,targetGraph:this.targetGraph,draggingGraph:this.draggingGraph}),r=o.getBBox();s.x+=r.x-r.width/2,s.y+=r.y-r.height/2;const g=this.snapOffset?1:t.getGridSize();o.position(d.GeometryUtil.snapToGrid(s.x,g),d.GeometryUtil.snapToGrid(s.y,g)),o.removeZIndex();const l=this.options.validateNode,p=l?l(o,{sourceNode:a,draggingNode:e,droppingNode:o,targetGraph:t,draggingGraph:this.draggingGraph}):!0;return typeof p=="boolean"?p?(i.addCell(o,{stencil:this.cid}),o):null:d.FunctionExt.toDeferredBoolean(p).then(u=>u?(i.addCell(o,{stencil:this.cid}),o):null)}return null}onRemove(){this.draggingGraph&&(this.draggingGraph.view.remove(),this.draggingGraph.dispose())}dispose(){this.remove(),d.CssLoader.clean(this.name)}}m([d.View.dispose()],c.prototype,"dispose",null);(function(h){h.defaults={getDragNode:e=>e.clone(),getDropNode:e=>e.clone()},h.documentEvents={mousemove:"onDragging",touchmove:"onDragging",mouseup:"onDragEnd",touchend:"onDragEnd",touchcancel:"onDragEnd"}})(c||(c={}));exports.Dnd=c;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { Graph as w, Basecoat as j, DataUri as G, Vector as E, NumberExt as V, Dom as O, Rectangle as C, FunctionExt as N } from "@antv/x6";
|
|
2
|
+
w.prototype.toSVG = function(a, e) {
|
|
3
|
+
const t = this.getPlugin("export");
|
|
4
|
+
t && t.toSVG(a, e);
|
|
5
|
+
};
|
|
6
|
+
w.prototype.toPNG = function(a, e) {
|
|
7
|
+
const t = this.getPlugin("export");
|
|
8
|
+
t && t.toPNG(a, e);
|
|
9
|
+
};
|
|
10
|
+
w.prototype.toJPEG = function(a, e) {
|
|
11
|
+
const t = this.getPlugin("export");
|
|
12
|
+
t && t.toJPEG(a, e);
|
|
13
|
+
};
|
|
14
|
+
w.prototype.exportPNG = function(a, e) {
|
|
15
|
+
const t = this.getPlugin("export");
|
|
16
|
+
t && t.exportPNG(a, e);
|
|
17
|
+
};
|
|
18
|
+
w.prototype.exportJPEG = function(a, e) {
|
|
19
|
+
const t = this.getPlugin("export");
|
|
20
|
+
t && t.exportJPEG(a, e);
|
|
21
|
+
};
|
|
22
|
+
w.prototype.exportSVG = function(a, e) {
|
|
23
|
+
const t = this.getPlugin("export");
|
|
24
|
+
t && t.exportSVG(a, e);
|
|
25
|
+
};
|
|
26
|
+
var U = function(a, e, t, n) {
|
|
27
|
+
var i = arguments.length, s = i < 3 ? e : n === null ? n = Object.getOwnPropertyDescriptor(e, t) : n, f;
|
|
28
|
+
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") s = Reflect.decorate(a, e, t, n);
|
|
29
|
+
else for (var c = a.length - 1; c >= 0; c--) (f = a[c]) && (s = (i < 3 ? f(s) : i > 3 ? f(e, t, s) : f(e, t)) || s);
|
|
30
|
+
return i > 3 && s && Object.defineProperty(e, t, s), s;
|
|
31
|
+
};
|
|
32
|
+
class z extends j {
|
|
33
|
+
constructor() {
|
|
34
|
+
super(), this.name = "export";
|
|
35
|
+
}
|
|
36
|
+
get view() {
|
|
37
|
+
return this.graph.view;
|
|
38
|
+
}
|
|
39
|
+
init(e) {
|
|
40
|
+
this.graph = e;
|
|
41
|
+
}
|
|
42
|
+
exportPNG(e = "chart", t = {}) {
|
|
43
|
+
this.toPNG((n) => {
|
|
44
|
+
G.downloadDataUri(n, e);
|
|
45
|
+
}, t);
|
|
46
|
+
}
|
|
47
|
+
exportJPEG(e = "chart", t = {}) {
|
|
48
|
+
this.toPNG((n) => {
|
|
49
|
+
G.downloadDataUri(n, e);
|
|
50
|
+
}, t);
|
|
51
|
+
}
|
|
52
|
+
exportSVG(e = "chart", t = {}) {
|
|
53
|
+
this.toSVG((n) => {
|
|
54
|
+
G.downloadDataUri(G.svgToDataUrl(n), e);
|
|
55
|
+
}, t);
|
|
56
|
+
}
|
|
57
|
+
toSVG(e, t = {}) {
|
|
58
|
+
this.notify("before:export", t);
|
|
59
|
+
const n = this.view.svg, i = E.create(n).clone();
|
|
60
|
+
let s = i.node;
|
|
61
|
+
const f = i.findOne(`.${this.view.prefixClassName("graph-svg-stage")}`), c = t.viewBox || this.graph.graphToLocal(this.graph.getContentBBox()), h = t.preserveDimensions;
|
|
62
|
+
if (h) {
|
|
63
|
+
const o = typeof h == "boolean" ? c : h;
|
|
64
|
+
i.attr({
|
|
65
|
+
width: o.width,
|
|
66
|
+
height: o.height
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
if (i.removeAttribute("style").attr("viewBox", [c.x, c.y, c.width, c.height].join(" ")), f.removeAttribute("transform"), t.copyStyles !== !1) {
|
|
70
|
+
const o = n.ownerDocument, g = Array.from(n.querySelectorAll("*")), d = Array.from(s.querySelectorAll("*")), u = o.styleSheets.length, P = [];
|
|
71
|
+
for (let r = u - 1; r >= 0; r -= 1)
|
|
72
|
+
P[r] = o.styleSheets[r], o.styleSheets[r].disabled = !0;
|
|
73
|
+
const x = {};
|
|
74
|
+
g.forEach((r, m) => {
|
|
75
|
+
const y = window.getComputedStyle(r, null), v = {};
|
|
76
|
+
Object.keys(y).forEach((S) => {
|
|
77
|
+
v[S] = y.getPropertyValue(S);
|
|
78
|
+
}), x[m] = v;
|
|
79
|
+
}), u !== o.styleSheets.length && P.forEach((r, m) => {
|
|
80
|
+
o.styleSheets[m] = r;
|
|
81
|
+
});
|
|
82
|
+
for (let r = 0; r < u; r += 1)
|
|
83
|
+
o.styleSheets[r].disabled = !1;
|
|
84
|
+
const D = {};
|
|
85
|
+
g.forEach((r, m) => {
|
|
86
|
+
const y = window.getComputedStyle(r, null), v = x[m], S = {};
|
|
87
|
+
Object.keys(y).forEach((b) => {
|
|
88
|
+
!V.isNumber(b) && y.getPropertyValue(b) !== v[b] && (S[b] = y.getPropertyValue(b));
|
|
89
|
+
}), D[m] = S;
|
|
90
|
+
}), d.forEach((r, m) => {
|
|
91
|
+
O.css(r, D[m]);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const p = t.stylesheet;
|
|
95
|
+
if (typeof p == "string") {
|
|
96
|
+
const o = n.ownerDocument.implementation.createDocument(null, "xml", null).createCDATASection(p);
|
|
97
|
+
i.prepend(E.create("style", {
|
|
98
|
+
type: "text/css"
|
|
99
|
+
}, [o]));
|
|
100
|
+
}
|
|
101
|
+
const l = () => {
|
|
102
|
+
const o = t.beforeSerialize;
|
|
103
|
+
if (typeof o == "function") {
|
|
104
|
+
const d = N.call(o, this.graph, s);
|
|
105
|
+
d instanceof SVGSVGElement && (s = d);
|
|
106
|
+
}
|
|
107
|
+
const g = new XMLSerializer().serializeToString(s).replace(/ /g, " ");
|
|
108
|
+
this.notify("after:export", t), e(g);
|
|
109
|
+
};
|
|
110
|
+
if (t.serializeImages) {
|
|
111
|
+
const o = i.find("image").map((g) => new Promise((d) => {
|
|
112
|
+
const u = g.attr("xlink:href") || g.attr("href");
|
|
113
|
+
G.imageToDataUri(u, (P, x) => {
|
|
114
|
+
!P && x && g.attr("xlink:href", x), d();
|
|
115
|
+
});
|
|
116
|
+
}));
|
|
117
|
+
Promise.all(o).then(l);
|
|
118
|
+
} else
|
|
119
|
+
l();
|
|
120
|
+
}
|
|
121
|
+
toDataURL(e, t) {
|
|
122
|
+
let n = t.viewBox || this.graph.getContentBBox();
|
|
123
|
+
const i = V.normalizeSides(t.padding);
|
|
124
|
+
t.width && t.height && (i.left + i.right >= t.width && (i.left = i.right = 0), i.top + i.bottom >= t.height && (i.top = i.bottom = 0));
|
|
125
|
+
const s = new C(-i.left, -i.top, i.left + i.right, i.top + i.bottom);
|
|
126
|
+
if (t.width && t.height) {
|
|
127
|
+
const l = n.width + i.left + i.right, o = n.height + i.top + i.bottom;
|
|
128
|
+
s.scale(l / t.width, o / t.height);
|
|
129
|
+
}
|
|
130
|
+
n = C.create(n).moveAndExpand(s);
|
|
131
|
+
const f = typeof t.width == "number" && typeof t.height == "number" ? { width: t.width, height: t.height } : n;
|
|
132
|
+
let c = t.ratio ? parseFloat(t.ratio) : 1;
|
|
133
|
+
(!Number.isFinite(c) || c === 0) && (c = 1);
|
|
134
|
+
const h = {
|
|
135
|
+
width: Math.max(Math.round(f.width * c), 1),
|
|
136
|
+
height: Math.max(Math.round(f.height * c), 1)
|
|
137
|
+
};
|
|
138
|
+
{
|
|
139
|
+
const l = document.createElement("canvas"), o = l.getContext("2d");
|
|
140
|
+
l.width = h.width, l.height = h.height;
|
|
141
|
+
const g = h.width - 1, d = h.height - 1;
|
|
142
|
+
o.fillStyle = "rgb(1,1,1)", o.fillRect(g, d, 1, 1);
|
|
143
|
+
const u = o.getImageData(g, d, 1, 1).data;
|
|
144
|
+
if (u[0] !== 1 || u[1] !== 1 || u[2] !== 1)
|
|
145
|
+
throw new Error("size exceeded");
|
|
146
|
+
}
|
|
147
|
+
const p = new Image();
|
|
148
|
+
p.onload = () => {
|
|
149
|
+
const l = document.createElement("canvas");
|
|
150
|
+
l.width = h.width, l.height = h.height;
|
|
151
|
+
const o = l.getContext("2d");
|
|
152
|
+
o.fillStyle = t.backgroundColor || "white", o.fillRect(0, 0, h.width, h.height);
|
|
153
|
+
try {
|
|
154
|
+
o.drawImage(p, 0, 0, h.width, h.height);
|
|
155
|
+
const g = l.toDataURL(t.type, t.quality);
|
|
156
|
+
e(g);
|
|
157
|
+
} catch {
|
|
158
|
+
}
|
|
159
|
+
}, this.toSVG((l) => {
|
|
160
|
+
p.src = `data:image/svg+xml,${encodeURIComponent(l)}`;
|
|
161
|
+
}, Object.assign(Object.assign({}, t), { viewBox: n, serializeImages: !0, preserveDimensions: Object.assign({}, h) }));
|
|
162
|
+
}
|
|
163
|
+
toPNG(e, t = {}) {
|
|
164
|
+
this.toDataURL(e, Object.assign(Object.assign({}, t), { type: "image/png" }));
|
|
165
|
+
}
|
|
166
|
+
toJPEG(e, t = {}) {
|
|
167
|
+
this.toDataURL(e, Object.assign(Object.assign({}, t), { type: "image/jpeg" }));
|
|
168
|
+
}
|
|
169
|
+
notify(e, t) {
|
|
170
|
+
this.trigger(e, t), this.graph.trigger(e, t);
|
|
171
|
+
}
|
|
172
|
+
dispose() {
|
|
173
|
+
this.off();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
U([
|
|
177
|
+
j.dispose()
|
|
178
|
+
], z.prototype, "dispose", null);
|
|
179
|
+
export {
|
|
180
|
+
z as Export
|
|
181
|
+
};
|