2016-04-18 4 views
1

Ich habe eine SVG circle und rectangles um das gezogen. Jetzt zeichne ich 2 rectangles als group. Die rectangle combo kann mittig oder nach außen gerichtet sein. Es hängt von der height der rectangle. Das Problem, vor dem ich stehe, ist nicht in der Lage, die Lücke zwischen ihnen universell zu machen. Es variiert während rectangle nach innen oder nach außen gerichtet ist.Lücken zwischen Rechtecken um einen SVG Circle mit D3.js ist nicht universell

Hier ist die jsfiddlehttps://jsfiddle.net/xcn35ycm/. Danke für die Hilfe im Voraus.

+0

Sie möchten, dass jedes rote/grüne Balkenpaar parallel ist? Weil sie jetzt einen etwas anderen Winkel haben (um 5 Grad). – Paul

+0

Ja genau das ist was ich will. jedes Paar muss parallel sein, ungeachtet der Ausrichtung nach außen oder nach außen. – curiousguy

Antwort

0

Da rote und grüne Balken einen anderen Winkel haben, müssen Sie diesen Winkel anpassen, wenn Sie die Drehung anwenden. Ihre Transformation sollte so etwas wie:

.attr('transform', function(d) { 
var x = this.getAttribute('x'), 
    y = this.getAttribute('y'), 
    z = this.getAttribute('key'), 
    c = d.color, 
    a = (c=='green') ? -5 : 0; 
    if(z>=0) 
    { 
     return "rotate ("+ (d.angle+ang0+a) +" "+ x +" "+ y +")" 
    }else{ 
     return "rotate ("+ (d.angle+a) +" "+ (x) +" "+ (y) +")" 
    } 

Siehe DEMO.

Ein besserer Ansatz wäre, zunächst die eigentlichen Gruppen <svg:g> zu erstellen und dann die Balken innerhalb dieser (gedrehten) Gruppe hinzuzufügen, da die Basis der Balken in jedem Paar aufgrund der Berechnung der Koordinaten immer noch etwas abweicht Winkel.

Sie müssten Ihr Datenobjekt so ändern, dass sowohl rote als auch grüne Werte für eine Gruppe in einem Satz vorhanden sind. Als nächstes ändern Sie Ihr Skript, um zuerst die Gruppen zu zeichnen und dann die Balken anzufügen. Sehen Sie diesen Schnipsel für ein Beispiel:

var squares = [ 
 
    {angle: 45, color1: 'red', height1:-55, key1:-55, color2: 'green', height2:25, key2:25}, 
 
    {angle: 90, color1: 'red', height1:50, key1:50, color2: 'green', height2:-30, key2:-30}, 
 
    {angle: 135, color1: 'red', height1:35, key1:35, color2: 'green', height2:55, key2:55}, 
 
    {angle: 180, color1: 'red', height1:10, key1:10, color2: 'green', height2:30, key2:30}, 
 
    {angle: 225, color1: 'red', height1:75, key1:75, color2: 'green', height2:15, key2:15}, 
 
    {angle: 270, color1: 'red', height1:15, key1:15, color2: 'green', height2:15, key2:15}, 
 
    {angle: 315, color1: 'red', height1:25, key1:25, color2: 'green', height2:25, key2:25}, 
 
    {angle: 360, color1: 'red', height1:55, key1:55, color2: 'green', height2:55, key2:55}, 
 
]; 
 
var x0 = 190, y0 = 190, r= 100, w = 10, h= 55, ang0 = 180; 
 
var combos = d3.select('svg').selectAll("g").data(squares) 
 
    .enter() 
 
    .append("g") 
 
    .attr({width: 2 * w}) 
 
    .attr('height', function (d) { 
 
\t \t \t return Math.max(d.height1, d.height2) + r; 
 
\t \t }) 
 
    .attr('x', function (d) { 
 
    \t \t return x0; 
 
    }) 
 
    .attr('y', function (d) { 
 
    \t \t return y0; 
 
    }) 
 
    .attr('transform', function(d) { 
 
    \t return 'rotate(' + (d.angle + ang0) + ', ' + x0 + ', ' + y0 + ') translate(' + x0 + ', ' + y0 + ')'; 
 
    }); 
 
combos.append("rect") 
 
    .attr({width: w}) 
 
    .attr('x', -w) 
 
    .attr('y', function(d) { 
 
    \t return d.height1 < 0 ? r + d.height1 : r; 
 
    }) 
 
    .attr('height', function (d) { 
 
     return Math.abs(d.height1); 
 
    }) 
 
    .attr('key', function (d) { 
 
     return d.key1; 
 
    }) 
 
    .attr('fill', function(d) { 
 
    \t return d.color1; 
 
    }); 
 
     
 
combos.append("rect") 
 
    .attr('x', 0) 
 
    .attr('y', function(d) { 
 
    \t return d.height2 < 0 ? r + d.height2 : r; 
 
    }) 
 
    .attr({width: w}) 
 
    .attr('height', function (d) { 
 
     return Math.abs(d.height2); 
 
    }) 
 
    .attr('key', function (d) { 
 
     return d.key2; 
 
    }) 
 
    .attr('fill', function(d) { 
 
    \t return d.color2; 
 
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<svg width='400' height='400'> 
 
    <circle cx='190' cy='190' r='100' fill='none' stroke='red'></circle> 
 
</svg>

Ihr Skript zu vereinfachen, habe ich ein paar Änderungen. Sie müssen zum Beispiel keine x- und y-Koordinaten mithilfe des Winkels berechnen, wenn Sie die Transformation nur auf die Mitte der Kreise zentrieren. Die einzige Änderung, die für die Gruppe und die Balken erforderlich ist, besteht darin, den Radius hinzuzufügen. Auch erhältlich als DEMO.

+0

Danke @Paul für die Antwort. Könnten Sie mir bitte dafür eine Frage stellen? Weil das gleiche Problem auch bei mir besteht. Ich kann sie verwalten, während beide nach außen oder nach innen gerichtet sind. Aber entweder nach innen oder nach außen funktioniert es nicht – curiousguy

+0

Ich habe bereits eine Geige für die obige Lösung enthalten, klicken Sie auf den Link [DEMO] (https://jsfiddle.net/xcn35ycm/1/) in meiner Antwort. Um den vorgeschlagenen besseren Ansatz zu erreichen, müssten Sie Ihr Datenobjekt schließlich so ändern, dass sowohl grüne als auch rote Werte in einem Satz enthalten sind. Sie würden dann für jede Gruppe eine Gruppe erstellen und die Balken an diese Gruppe anhängen. – Paul

+0

Yeh eigentlich suchte ich nach einer Geige für den besseren Ansatz. Ich kann meine Daten ändern, wie es mir geht. Aber nicht sicher, wie Sie wollen, dass ich das Format ändere und wie ich die Gruppe erstelle. Da fragte ich nach einer Geige. – curiousguy