如何在力导向图中创建多个属性的慢同时转换?

时间:2013-07-12 01:23:55

标签: d3.js transition force-layout

在上一篇名为“D3: How to create slow transition of Circles for nodes in Force Directed Graphs FDG?”的帖子中,我对如何在D3中转换单个元素(例如“只是圆圈”的半径)得到了很好的答案。

我的后续问题现在是关于如何同时转换“多个D3属性”......

提醒一下,我正在使用D3生成的单选按钮在FDG布局(鼠标单击)中将节点的大小从默认大小切换到缩放大小。您可以在Node Cluster Diagramhttp://nounz.if4it.com/Nouns/Applications/A__Application_1.NodeCluster.html)左上角找到单选按钮

在默认数字和缩放幅度(现在使用过渡)之间切换节点圆圈的代码如下所示......

    var densityControlClick = function() {

      var thisObject = d3.select(this);
      var typeValue = thisObject.attr("density_type");
      var oppositeTypeValue = (function() {
        if(typeValue=="On") {
          return "Off";
        } else {
          return "On";
        }
      })();

      var densityBulletSelector = "." + "densityControlBullet-" + typeValue;
      var selectedBullet = d3.selectAll(densityBulletSelector);
      selectedBullet.style("fill", "Black") 

      var oppositeDensityBulletSelector = "." + "densityControlBullet-" + oppositeTypeValue;
      var selectedOppositeBullet = d3.selectAll(oppositeDensityBulletSelector);
      selectedOppositeBullet.style("fill", "White") 

      if(typeValue=="On") {
        var selectedNodeCircles = d3.selectAll("#NODE");
        selectedNodeCircles.transition().duration(500).attr("r", function(d){ return rRange(d.rSize); });
      }
      else {
        var selectedNodeCircles = d3.selectAll("#NODE");            selectedNodeCircles.transition().duration(500).attr("r", function(d) { if (d.id==focalNodeID) { return centerNodeSize; } else { return defaultNodeSize; } } );
      }

    }

一切都很好,当您选择单选按钮时,您可以看到较慢的节点转换。但是,我现在想学习如何同时转换多个元素,例如半径和边长,以及背后的理论,以展示D3的动态特性。

我的问题是:鉴于我已经可以成功转换圆的半径,我如何根据“alpha”,“friction”等属性转换其他元素,如边长,以及......什么是转换多个元素背后的理论(换句话说,代码的含义是什么,用英语)? D3 API似乎没有明确地涉及同时转换多个属性的理论。

1 个答案:

答案 0 :(得分:4)

因此,转换多个属性是这个问题的简单部分。就像常规选择一样,您可以在转换时一次设置多个属性:

selectedNodeCircles.transition().duration(500)
    .attr("r", function(d){ return rRange(d.rSize); })
    .attr("stroke", 'red');

这将转换您的半径和线条颜色。转换是DOM元素的属性(在本例中为圆圈),它将根据您的喜好转换尽可能多的DOM属性。要记住的是每个DOM元素上只有一个转换对象。因此,如果您创建另一个,您将覆盖旧的。

// This will NOT work
circles.transition().duration(1000).attr('r', 50);
// The radius transition will be overridden by the fill 
// transition and so will not complete
circles.transition().duration(1000).attr('fill', 'red');

这实际上非常有用,因为您不必担心中断正在进行的动画并弄清楚它们的距离,然后开始新动画 - 这通常会自动处理。

在您的情况下,您想要在图表中转换边长。这些由节点的位置属性确定。根据您的成品判断,这些属性已经被设置为动画,因为您在布局算法的每次迭代(而不是通过转换)中更新DOM,可能在tick()回调中。

因此,您可以在tick回调中使用转换,这可能看起来很奇怪,并且可能很难与半径转换保持同步(您必须在转换中设置两个属性)。但它可能正是你所需要的。

或者,如果您可以等待,请不要更新tick回调中的DOM。让布局完成 - 当它不在每个刻度上渲染时运行得更快 - 一旦完成,您可以将半径和x和y属性设置为最终位置的动画。当然这意味着你需要良好的起始位置。