在我要实现的一个小例程中,我使用d3.js的bisectLeft函数。 我正在使用最新版本(v5.9.2)。 如果我这样做,一切都很好:
var dataArray = [10, 20, 50, 40, 30, 600];
d3.bisectLeft(dataArray, 30); //2
但是,如果我这样做,则不会:
var dataArray = [[10,1],[20,2],[50,5],[40,4],[30,3],[600,60]];
d3.bisectLeft(dataArray, 30); //0 Bad!
这很好用:
var dataArray = [[10,1],[20,2],[50,5],[40,4],[30,3],[600,60]];
d3.bisectLeft(dataArray, '30'); //2 Good!
这是设计使然吗?我已经查看了源代码和文档,但我不明白为什么会这样。 曾经知道这个问题很容易在我的代码中解决,但是我仍然有疑问,我不知道我是否缺少某些东西。
答案 0 :(得分:3)
这里的问题是您有一个数组数组。在这种情况下,您必须将d3.bisector
与适当的访问器功能配合使用,以便D3知道要比较的值是什么。根据文档,此方法...
使用指定的访问器或比较器功能返回一个新的平分线。此方法可用于将对象数组一分为二,而不仅限于简单的基元数组。 (强调我的)
在您的情况下,这将是:
const bisector = d3.bisector(function(d) { return d[0]; }).left;
如您所见,这将通过选择每个内部数组中的第一个数字,就像将问题中的第一个代码片段一样,有效地将数组变成单个数字数组。
另外,请注意需要对数组进行排序的事实(否则人们将永远无法理解为什么2
在您的问题中是“好” !)。
这是演示:
var dataArray = [
[10, 1],
[20, 2],
[50, 5],
[40, 4],
[30, 3],
[600, 60]
];
dataArray = dataArray.sort(function(a, b) {
return a[0] - b[0];
});
const bisector = d3.bisector(function(d) {
return d[0];
}).left;
const result = bisector(dataArray, 30);
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>