D3在超过1个svg元素上转换

时间:2013-04-23 07:35:19

标签: graph d3.js transitions

我是D3的新手,并尝试学习一些基础知识。我一直在使用D3提示和技巧书,并尝试调整线图以获得两个过渡的线。基本思路是A行从数据A开始,B行用数据B开始。然后单击按钮,A行转换为数据C,B行转换为数据D.

线图是一个随时间变化的图,所以我将x轴设置为时间轴。

这是我正在使用的代码(减少一点)

      // Define the axes
var xAxis = d3.svg.axis().scale(x)                          
.orient("bottom").ticks(10);            
var yAxis = d3.svg.axis().scale(y)                      
.orient("left").ticks(5);                               

// Define the line
var valueline = d3.svg.line()                               
.x(function(d) { return x(d.date); })                   
.y(function(d) { return y(d.number); });                    

// Define the line
var valueline2 = d3.svg.line()                              
.x(function(d) { return x(d.date); })                   
.y(function(d) { return y(d.number2); });                   

// Define the line
var valueline3 = d3.svg.line()                              
.x(function(d) { return x(d.date); })                   
.y(function(d) { return y(d.number3); });                   

// Define the line
var valueline4 = d3.svg.line()                              
.x(function(d) { return x(d.date); })                   
.y(function(d) { return y(d.number4); });                   

// Adds the svg canvas
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 + ")"); 
// Get the data
d3.tsv("data/data3.tsv", function(error, data) {                
d.date = parseDate(d.date);                         
d.number = +d.number;                               
d.number2 = +d.number2; 
d.number3 = +d.number3; 
d.number4 = +d.number4; 
d.number5 = +d.number5; 
});

// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));      
y.domain([0, d3.max(data, function(d) { return d.number4; })]); 

// Add the  path.
svg.append("path")                                  
.attr("d", valueline(data));    

    //Add the transition for the first line                 
d3.select("p2")
.on("click", function() {
svg.select("path")
.data(data)
.transition()
.delay(function(d, i) {
return i / 40 * 1000;
})
.duration(1500)                         
.attr("d", valueline3(data));
}) ;



// Add the second path.
svg.append("path")                                                                  
    .attr("d", valueline2(data))    

//Add the transition for the second line        
d3.select("p3")
            .on("click", function() {
                svg.select("path")
                   .data(data)
                   .transition()
                   .delay(function(d, i) {
                       return i / 40 * 1000;
                   })
                   .duration(1500)      
                    .attr("d", valueline4(data));


                   }) 

问题是,转换最终会应用到第一行,第二行是静态我做错了什么?

1 个答案:

答案 0 :(得分:2)

问题是你在点击处理程序中调用了svg.select("path")。这将选择SVG中的第一个路径 - 也就是说,将选择和更改相同路径(您首先添加的路径)的两个路径。

缓解此问题的方法是在附加到特定路径的点击处理程序中引用this,即替换

svg.select("path")

d3.select(this)

一些一般性评论。选择路径的方法是调用d3.select("p2")。这几乎肯定不是你想要的 - 这是选择具有该名称的DOM元素。如果您已为相应路径指定了ID,请使用d3.select("#p2"),如果您已指定课程使用d3.select(".p2")

如果您将路径作为数组传递,则创建路径时也不需要引用data两次。也就是说,而不是

svg.select("path").data(data)                        
   .attr("d", valueline3(data));

你可以做到

svg.select("path").data([data])                        
   .attr("d", valueline3);

删除了一些冗余。

最后,D3的方法是使用相同的行生成器并为不同的行传入不同的数据数组。您只需将原始数据提取到四个不同的数组中并使用它们,而不是使用四个不同的线生成器。您也可以通过一次通话完全完成。 This question有更多信息。