2

我是 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));


                   }) 

问题是其他转换最终适用于第一行,而第二行是静态的 我做错了什么?

4

1 回答 1

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 方法是使用相同的行生成器并为不同的行传入不同的数据数组。无需使用四个不同的线生成器,您只需将原始数据提取到四个不同的数组中并使用它们。您也可以通过一个电话完全完成。这个问题有更多信息。

于 2013-04-23T08:20:47.593 回答