如何处理d3中Beeswarm图中的碰撞? [英] How to handle collisions in Beeswarm plot in d3?

查看:127
本文介绍了如何处理d3中Beeswarm图中的碰撞?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在玩这个例子这里一会儿。我想做的是突出显示单个节点/圆圈(通过使其更大的边框;后来我想添加文本或其中的字母)。

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:

.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.

链接到Plunkr - https:/ /plnkr.co/edit/rG6X07Kzkg9LeVVuL0PH?p=preview

Link to Plunkr - https://plnkr.co/edit/rG6X07Kzkg9LeVVuL0PH?p=preview

我尝试以下操作来添加字母bhutan圆圈

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");

更新Plunkr - https://plnkr.co/edit/Bza5AMxqUr2HW9CYdpC6?p=preview

Updated Plunkr - https://plnkr.co/edit/Bza5AMxqUr2HW9CYdpC6?p=preview

推荐答案

这是一个稍微不同的问题,在这个问题在这里:如何更改D3.js中的蜂巢图中的点的大小

This is a slightly different problem than in this question here: How to change the size of dots in beeswarm plots in D3.js

你可以想到几个选项:


  • 设置 forceCollide 成为你的最大可能半径* 1.33 ,例如(r + 4)* 1.33

  • 将radius属性添加到数组中的每个条目,并使碰撞工作基于它,它

  • Set the forceCollide to be your largest possible radius * 1.33, e.g. (r + 4) * 1.33. This will prevent overlapping, but spread things out a lot and doesn't look that great.
  • Add the radius property to each entry in your array and make the collide work based off that, which will look a bit better but not perform as awesomely for large sets.

下面是一个例子:

...
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; })
....

使用 d3.csv 中为 r 的每个成员添加一个属性的code>请检查国家/地区名称以确定哪个国家/地区获得的值较大。

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. Then use that value wherever you need to mess with the radius.

我猜想在半径受到影响的地方可以检查国家名称(例如 .force(collide,d3.forceCollide(function(d){return d.countryName ===Bhutan?(r + 4)* 1.33:r * 1.33;}),等等)。这对我来说有点干净,但它可能通过从数据条目本身抽象出半径来更清洁...

I guess it would've been possible to check the country name everywhere the radius was impacted (e.g. .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...

Forked您的plunk: https://plnkr.co/edit/Tet1DVvHtC7mHz91eAYW?p=preview

Forked your plunk here: https://plnkr.co/edit/Tet1DVvHtC7mHz91eAYW?p=preview

这篇关于如何处理d3中Beeswarm图中的碰撞?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆