2012-12-02 16 views
7

Sto giocando un po 'con D3.js e ho lavorato quasi tutto. Ma voglio mettere le mie forme svg in un cerchio. Quindi mostrerò la differenza nei dati con il colore e il testo. So come disegnare cerchi e grafici a torta, ma in pratica voglio avere una cerchia di cerchi delle stesse dimensioni. E non averli si sovrappongono, l'ordine è irrilevante. Non so da dove iniziare, per scoprire x & y per ogni cerchio.Come posizionare forme svg in un cerchio?

risposta

6

Ecco un altro approccio a questo, per le forme di dimensione arbitraria, utilizzando tree il layout di D3: http://jsfiddle.net/nrabinowitz/5CfGG/

Il layout tree (docs, example) sarà capire il x, y posizionamento di ogni oggetto per te, sulla base di un dato raggio e una funzione che restituisce la separazione tra i centri di due elementi. In questo esempio, ho usato cerchi di varie dimensioni, in modo che la separazione tra loro è una funzione della loro raggi:

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

Uso del tree la layout D3 risolve il primo problema, che colloca gli elementi in un cerchio. Il secondo problema, come osserva @Markus, è come calcolare il raggio giusto per il cerchio. Ho preso un approccio un po 'approssimativo qui, per motivi di convenienza: stimiamo la circonferenza del cerchio come la somma dei diametri dei vari oggetti, con una data imbottitura in mezzo, quindi calcolare il raggio dalla circonferenza:

La circonferenza qui non è esatta, e questo sarà sempre meno preciso nel minor numero di oggetti che hai nel cerchio, ma è abbastanza vicino per questo scopo.

+0

Questo è il pezzo mancante, grazie per quello. – user1870877

9

Se ho capito bene, questa è una questione di matematica abbastanza standard:

Semplicemente ciclo su alcuni angolo variabile nella dimensione del passo appropriato e utilizzare sin() e cos() per calcolare il vostro valori xey.

Ad esempio:

Diciamo che si sta tentando di mettere 3 oggetti. Ci sono 360 gradi in un cerchio. Quindi ogni oggetto è a 120 gradi dal successivo. Se gli oggetti sono pixel 20x20 di dimensione, metterli nei seguenti punti:

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 

Qui, r è il raggio del cerchio e (xc, yc) sono le coordinate del punto centrale del cerchio. Il -10's si assicura che gli oggetti abbiano il loro centro (piuttosto che il loro angolo in alto a sinistra) sul cerchio. Il * pi()/180 converte i gradi in radianti, che è l'unità che richiede la maggior parte delle implementazioni di sin() e cos().

Nota: questo posiziona le forme equamente distribuite attorno al cerchio. Per assicurarti che non si sovrappongano, devi scegliere il tuo r abbastanza grande. Se gli oggetti hanno confini semplici e identici, disponi solo 10 di essi e calcola il raggio di cui hai bisogno e poi, se devi piazzare 20, raddoppia il raggio due volte, per 30 tre volte più grande e così via. Se gli oggetti sono di forma irregolare e vuoi posizionarli nell'ordine ottimale attorno al cerchio per trovare il cerchio più piccolo possibile, questo problema diventerà estremamente disordinato. Forse c'è una libreria per questo, ma non ne ho uno in testa e visto che non ho usato D3.js, non sono sicuro se fornirà questa funzionalità.

+0

Grazie per le informazioni sulla partita in background, stavo cercando una soluzione specifica per D3js, ma questo aiuta a capire. – user1870877

+0

Sto cercando una soluzione che consenta di posizionare i punti in altre forme di percorso, come le mezzelune e i cerchi. http://stackoverflow.com/questions/22340334/d3-js-user-viewer-chart –

+0

questa è la risposta :) – mithunsatheesh