D3增加力量单个节点
我一直在使用D3的动力布局,以创建向中间力量做了一个分组气泡图,就像这样:D3增加力量单个节点
var forceStrength = 0.03;
var center = { x: widthBubbles/2, y: heightBubbles/2 };
var simulation = d3.forceSimulation()
.velocityDecay(0.2)
.force('x', d3.forceX().strength(forceStrength).x(center.x))
.force('y', d3.forceY().strength(forceStrength).y(center.y))
.force('charge', d3.forceManyBody().strength(charge))
.on('tick', ticked);
function charge(d) {
return -forceStrength * Math.pow(d.r, 2.0);
}
function ticked() {
bubbles
.attr('cx', function (d) { return d.x; })
.attr('cy', function (d) { return d.y; });
}
我的图表看起来类似于这样:Gates Foundation Educational Spending
我希望能够在单个节点上单击时施加一个力,以便点击的节点将移动到另一个区域。在D3的文档中,有一些称为“定位力”的东西,根据文档打算用于多个节点:
虽然这些力可用于定位各个节点,但它们主要用于适用于所有(或大多数)节点的全球力量。
所以我的问题是如果有一种方法可以将力量应用于D3中的单身节点。
我通过创建一个函数,这是所谓的每点击一个气泡时间解决了这个问题:
//Function for moving bubbles when selected
function moveSelectedBubbles() {
simulation.force('x', d3.forceX().strength(forceStrength).x(function(d){
//Check if bubble is selected
return (selectedCountries.indexOf(d.data.country) >= 0) ? selectedCenter.x : center.x;
}));
simulation.alpha(1).restart();
}
但是这个功能被选择的气泡每次设置每个节点的力。也许有一种更有效的方式来处理案件。
从你的解决方案看来,你的力量实际上是作用于所有节点的,因为如果它没有被选中,你将它设置为'center.x'。如果情况并非如此,并且您想仅隔离一个节点/一组节点,那么最近有一个很酷的mbostock块:https://bl.ocks.org/mbostock/b1f0ee970299756bc12d60aedf53c13b我发现它很有用。另外,我认为你应该能够在'forceX(here)'函数中移动你的'.x(函数(d)...'代码来简化事情(我不认为你应该设置这个力每一个点击处理程序btw) – ibgib
还有一件事:你也可以在'd'对象本身存储一个临时标志,例如'd.isSelected',并对其进行过滤,而不是每次重新计算'indexOf'(这需要你也要处理何时将这个标志设置为false,很明显。) – ibgib
谢谢你的评论,我会检查一下。 – martin36
这可能只是[*“碰撞检测丢失后切换(d3v4)”*](/ q/41479452)中讨论的解决方案的特例。 – altocumulus
它可能是相似的,但我的问题是如何改变只有一个节点的力量。 – martin36