js实现流图自动布局算法实现?
目前真正的问题:需要一个通用的连线路径画法 drawLinePath
let drawLinePath = (node1,node2,nodes) => {
//通过node1和node2的节点大小和坐标信息绘制一条通用优雅的有向连线
return linePath;
}
更:根据目前的算法和需求分析,引入力导布局算法或许是最优解。目前的做法是使用Webgraphviz,在需要自动布局时渲染出svg画板,再通过设置setTimeout(Viz渲染生成的dom在主线程中获取不到),在里边获取刚生成的dom节点的信息和坐标,把坐标信息赋给真正的流图画板。此时,通过Viz()生成的svg画板功成身退,毁尸灭迹。
结果,坐标信息拿到了,差个坐标的相对位置问题和连线路径。
发现拿到的坐标位置和真正画板中节点的坐标有误差(这个只能手动做点调整)。
主要缺的还是连线路径,没有统一的连线公式,准确说是不知道viz里的连线规则。
这两天试着看了d3源码(因为没找到其他力导布局的js代码实现或简单易解的例子),现在还是一脸蒙蔽。
原问题描述:
目的:给出节点和连线的json数据,用vue绘制一个流图。画板中的流图为若干个有向图组成、要求流图中的画板可缩放,节点大小可设置、坐标能获取、能填充图片、能在下方显示标签信息、且节点和连线都有事件监听,节点可移动,连线位置随之更新,最最重要的是画板能自动布局。
json数据格式如下:
{
"nodes":{
"node1":{
"id": "node1",
"imgSrc": "img1",
"label": "节点1",
"width": "50",
"height": "50",
},
"node2":{
"id": "node2",
"imgSrc": "img2",
"label": "节点2",
"width": "50",
"height": "50",
},
"node2":{
"id": "node2",
"imgSrc": "img1",
"label": "节点2",
"width": "50",
"height": "50",
}
},
"lines":[
["node1","node2"] //表示node1->node2
]
}
上图为以前自己用vue+svg实现的,没用其他框架和库,以上要求实现了,就是自动布局算法自己写的有点糙。
现在想要把自动布局算法那块优化,自动布局和连线的路径画法是有关联的,不希望有连线重叠从而影响连线的判断。
网上查到有力导布局,觉得这个或许能实现我的目的。但是不知道怎么用,用了之后连线的路径又该怎么设置,希望老司机能指点一下
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于流图(有向无环图)布局,不建议用力引导布局,可以用bary-center算法,从左到右扫描,下一层的点的顺序由上一层父节点的平均值获得,得到顺序后再算具体坐标,再从右向左扫描,直到迭代到合适的线交叉率为止。
可以参考d3的桑吉图(d3-sankey)实现;也可以参考dagre.js(我都是直接调用的。。。)。
这个是一个很复杂的工程,建议参考D3实现代码中关于力导向图处理实现算法。
另外,我提供一个其它的思路:
先生成所有路径,按层级递归生成,每次生成1个枝干(深度优先),这样对1个枝干来说,每个节点位置都可以确定出来,这样就不会存在交叉的问题。因为所有后绘制的节点都是在已有基础上绘制,已有的节点是位置确定的,比如