2014-06-20 7 views
6


So verwende ich den gleichen Code wie dieser Galerie Beispiel D3 (mit eigenen Daten):D3 bubble chart/pack layout - Wie man Blasen von den größten Blasen auf die kleinsten strahlen lässt?

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


Ich möchte ein Blasendiagramm erhalten, wo die Kreise sind mit den größten in der Mitte angeordnet und strahlen dann bis zum kleinsten aus.


hier ein Mock ist ich in Photoshop up erstellt:

What I actually want



Hier ist, was ich bekomme, wenn ich das Beispiel (der Standard Kreis Verp Algorithmus mit Standardsortierung verwenden):

Default packing



Ich habe versucht, die Sortierung zu optimieren (einschließlich versuchen d3.ascending und d3.descending). Das Beste, was ich mit im Grunde nur einfiel gräbt die Art mit einem konstanten (ha!), Aber immer noch weit davon entfernt, was Ich mag würde:

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

Best I could get by tweaking sort



Ok, also jeden Möglichkeit, dass dies getan werden kann, ohne den tatsächlichen D3-Pack-Layout-Algorithmus ändern zu müssen? Wenn nicht, hat vielleicht jemand das Packlayout erweitert oder modifiziert und könnte mir die 5 Zeilen nennen, die ich in der D3-Quelle ändern könnte, um dies zu hacken.



Vielen Dank im Voraus!


Edit:

Wie gewünscht, hier ist der Code ich verwende. Grundsätzlich ist das gleiche wie die verknüpfte Probe oben, mit einem paar oberflächlichen Veränderungen, wie durch die kommentierten Zeilen angezeigt:

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"); 

Und meine Daten.JSON-Datei:

{ 
    "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

Sie müssen Ein benutzerdefiniertes Layout dafür - das Packlayout packt immer kleine Kreise zwischen große Kreise, was den verschwendeten Platz reduziert. Oh, und es ist nicht nötig, alles fett zu machen **. –

+0

Macht natürlich Sinn, nur zu hoffen, dass jemand in einen ähnlichen Anwendungsfall gestoßen ist und bereits die Lösung hatte. Ja, keine Notwendigkeit für alle Fett; Es handelte sich größtenteils um einen Faux-Pas-Schnitt. Nur die Bildführer sind jetzt fett :) – SoldierOfFortran

+0

@SoldierOfFortran, kannst du einfach die Daten aus deinem Beispiel anhängen? Der Code (mindestens die Schlüsselteile) ist ebenfalls wünschenswert. – VividD

Antwort

13

Alles, was Sie tun müssen, um spezifizieren:

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

Dies ist anders als .sort(d3.ascending) oder .sort(d3.descending) Angabe, da d3.ascending und d3.descending sind definiert als

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

und

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

respektive, und das Pack-Layout ist von ihrer "Unempfindlichkeit" auf die Differenz der Datenpunkte betroffen.

Dies ist mein Test-Beispiel: (mit Ihren Daten) jsfiddle

enter image description here


Experimentell angewendet ich folgende Sortierfunktion auch: (es ist eine Art Hybrid)

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

... und für Werte für den Schwellenwert von 10000000, 3000000, 1000000, 300000, 100000, 30000 bzw. erhielt ich: 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