@ichooss/xflow
Version:
[English (US)](README.md) | 简体中文
1,431 lines (1,391 loc) • 41.9 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
// ../../node_modules/.pnpm/classnames@2.3.2/node_modules/classnames/index.js
var require_classnames = __commonJS({
"../../node_modules/.pnpm/classnames@2.3.2/node_modules/classnames/index.js"(exports, module2) {
(function() {
"use strict";
var hasOwn = {}.hasOwnProperty;
var nativeCodeString = "[native code]";
function classNames2() {
var classes = [];
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
if (!arg)
continue;
var argType = typeof arg;
if (argType === "string" || argType === "number") {
classes.push(arg);
} else if (Array.isArray(arg)) {
if (arg.length) {
var inner = classNames2.apply(null, arg);
if (inner) {
classes.push(inner);
}
}
} else if (argType === "object") {
if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes("[native code]")) {
classes.push(arg.toString());
continue;
}
for (var key in arg) {
if (hasOwn.call(arg, key) && arg[key]) {
classes.push(key);
}
}
}
}
return classes.join(" ");
}
if (typeof module2 !== "undefined" && module2.exports) {
classNames2.default = classNames2;
module2.exports = classNames2;
} else if (typeof define === "function" && typeof define.amd === "object" && define.amd) {
define("classnames", [], function() {
return classNames2;
});
} else {
window.classNames = classNames2;
}
})();
}
});
// src/index.ts
var src_exports = {};
__export(src_exports, {
Background: () => Background,
Clipboard: () => Clipboard,
Control: () => Control,
ControlEnum: () => ControlEnum,
Dom: () => import_x66.Dom,
Edge: () => import_x66.Edge,
Graph: () => import_x66.Graph,
Grid: () => Grid,
History: () => History,
Line: () => import_x66.Line,
Markup: () => import_x66.Markup,
Minimap: () => Minimap,
Path: () => import_x66.Path,
Point: () => import_x66.Point,
Polyline: () => import_x66.Polyline,
Rectangle: () => import_x66.Rectangle,
Snapline: () => Snapline,
Transform: () => Transform,
Vector: () => import_x66.Vector,
Wrapper: () => Wrapper,
XFlow: () => XFlow,
XFlowGraph: () => XFlowGraph,
apply: () => apply,
flatten: () => flatten,
getSubGraph: () => getSubGraph,
getSuperGraph: () => getSuperGraph,
useClipboard: () => useClipboard,
useDnd: () => useDnd,
useExport: () => useExport,
useGraphEvent: () => useGraphEvent,
useGraphInstance: () => useGraphInstance,
useGraphStore: () => useGraphStore,
useHistory: () => useHistory,
useKeyboard: () => useKeyboard
});
module.exports = __toCommonJS(src_exports);
var import_x66 = require("@antv/x6");
// src/components/Wrapper.tsx
var import_react3 = __toESM(require("react"));
// src/hooks/useGraphInstance.ts
var import_react2 = require("react");
// src/context/GraphContext.tsx
var import_react = __toESM(require("react"));
var GraphContext = (0, import_react.createContext)({
graph: null,
setGraph: () => {
}
});
var GraphProvider = ({ children }) => {
const [graph, setGraph] = (0, import_react.useState)(null);
return /* @__PURE__ */ import_react.default.createElement(GraphContext.Provider, { value: { graph, setGraph } }, children);
};
// src/hooks/useGraphInstance.ts
var useGraphInstance = () => {
const { graph } = (0, import_react2.useContext)(GraphContext);
return graph;
};
// src/components/Wrapper.tsx
var Wrapper = ({ children }) => {
const graph = useGraphInstance();
if (graph) {
return /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, children);
}
return null;
};
// src/components/XFlow.tsx
var import_react5 = __toESM(require("react"));
// src/context/StoreContext.tsx
var import_react4 = __toESM(require("react"));
// src/store/index.ts
var import_immer = require("immer");
var import_zustand = require("zustand");
// src/util/algorithm.ts
var getSuperGraph = (graph, nodeId, nodeIds = []) => {
nodeIds.push(nodeId);
const incomingEdges = graph.getIncomingEdges(nodeId);
incomingEdges?.forEach((edge) => {
const source = edge.getSourceCellId();
getSuperGraph(graph, source, nodeIds);
});
return nodeIds;
};
var getSubGraph = (graph, nodeId, nodeIds = []) => {
nodeIds.push(nodeId);
const outgoingEdges = graph.getOutgoingEdges(nodeId);
outgoingEdges?.forEach((edge) => {
const target = edge.getTargetCellId();
getSubGraph(graph, target, nodeIds);
});
return nodeIds;
};
// src/util/object.ts
var import_x6 = require("@antv/x6");
function apply(target, patchItem) {
if (typeof patchItem !== "object" || Array.isArray(patchItem) || !patchItem) {
return JSON.parse(JSON.stringify(patchItem));
}
if (typeof patchItem === "object" && patchItem.toJSON !== void 0 && typeof patchItem.toJSON === "function") {
return patchItem.toJSON();
}
let targetResult = target;
if (typeof target !== "object") {
targetResult = { ...patchItem };
}
Object.keys(patchItem).forEach((k) => {
if (!Object.prototype.hasOwnProperty.call(targetResult, k))
targetResult[k] = patchItem[k];
if (patchItem[k] === null) {
delete targetResult[k];
} else if (targetResult[k] !== null && targetResult[k] !== void 0) {
targetResult[k] = apply(targetResult[k], patchItem[k]);
}
});
return targetResult;
}
function flatten(obj, delim = "/", stop) {
const ret = {};
Object.keys(obj).forEach((key) => {
const val = obj[key];
let deep = import_x6.ObjectExt.isPlainObject(val);
if (deep && stop && stop(val)) {
deep = false;
}
if (deep) {
const flatObject = flatten(val, delim, stop);
Object.keys(flatObject).forEach((flatKey) => {
ret[key + delim + flatKey] = flatObject[flatKey];
});
} else {
ret[key] = val;
}
});
for (const key in obj) {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
continue;
}
}
return ret;
}
// src/store/index.ts
var import_x62 = require("@antv/x6");
var createGraphStore = () => {
return (0, import_zustand.create)((set) => ({
nodes: [],
edges: [],
changeList: [],
initData: (data, options) => set(
(0, import_immer.produce)((state) => {
state.nodes = data.nodes;
state.edges = data.edges;
if (!options?.silent) {
state.changeList.push({
command: "init",
data
});
}
})
),
addNodes: (ns, options) => set(
(0, import_immer.produce)((state) => {
if (!ns.length)
return;
ns.forEach((n) => {
if (!n.id) {
n.id = import_x62.StringExt.uuid();
}
});
const duplicated = state.nodes.find(
(n) => ns.some((m) => m.id && m.id === n.id)
);
if (!duplicated) {
state.nodes.push(...ns);
if (!options?.silent) {
state.changeList.push({
command: "addNodes",
data: ns
});
}
} else {
console.error(`node id=${duplicated.id} already existed`);
}
})
),
removeNodes: (ids, options) => set(
(0, import_immer.produce)((state) => {
if (!ids.length)
return;
state.nodes = state.nodes.filter((n) => !ids.includes(n.id));
if (!options?.silent) {
state.changeList.push({
command: "removeNodes",
data: ids
});
}
})
),
updateNode: (id, data, options) => set(
(0, import_immer.produce)((state) => {
const node = state.nodes.find((n) => n.id === id);
if (node) {
const changed = typeof data === "function" ? data((0, import_immer.original)(node) || {}) : data;
if (changed.id !== void 0 || changed.shape !== void 0) {
console.error(`id and shape can't be changed`);
return;
}
apply(node, changed);
if (!options?.silent) {
state.changeList.push({
command: "updateNode",
data: { id, data: changed }
});
}
}
})
),
addEdges: (es, options) => set(
(0, import_immer.produce)((state) => {
if (!es.length)
return;
es.forEach((e) => {
if (!e.id) {
e.id = import_x62.StringExt.uuid();
}
});
const duplicated = state.edges.find(
(e) => es.some((m) => m.id && m.id === e.id)
);
if (!duplicated) {
state.edges.push(...es);
if (!options?.silent) {
state.changeList.push({
command: "addEdges",
data: es
});
}
} else {
console.error(`edge id=${duplicated.id} already existed`);
}
})
),
removeEdges: (ids, options) => set(
(0, import_immer.produce)((state) => {
if (!ids.length)
return;
state.edges = state.edges.filter((n) => !ids.includes(n.id));
if (!options?.silent) {
state.changeList.push({
command: "removeEdges",
data: ids
});
}
})
),
updateEdge: (id, data, options) => set(
(0, import_immer.produce)((state) => {
const edge = state.edges.find((n) => n.id === id);
if (edge) {
const changed = typeof data === "function" ? data((0, import_immer.original)(edge) || {}) : data;
if (changed.id !== void 0 || changed.shape !== void 0) {
console.error(`id and shape can't be changed`);
return;
}
apply(edge, changed);
if (!options?.silent) {
state.changeList.push({
command: "updateEdge",
data: { id, data: changed }
});
}
}
})
),
clearChangeList: () => set(
(0, import_immer.produce)((state) => {
state.changeList = [];
})
)
}));
};
// src/context/StoreContext.tsx
var StoreContext = (0, import_react4.createContext)(null);
var StoreProvider = ({ children }) => {
const storeRef = (0, import_react4.useRef)();
if (!storeRef.current) {
storeRef.current = createGraphStore();
}
return /* @__PURE__ */ import_react4.default.createElement(StoreContext.Provider, { value: storeRef.current }, children);
};
// src/components/XFlow.tsx
var import_styles = require("./index-5FC5FO7Q.less");
var XFlow = ({ children }) => {
return /* @__PURE__ */ import_react5.default.createElement(StoreProvider, null, /* @__PURE__ */ import_react5.default.createElement(GraphProvider, null, children));
};
// src/components/Graph.tsx
var import_x64 = require("@antv/x6");
var import_x6_plugin_keyboard = require("@antv/x6-plugin-keyboard");
var import_x6_plugin_scroller = require("@antv/x6-plugin-scroller");
var import_x6_plugin_selection = require("@antv/x6-plugin-selection");
var import_react16 = __toESM(require("react"));
// src/components/State.tsx
var import_x63 = require("@antv/x6");
var import_react15 = require("react");
// src/hooks/useGraphStore.ts
var import_react6 = require("react");
var import_zustand2 = require("zustand");
var useGraphStore = (selector) => {
const store = (0, import_react6.useContext)(StoreContext);
if (!store) {
throw new Error("can only be get inside the xflow component.");
}
return (0, import_zustand2.useStore)(store, selector);
};
// src/hooks/useGraphEvent.ts
var import_react8 = require("react");
// src/hooks/useLatest.ts
var import_react7 = require("react");
function useLatest(value) {
const ref = (0, import_react7.useRef)(value);
ref.current = value;
return ref;
}
// src/hooks/useGraphEvent.ts
var useGraphEvent = (name, callback) => {
const cbRef = useLatest(callback);
const graph = useGraphInstance();
(0, import_react8.useEffect)(() => {
if (graph) {
cbRef.current = callback;
graph.on(name, (args) => {
cbRef.current(args);
});
}
return () => {
if (graph && cbRef.current) {
graph.off(name, cbRef.current);
}
};
}, [graph]);
};
// src/hooks/useDnd.ts
var import_x6_plugin_dnd = require("@antv/x6-plugin-dnd");
var import_react9 = require("react");
var useDnd = (options) => {
const graph = useGraphInstance();
const ref = (0, import_react9.useRef)();
(0, import_react9.useEffect)(() => {
if (graph && !ref.current) {
ref.current = new import_x6_plugin_dnd.Dnd({
target: graph,
getDragNode: (node) => node.clone({ keepId: true }),
getDropNode: (node) => node.clone({ keepId: true }),
...options
});
}
}, [graph]);
const startDrag = (0, import_react9.useCallback)(
(n, e) => {
if (graph && ref.current) {
e.persist();
ref.current.start(graph.createNode(n), e.nativeEvent);
}
},
[graph]
);
return { startDrag };
};
// src/hooks/useClipboard.ts
var import_react11 = require("react");
// src/hooks/useLoaded.ts
var import_react10 = require("react");
var useLoaded = (name) => {
const graph = useGraphInstance();
const isLoaded = (0, import_react10.useCallback)(
(cb) => {
if (!graph) {
console.warn("graph can only be get inside the xflow component.");
return false;
}
const plugin = graph.getPlugin(name);
if (!plugin) {
if (cb) {
return cb();
}
console.warn(`${name} is not loaded, please use ${name} component first.`);
return false;
}
return true;
},
[graph, name]
);
return {
isLoaded
};
};
// src/hooks/useClipboard.ts
var useClipboard = () => {
const graph = useGraphInstance();
const { isLoaded } = useLoaded("clipboard");
const copy = (0, import_react11.useCallback)(
(ids, copyOptions) => {
if (isLoaded() && graph) {
const cells = ids.map((id) => graph?.getCellById(id)).filter(Boolean);
graph.copy(cells, copyOptions);
}
},
[graph, isLoaded]
);
const cut = (0, import_react11.useCallback)(
(ids, cutOptions) => {
if (isLoaded() && graph) {
const cells = ids.map((id) => graph?.getCellById(id)).filter(Boolean);
graph.cut(cells, cutOptions);
}
},
[graph, isLoaded]
);
const paste = (0, import_react11.useCallback)(
(pasteOptions) => {
if (isLoaded() && graph) {
const cells = graph.paste(pasteOptions);
return cells;
}
return [];
},
[graph, isLoaded]
);
return { copy, cut, paste };
};
// src/hooks/useExport.ts
var import_x6_plugin_export = require("@antv/x6-plugin-export");
var import_react12 = require("react");
var useExport = () => {
const graph = useGraphInstance();
const { isLoaded } = useLoaded("export");
const ensure = (0, import_react12.useCallback)(() => {
return isLoaded(() => {
graph?.use(new import_x6_plugin_export.Export());
return true;
});
}, [graph, isLoaded]);
const exportPNG = (0, import_react12.useCallback)(
(fileName = "chart", options = {}) => {
if (ensure() && graph) {
graph.exportPNG(fileName, options);
}
},
[graph, ensure]
);
const exportJPEG = (0, import_react12.useCallback)(
(fileName = "chart", options = {}) => {
if (ensure() && graph) {
graph.exportJPEG(fileName, options);
}
},
[graph, ensure]
);
const exportSVG = (0, import_react12.useCallback)(
(fileName = "chart", options = {}) => {
if (ensure() && graph) {
graph.exportSVG(fileName, options);
}
},
[graph, ensure]
);
return { exportPNG, exportJPEG, exportSVG };
};
// src/hooks/useHistory.ts
var import_react13 = require("react");
var useHistory = () => {
const graph = useGraphInstance();
const { isLoaded } = useLoaded("history");
const [canUndo, setCanUndo] = (0, import_react13.useState)(false);
const [canRedo, setCanRedo] = (0, import_react13.useState)(false);
const undo = (0, import_react13.useCallback)(
(options) => {
if (isLoaded() && graph) {
return graph.undo(options);
}
return null;
},
[graph, isLoaded]
);
const redo = (0, import_react13.useCallback)(
(options) => {
if (isLoaded() && graph) {
return graph.redo(options);
}
return null;
},
[graph, isLoaded]
);
useGraphEvent("history:change", () => {
if (graph) {
setCanUndo(graph.canUndo());
setCanRedo(graph.canRedo());
}
});
return { undo, redo, canUndo, canRedo };
};
// src/hooks/useKeyboard.ts
var import_react14 = require("react");
var useKeyboard = (key, callback, action) => {
const cbRef = useLatest(callback);
const graph = useGraphInstance();
(0, import_react14.useEffect)(() => {
if (graph) {
cbRef.current = callback;
graph.bindKey(
key,
(e) => {
cbRef.current(e);
},
action
);
}
return () => {
if (graph) {
graph.unbindKey(key);
}
};
}, [graph]);
};
// src/components/State.tsx
var INNER_CALL = "__inner__";
var preprocess = (key, value, graph) => {
if (key === "position") {
const { x, y } = import_x63.Point.create(value).snapToGrid(graph.getGridSize());
return {
position: {
x,
y
}
};
}
if (key === "size") {
return {
size: {
width: value.width,
height: value.height
}
};
}
return {
[key]: value
};
};
var XFlowState = (props) => {
const { centerView, centerViewOptions, fitView, fitViewOptions } = props;
const graph = useGraphInstance();
const updateNode = useGraphStore((state) => state.updateNode);
const updateEdge = useGraphStore((state) => state.updateEdge);
const addNodes = useGraphStore((state) => state.addNodes);
const addEdges = useGraphStore((state) => state.addEdges);
const removeNodes = useGraphStore((state) => state.removeNodes);
const removeEdges = useGraphStore((state) => state.removeEdges);
const changeList = useGraphStore((state) => state.changeList);
const clearChangeList = useGraphStore((state) => state.clearChangeList);
const changeSelectionStatus = (status) => {
if (graph) {
const added = status.filter((item) => item.selected);
const removed = status.filter((item) => !item.selected);
graph.select(
added.map((item) => item.id),
{ [INNER_CALL]: true }
);
graph.unselect(
removed.map((item) => item.id),
{ [INNER_CALL]: true }
);
}
};
const changeAnimatedStatus = (status) => {
if (graph) {
status.forEach((item) => {
const cell = graph.getCellById(item.id);
if (cell) {
if (item.animated) {
let strokeDasharray = 5;
let animation = "animated-line 30s infinite linear";
if (typeof item.animated !== "boolean") {
if (item.animated.strokeDasharray)
strokeDasharray = item.animated.strokeDasharray;
if (item.animated.animation)
animation = item.animated.animation;
}
cell.attr("line/strokeDasharray", strokeDasharray, { [INNER_CALL]: true });
cell.attr("line/style/animation", animation, {
[INNER_CALL]: true
});
} else {
cell.attr("line/strokeDasharray", 0, { [INNER_CALL]: true });
cell.attr("line/style/animation", "", { [INNER_CALL]: true });
}
}
});
}
};
const initData = (g, data) => {
g.fromJSON(import_x63.ObjectExt.cloneDeep(data));
if (centerView) {
g.centerContent(centerViewOptions);
}
if (fitView) {
g.zoomToFit({ maxScale: 1, ...fitViewOptions });
}
const { nodes, edges } = data;
changeSelectionStatus([...nodes, ...edges]);
changeAnimatedStatus([...edges]);
};
const onSpecialPropChange = (id, data) => {
if (graph) {
const keys = Object.keys(data);
if (keys.includes("selected")) {
const selected = !!data.selected;
changeSelectionStatus([{ id, selected }]);
} else if (keys.includes("animated")) {
const animated = !!data.animated;
changeAnimatedStatus([{ id, animated }]);
}
}
};
const onPropChange = (id, data, batchName) => {
if (graph) {
const cell = graph.getCellById(id);
if (cell) {
graph.startBatch(batchName);
const changed = cell.preprocess(data, true);
const properties = flatten(changed);
Object.keys(properties).forEach((key) => {
cell.setPropByPath(key, properties[key], {
[INNER_CALL]: true,
rewrite: true
});
});
onSpecialPropChange(id, data);
graph.stopBatch(batchName);
}
}
};
const handleGraphChange = (g, changes) => {
changes.forEach((changeItem) => {
const { command, data } = changeItem;
switch (command) {
case "init":
initData(g, data);
break;
case "addNodes":
const nodes = import_x63.ObjectExt.cloneDeep(data);
g.addNodes(nodes, { [INNER_CALL]: true });
changeSelectionStatus(nodes);
break;
case "removeNodes":
g.removeCells(data, { [INNER_CALL]: true });
break;
case "updateNode":
onPropChange(data.id, data.data, "updateNode");
break;
case "addEdges":
const edges = import_x63.ObjectExt.cloneDeep(data);
g.addEdges(edges, { [INNER_CALL]: true });
changeSelectionStatus(edges);
changeAnimatedStatus(edges);
break;
case "removeEdges":
g.removeCells(data, { [INNER_CALL]: true });
break;
case "updateEdge":
onPropChange(data.id, data.data, "updateEdge");
break;
default:
break;
}
});
clearChangeList();
};
(0, import_react15.useEffect)(() => {
if (graph && changeList.length) {
handleGraphChange(graph, changeList);
}
}, [changeList, graph]);
useGraphEvent("cell:added", ({ cell, options }) => {
if (!options[INNER_CALL]) {
if (cell.isNode()) {
const nodes = [cell.toJSON()];
addNodes(nodes, { silent: true });
changeSelectionStatus(nodes);
} else if (cell.isEdge()) {
const edges = [cell.toJSON()];
addEdges(edges, { silent: true });
changeSelectionStatus(edges);
changeAnimatedStatus(edges);
}
}
});
useGraphEvent("cell:removed", ({ cell, options }) => {
if (!options[INNER_CALL]) {
if (cell.isNode()) {
removeNodes([cell.id], { silent: true });
} else if (cell.isEdge()) {
removeEdges([cell.id], { silent: true });
}
}
});
useGraphEvent(
"cell:change:*",
import_x63.FunctionExt.debounce(
({ cell, key, current, options }) => {
if (!options[INNER_CALL] && graph) {
if (cell.isNode()) {
updateNode(cell.id, preprocess(key, current, graph), { silent: true });
} else if (cell.isEdge()) {
updateEdge(cell.id, { [key]: current }, { silent: true });
}
}
},
100
)
);
useGraphEvent("selection:changed", ({ added, removed, options }) => {
if (!options[INNER_CALL]) {
added.forEach((item) => {
if (item.isNode()) {
updateNode(item.id, { selected: true }, { silent: true });
} else if (item.isEdge()) {
updateEdge(item.id, { selected: true }, { silent: true });
}
});
removed.forEach((item) => {
if (item.isNode()) {
updateNode(item.id, { selected: false }, { silent: true });
} else if (item.isEdge()) {
updateEdge(item.id, { selected: false }, { silent: true });
}
});
}
});
return null;
};
// src/components/Graph.tsx
var XFlowGraph = (props) => {
const container = (0, import_react16.useRef)(null);
const {
className,
style,
readonly,
virtual,
minScale,
maxScale,
zoomable,
zoomOptions,
pannable,
panOptions,
embedable,
embedOptions,
restrict,
restrictOptions,
connectionOptions,
selectOptions,
keyboardOptions,
scroller,
scrollerOptions,
connectionEdgeOptions,
defaultHighlightOptions,
embedHighlightOptions,
nodeAvailableHighlightOptions,
magnetAvailableHighlightOptions,
magnetAdsorbedHighlightOptions,
onEdgeLabelRendered
} = props;
const { graph, setGraph } = (0, import_react16.useContext)(GraphContext);
(0, import_react16.useEffect)(() => {
const g = new import_x64.Graph({
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
container: container.current,
autoResize: true,
virtual,
scaling: {
min: minScale,
max: maxScale
},
connecting: {
...connectionOptions,
createEdge: connectionOptions?.createEdge || function() {
return this.createEdge({
shape: "edge",
...connectionEdgeOptions
});
}
},
highlighting: {
default: defaultHighlightOptions,
embedding: embedHighlightOptions,
nodeAvailable: nodeAvailableHighlightOptions,
magnetAvailable: magnetAvailableHighlightOptions,
magnetAdsorbed: magnetAdsorbedHighlightOptions
},
onEdgeLabelRendered
});
g.use(new import_x6_plugin_selection.Selection({ enabled: true, ...selectOptions }));
g.use(new import_x6_plugin_keyboard.Keyboard({ enabled: true, ...keyboardOptions }));
if (scroller) {
g.use(new import_x6_plugin_scroller.Scroller({ enabled: true, ...scrollerOptions }));
}
setGraph(g);
return () => {
if (g) {
g.dispose();
setGraph(null);
}
};
}, []);
(0, import_react16.useEffect)(() => {
if (graph) {
if (readonly) {
graph.options.interacting = false;
} else {
graph.options.interacting = {
nodeMovable: (view) => {
const cell = view.cell;
return cell.prop("draggable") !== false;
},
edgeMovable: (view) => {
const cell = view.cell;
return cell.prop("draggable") !== false;
}
};
}
}
}, [graph, readonly]);
(0, import_react16.useEffect)(() => {
if (graph) {
if (zoomable) {
graph.enableMouseWheel();
graph.options.mousewheel = {
...import_x64.Options.defaults.mousewheel,
...zoomOptions,
enabled: true
};
} else {
graph.disableMouseWheel();
}
}
}, [graph, zoomable, zoomOptions]);
(0, import_react16.useEffect)(() => {
if (graph) {
if (pannable) {
graph.options.panning = {
...import_x64.Options.defaults.panning,
enabled: true,
...panOptions
};
graph.enablePanning();
} else {
graph.disablePanning();
}
}
}, [graph, pannable, panOptions]);
(0, import_react16.useEffect)(() => {
if (graph) {
if (embedable) {
graph.options.embedding = {
...import_x64.Options.defaults.embedding,
enabled: true,
validate: () => true,
...embedOptions
};
} else {
graph.options.embedding = { enabled: false, validate: () => false };
}
}
}, [graph, embedable, embedOptions]);
(0, import_react16.useEffect)(() => {
if (graph) {
if (restrict) {
graph.options.translating = {
restrict: restrictOptions ? restrictOptions.bound : restrict
};
} else {
graph.options.translating = { restrict: false };
}
}
}, [graph, restrict, restrictOptions]);
return /* @__PURE__ */ import_react16.default.createElement("div", { style: { width: "100%", height: "100%", ...style }, className }, /* @__PURE__ */ import_react16.default.createElement("div", { ref: container, style: { width: "100%", height: "100%" } }), /* @__PURE__ */ import_react16.default.createElement(Wrapper, null, /* @__PURE__ */ import_react16.default.createElement(
XFlowState,
{
connectionEdgeOptions,
centerView: props.centerView,
centerViewOptions: props.centerViewOptions,
fitView: props.fitView,
fitViewOptions: props.fitViewOptions
}
)));
};
// src/components/Grid.tsx
var import_react17 = require("react");
var Grid = (props) => {
const graph = useGraphInstance();
const { visible, size, type, options } = props;
(0, import_react17.useEffect)(() => {
if (graph) {
graph.clearGrid();
graph.drawGrid({
type,
...options
});
graph.showGrid();
}
}, [graph, type, options]);
(0, import_react17.useEffect)(() => {
if (graph) {
if (visible === false) {
graph.hideGrid();
} else {
graph.showGrid();
}
}
}, [graph, visible]);
(0, import_react17.useEffect)(() => {
if (graph) {
if (size) {
graph.setGridSize(size);
}
}
}, [graph, size]);
return null;
};
// src/components/Background.tsx
var import_react18 = require("react");
var Background = (props) => {
const graph = useGraphInstance();
(0, import_react18.useEffect)(() => {
if (graph) {
graph.clearBackground();
graph.drawBackground(props);
}
}, [graph, props]);
return null;
};
// src/components/Clipboard.tsx
var import_x6_plugin_clipboard = require("@antv/x6-plugin-clipboard");
var import_react19 = require("react");
var Clipboard = (props) => {
const graph = useGraphInstance();
(0, import_react19.useEffect)(() => {
if (graph) {
if (graph.getPlugin("clipboard")) {
graph.disposePlugins("clipboard");
}
graph.use(
new import_x6_plugin_clipboard.Clipboard({
enabled: true,
...props
})
);
}
}, [graph, props]);
return null;
};
// src/components/History.tsx
var import_x6_plugin_history = require("@antv/x6-plugin-history");
var import_react20 = require("react");
var History = (props) => {
const graph = useGraphInstance();
(0, import_react20.useEffect)(() => {
if (graph) {
if (graph.getPlugin("history")) {
graph.disposePlugins("history");
}
graph.use(
new import_x6_plugin_history.History({
enabled: true,
...props
})
);
}
}, [graph, props]);
return null;
};
// src/components/Minimap.tsx
var import_x65 = require("@antv/x6");
var import_x6_plugin_minimap = require("@antv/x6-plugin-minimap");
var import_react21 = __toESM(require("react"));
var _SimpleNodeView = class extends import_x65.NodeView {
renderMarkup() {
const tag = this.cell.shape === "circle" ? "circle" : "rect";
return this.renderJSONMarkup({
tagName: tag,
selector: "body"
});
}
update() {
super.update({
body: {
refWidth: "100%",
refHeight: "100%",
fill: _SimpleNodeView.nodeBackground
}
});
}
};
var SimpleNodeView = _SimpleNodeView;
__publicField(SimpleNodeView, "nodeBackground", "#8f8f8f");
var Minimap = (props) => {
const { style, className, simple, simpleNodeBackground, ...others } = props;
const ref = (0, import_react21.useRef)(null);
const graph = useGraphInstance();
(0, import_react21.useEffect)(() => {
if (graph && ref.current) {
if (graph.getPlugin("minimap")) {
graph.disposePlugins("minimap");
}
SimpleNodeView.nodeBackground = simpleNodeBackground || SimpleNodeView.nodeBackground;
graph.use(
new import_x6_plugin_minimap.MiniMap({
container: ref.current,
width: 200,
height: 160,
padding: 10,
graphOptions: simple ? {
createCellView(cell) {
if (cell.isEdge()) {
return null;
}
if (cell.isNode()) {
return SimpleNodeView;
}
return void 0;
}
} : void 0,
...others
})
);
}
}, [graph, others]);
return /* @__PURE__ */ import_react21.default.createElement("div", { ref, style: { ...style }, className });
};
// src/components/Snapline.tsx
var import_x6_plugin_snapline = require("@antv/x6-plugin-snapline");
var import_react22 = require("react");
var Snapline = (props) => {
const graph = useGraphInstance();
(0, import_react22.useEffect)(() => {
if (graph) {
if (graph.getPlugin("snapline")) {
graph.disposePlugins("snapline");
}
graph.use(
new import_x6_plugin_snapline.Snapline({
enabled: true,
...props
})
);
}
}, [graph, props]);
return null;
};
// src/components/Transform.tsx
var import_x6_plugin_transform = require("@antv/x6-plugin-transform");
var import_react23 = require("react");
var Transform = (props) => {
const graph = useGraphInstance();
const { resizing, rotating } = props;
const parseOptions = (options) => {
if (typeof options === "boolean") {
return options;
}
if (typeof options === "object") {
return {
enabled: true,
...options
};
}
return false;
};
(0, import_react23.useEffect)(() => {
if (graph) {
if (graph.getPlugin("transform")) {
graph.disposePlugins("transform");
}
graph.use(
new import_x6_plugin_transform.Transform({
resizing: parseOptions(resizing),
rotating: parseOptions(rotating)
})
);
}
}, [graph, resizing, rotating]);
return null;
};
// src/components/Control.tsx
var import_react24 = __toESM(require("@tippyjs/react"));
var import_classnames = __toESM(require_classnames());
var import_lucide_react = require("lucide-react");
var import_react25 = __toESM(require("react"));
var import_tippy = require("tippy.js/dist/tippy.css");
var import_styles2 = require("./index-5FC5FO7Q.less");
var ControlEnum = /* @__PURE__ */ ((ControlEnum2) => {
ControlEnum2["ZoomTo"] = "zoomTo";
ControlEnum2["ZoomIn"] = "zoomIn";
ControlEnum2["ZoomOut"] = "zoomOut";
ControlEnum2["ZoomToFit"] = "zoomToFit";
ControlEnum2["ZoomToOrigin"] = "zoomToOrigin";
return ControlEnum2;
})(ControlEnum || {});
var dropDownItems = [
{
key: "1",
label: "50%"
},
{
key: "2",
label: "75%"
},
{
key: "3",
label: "100%"
},
{
key: "4",
label: "125%"
},
{
key: "5",
label: "150%"
}
];
var ControlToolMap = {
["zoomIn" /* ZoomIn */]: {
label: "\u653E\u5927",
icon: /* @__PURE__ */ import_react25.default.createElement(import_lucide_react.Plus, { color: "#545456", size: 20 })
},
["zoomOut" /* ZoomOut */]: {
label: "\u7F29\u5C0F",
icon: /* @__PURE__ */ import_react25.default.createElement(import_lucide_react.Minus, { color: "#545456", size: 20 })
},
["zoomTo" /* ZoomTo */]: {
label: "\u7F29\u653E\u81F3",
icon: /* @__PURE__ */ import_react25.default.createElement(import_lucide_react.Plus, { color: "#545456", size: 20 })
},
["zoomToFit" /* ZoomToFit */]: {
label: "\u81EA\u9002\u5E94\u7A97\u53E3\u5927\u5C0F",
icon: /* @__PURE__ */ import_react25.default.createElement(import_lucide_react.Minimize, { color: "#545456", size: 20 })
},
["zoomToOrigin" /* ZoomToOrigin */]: {
label: "\u5B9E\u9645\u50CF\u7D20\u5C55\u793A",
icon: /* @__PURE__ */ import_react25.default.createElement(import_lucide_react.Dice5, { color: "#545456", size: 20 })
}
};
var ControlActionList = [
"zoomTo",
"zoomIn",
"zoomOut",
"zoomToFit",
"zoomToOrigin"
];
var Control = (props) => {
const { items, direction = "horizontal", placement = "top" } = props;
const graph = useGraphInstance();
const [zoom, setZoom] = (0, import_react25.useState)(1);
useGraphEvent("scale", ({ sx }) => {
setZoom(sx);
});
(0, import_react25.useEffect)(() => {
if (graph) {
setZoom(graph.zoom());
}
}, [graph, props]);
const changeZoom = (type, args) => {
if (!graph)
return;
const key = parseInt(args || "1", 10);
const zoomNum = 0.25 * (key + 1);
switch (type) {
case "zoomIn" /* ZoomIn */:
if (zoom < 1.5) {
graph.zoom(0.25);
}
break;
case "zoomOut" /* ZoomOut */:
if (zoom > 0.5) {
graph.zoom(-0.25);
}
break;
case "zoomToFit" /* ZoomToFit */:
graph.zoomToFit({ maxScale: 1 });
break;
case "zoomToOrigin" /* ZoomToOrigin */:
graph.zoomTo(1);
break;
case "zoomTo" /* ZoomTo */:
graph.zoomTo(zoomNum);
break;
default:
break;
}
setZoom(graph.zoom());
};
const isToolButtonEnabled = (type) => {
if (type == "zoomIn" /* ZoomIn */) {
return zoom < 1.5;
} else if (type === "zoomOut" /* ZoomOut */) {
return zoom > 0.51;
}
return true;
};
return /* @__PURE__ */ import_react25.default.createElement(
"div",
{
className: (0, import_classnames.default)("toolButton", {
toolbuttonVertical: direction === "vertical"
})
},
items.map((tool) => {
if (tool === "zoomTo") {
return /* @__PURE__ */ import_react25.default.createElement(
import_react24.default,
{
key: tool,
content: /* @__PURE__ */ import_react25.default.createElement("div", { className: "tippyBtnContent" }, dropDownItems.map((item) => {
return /* @__PURE__ */ import_react25.default.createElement("button", { key: item.key, onClick: () => changeZoom(tool, item.key) }, item.label);
})),
interactive: true,
placement: "top",
arrow: false,
theme: "light-border"
},
/* @__PURE__ */ import_react25.default.createElement("button", { className: "dropDownBtn" }, `${Math.floor(zoom * 100)}%`)
);
} else if (ControlActionList.includes(tool)) {
return /* @__PURE__ */ import_react25.default.createElement(
import_react24.default,
{
key: tool,
content: ControlToolMap[tool].label,
placement,
arrow: true
},
/* @__PURE__ */ import_react25.default.createElement(
"button",
{
onClick: () => changeZoom(tool),
disabled: !isToolButtonEnabled(tool)
},
ControlToolMap[tool].icon
)
);
} else {
return null;
}
})
);
};
// src/index.ts
__reExport(src_exports, require("@antv/x6-react-shape"), module.exports);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Background,
Clipboard,
Control,
ControlEnum,
Dom,
Edge,
Graph,
Grid,
History,
Line,
Markup,
Minimap,
Path,
Point,
Polyline,
Rectangle,
Snapline,
Transform,
Vector,
Wrapper,
XFlow,
XFlowGraph,
apply,
flatten,
getSubGraph,
getSuperGraph,
useClipboard,
useDnd,
useExport,
useGraphEvent,
useGraphInstance,
useGraphStore,
useHistory,
useKeyboard,
...require("@antv/x6-react-shape")
});
/*! Bundled license information:
classnames/index.js:
(*!
Copyright (c) 2018 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*)
*/
//# sourceMappingURL=index.cjs.js.map