我有一个包含多个聚类的D3可视化,并且我使用了引力函数将所有圆都移到焦点的中心。但是,与此相关,圆圈是重叠的。
我尝试将此块https://bl.ocks.org/mbostock/3231298转换为V5,但无法正常工作。
我正在使用负电荷排斥节点,很明显,当我在tick中调用引力函数时,它将代码移至群集焦点的中心
force = d3.forceSimulation(nodes)
.force('charge', d3.forceManyBody(-100))
.force('collision', d3.forceCollide().radius(function (d) {
return 1.1*d.radius;
}))
.on('tick', tick);
force.alpha(0.01);
force.alphaDecay = 0.1;
force.alphaTarget(.001);
force.force('x', d3.forceX().x(function (d) {
return foci[d.choice].x;
}))
force.force('y', d3.forceY().y(function (d) {
return foci[d.choice].y;
}))
console.log(JSON.stringify(foci));
// Draw circle for each node.
circle = svg.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("id", function (d) {
return d.id;
})
.attr("class", "node")
.style("stroke", "black");
;
// For smoother initial transition to settling spots.
// Need to research more on this
circle.transition()
.duration(100)
.delay(function (d, i) {
return i * 5;
})
.attrTween("r", function (d) {
var i = d3.interpolate(0, d.radius);
return function (t) {
return d.radius = i(t);
};
});
function tick(e) {
circle
.each(collide(0.5))
.each(gravity(.051 * .8))
.style("fill", function (d) {
//category is either 0 or 1
//so it's either 0+the choice or 6+the choice
//d.choice is between 0 and 5
multiplier = d.category
return colors[foci_count * multiplier + d.choice];
})
.attr("cx", function (d) {
return d.x;
})
.attr("cy", function (d) {
return d.y;
})
.attr("r", function(d) {
return d.radius;
})
;
}
function collide(alpha) {
var quadtree = d3.quadtree().addAll(nodes);
return function (d) {
// var r = d.radius + maxNodeRadius + Math.max(padding, clusterPadding),
var r = d.radius + 10,
nx1 = d.x - r,
nx2 = d.x + r,
ny1 = d.y - r,
ny2 = d.y + r;
quadtree.visit(function (quad, x1, y1, x2, y2) {
console.log("visit")
if (quad.point && (quad.point !== d)) {
var x = d.x - quad.point.x,
y = d.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = d.radius + quad.point.radius + 10;
console.log(d.cluster);
if (l < r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
});
};
}
// Move nodes toward cluster focus.
function gravity(alpha) {
return function (d) {
d.y += (foci[d.choice].y - d.y) * alpha;
d.x += (foci[d.choice].x - d.x) * alpha;
};
}
答案 0 :(得分:0)
正如@ rioV8所提到的,我要做的就是用更新的节点重新初始化碰撞力。因此,我将tick函数更新为以下
function tick(e) {
circle
.each(gravity(.051 * .8))
.style("fill", function (d) {
//category is either 0 or 1
//so it's either 0+the choice or 6+the choice
//d.choice is between 0 and 5
multiplier = d.category
return colors[foci_count * multiplier + d.choice];
})
.attr("cx", function (d) {
return d.x;
})
.attr("cy", function (d) {
return d.y;
})
.attr("r", function(d) {
return d.radius;
});
force.force('collision', d3.forceCollide().radius(function (d) {
return 1.3 * d.radius;
}));
}