d3.js尝试在同一选择器上调用数据方法两次会产生奇怪的结果

d3.js尝试在同一选择器上调用数据方法两次会产生奇怪的结果,d3.js,D3.js,我是D3新手,正在尝试用矩形构建一个类似表格的结构。我想标题是一个不同的颜色比其余的矩形。我编写了以下代码: table = svgContainer.selectAll('rect') .data([managedObj]) .enter() .append('rect') .attr("width", 120)

我是D3新手,正在尝试用矩形构建一个类似表格的结构。我想标题是一个不同的颜色比其余的矩形。我编写了以下代码:

table = svgContainer.selectAll('rect')
                    .data([managedObj])
                    .enter()
                    .append('rect')
                    .attr("width", 120)
                    .attr("height", 20)
                    .attr("fill", "blue")
                    .text(function(d) {
                        return d.name;
                    });

                // create table body
                table.selectAll('rect')
                    .data(managedObj.data)
                    .enter()
                    .append('rect')
                    .attr("y", function() {
                        shift += 20;
                        return shift;
                    })
                    .attr("width", 120)
                    .attr("height", 20)
                    .attr("fill", "red")
                    .text(function(d) {
                        return d.name;
                    });
这将产生以下结果:


除了将第二组矩形嵌套在第一个矩形中之外,这几乎是我想要的。这将导致仅第一个蓝色矩形可见。我假设这与调用数据方法两次有关。如何解决此问题?

我想我了解预期结果,因此我将尝试一下:

这一行:

table.selectAll('rect')
正在选择刚刚在此处创建的矩形:

table = svgContainer.selectAll('rect')....append('rect')....
您不希望将矩形附加到该矩形(或任何矩形)上,因为这不起作用,但您确实希望将它们附加到SVG本身

因此,您应该使用
svgContainer.selectAll,而不是
table.selectAll
,但还有两个问题:

  • 如果您使用
    svgContainer.selectAll('rect')
    您将选择已经附加的
    rect
    ,而实际上您需要一个空选择。看

  • 不能将文本放在矩形中(请参见),而是可以附加
    g
    元素,然后将
    text
    rect
    元素附加到这些元素中。而且,为了便于定位,您可以翻译
    g
    元素,以便更直接地定位矩形和文本

  • 因此,您的代码可能如下所示:

    var数据=[“test1”、“test2”、“test3”、“test4”];
    var svgContainer=d3.select('body').append('svg').attr('width',900.attr('height',400);
    var header=svgContainer.selectAll('g')
    .数据([数据])
    .输入()
    .append('g')
    .attr('transform','translate(0,0)');
    header.append('rect')
    .attr(“宽度”,120)
    .attr(“高度”,20)
    .attr(“填充”、“蓝色”);
    header.append('text')
    .attr('y',15)
    .attr('x',5)
    .文本(功能(d){
    返回“标题”;
    });
    //创建表体
    var-box=svgContainer.selectAll(“.box”)
    .数据(数据)
    .输入()
    .append('g')
    .attr('class','box')
    .attr('transform',函数(d,i){return'translate(0,+((i+1)*20)+');});
    box.append('rect').attr(“宽度”,120)
    .attr(“高度”,20)
    .attr(“填充”、“红色”);
    box.append('text')
    .attr('y',15)
    .attr('x',5)
    .文本(功能(d){
    返回d;
    });
    
    我想我理解预期的结果,所以我要试一试:

    这一行:

    table.selectAll('rect')
    
    正在选择刚刚在此处创建的矩形:

    table = svgContainer.selectAll('rect')....append('rect')....
    
    您不希望将矩形附加到该矩形(或任何矩形)上,因为这不起作用,但您确实希望将它们附加到SVG本身

    因此,您应该使用
    svgContainer.selectAll,而不是
    table.selectAll
    ,但还有两个问题:

  • 如果您使用
    svgContainer.selectAll('rect')
    您将选择已经附加的
    rect
    ,而实际上您需要一个空选择。看

  • 不能将文本放在矩形中(请参见),而是可以附加
    g
    元素,然后将
    text
    rect
    元素附加到这些元素中。而且,为了便于定位,您可以翻译
    g
    元素,以便更直接地定位矩形和文本

  • 因此,您的代码可能如下所示:

    var数据=[“test1”、“test2”、“test3”、“test4”];
    var svgContainer=d3.select('body').append('svg').attr('width',900.attr('height',400);
    var header=svgContainer.selectAll('g')
    .数据([数据])
    .输入()
    .append('g')
    .attr('transform','translate(0,0)');
    header.append('rect')
    .attr(“宽度”,120)
    .attr(“高度”,20)
    .attr(“填充”、“蓝色”);
    header.append('text')
    .attr('y',15)
    .attr('x',5)
    .文本(功能(d){
    返回“标题”;
    });
    //创建表体
    var-box=svgContainer.selectAll(“.box”)
    .数据(数据)
    .输入()
    .append('g')
    .attr('class','box')
    .attr('transform',函数(d,i){return'translate(0,+((i+1)*20)+');});
    box.append('rect').attr(“宽度”,120)
    .attr(“高度”,20)
    .attr(“填充”、“红色”);
    box.append('text')
    .attr('y',15)
    .attr('x',5)
    .文本(功能(d){
    返回d;
    });
    
    这里没有什么奇怪的
    svgContainer
    是矩形的输入选择。不能将一个矩形附加到另一个矩形。这里没有什么奇怪的
    svgContainer
    是矩形的输入选择。不能将一个矩形附加到另一个矩形。