【问题标题】:Using D3, can semantic zoom be applied to a radial tree?使用 D3,语义缩放可以应用于径向树吗?
【发布时间】:2014-02-01 17:11:44
【问题描述】:

我正在使用 D3 node link tree,但在尝试对其应用语义缩放时遇到了麻烦。

我已经花了一些时间大惊小怪,试图让它工作 - 所以我想我会在这里问一下,在我花更多时间之前看看是否有可能......我不确定语义缩放是否是一种纯线性的东西。

编辑 - 工作解决方案

这是我的工作解决方案。我没有清理这里的代码 - 但它应该给你一个想法。

http://codepen.io/toadums/pen/wjovC

【问题讨论】:

  • 你见过this question吗?
  • 是的,@LarsKotthoff,我读过那个。在这种树上实现对我来说很容易(我称之为线性..)。但是当我在径向树上尝试它时,它就下地狱了......谢谢!
  • 你能做一个 jsfiddle 或类似的东西来证明你遇到的问题吗?
  • 我在下面答案的评论部分发布了此解决方案的 Javascript 版本 的链接。
  • 谢谢@FernOfTheAndes :)

标签: javascript d3.js zooming


【解决方案1】:

由于d.xd.y 在径向树中的解释方式不同,简单的“语义缩放”方法(让行为对象和比例尺进行所有计算)不起作用。

树布局计算的 (x,y) 坐标用于绘制径向树中与中心的角度和距离。这些值不会直接转换为缩放行为创建的 x 和 y 坐标。因此,您不能只是将比例附加到缩放行为中,在缩放时自动调整比例域,然后使用比例重新绘制点。

(附注:我假设您只需要正常缩放来放大图表的一部分,而不是像 Jason Davies 的 zoomable sunburst 示例那样重新计算角度。)

概述如何为初始布局转换元素:

  • 在包含图形的<g> 元素上进行转换,将 (0,0) 坐标定位在绘图区域的中心。

  • 根据布局中的d.x 值(始终介于 0 和 360 之间)计算每个节点组的旋转设置角度。

  • 然后 然后(顺序很重要),根据布局中的 d.y 值,每个节点组上的平移会沿着旋转的基线将其从中心移开根据所需的圆半径进行缩放。

请注意,径向树示例在树布局函数内进行所有缩放(通过调用size() 方法)——没有使用缩放。

为了放大圆圈的一部分,您需要:

  • 通过对<g> 元素应用变换,将布局中心平移到绘图中心以外的位置。

  • 要么通过<g>元素上的第二次变换来更改整个图像的比例(这也会缩放文本、圆圈大小等)

    李>
  • 根据比例因子改变每个节点的水平平移。

请注意,您不要单独考虑节点的旋转角度!

如果您不介意缩放文本和节点大小,则将变换应用到 <g> 元素相当简单。

如果您想在不增加单个元素大小的情况下缩放布局,则需要更改距布局中心的距离的计算方式。

要正确翻译中心:

  • 在您的缩放功能中,使用d3.event.translate 访问整个图形所需平移的 (x,y) 数组。

  • 使用它来覆盖 <g> 元素上的变换,记住对于 (0,0) 的缩放平移,您仍然希望 <g> 元素具有 (width/2, height/ 2)。所以你需要这样的东西:

    svg.attr("transform", "translate(" + (width/2 + d3.event.translate[0]) +
    "," + (height/2 + d3.event.translate[1]) + ")" );

  • 1234563更自然地在平移之前或之后应用比例(scale(2) translate(50) 等于 translate(100) scale(2),因为平移坐标也会被缩放)。比例因子为d3.event.scale

要正确缩放距中心(“y”变量)的距离:

  • 使用域[0,1] 和范围[0,radius] 创建一个径向刻度。

  • 将树布局的大小设置为“高度”为 1,而不是直接使用半径。

  • 定位节点时,使用比例将布局中的 d.y 值(介于 0 和 1 之间)转换为转换中使用的实际径向距离。

    node.attr("transform", function(d) { return "rotate(" + (d.x - 90)
    + ")translate(" + radialScale(d.y) + ")"; })

  • 在您的缩放行为中,不要附加任何比例尺!尽管您需要根据缩放调整径向比例,但您只想调整比例而不是平移它——所有平移都将直接应用于定义圆心的<g> 元素。

  • 在您的缩放功能中,将径向刻度的域设置为[0, 1/d3.event.scale]。换句话说,如果缩放行为告诉我们将图像缩放 2,我们希望绘图区域的中心和边缘之间的距离(范围,您不会更改)表示之间距离的 1/2树的中心和边缘(域)。

  • 然后,使用与上述相同的语法重置各个节点组上的转换属性。 (您需要将该匿名函数设为命名函数,这样您就可以在代码的两个部分中传入函数名。)

所以,我不知道所有额外的代码是否还算作“语义缩放”。但它应该放大你的图表。如果您的小提琴正常工作,请返回并留下链接!

【讨论】:

  • 再次感谢您的帮助。我不认为没有它我会得到它的工作!如果你想看看,我把我的解决方案贴在最上面:) 再次感谢一百万!!!!!!
  • @Toadums 很高兴它成功了——你的演示看起来很棒。有时,您必须摆脱“几乎正确但不完全正确”的示例并从头开始解决问题。
  • @AmeliaBR - 确实是很好的解释。我想知道你是否看过我不久前提出的这个问题here。有什么想法吗?
  • 同时,上述解决方案的JAVASCRIPT版本在这个fiddle中。
猜你喜欢
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
  • 2014-02-25
  • 2014-02-16
  • 1970-01-01
  • 2013-12-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多