2014-06-20 17 views
6


Così sto usando lo stesso codice come questa galleria esempio D3 (con i miei dati):D3 bubble chart/pack layout - Come far emettere bolle dalle bolle più grandi al più piccolo?

http://bl.ocks.org/mbostock/4063269


mi piacerebbe ottenere un grafico a bolle in cui i cerchi sono disposti con il più grande al centro e quindi si irradiano al più piccolo.


Ecco un mock up che ho creato in Photoshop:

What I actually want



Ecco che cosa ottengo quando uso l'esempio (l'algoritmo cerchio di imballaggio di default con ordinamento predefinito):

Default packing



ho provato modificando il tipo (compreso il tentativo d3.ascending e d3.descending). Il meglio che ho potuto venire con appena fondamentalmente sovverte il genere con una costante (ah!), Ma ancora è lontano da quello che vorrei:

//... 
.sort(function(a, b) { return -1;}) 
//... 

Best I could get by tweaking sort



Ok, in modo che qualsiasi possibilità che ciò si possa fare senza dover modificare l'algoritmo del layout del pacchetto D3 vero e proprio? In caso contrario, forse qualcuno ha esteso o modificato il layout del pacchetto e potrebbe dirmi le 5 linee che potrei modificare nel sorgente D3 per hackerarlo.



Grazie in anticipo!


Edit:

Come richiesto, ecco il codice che sto usando. In sostanza lo stesso del campione linkato sopra, con alcune modifiche superficiali, come indicato dalle linee commentato:

var diameter = 960, 
format = d3.format(",d"), 
color = d3.scale.category20c(); 

var bubble = d3.layout.pack() 
// .sort(null) 
// .sort(d3.ascending) 
// .sort(d3.descending) 
    .sort(function(a, b) { return -1;}) // basically a < b always 
    .size([diameter, diameter]) 
    .padding(1.5); 

var svg = d3.select("body").append("svg") 
    .attr("width", diameter) 
    .attr("height", diameter) 
    .attr("class", "bubble"); 

d3.json("data.json", function(error, root) 
{ 
    var node = svg.selectAll(".node") 
     .data(bubble.nodes(classes(root)) 
     .filter(function(d) { return !d.children; })) 
     .enter().append("g") 
     .attr("class", "node") 
     .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 

    node.append("title") 
     .text(function(d) { return d.className + ": " + format(d.value); }); 

    node.append("circle") 
     .attr("r", function(d) { return d.r; }) 
     .style("fill", function(d) 
      { 
       // return color(d.packageName); 
       return color(d.value); // this gives a different color for every leaf node 
      }); 

    node.append("text") 
     .attr("dy", ".3em") 
     .style("text-anchor", "middle") 
    // .text(function(d) { return d.className.substring(0, d.r/3); }); 
}); 

// Returns a flattened hierarchy containing all leaf nodes under the root. 
function classes(root) 
{ 
    var classes = []; 

    function recurse(name, node) { 
    if (node.children) node.children.forEach(function(child) { recurse(node.name, child); }); 
    else classes.push({packageName: name, className: node.name, value: node.size}); 
    } 

    recurse(null, root); 
    return {children: classes}; 
} 

d3.select(self.frameElement).style("height", diameter + "px"); 

E i miei dati.di file JSON:

{ 
    "name": "Root", 
    "children": [ 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 2098629 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 104720 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 5430 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 102096 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 986974 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 59735 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 1902 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 120 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 870751 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 36672 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 274338 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 517693 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 145807 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 476178 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 11771 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 153 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 2138 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 8436 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 3572 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 120235 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 210945 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 56033 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 358704 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 295736 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 26087 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 33110 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 3828 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 1105544 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 98740 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 80723 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 5766 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 1453 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 10443176 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 14055 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 1890127 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 404575 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 272777 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 1269763 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 5081 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 3168510 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 717031 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 88418 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 762084 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 255055 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 535 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 81238 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 17075 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 5331 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 74834 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 110359 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 27333 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 143 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 12721 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 529 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 115684 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 3990850 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 6045060 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 2445766 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 479865 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 105743 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 183750 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 661 
     }, 
     { 
      "name": "Leaf", 
      "children": null, 
      "size": 11181 
     } 
    ], 
    "size": 41103329 
} 
+0

Sarà necessario un layout personalizzato per questo: il layout del pacco racchiude sempre piccoli cerchi tra i grandi cerchi in quanto riduce lo spazio sprecato. Oh e non è necessario ** mettere tutto in grassetto **. –

+0

Ovviamente, spero solo che qualcuno si sia imbattuto in un caso d'uso abbastanza simile e abbia già avuto la soluzione. Sì, non c'è bisogno di tutto il grassetto; era in gran parte un passo falso e incollato. Solo i leader dell'immagine sono audaci ora :) – SoldierOfFortran

+0

@SoldierOfFortran, puoi semplicemente allegare i dati del tuo esempio? Il codice (ha mangiato almeno le parti chiave) è anche desiderabile. – VividD

risposta

13

Tutto quello che devi fare è specificare:

.sort(function(a, b) { 
    return -(a.value - b.value); 
}) 

Questo è diverso che specificare .sort(d3.ascending) o .sort(d3.descending), dal momento che d3.ascending e d3.descending sono definiti come

function(a, b) { 
    return a < b ? -1 : a > b ? 1 : 0; 
} 

e

function(a, b) { 
    return b < a ? -1 : b > a ? 1 : 0; 
} 

rispettosamente, e il layout del pacchetto è influenzato dalla loro "insensibilità" alla differenza di punti dati.

Questo è il mio esempio di prova: (con i tuoi dati) jsfiddle

enter image description here


Sperimentalmente, ho applicato anche a seguito di funzione di ordinamento: (si tratta di una sorta di ibrido)

.sort(function(a, b) { 
    var threshold = 10000000; 
    if ((a.value > threshold) && (b.value > threshold)) { 
     return -(a.value - b.value); 
    } else { 
     return -1; 
    } 
}) 

... e per i valori di soglia di 10000000, 3000000, 1000000, 300000, 100000, 30000 rispettivamente: jsfiddle

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Problemi correlati