'use strict'; const x6 = require('@antv/x6'); class NoxDraw { constructor(containerNode, options) { this.embedPadding = 20; this.options = { autoExpanded: false, ...options }; this.containerNode = containerNode; this.graph = null; this.fuelDispenserNodeSize = [180, 100]; this.gunNodeSize = [70, 30]; this.connecting = { router: { name: "metro", // metro, orth, manhattan args: { step: 10, startDirections: ["top"], endDirections: ["left", "top", "right"] } } }; this.translating = { restrict(view) { const cell = view.cell; if (cell.isNode()) { const parent = cell.getParent(); if (parent) { return parent.getBBox(); } } return null; } }; this.ctrlPressed = false; x6.Graph.registerNode("custom-node", { inherit: "rect", width: 140, height: 40, attrs: { body: { stroke: "#8f8f8f", strokeWidth: 1, fill: "#fff", rx: 6, ry: 6 } } }); this.init(); } init() { this.graph = new x6.Graph({ container: document.getElementById(this.containerNode), width: window.outerWidth, height: window.innerHeight, background: { color: "#F2F7FA" }, autoResize: true, connecting: this.connecting, grid: true, translating: this.translating // embedding: { // enabled: true // } }); if (this.options.autoExpanded) { this.autoExpandParentNode(); } } embeddingListener() { this.graph.on("node:embedding", ({ e }) => { this.ctrlPressed = e.metaKey || e.ctrlKey; }); this.graph.on("node:embedding", () => { this.ctrlPressed = false; }); } changeSizeListener() { this.graph.on("node:change:size", ({ node, options }) => { if (options.skipParentHandler) { return; } const children = node.getChildren(); if (children && children.length) { node.prop("originSize", node.getSize()); } }); } changePositionListener() { this.graph.on("node:change:position", ({ node, options }) => { if (options.skipParentHandler || this.ctrlPressed) { return; } const children = node.getChildren(); if (children && children.length) { node.prop("originPosition", node.getPosition()); } const parent = node.getParent(); if (parent && parent.isNode()) { let originSize = parent.prop("originSize"); if (originSize == null) { originSize = parent.getSize(); parent.prop("originSize", originSize); } let originPosition = parent.prop("originPosition"); if (originPosition == null) { originPosition = parent.getPosition(); parent.prop("originPosition", originPosition); } let x = originPosition.x; let y = originPosition.y; let cornerX = originPosition.x + originSize.width; let cornerY = originPosition.y + originSize.height; let hasChange = false; const parentChildren = parent.getChildren(); if (parentChildren) { parentChildren.forEach((child) => { const bbox = child.getBBox().inflate(this.embedPadding); const corner = bbox.getCorner(); if (bbox.x < x) { x = bbox.x; hasChange = true; } if (bbox.y < y) { y = bbox.y; hasChange = true; } if (corner.x > cornerX) { cornerX = corner.x; hasChange = true; } if (corner.y > corner.y) { cornerY = corner.y; hasChange = true; } }); } if (hasChange) { parent.prop( { position: { x, y }, size: { width: cornerX - x, height: cornerY - y } }, { skipParentHandler: true } ); } } }); } autoExpandParentNode() { this.embeddingListener(); this.changeSizeListener(); this.changePositionListener(); } /** 创建容器 */ createContainer(node, x, y, options) { const container = this.graph.addNode({ shape: "rect", x, y, width: options?.width || 1e3, height: options?.height || 100, zIndex: 1, attrs: { body: { fill: options?.background || "#ffb2a3", rx: 6, ry: 6 } } }); if (Array.isArray(node)) { node.forEach((n) => { container.addChild(n); }); } else { container.addChild(node); } } /** * 创建油罐节点 * @param label - 节点名称 * @param x - 横坐标位置,原点为左上角 * @param y - 纵坐标位置,原点为左上角 * @returns */ createTankNode(label, x = 40, y = 400) { return this.graph.addNode({ shape: "custom-node", x, y, label, zIndex: 2 }); } /** * 创建加油机节点 * @param label - 节点名称 * @param x - 横坐标位置,原点为左上角 * @param y - 纵坐标位置,原点为左上角 * @returns */ createFuelDispenserNode(label, x = 40, y = 100) { return this.graph.addNode({ shape: "custom-node", x, y, width: 180, height: 100, label, attrs: { body: { fill: "#fffbe666", stroke: "#ffe7ba66" } } }); } createGunNode(label, x = 40, y = 100) { return this.graph.addNode({ shape: "custom-node", x, y, width: 70, height: 30, label }); } createPipe(source, target) { return this.graph.addEdge({ source: { cell: source, anchor: { name: "top", dx: -Math.floor(Math.random() * 10 + 10) }, connectionPoint: "anchor" }, target: { cell: target }, attrs: { line: { stroke: this.randomColor(), strokeWidth: 3, strokeDasharray: Math.floor(Math.random() * 10 + 5), style: { animation: "ant-line 60s infinite linear" } } } }); } randomColor() { const r = Math.floor(Math.random() * 360); const g = Math.floor(Math.random() * 360); const b = Math.floor(Math.random() * 360); return `rgb(${r}, ${g}, ${b})`; } /** * 将原始数据转换为生成图里的可用数据 * @param dataJson - 原始数据 * @returns */ transformFuelDispenser(dataJson) { const result = []; const itemMap = []; dataJson.forEach((item) => { const { fuelDispenser } = item; itemMap.push(fuelDispenser); }); const dataSet = new Set(itemMap); for (const i of [...dataSet]) { result.push({ fuelDispenser: i, guns: [] }); } const fuelDispenserList = result.map((item) => { const guns = []; dataJson.map((data) => { if (item.fuelDispenser === data.fuelDispenser) { guns.push(data.gun); } }); return { ...item, guns }; }); return fuelDispenserList; } verify() { console.log("success"); } } module.exports = NoxDraw;