2016-03-28 6 views
2

sei angenommen, dass I-Daten wie diese haben:Erzeugen mehrerer DOM Elemente aus einem einzelnen Datenpunkt mit D3.js

[{from: 3, to: 5}, {from: 1, to: 2}] 

Ich möchte das folgende SVG generieren:

<svg width="100" height="100"> 
    <g transform="translate(0,0)"> 
    <rect x="0" width="5" height="5"></rect> 
    <rect x="10" width="5" height="5"></rect> 
    <rect x="20" width="5" height="5"></rect> 
    </g> 
    <g transform="translate(0,30)"> 
    <rect x="0" width="5" height="5"></rect> 
    <rect x="10" width="5" height="5"></rect> 
    </g> 
</svg> 

Grundsätzlich Für jeden Datenpunkt muss ich to - from + 1 Rechtecke generieren. So habe ich angefangen:

var width = 100; 
var x = d3.scale.ordinal() 
    .domain(d3.range(10)) 
    .rangeRoundBands([0, width]); 

var svg = d3.select('svg').append('svg') 
    .attr('width', width) 
    .attr('height', 100); 
var row = svg.selectAll('g') 
    .data(data) 
    .enter().append('g') 
    .attr('transform', function(d, i) { return 'translate(0,' + i * 30 + ')';}); 

Nun, wie erzeuge ich mehrere Rectures für jeden Datenpunkt mit der Kettensyntax?

Ich weiß, dass ich es so tun könnte:

var rects = row.selectAll('rect') 
    .data(function(d) { return d3.range(d.to - d.from + 1);}) 

aber ich möchte die Schaffung nutzlos Arrays zu vermeiden.

+1

Ihre Reichweite Idee ist wahrscheinlich der beste Weg zu gehen, da d3 grundsätzlich dom Elemente erzeugt eine Eins-zu -ein gegen Daten. Ich würde über irgendwelche Effizienz-/Müllsammlungsprobleme mit einem Array einiger Integer nicht sorgen. – mgraham

Antwort

1

Sie in der append() Funktion laufen könnte und Ihre Rects dynamisch erstellen dort:

var data = [{from: 3, to: 5}, {from: 1, to: 2}, {from: 4, to: 9}]; 
 

 
var width = 100; 
 

 
var x = d3.scale.ordinal() 
 
    .domain(d3.range(10)) 
 
    .rangeRoundBands([0, width]); 
 

 
var svg = d3.select('div').append('svg') 
 
    .attr('width', width) 
 
    .attr('height', 100); 
 

 
var row = svg.selectAll('g') 
 
    .data(data) 
 
    .enter().append(function(d) { 
 
    var rects = document.createElementNS('http://www.w3.org/2000/svg', 'g'); 
 
    for (var i = d.from; i <= d.to; i++) { 
 
     var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); 
 
     rect.setAttribute('width', 5); 
 
     rect.setAttribute('height', 5); 
 
     rect.setAttribute('x', (i - d.from) * 10); 
 
     rects.appendChild(rect); 
 
    } 
 
    return rects; 
 
    }) 
 
    .attr('transform', function(d, i) { 
 
    return 'translate(0,' + i * 30 + ')'; 
 
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<div></div>

+0

Danke für die Antwort! Ich habe Probleme mit verschachtelten Daten. Wenn Sie Zeit haben, können Sie bitte einen Blick darauf werfen ([JS Bin] (http://jsbin.com/jewicoxivo/edit?html,js))? Die erste Zeile des Diagramms sollte zwei Segmente enthalten, aber nur eine wird angezeigt. Einige 'g' Gruppen sind leer! Zugegeben, das passiert auch mit der 'd3.range' Lösung, aber ich kann nicht erklären warum ... – rubik

+0

Nevermind! Ich foudn den Fehler in meinem Code! – rubik

Verwandte Themen