不久前,我需要流程图,该流程图涉及需求中自动调整布局的功能
这使我的算法xiaobai真的想打破脑海
但最终让我找到一种布局算法,该算法可用于调整视觉节点图表的布局,例如流程图,以便页面空间利用率更高
这是今天要说的紧凑树布局算法
我要感谢这两个大家在这里的代码,这样我就受益匪浅
以下内容是大家代码之后的简单实现
如果您想更深入地学习,则可以去大兄弟的Github克隆人,然后慢慢学习。
紧凑的树布局算法实现
基于VUE和JSPlumb的工作流编辑器的开发(2)
我的演示代码
前端可视化:紧凑的树形布局算法实现(简单版本)
以下是我们想要做的预期效果。由于本文仅研究节点布局并且不涉及连接,因此我们忽略了连接的步骤。
我们要做的效果如下。相邻节点之间存在最小距离,并且不会重叠。
所有分支节点均基于父节点。
这种布局首先是美丽的,并且空间利用率很高。
首先,让我们使用需要的树数据
通常将后端给我们一个维度的对象数组
只有一些简单的名字,ID,父母,孩子,
父子节点的关系请参考上面的图片
接下来,我们创建一个HTML文件来介绍我们的VUE软件包,并使用VUE模板渲染进行布局。当然,您使用React也是如此。
首先显示一些样式信息
接下来是模板语法部分
接下来是VUE的状态部分,功能部分
在这里,我们关注一些常数的含义:
这些常数可以根据实际开发的不同分辨率进行调整
我们在上面的数据中看到了Layouttree,Hashtree和rootNode的三个响应数据
接下来,我们来建造这三件事:
在上面的代码中,我们使用数组方法映射来构造Layouttree,添加:0,顶部:0.我们给出节点的初始坐标为(0,0),并且
然后,我们发现了rootnode,并进一步转换了布局,将孩子通过foreach转变为对象阵列。
然后,我们使用递归调用Gethashtree创建哈希特里。这里的递归用法相对简单,并且没有分析。
有了这三个数据,我们可以开始布局
布局整体分为三个步骤:
我们算法的核心是最后一个,即x轴节点调节。
这种布局相对简单,因为我们和Hashtree(显示了层次关系),
在y轴方向上完成设置非常容易
然后我们打电话给钩子:
让我们看看效果
您可以看到Y轴方向的设置已经完成,并且随后的布局不需要再次更改。
在此步骤中,我们必须执行的效果是根据集合x最小水平距离布置布局,
这有点困难。也许不同的人会有不同的写作方式。在这里,我选择了递归方法。
邮政编码首先
让我们在钩函数中称呼它
让我们解释一些关键代码:
红色框1代码:调用递归函数,传递在根节点中,并且容器的中线请注意,稍后传递的参数是节点的中线坐标。
红色框2代码:设置节点的水平坐标。由于节点的高度,需要减少中间线坐标以减少一半的节点坐标
红色帧3代码:寻求所有子节点的宽度,您需要考虑节点本身的宽度,即节点x节点宽度+(node-1的数量)x最小节点垂直距离,最后使用传输的左室,以减去该值的值
红色框4代码:穿越子节点,子节点的中线坐标
最后的效果如下:
我们可以看到,在节点2和节点3的子节点中,有重叠的部分。该算法的核心是处理这种情况。
这是整个布局算法的核心。我们将再次使用Hashtree使用数据结构来展示上面的图片
让我们先进行调整步骤,然后使用代码实现
步骤1:以倒数顺序从最后一层开始遍历哈希特里,两个或两个节点比较左值,有一个重叠或小于最小间距的情况,并在共同祖先节点下找到相同的层节点(例如上述节点2和节点3 3、3和节点3)
步骤2:根据重叠节点和最小水平间距之间的差异,计算整个节点3,以及子树需要偏移到右侧的多少,以消除节点的重叠,也就是右OffsetLeftoft的右偏移量的整体树3。
步骤3:由于已经执行了子树的子缩短,因此我们需要重新保存整个布局。目前,我们找到了节点3的父节点1,该节点1基于子分支的数量和sub -nodes的数量的多个分支。
步骤4:由于已经执行了子树偏移量,因此我们需要返回最后一层以重新回顾,直到布局完成
因此整个布局过程主要分为上述3个步骤
代码显示如下:
遍历哈斯特里的代码
这是Hashtree的主要遍历,然后判断同一层的两个节点。在这里,左offset的计算是(最小水平间距+节点宽度 - 后一个节点左值很差),然后将子树移动调整,最后将i设置为最后一层以重新创建。
节点和子树之间的代码偏移
这里使用重建
代码调整代码
这主要是为了计算单个节点的左foffset和Multi
请注意此处的红色框中的计算代码
摘要是:查找重叠,移动子树,调整中心并再次穿越吊带
布局可以在含树结构的视觉显示中使用
例如,一些自动安排功能
它可以有效提高空间利用率
希望大家,如果您遇到类似的需求
您也可以使用此算法
原始:https://juejin.cn/post/7101485031981318174
