赞
踩
d3 echarts 都可以画关系拓扑图(有环),但是总觉得不是自己想要的,改起来也很麻烦,所以可以用JSPlumb 自己绘制自己的关系拓扑图,拓扑图 = 绘图 + 自动布局算法。jsplumb 可以实现绘自己的结点,而自动布局则可以采用 力导向布局算法。
这里参考的是 https://www.jianshu.com/p/d3c64a39535a
/** * A force directed graph layout implementation by liuchang on 2018/05/10. */ const CANVAS_WIDTH = 1000; const CANVAS_HEIGHT = 1000; let k; let mNodeList = []; let mEdgeList = []; let mDxMap = { }; let mDyMap = { }; let mNodeMap = { }; var json ={ } ; function ForceDirected() { //generate nodes and edges for (let i = 0; i < 20; i++) { mNodeList.push(new Node(i)); } for (let i = 0; i < 20; i++) { let edgeCount = Math.random() * 8 + 1; for (let j = 0; j < edgeCount; j++) { let targetId = Math.floor(Math.random() * 20); let edge = new Edge(i, targetId); mEdgeList.push(edge); } } if (mNodeList && mEdgeList) { k = Math.sqrt(CANVAS_WIDTH * CANVAS_HEIGHT / mNodeList.length); } for (let i = 0; i < mNodeList.length; i++) { let node = mNodeList[i]; if (node) { mNodeMap[node.id] = node; } } //随机生成坐标. Generate coordinates randomly. let initialX, initialY, initialSize = 40.0; for (let i in mNodeList) { initialX = CANVAS_WIDTH * .5; initialY = CANVAS_HEIGHT * .5; mNodeList[i].x = initialX + initialSize * (Math.random() - .5); mNodeList[i].y = initialY + initialSize * (Math.random() - .5); } //迭代200次. Iterate 200 times. for (let i = 0; i < 200; i++) { calculateRepulsive(); calculateTraction(); updateCoordinates(); } json = JSON.stringify(new Result(mNodeList, mEdgeList)); //console.log(); } function Node(id = null) { this.id = id; this.x = 22; this.y = null; } function Edge(source = null, target = null) { this.source = source; this.target = target; } /** * 计算两个Node的斥力产生的单位位移。 * Calculate the displacement generated by the repulsive force between two nodes.* */ function calculateRepulsive() { let ejectFactor = 6; let distX, distY, dist; for (let i = 0; i < mNodeList.length; i++) { mDxMap[mNodeList[i].id] = 0.0; mDyMap[mNodeList[i].id] = 0.0; for (let j = 0; j < mNodeList.length; j++) { if (i !== j) { distX = mNodeList[i].x - mNodeList[j].x; distY = mNodeList[i].y - mNodeList[j].y; dist = Math.sqrt(distX * distX + distY * distY); } if (dist < 30) { ejectFactor = 5; } if (dist > 0 && dist < 250) { let id = mNodeList[i].id; mDxMap[id] = mDxMap[id] + distX / dist * k * k / dist * ejectFactor; mDyMap[id] = mDyMap[id] + distY / dist * k * k / dist * ejectFactor; } } } } /** * 计算Edge的引力对两端Node产生的引力。 * Calculate the traction force generated by the edge acted on the two nodes of its two ends. */ function calculateTraction() { let condenseFactor = 3; let startNode, endNode; for (let e = 0
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。