在上一篇名为“D3: How to create slow transition of Circles for nodes in Force Directed Graphs FDG?”的帖子中,我对如何在D3中转换单个元素(例如“只是圆圈”的半径)得到了很好的答案。
我的后续问题现在是关于如何同时转换“多个D3属性”......
提醒一下,我正在使用D3生成的单选按钮在FDG布局(鼠标单击)中将节点的大小从默认大小切换到缩放大小。您可以在Node Cluster Diagram(http://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似乎没有明确地涉及同时转换多个属性的理论。
答案 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属性设置为最终位置的动画。当然这意味着你需要良好的起始位置。