ACK*_*low 7 javascript svg d3.js
使用D3 2.4.2,我创建了许多路径元素,如下所示:
for (var i = 0; i < pathIndices.length; i++) {
graph.append("svg:path")
.style("stroke", colors[pathIndices[i]])
.style("stroke-width", "2.5px")
.style("fill", "none")
.attr("class", PATH_CLASS)
.attr("id", PATH_ID_PREFIX + pathIndices[i])
.attr("d", lineFunc(data))[0];
}
Run Code Online (Sandbox Code Playgroud)
它们都按预期绘制到屏幕上.稍后,我想在用户输入一些内容时将其中一个带到前面,所以我有一个事件处理程序来执行此操作:
var pathToHighlight = selectPath(pathIndex);
var paths = d3.selectAll("." + PATH_CLASS);
paths.sort(
function(a, b) {
if (a === pathToHighlight) {
return -1;
}
else if (b === pathToHighlight) {
return 1;
}
else {
return 0;
}
}
);
Run Code Online (Sandbox Code Playgroud)
在Chrome中设置断点表示此处的路径选择成功(paths是一个SVGPathElements数组).但代码什么都不做,并且在sort函数中设置断点显示a并且b始终未定义.进入d3代码,我看到当内部函数d3_selection_sortComparator使用适当的参数调用我的比较器时,除了它们与它们自己的未定义__data__成员进行AND运算,这导致undefined传入:
// a and b are correct, but a.__data__ and b.__data__ are undefined
return comparator(a && a.__data__, b && b.__data__);
Run Code Online (Sandbox Code Playgroud)
我在这做错了什么?我的路径正确地绘制到屏幕上,所以看起来他们应该有正确的数据.对?
编辑:图片:


你正在使用selection.sort它听起来像你期待的那样Array.sort.该selection.sort方法用于基于绑定到元素和的数据对选择进行排序.如果您的元素没有绑定到它们的数据,那么这将不起作用.如果你想根据其他东西对选择进行排序(比如测试一个元素引用是否等于另一个),你应该在调用之前从选择中获取元素数组,如下所示:ab.sort()
// `paths` is a Selection
var paths = d3.selectAll("." + PATH_CLASS);
// `pathElements` is an Array
var pathElements = paths[0];
pathElements.sort(function(a,b) {
// now `a` and `b` are Element references
// ...
})
Run Code Online (Sandbox Code Playgroud)
然后,您必须采取额外步骤将DOM顺序与结果数组的顺序进行匹配.
也就是说,如果你只是想把它带到pathToHighlight前面,更好的方法是将这个单个元素重新附加到DOM.
如果pathToHighlight是选择,你会这样做:
var el = pathToHighlight.node();
el.parentNode.appendChild(el);
Run Code Online (Sandbox Code Playgroud)
或者,如果它已经是元素参考,您可以这样做:
pathToHighlight.parentNode.appendChild(pathToHighlight);
Run Code Online (Sandbox Code Playgroud)
您可以尝试使用.datum()function 来代替 吗.__data__?
https://github.com/mbostock/d3/wiki/Selections#wiki-datum
Selection.datum([value])
获取或设置每个选定元素的绑定数据