为什么我的d3.js selectAll + filter没有过滤?

时间:2015-04-08 18:23:17

标签: javascript d3.js

我正在尝试为每天创建一个父 g 标记,其中包含标签的子 g 标记。代码的第一项代码正确地生成父项:

var content = d3.select(".content").attr("height", 1000).attr("width", 1000);

//create day groups
var days = content.selectAll("g").filter(".day")
        .data([0,1,2,3,4,5,6,7,8,9])
        .enter().append("g")
        .attr("class", "day");

当我尝试为每个人添加子 g 标签时,它不起作用:

// create the day headers
var day_labels = days.selectAll("g").filter(".day_label")    
        .data(function (d) {
            return d;
        })
        .enter().append("g")
        .attr("class", "day_label");

我的语法有问题吗?

1 个答案:

答案 0 :(得分:2)

问题在于您的数据绑定。 selection.data()期望绑定一个数组,在第一部分创建日期组时效果很好。但请记住,d3.selectAll()会将发现的元素分组到相应的组中。第二部分中的selection.selectAll()将保留此分组,并对先前每组绑定的数据进行操作。因此,使用标识函数将数据绑定到子节点将返回绑定到相应日节点的数组项。例如,对于第一天标签,这将返回数组中仅0的第一项。但是,要使selection.data()处理子选择,这应该是一个数组。

检查further details的api参考和示例:

  

例如,您可以将二维数组绑定到初始数组   选择,然后将包含的内部数组绑定到每个   子选择。在这种情况下,值函数是标识   function:被传递给每个子元素组   绑定到父元素的数据,并返回此数据数组。

要实现这一点,您可以:

  1. 绑定一个二维数组,在你的情况下有点笨拙。

    var days = content.selectAll("g.day")
            .data([[0],[1],[2],[3],[4],[5],[6],[7],[8],[9]])
            .enter()
                .append("g")
                    .attr("class", "day");
    

    这会使子部分保持原样。

  2. 结合父母与子女的创作。

    var day_labels = content.selectAll("g.day")
                        .data([0,1,2,3,4,5,6,7,8,9])
                        .enter()
                            .append("g")
                                .attr("class", "day")
                            .append("g")
                                .attr("class", "day_label");
    
  3. 您的选择主要取决于您要对数据绑定做什么。

    顺便问一下,你看过迈克博斯托克关于"How Selections Work"的文章吗?它绝对值得花时间阅读。

相关问题