更新嵌套选择的属性

时间:2014-05-22 18:00:37

标签: d3.js

我无法更新附加嵌套选择的dom元素的属性。

在这里摆弄:http://jsfiddle.net/k9zA7/1/

简而言之,我的问题是:给定嵌套数据结构选择嵌套节点的正确方法是什么,以便每次运行代码时都可以更新其属性,而不管数据结构如何变化?

认为我知道选择和数据加入的东西,但下面的行为让我感到困惑,所以我很遗憾。谢谢!

    var cities = [
        {name: 'Detroit', streets: [{name: 'E Warren Ave'}, {name: 'E Canfield St'}]},
        {name: 'San Francisco', streets: [{name: 'Capp St'}, {name: 'Mission St'}]},
        {name: 'Brooklyn', streets: [{name: '18th St'}, {name: 'Prospect Park West'}]}
    ];

    var colors = ['red', 'green', 'blue'];

    var run_count = 0;

    var draw = function() {

        var sel = d3.select('#cities').selectAll('div').data(cities);

        var streets_ul = sel.enter()
            .append('div')
            .attr('class', 'city')
            .text(function(city){return city.name})
            .append('ul')
            .attr('class', 'streets');

        // This updates the color every time it's executed, as expected
        sel.style('color', colors[run_count % 3]);

        var streets_sel = streets_ul.selectAll('streets')
                            .data(function(city){ return city.streets});

        streets_sel.enter()
            .append('li')
            .text(function(street){return street.name});

        // This only updates the color the first time it's run and is ignored on
        // subsequent executions. Why?
        streets_sel.style('color', colors[(run_count + 1) % 3]);

        run_count += 1;
    }

更新

为了让这项功能符合预期,我需要创建一个全新的选择来附加城市名称<li>元素,而不是创建我的第一个sel输入选择的子选择。工作小提琴:http://jsfiddle.net/k9zA7/4/

        var streets_sel = d3.selectAll('.city ul').selectAll('li')
                    .data(function(city){ return city.streets});

1 个答案:

答案 0 :(得分:1)

您的代码中只有少数拼写错误。首先,streets_ul(您用于嵌套选择)仅包含div的输入选择,因此它只会在您第一次运行代码时执行某些操作。将其更改为sel

其次,您选择的streets元素不存在。这是后续调用的问题,因为它会导致li元素再次附加。而是选择li元素。最后,colors[run_count + 1 % 3]应为colors[(run_count + 1) % 3],以达到您所追求的效果。

完整演示here