我正在研究用D3制作图表,偶然发现了d3.bisector
。但是,我不明白它是什么或从文档中做了什么。
我在网上找到的几乎所有示例都使用Date数组,类似于官方文档中的示例:
var data = [
{date: new Date(2011, 1, 1), value: 0.5},
{date: new Date(2011, 2, 1), value: 0.6},
{date: new Date(2011, 3, 1), value: 0.7},
{date: new Date(2011, 4, 1), value: 0.8}
];
var bisect = d3.bisector(function(d) { return d.date; }).right;
那么除了从数组元素中选择日期对象之外,平分线器还能做什么? *.right
返回什么?
如果我有一个简单的1维数组,如var data = [3, 6, 2, 7, 5, 4, 8]
,它有用吗?
感谢您的启发。
答案 0 :(得分:112)
bisect
背后的基本理念是:
考虑一下你提到的数组 - var data = [3, 6, 2, 7, 5, 4, 8]
您希望在3.5
数组中插入一个新值,让我们说data
,并想知道它将如何'分区'。换句话说,如果在3.5
数组已排序时插入data
,您想知道 var data = [3, 6, 2, 7, 5, 4, 8]
//Sorted data
[2, 3, 4, 5, 6, 7, 8]
//You want to insert 3.5
The sorted array after insertion of 3.5 should look something like:
[2, 3, 3.5, 4, 5, 6, 7, 8]
So the index of 3.5 in sorted data array is "2".
的索引是什么。
bisectLeft
在某些情况下,您可能想知道该元素的插入如何“平分”或“划分”数组。在这种情况下,您可能希望首先对该数组进行排序并执行我们称之为Binary Search的操作,以找出插入该元素的正确位置。
bisectRight
和3
注意在您想要输入数组中已存在的元素的情况下澄清异常。假设您要在数组中输入另一个 3* -> The new element to be entered
[2, 3*, 3, 4, 5, 6, 7, 8] -> entered at "1" (array is still sorted)
[2, 3, 3*, 4, 5, 6, 7, 8] -> entered at "2" (array is still sorted)
。有两种情况:
bisectLeft
因此,根据我们如何处理这种歧义,我们可以将该元素输入到现有元素的“左”或“右”。从docs(强调标记):
返回的插入点我将数组分成两半,以便所有v < x for array.slice(lo,i)中的左侧和所有v &gt ; = x代表右侧的array.slice(i,hi)中的v。
在bisecRight
中,我们得到1作为合适的索引,所有重复的条目将位于该索引的右侧,而bisectLeft
中的情况正好相反。
现在您知道bisectRight
和bisector
的工作方式,comparator
只允许我们定义自定义accessor
或 var bisect = d3.bisector(function(d) { return d.date; }).right;
var bisect = d3.bisector(function(a, b) { return a.date - b.date; }).right;
函数来对值进行分区或者也可以理解对象上的< 和> 。
所以这段代码:
bisectRight
只是指定使用bisector
选项并返回一个合适的索引来插入一个元素,假设数组已经排序(按升序排列)。
因此,如果我要构建您的示例并假设bisect
名为 bisect(data, 3); //it would return 2.
。你做了:
{{1}}
我希望它澄清事情,让你开始朝着正确的方向前进。
答案 1 :(得分:3)
从文档(您已链接到):
在数组中找到x的插入点以维护排序顺序。
它的作用。它告诉你应该在哪里插入一个新元素,之后仍然有一个排序数组。阵列可以是任何类型的结构,这就是为什么有一个访问器功能允许你分解"这个结构用于搜索。
左和右二等分之间的区别在于插入点(最接近元素的左侧或右侧) - 数组是按升序还是降序排序。
平分线的一个用例是,当您将鼠标移到图表上时,您想要突出显示最近的数据点,例如, this example