我正在制作一个d3图,我有多个元素,在绘制时可能会重叠。
每个元素都会渲染一个时间轴,并有多个图形单元(起始圆,直线和结束圆),如下所示:
O----------O O
O--------------------O
O-------O-----O-------O
例如,第三行有两个时间线绘图元素,它们重叠,因为第二个时间轴的开始时间是在第一个时间轴的结束时间之前。请注意,第一行中的第二个时间轴只有开始时间(因为结束时间和开始时间相同)。
现在,下面的代码通过将DOM节点移动到其父节点的最后一个子节点,将时间轴的元素带到鼠标悬停的前面。
d3.selection.prototype.moveToFront = function() {
return this.each(function(){
this.parentNode.appendChild(this);
});
};
但问题在于,这并没有改变绑定数据的顺序,并打破了整体情节。
每个绘图元素在dom中具有特定顺序,该顺序以相同顺序绑定到d3数据。当上面的代码更改顺序以将任何元素带到前面时它会破坏顺序,它仍然认为子项的顺序是相同的,这是错误的。
以下是一个描述问题的JSFiddle示例: https://jsfiddle.net/pixelord/g2gt1f03/57/
一旦我更改了dom元素,如何保留数据顺序? 谢谢。
答案 0 :(得分:2)
不要自己做html更新,让d3这样做,记住d3代表数据驱动文档,所以重写你的问题
在鼠标悬停时将选择的数据移动到最后一个位置,然后重新渲染图形
想象一下,您的数据是[0,1,2,3]
,当您将鼠标悬停在代表第二个数据的任何元素上时,您将第二个数据移动到最后一个位置,即[0,2,3,1]
,而且几乎就是< / p>
.on("mouseover", function() {
var selection = d3.select(this);
var d = selection.datum()
// find d in data, extract it and push it
var index = data.indexOf(d)
var extract = data.splice(index, 1)
data = data.concat(extract)
draw()
});
接下来当您绑定数据时,请确保添加一种方法来区分使用发送到.data()
函数的第二个参数完成的两个状态,这可能是一个id
var data = [
[5, 8, 6],
[10, 10, 6],
[20, 25, 6],
[23, 27, 6]
].map(function (d, i) {
return {
id: i,
x1: d[0],
y1: d[2],
x2: d[1],
y2: d[2]
}
});
// ...
var itemGroup = maingroup.selectAll(".itemGroup")
.data(data, function (d) { return d.id })
最后你需要告诉d3我们已经修改了元素的顺序,并且它需要做你手工做的事情,这是重新排序元素
// update
itemGroup.order()
答案 1 :(得分:1)
我喜欢Mauricio解决问题的方式。
然而,经过一些调查后,我才知道我可以在绑定数据时指定键值。所以这是我的解决方案,没有重新排序数据本身:
我在绑定数据时指定键值,如
data(data_list,funcion(d){return d.keyValue})
问题得到解决。