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

时间:2017-02-07 05:44:38

标签: d3.js

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

这产生以下结果: enter image description here

这几乎是我的意图,除了它在第一个矩形内嵌套第二组矩形。这导致仅第一个蓝色矩形可见。我假设这与调用数据方法两次有关。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

我想我理解了预期的结果,所以我会试一试:

这一行:

table.selectAll('rect')

正在选择刚创建的矩形:

table = svgContainer.selectAll('rect')....append('rect')....

您不希望将矩形附加到该矩形(或任何矩形),因为这不会起作用,但您确实希望将它们附加到SVG本身。

因此,您应使用table.selectAll代替svgContainer.selectAll,但还有其他两个问题:

  1. 如果你使用svgContainer.selectAll('rect'),当你真正想要一个空的选择时,你将选择你已经附加的rect。请参阅answer here

  2. 您无法在矩形中放置文字(请参阅answer here),而是可以附加g元素,然后将textrect元素附加到这些元素。而且,为了便于定位,您可以翻译g元素,以便更直接地定位矩形和文本。

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

    
    
    var data = ["test1","test2","test3","test4"];
    	
    var svgContainer = d3.select('body').append('svg').attr('width',900).attr('height',400);
    
    
    	
    var header = svgContainer.selectAll('g')
    	.data([data])
        .enter()
        .append('g')
    	.attr('transform','translate(0,0)');
    					
    header.append('rect')
        .attr("width", 120)
        .attr("height", 20)
        .attr("fill", "blue");
    	
    header.append('text')
        .attr('y',15)
        .attr('x',5)
        .text(function(d) {
             return "header";
        });
    
         // create table body
    var boxes = svgContainer.selectAll('.box')
        .data(data)
        .enter()
        .append('g')
    	.attr('class','box')
    	.attr('transform',function(d,i) { return 'translate(0,'+((i+1)*20)+')'; });
    					
           
    boxes.append('rect').attr("width", 120)
    	.attr("height", 20)
    	.attr("fill", "red");
    						
    boxes.append('text')
    	.attr('y',15)
    	.attr('x',5)
    	.text(function(d) {
            return d;
        });
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    &#13;
    &#13;
    &#13;