2012-12-02 13 views
7

Ich spiele ein bisschen mit D3.js und ich habe die meisten Dinge funktioniert. Aber ich möchte meine SVG-Formen in einen Kreis legen. Also werde ich den Unterschied in Daten mit Farbe und Text zeigen. Ich weiß, wie man Kreise und Tortendiagramme zeichnet, aber ich möchte im Grunde einen Kreis von Kreisen gleicher Größe haben. Und sie müssen sich nicht überschneiden, die Reihenfolge ist irrelevant. Ich weiß nicht, wo ich anfangen soll, um die x & y für jeden Kreis herauszufinden.Wie platziere ich SVG-Formen in einem Kreis?

Antwort

6

Hier ist ein weiterer Ansatz dazu, für Formen von beliebiger Größe, D3 mit tree Layout: http://jsfiddle.net/nrabinowitz/5CfGG/

Das tree Layout (docs, example) wird für Sie die x, y Platzierung der einzelnen Elemente herauszufinden, basierend auf ein gegebener Radius und eine Funktion, die den Abstand zwischen den Zentren von zwei beliebigen Elementen zurückgibt. In diesem Beispiel habe ich Kreise in verschiedenen Größen, so dass der Abstand zwischen ihnen ist eine Funktion ihrer Radius:

var tree = d3.layout.tree() 
    .size([360, radius]) 
    .separation(function(a, b) { 
     return radiusScale(a.size) + radiusScale(b.size); 
    }); 

Mit dem D3 tree Layout löst das erste Problem, die Elemente in einem Kreis Auslegen. Das zweite Problem, wie @Markus bemerkt, ist, wie man den richtigen Radius für den Kreis berechnet. Ich bin hier aus Gründen der Zweckmäßigkeit etwas grob vorgegangen: Ich schätze den Umfang des Kreises als die Summe der Durchmesser der verschiedenen Gegenstände, mit einer gegebenen Polsterung dazwischen, und berechne dann den Radius vom Umfang:

Der Umfang hier ist nicht genau, und dies wird immer weniger genau, je weniger Elemente Sie im Kreis haben, aber es ist nahe genug für diesen Zweck.

+0

Das ist das fehlende Stück, danke dafür. – user1870877

9

Wenn ich Dich richtig verstehe, ist dies eine ziemlich Standard-Mathematik-Frage:

einfach Schleife über einige Winkel Variable in der entsprechenden Schrittgröße und sin() und cos() verwenden Ihre x- und y-Werte zu berechnen.

Zum Beispiel:

Angenommen, Sie 3 Objekte zu platzieren versuchen. Es gibt 360 Grad in einem Kreis. Jedes Objekt ist also 120 Grad vom nächsten entfernt. Wenn Ihre Objekte 20x20 Pixel groß sind, legen Sie sie an folgenden Stellen:

x1 = sin( 0 * pi()/180) * r + xc - 10; y1 = cos( 0 * pi()/180) * r + yc - 10 
x2 = sin(120 * pi()/180) * r + xc - 10; y2 = cos(120 * pi()/180) * r + yc - 10 
x3 = sin(240 * pi()/180) * r + xc - 10; y3 = cos(240 * pi()/180) * r + yc - 10 

Hier r der Radius des Kreises und (xc, yc) sind die Koordinaten des Mittelpunkts des Kreises. Die -10's stellen Sie sicher, dass die Objekte ihren Mittelpunkt (und nicht ihre obere linke Ecke) auf dem Kreis haben. Die * pi()/180 wandelt die Grad in Radianten um, was die Einheit ist, die die meisten Implementierungen von sin() und cos() erfordern.

Hinweis: Dadurch werden die Formen gleichmäßig über den Kreis verteilt. Um sicherzustellen, dass sie sich nicht überlappen, müssen Sie Ihre r groß genug auswählen. Wenn die Objekte einfache und identische Grenzen haben, legen Sie einfach 10 von ihnen und berechnen Sie den Radius, den Sie brauchen, und dann, wenn Sie 20 platzieren müssen, machen Sie den Radius doppelt so groß, für 30 dreimal so groß und so weiter. Wenn die Objekte unregelmäßig geformt sind und Sie sie in der optimalen Reihenfolge um den Kreis platzieren möchten, um den kleinsten möglichen Kreis zu finden, wird dieses Problem extrem unordentlich. Vielleicht gibt es eine Bibliothek dafür, aber ich habe keine in meinem Kopf und da ich D3.js nicht benutzt habe, bin ich mir nicht sicher, ob es Ihnen auch diese Funktionalität bietet.

+0

Danke für die Hintergrund-Match-Informationen, ich suchte nach einer bestimmten D3js-Lösung, aber das hilft Verständnis. – user1870877

+0

Ich suche nach einer Lösung - die es ermöglicht, die Punkte in andere Pfadformen zu platzieren - wie Halbmonde und Kreise. http://stackoverflow.com/questions/22340334/d3-js-user-viewer-chart –

+0

das ist die Antwort :) – mithunsatheesh

Verwandte Themen