Мое понимание svg заключается в том, что сначала создаются элементы, созданные первым, а последующие элементы раскрашены в верхнюю часть предыдущих элементов (алгоритм художника).svg порядок рендеринга линий и фигур при использовании d3
Я делаю древовидную визуализацию, состоящую из групп, каждая из которых является компанией. Каждая группа имеет 5 элементов. Во-первых, существует прямая линия для временной шкалы с кругами на каждом конце, включающая начало и конец компании.
Тогда есть вертикальная линия, которая крепится к другой окружности на временной шкале компании, приобретенной его.
Все это работает в теге <g>
в d3 (текст находится поверх кругов, расположенных поверх строк).
Однако это поведение не распространяется на группы. Текст может быть перед собственной линией сбора, но за линиями других.
Пример:
Здесь текст остается в передней части пути в своей группе, но получает за линиями других групп, даже если текст должен быть последняя часть добавляется ко всему SVG.
Heres соответствующий код:
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);
Не думаю, что это делает разницу, но весь этот код находится внутри угловой директивы.