【问题标题】:D3 transitions on more than 1 svg element超过 1 个 svg 元素的 D3 转换
【发布时间】:2013-04-23 07:35:18
【问题描述】:

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


                   }) 

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

【问题讨论】:

    标签: graph d3.js transitions


    【解决方案1】:

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

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

    svg.select("path")
    

    d3.select(this)
    

    一些通用的cmets。您选择路径的方式是调用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 有更多信息。

    【讨论】:

    • 非常感谢。无论是主要观点还是随后的整理要点,这都非常有帮助。塔!
    • 哦,等等,我想我有点搞混了。这对我不起作用,我想我知道为什么。 p2 p3 等是其他地方的文本,而不是行本身。所以当我使用“this”来指代文本时,对吗?而不是线。所以这不会更新现有的行吗?
    • 处理程序中的this 引用选定的DOM 元素。答案应该是d3.select(this) 而不是svg.select(this)——我的错,我会修复它。
    • 嘿,再次感谢。实际上,我使用您的其他建议以迂回的方式修复了它 - 我给了这些行一个 id,然后引用了 id。在d3中给猫剥皮的方法有很多,看起来......
    • 是的,您也可以这样做。在处理函数中做某事的好处是您可以直接访问this 中的 DOM 元素,这可以使事情变得更容易——不过任何其他方式都可以。
    猜你喜欢
    • 2022-01-21
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    • 2017-03-07
    相关资源
    最近更新 更多