2017-02-07 2 views
0

Ich bin neu in D3 und versuche, aus Rechtecken eine tabellenähnliche Struktur zu erstellen. Ich möchte, dass der Header eine andere Farbe hat als der Rest der Rechtecke. Ich habe den folgenden Code geschrieben:d3.js versucht, die Datenmethode zweimal auf demselben Selektor aufzurufen, führt zu seltsamen Ergebnissen

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

Dies erzeugt die folgenden Ergebnisse: enter image description here

Das ist fast, was soll ich außer es die zweite Gruppe von Rechtecke innerhalb des ersten Rechtecks ​​nisten. Dies bewirkt, dass nur das erste blaue Rechteck sichtbar ist. Ich gehe davon aus, dass dies etwas damit zu tun hat, die Datenmethode zweimal aufzurufen. Wie kann ich dieses Problem beheben?

+0

Es gibt hier nichts fremd. 'svgContainer' ist eine Eingabeauswahl für ein Rechteck. Sie können ** nicht ein rect an ein anderes rect anhängen. –

Antwort

2

Ich glaube, ich das beabsichtigte Ergebnis zu verstehen, also werde ich es versuchen:

Diese Zeile:

table.selectAll('rect') 

das Rechteck erstellt ist die Auswahl gerade hier:

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

Sie möchten diesem Rechteck (oder einem anderen Rechteck) keine Rechtecke hinzufügen, da dies nicht funktioniert, Sie diese jedoch an das SVG selbst anhängen möchten.

Also statt table.selectAll sollten Sie svgContainer.selectAll verwenden, aber es gibt zwei andere Fragen:

  1. , wenn Sie verwenden svgContainer.selectAll('rect') Sie die Auswahl wird die rect Sie bereits angehängt, wenn Sie tatsächlich eine leere Auswahl wollen . Siehe die answer here.

  2. Sie können Text in einem rect platzieren (siehe answer here), stattdessen könnten Sie g Elemente anhängen und dann text und rect Elemente, die denen hängen. Und zur einfacheren Positionierung könnten Sie die g Elemente so übersetzen, dass die Rechtecke und der Text einfacher ausgerichtet sind.

So könnte Ihr Code wie folgt aussehen:

var data = ["test1","test2","test3","test4"]; 
 
\t 
 
var svgContainer = d3.select('body').append('svg').attr('width',900).attr('height',400); 
 

 

 
\t 
 
var header = svgContainer.selectAll('g') 
 
\t .data([data]) 
 
    .enter() 
 
    .append('g') 
 
\t .attr('transform','translate(0,0)'); 
 
\t \t \t \t \t 
 
header.append('rect') 
 
    .attr("width", 120) 
 
    .attr("height", 20) 
 
    .attr("fill", "blue"); 
 
\t 
 
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') 
 
\t .attr('class','box') 
 
\t .attr('transform',function(d,i) { return 'translate(0,'+((i+1)*20)+')'; }); 
 
\t \t \t \t \t 
 
     
 
boxes.append('rect').attr("width", 120) 
 
\t .attr("height", 20) 
 
\t .attr("fill", "red"); 
 
\t \t \t \t \t \t 
 
boxes.append('text') 
 
\t .attr('y',15) 
 
\t .attr('x',5) 
 
\t .text(function(d) { 
 
     return d; 
 
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Verwandte Themen