我对svg的理解是首先绘制的元素首先绘制,后面的元素绘制在前面元素的顶部(painter算法)。
我正在制作一个树状的可视化,由群组成,每个群组都是公司。每组有5个元素。首先,时间轴上有直线,每端有圆圈,包括公司的开始和结束。
然后,有一条垂直线连接到获得它的公司时间轴上的另一个圆圈。
所有这些都适用于d3中的<g>
标记内(文字位于圆圈顶部,位于行顶部)。
但是,这种行为不适用于各组。该文本可能位于其自己的采集线之前,但落后于其他采访线。
示例:
这里,文本保留在其组中的路径前面,但是后面是其他组的行,即使文本应该是添加到整个svg的最后一部分。
见下相关代码:
function start(root) {
var duration = d3.event && d3.event.altKey ? 5000: 500;
var nodes = tree.nodes(root);
var node = sv.selectAll("g.node")
.data(nodes, function(d) {return d.id || (d.id = ++i); });
node.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) {
if(d.depth === 0){
d.xy = [0, centerline + d.position];
}
else{
d.xy = [(2016-parseInt(d.acquisition_date))*30, centerline + d.position];
}
//don't need this anymore
return "scale(" + 1 + "," + 1 + ")"; });
function lines(node){
node.append("svg:line")
.attr("x1", function(d){
return d.xy[0];
})
.attr("y1", function(d){
return centerline + d.position;
})
.attr("x2",function(d){
return (2016 - parseInt(d.founded_date))*30;
})
.attr("y2", function(d){
return centerline + d.position;
})
.attr("timeline", function(d){
return d.name;
})
.style("stroke", function(k){
if(k.depth === 0) {
return "black";
}
return "#ccc";
})
.style("stroke-width", "2.5");
node.append("svg:path")
.filter(function(d){
if(d.parent){
d.acquiz = [((2016)- parseInt(d.acquisition_date))*30, centerline + d.parent.position];
}
return d.hasOwnProperty('parent');
})
.attr("acquired_by", function(d){
return d.parent.name;
})
.attr("acquired", function(d){
return d.name;
})
.attr("d", function(d){
return "M" + d.xy[0] +"," + d.xy[1] + " L" + d.acquiz[0] + "," +d.acquiz[1];
})
.attr("stroke", "#ccc")
.attr("stroke-width", 2)
.style("fill", "none");
}
function circles(node){
node.append("svg:circle")
.attr("cx", function(d){
return (2016 - parseInt(d.founded_date))*30;
})
.attr("cy", function(d){
return centerline + d.position;
})
.attr("r", 4.5)
.style("fill", function(d){ return d.children ? "white"
: "white"; });
node.append("svg:circle")
.attr("cx", function(d){
if(d.acquisition_date){
return (2016 - parseInt(d.acquisition_date))*30;
}
else{
return 0;
}
})
.attr("cy", function(d){
return centerline + d.position;
})
.attr("r", 4.5)
.style("fill", function(d) { return d.children ? "white"
: "white"; });
node.append("svg:circle")
.filter(function(d){
return d.hasOwnProperty('parent');
})
.attr("cx", function(d){
return ((2016 - parseInt(d.acquisition_date))*30);
})
.attr("name", function(d){
return d.name;
})
.attr("cy", function(d){
return centerline + d.parent.position;
})
.attr("r", 5.5)
.attr("acq", function(d){return d.name;})
.style("fill", "lightsteelblue");
}
function text(node){
node.append("svg:a")
.attr("ng-attr-xlink:href", function(d){
return "http://xxxxxxxxxxxx.edu/company/" + encodeURIComponent(d.name);
})
.append("svg:text")
.attr("x", function(d){
return d.refined[0]; })
.attr("dy", "1.5em")
.attr("y", function(d){
return d.refined[1];
})
.style("fill-opacity", 1)
.attr("text-anchor", function(d) { return d.children || d.children ? "middle" : "middle"; })
.text(function(d) {
return d.name;
});
}
lines(node);
circles(node);
text(node);
不要认为这有所不同,但所有这些代码都在一个角度指令中。
答案 0 :(得分:2)
前景中的内容和后台内容的顺序不依赖于何时通过 d3.js 插入元素(也就是创建SVG DOM元素并添加它通过d3.js'API)到SVG文档,但取决于生成的 SVG 中的顺序。
也就是说,text(node)
的调用会导致文本元素附加到已添加到SVG的各种g
元素中,这已决定了绘制顺序
我要尝试的是将所有text
元素附加到SVG文档的末尾。会产生类似的结果:
...
<g class="node">...</g>
<g class="node">...</g>
<g class="node">...</g>
<g class="text-overlays">
<text>1</text
<text>2</text
...
</g>
...