【问题标题】:How to draw a presentable tree using CFTree?如何使用 CFTree 绘制一个像样的树?
【发布时间】:2013-12-03 08:06:56
【问题描述】:
我必须使用CFTree 绘制一棵漂亮的树。你可以在图片中看到
应满足this link 中所述的所有原则。
原理是:
原则 1:树的边缘不应相互交叉。
原则2:同一深度的所有节点应绘制在同一水平线上。这有助于明确树的结构。
原则 3:树的绘制应尽可能窄。
原则 4:父母应该以孩子为中心。
原则 5:无论它位于树的哪个位置,都应该绘制相同的子树。
原则6:父节点的子节点要等间距。
我应该如何计算每个节点的 X,Y 位置?
【问题讨论】:
标签:
ios
objective-c
tree
core-foundation
【解决方案1】:
你可以递归解决这个问题。
没有图表(这会很有帮助!)这里有一个大纲 - 您需要填写详细信息! - 一种算法。该算法被直接输入到答案中 - 预期错误。
第一:
-
边界框一个包围(子)树绘图的矩形。
-
锚点作为连接弧将绘制的点朝向(弧的一部分可能被节点的绘制遮挡)以连接到(子)树。
- 锚点将是边界框的坐标原点 - 因此边界框是相对于该点的测量值。
- 边界框可能有 children - 子树的边界框。每个孩子的位置都相对于框锚点。
现在:
考虑首先绘制一个没有子节点的单个节点。根据您所需的大小,您可以确定此单个节点的边界框。您正在使用圆形,因此锚点,边界框的 (0,0) 坐标原点位于中心,边界框是相对于它的 +/- 半径。所以你有边界框的锚点,(0,0),它的大小相对于那个 - 比如说(x最小值,x最大值,y最小值,y最大值)是(-radius,+radius,-radius,+radius)。您可能还希望存储节点的标签。因此,例如,对于图表中的“L”节点,您总共有一个表示(即对象),其中包含:(0,0)、(-radius、+radius、-radius、+radius)和“L”。
现在考虑绘制一个只有一个子节点的节点。通过递归调用确定孩子的边界框。构造一个边界框,将您的节点包含在该框的顶部中心以及其正下方的子边界框中。所以你有边界框的锚点,它的大小相对于锚点,以及一个与锚点偏移的子节点。例如,对于上面的“H”节点,您有:(0,0),(xmin,xmax,ymin,ymax),“H”,1 个子节点位于(xoffset,yoffset),子节点是(对对象的引用) (0,0), (-radius, +radius, -radius, +radius) & "L"。
现在考虑绘制一个有 2 个子节点的节点,等等。
从树的根部开始的一次递归遍历,在每个节点处结合从子树返回的信息,生成一个描述树布局的结构。现在画吧!
HTH
【解决方案2】:
我意识到这是一个旧线程,但对于在 CFTREE 上搜索并找到此图像并正在寻找类似图表的其他任何人,我可以推荐 GraphViz 作为解决方案。我用过它,它既简单又强大。从 ColdFusion 或任何其他语言,您可以通过命令行调用它,让它创建一个图像,使用该图像,然后删除该图像。我提到这个软件的原因是在如何构建这样的图表背后有一整套科学(算法)。与其自己编写,不如使用这个免费软件。
要获取按父/子排序的数据,在 Oracle 中可以使用 CONNECT BY 语句。
构建您的数据字符串,然后调用 GraphViz - 例如,
然后参考图片
然后删除它: