Zugriff auf SVG-Pfad-Länge in d3
Ich habe ein multi-line-Diagramm, das einen übergang einstellen, damit die Linien 'gezogen' und die Etiketten eins nach dem anderen. Es funktioniert, aber ich kann nicht sehen, wie Sie auf die Länge der jede Zeile einzeln. Der code, den ich habe gibt die Länge für den ersten Pfad, der nur über .node()
. Das Ergebnis dieser ist, dass alle Wege sind angesichts der Länge des ersten, das gibt falsche start-Punkte für die anderen Wege. Der code ist unten. Jede Hilfe wird sehr geschätzt.
var margin = {top: 20, right: 80, bottom: 30, left: 60},
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangePoints([0, width], 1);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category20();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("linear")
.x(function(d) { return x(d.month); })
.y(function(d) { return y(d.rainfall); });
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("data.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Month"; }));
var countries = color.domain().map(function(country) {
return {
country: country,
values: data.map(function(d) {
return {month: d.Month, rainfall: +d[country]};
})
};
});
x.domain(data.map(function(d) { return d.Month; }));
y.domain([
d3.min(countries, function(c) { return d3.min(c.values, function(v) { return v.rainfall - 7; }); }),
d3.max(countries, function(c) { return d3.max(c.values, function(v) { return v.rainfall + 7; }); })
]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", "1.1em")
.style("text-anchor", "end")
.text("Rainfall (mm)");
var country = svg.selectAll(".country")
.data(countries)
.enter().append("g")
.attr("class", "country");
var path = country.append("path")
.attr("id", function(d, i) { return "line" + i; })
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.country); })
var totalLength = path.node().getTotalLength();
path.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.delay(function(d, i) { return i * 1000; })
.duration(1000)
.ease("linear")
.attr("stroke-dashoffset", 0)
.each("end", function() {
labels.transition()
.delay(function(d, i) { return i * 1000; })
.style("opacity", 1);
});
var labels = country.append("text")
.datum(function(d) { return {country: d.country, value: d.values[d.values.length - 1]}; })
.attr("class", "label")
.attr("transform", function(d) { return "translate(" + x(d.value.month) + "," + y(d.value.rainfall) + ")"; })
.attr("x", 3)
.attr("dy", ".35em")
.style("opacity", 0)
.text(function(d) { return d.country; });
});
Du musst angemeldet sein, um einen Kommentar abzugeben.
Könnte man hinzufügen, dass die gesamte Länge des Pfades als ein weiteres Attribut zu den Daten und verwenden Sie dann, dass: