我想在圆圈上方添加一些圆圈和红线到我的SVG。 然而,无论它们附加在哪个顺序:我总是在后面有这条线。
如何将它带到前面? 我试图使用moveToFront和z轴属性,但我无法解决它。
我的暂定:
d3.select("svg")
.append("g")
.attr("id", "chart")
.attr("width", width)
.attr("height", height)
filename = "assets/sources/datafile.csv"
d3.csv(filename, d => dataViz(d));
function dataViz(input_data) {
d3.select("svg")
.selectAll("circle")
.data(input_data)
.enter()
.append("circle")
}
d3.select("#chart")
.append('line')
.attr("id", "avg_line")
.attr("x1", xScale(0))
.attr("y1", yScale(3.75))
.attr("x2", xScale(upper_limit))
.attr("y2", yScale(3.75))
.attr("stroke-width", 5)
.attr("stroke", "red")
答案 0 :(得分:3)
这是d3.json
上众所周知的主题的有趣变体!由于d3.json
异步,因此在加载完成之前不会调用回调。虽然在附加圈子之后附加行似乎的调用似乎,但它实际上会立即执行,即在追加圈子之前从而在任何情况下将线定位在圆圈下方。解决方法是在附加圆圈后将回调行附加到回调中。
function dataViz(input_data) {
d3.select("svg")
.selectAll("circle")
.data(input_data)
.enter()
.append("circle")
d3.select("#chart") // <-- This should be inside the callback.
.append('line')
.attr("id","avg_line")
.attr("x1", xScale(0))
.attr("y1", yScale(3.75))
.attr("x2", xScale(upper_limit))
.attr("y2", yScale(3.75))
.attr("stroke-width",5)
.attr("stroke","red");
}
另一个错误在于您选择要追加的元素的方式。上面更正的代码将生成以下结构:
<svg>
<g id="chart" width="" height="">
<line id="avg_line" x1="" y1="" x2="" y2="" stroke-width="5" stroke="red"></line>
</g>
<circle></circle>
</svg>
这是因为您首先将<g id="chart">
附加到仅附加了该行的<svg>
。另一方面,圆圈会附加到<svg>
本身。看看这个结构很明显,为什么线仍然位于圆圈后面。
鉴于您没有提供完整的代码,我无法确定最佳解决方案是什么。但是,由于<g>
只是一个容器元素,它没有width
和height
属性,因此第一个语句应该放弃.append("g")
。另一方面,因为svg
是你想要追加的元素,所以最好保留对它的引用,这也可以让你不必反复重新选择相同的元素:
var svg = d3.select("svg") // Keep the reference to the <svg> for later use.
.attr("id", "chart")
.attr("width",width)
.attr("height",height);
在您的回调中,您可以使用此引用以所需顺序附加元素。把所有这些放在一起你得到的结果如下:
var svg = d3.select("svg")
.attr("id", "chart")
.attr("width",width)
.attr("height",height);
filename="assets/sources/datafile.csv"
d3.csv(filename, dataViz);
function dataViz(input_data) {
svg.selectAll("circle")
.data(input_data)
.enter()
.append("circle")
svg.append('line')
.attr("id","avg_line")
.attr("x1", xScale(0))
.attr("y1", yScale(3.75))
.attr("x2", xScale(upper_limit))
.attr("y2", yScale(3.75))
.attr("stroke-width",5)
.attr("stroke","red");
}
生成的SVG结构如下所示,将线条呈现在任何圆圈上方:
<svg id="chart" width="" height="">
<circle></circle>
<line id="avg_line" x1="" y1="" x2="" y2="" stroke-width="5" stroke="red"></line>
</svg>
Protip 与您的问题无关:
请注意,我如何简化您对d3.csv()
的通话。以下两个语句基本上是等价的(好吧,在我得到chastized之前,这不是完全是真的,但是在一阶近似中它们是):
d3.csv(filename, d => dataViz(d));
d3.csv(filename, dataViz);
无需将函数dataViz()
包装在另一个匿名箭头函数中;只要传递对它的引用,D3就会负责调用它。