如何在D3.js v4中创建具有固定bin宽度的直方图?

时间:2016-12-30 12:22:51

标签: d3.js

the official D3.js v4 histogram example开始,我想显示虹膜“PetalLength”值的直方图。

请参阅http://codepen.io/netzwerg/pen/KNOYBy

我的问题是最后一个bin超出了x轴的上限:

enter image description here

在查看垃圾箱时,这非常有意义:它们的宽度均为1,除了最后一个,只有x0: 6x1: 6.9

鉴于所有svg矩形都是以固定宽度创建的(基于bins[0]),可以解释重叠。

我可以手动使x范围“更好”(四舍五入到7):

var x = d3.scaleLinear()
      .domain(d3.extent(values))
      .rangeRound([0, width])
      .nice();

“修复”了这个问题。

或者,我可以将svg矩形宽度计算调整为基于每个单独bin的x0x1,这将绘制宽度较窄的最后一个bin。

但最终,我的问题是:

如何告诉d3.histogram创建宽度相同的垃圾箱?

1 个答案:

答案 0 :(得分:3)

根据文件:

  

阈值定义为值数组[x0,x1,...]。任何小于x0的值都将放在第一个bin中;任何大于或等于x0但小于x1的值都将放在第二个bin中;等等。

话虽如此,你的门槛是不正确的。这样:

.thresholds(x.ticks(5));

会给你:

[1, 2, 3, 4, 5, 6];

并且,正因为如此,最后一个bin只是从6.06.9(宽度为0.9),比之前的那个更宽(宽度为1.0)。

而不是这个,这应该是你的门槛:

.thresholds(d3.range(1, x.domain()[1], (x.domain()[1]-1)/6));
//          start----^    end---^          step----^

这将为您提供正确的值:

[1, 1.983, 2.966, 3.95, 4.933, 5.916]

以下是您更新的CodePen,仅更改了此内容:http://codepen.io/anon/pen/aBegWW?editors=0010

你可以看到,现在这些箱子的宽度相同,为0.983,其中 none 不再以圆形刻度结束。

编辑:根据OP的this comment,我同意这一点,这是一个更具可读性的选择:

const [min, max] = d3.extent(values); 
const thresholds = d3.range(min, max, (max - min) / binCount);