2017-03-01 2 views
1

Ich versuche Box-Plots als Teil einer Datenvisualisierungsschnittstelle zu implementieren, die d3 und AngularJS verwendet. Ich arbeite mit diesem Box-Plot-Paket: https://bl.ocks.org/mbostock/4061502.d3.js Box Plot Positionierung Problem mit box.js

Ich kann jedoch nicht herausfinden, welcher Teil des Beispielcodes die Positionierung der Box-Plots steuert. Im Beispiel sind die fünf Boxplots sequenziell angeordnet. Wenn ich versuche, meine Plots zu generieren, erscheinen sie alle übereinander.

enter image description here

Hier ist der Code, dass ich die Box-Plots zu erzeugen bin mit:

  boxplots = svg.selectAll("svg") 
       .data(boxPlotData) 
       .enter().append("svg") 
       .attr("class", "box") 
       .attr("width", boxWidth + margin.left + margin.right) 
       .attr("height", boxHeight + margin.bottom + margin.top) 
       .append("g") 
       .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
       .call(chart); 

Hier ist der Code für wie meine svg Leinwand erstellt. Dies wird in einer Winkel Richtlinie getan:

template:"<svg width='825' height='600'></svg>", 
    link: function($scope, elem){ 

     var d3 = $window.d3; 
     var rawSvg=elem.find('svg'); // this is the svg created in the template 

     var width = rawSvg[0].attributes[0].value; 
     var height = rawSvg[0].attributes[1].value; 

     var svg = d3.select(rawSvg[0]); 

Edit: noch nicht perfekt, aber es bekommen:

enter image description here

+1

Was ist das übergeordnete Element der '' Elemente, die Sie erstellen? Beachten Sie, dass das übergeordnete Element im Beispiel ein HTML-Element und kein SVG-Element ist. Im Grunde erstellen sie für jede Box ein eigenes Bild, das automatisch nebeneinander platziert wird. – Sirko

+0

Ich habe meinen ursprünglichen Post mit dem Code aktualisiert, der meine SVG-Leinwand erstellt. Da ich ein SVG-Element als übergeordnetes Element für die Box-Plots habe, scheint es, dass sie beide standardmäßig auf (0, 0) für ihren Startort festgelegt sind. Ich gehe davon aus, dass ich sie an den richtigen Ort übersetzen muss? Wohin geht dieser Code? Sie werden beide auf einmal erstellt, so dass ich mir nicht sicher bin, wie ich ihnen verschiedene Übersetzungskoordinaten geben kann. –

Antwort

2

Was Sie brauchen, ist ein Ordinalskala der SVG-Elemente für die Boxen zu positionieren innerhalb die Eltern svg. Unter der Annahme, width stellt die Breite des svg Element Eltern- und data ist ein Array von Ihrer Datenelemente, können Sie diese verwenden, um die Skala zu erstellen:

const x = d3.scaleBand() 
       .range([0, width]) 
       .domain(data.map((el,i) => i)); 

Im svg Schöpfung können Sie jetzt

boxplots = svg.selectAll("svg") 
       .data(boxPlotData) 
       .enter().append("svg") 
       .attr("x", (d,i) => x(i)) // this is added 
       .attr("class", "box") 
       .attr("width", boxWidth + margin.left + margin.right) 
       .attr("height", boxHeight + margin.bottom + margin.top) 
       .append("g") 
       .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
       .call(chart); 

PS: Dies setzt voraus, dass Sie v4 von d3js verwenden. Die Syntax in v3 für die Skalierung ist unterschiedlich.

PPS: Ich kann den Code derzeit nicht testen, aber es sollte wie beschrieben funktionieren.

+0

Ich habe Ihren Code hinzugefügt. Muss etwas optimiert werden - die Breite jedes Boxplots wird durch eine Variable definiert (boxWidth, sollte jetzt 80 Pixel betragen), so dass sie mindestens um diesen Wert verschoben werden müssen. Ich bin sicher, ich kann es bekommen, wenn ich ein bisschen herumspiele. –

+0

Nachfolgefrage: Kann ich mit scaleBand zwei verschiedene Gruppen von Boxplots erstellen? Letztendlich brauche ich vier Diagramme, zwei auf jeder Seite des Bildschirms. –

+0

Ich werde morgen noch einmal rennen. Ich habe momentan keine Zeit. – Sirko