2014-01-15 73 views
3

我已经把一个多行图表放在一起,它有一个转换集,所以行被“绘制”并且标签依次连接。它的工作原理,但我不明白如何分别访问每一行的长度。我有的代码仅通过.node()返回第一条路径的长度。这样做的结果是,所有路径被赋予第一个给其他路径的起点不正确的长度。代码如下。任何帮助深表感谢。访问d3中的SVG路径长度

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; }); 

});

回答

6

您可以添加路径的总长度为另一个属性的数据,然后使用:在

path.each(function(d) { d.totalLength = this.getTotalLength(); }) 
    .attr("stroke-dasharray", function(d) { return d.totalLength + " " + d.totalLength; }) 
    .attr("stroke-dashoffset", function(d) { return d.totalLength; }) 
// etc 
+0

点。感谢所有的帮助! – user3194692

+0

嗨拉尔斯。这将如何工作的单个路径对象?例如http://jsfiddle.net/5e2HD/ – geotheory

+0

不确定你的意思 - 应该完全一样http://jsfiddle.net/5e2HD/1/ –