[英]How to handle collisions in Beeswarm plot in d3?
I've been playing around with this example here for a little while. 我一直在这里玩这个例子。 What I'm trying to do is highlight a single node/circle in the plot (by making it larger with a border; later I want to add text or a letter inside it too).
我要做的是在图中突出显示单个节点/圆(通过使边框更大;稍后我想在其中添加文本或字母)。
Currently, I've made the circle for Bhutan
larger in the plot like the following: 目前,我已经在不同的情节中为
Bhutan
做了更大的圈子,如下所示:
.attr("r",
function(d){return ( d.countryName === "Bhutan" ? r + 4 : r);})
.attr("stroke", function(d){if (d.countryName==="Bhutan"){return "black"}})
However, it overlaps with the other circles. 但是,它与其他圆圈重叠。 What would be the best approach to avoid these collisions/overlaps?
什么是避免这些碰撞/重叠的最佳方法? Thanks in advance.
提前致谢。
Link to Plunkr - https://plnkr.co/edit/rG6X07Kzkg9LeVVuL0PH?p=preview 链接到Plunkr - https://plnkr.co/edit/rG6X07Kzkg9LeVVuL0PH?p=preview
I tried the following to add a letter inside the bhutan circle 我尝试了以下内容在不丹圈内添加一封信
//find bhutan circle and add a "B" to it
countriesCircles
.data(data)
.enter().append("text")
.filter(function(d) { return d.countryName === "Bhutan"; })
.text("B");
Updated Plunkr - https://plnkr.co/edit/Bza5AMxqUr2HW9CYdpC6?p=preview 更新了Plunkr - https://plnkr.co/edit/Bza5AMxqUr2HW9CYdpC6?p=preview
This is a slightly different problem than in this question here: How to change the size of dots in beeswarm plots in D3.js 这是一个与此问题略有不同的问题: 如何在D3.js中改变beeswarm图中点的大小
You have a few options that I can think of: 你有几个我能想到的选择:
forceCollide
to be your largest possible radius * 1.33
, eg (r + 4) * 1.33
. forceCollide
设置为您largest possible radius * 1.33
的largest possible radius * 1.33
,例如(r + 4) * 1.33
。 This will prevent overlapping, but spread things out a lot and doesn't look that great. Here's an example of how to do that: 这是一个如何做到这一点的例子:
...
d3.csv("co2bee.csv", function(d) {
if (d.countryName === "Bhutan") {
d.r = r + 4;
} else {
d.r = r;
}
return d;
}, function(error, data) {
if (error) throw error;
var dataSet = data;
...
var simulation = d3.forceSimulation(dataSet)
...
.force("collide", d3.forceCollide(function(d) { return d.r * 1.33; }))
...
countriesCircles.enter()
.append("circle")
.attr("class", "countries")
.attr("cx", 0)
.attr("cy", (h / 2)-padding[2]/2)
.attr("r", function(d){ return d.r; })
....
Use the row
function in d3.csv
to add a property to each member of the array called r
, and check the country name to determine which one gets the larger value. 使用
d3.csv
的row
函数将属性添加到名为r
的数组的每个成员,并检查国家/地区名称以确定哪个获取更大的值。 Then use that value wherever you need to mess with the radius. 然后在需要的地方使用该值来弄乱半径。
I guess it would've been possible to check the country name everywhere the radius was impacted (eg .force("collide", d3.forceCollide(function(d) { return d.countryName === "Bhutan" ? (r + 4) * 1.33 : r * 1.33; })
, etc.). This feels a bit cleaner to me, but it might be cleaner still by abstracting out the radius from the data entries themselves... 我想有可能在半径受影响的地方检查国名:例如
.force("collide", d3.forceCollide(function(d) { return d.countryName === "Bhutan" ? (r + 4) * 1.33 : r * 1.33; })
等。)这对我来说感觉有点干净,但是通过从数据条目本身中抽象出半径,它可能更清晰......
Forked your plunk here: https://plnkr.co/edit/Tet1DVvHtC7mHz91eAYW?p=preview 在这里分叉你的插件: https ://plnkr.co/edit/Tet1DVvHtC7mHz91eAYW ? p = preview
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.