2014-11-25 5 views
8

Ich möchte einen Zweig von Sankey-Diagramm an der Spitze zu zwingen.Wie erzwinge ich die Position einer Verzweigung in d3 sankey plugin?

Statt Diagramm wie folgt aus: Current diagram

möchten Diagramm erzeugen, in den Knoten 1, 2, 7, 15, 10 und 14 sind immer an der Spitze: Modified diagram

Verbindung mit aktueller Geige Code: http://jsfiddle.net/w5jfp9t0/1/

var margin = {top: 1, right: 1, bottom: 6, left: 1}; 
var width = 1052 - margin.left - margin.right; 
var height = 500 - margin.top - margin.bottom; 

var formatNumber = d3.format(",.0f"), 
    format = function(d) { return formatNumber(d); }, 
    color = d3.scale.category20(); 

var svg = d3.select("#chart_sankey").append("svg") 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

var sankey = d3.sankey() 
         .nodeWidth(35) 
         .nodePadding(10) 
         .size([width, height]); 

var path = sankey.link(); 

raw = '{"nodes":[{"name":"Node 1"},{"name":"Node 2"},{"name":"Node 3"},{"name":"Node 4"},{"name":"Node 5"},{"name":"Node 6"},{"name":"Node 7"},{"name":"Node 8"},{"name":"Node 9"},{"name":"Node 10"},{"name":"Node 11"},{"name":"Node 12"},{"name":"Node 13"},{"name":"Node 14"},{"name":"Node 15"}],"links":[{"source":9,"target":13,"value":25},{"source":14,"target":9,"value":37},{"source":14,"target":11,"value":16},{"source":14,"target":12,"value":8},{"source":14,"target":10,"value":68},{"source":6,"target":14,"value":154},{"source":6,"target":8,"value":40},{"source":1,"target":6,"value":345},{"source":1,"target":7,"value":66},{"source":1,"target":3,"value":17},{"source":1,"target":4,"value":25},{"source":1,"target":5,"value":117},{"source":0,"target":1,"value":692},{"source":0,"target":2,"value":19}]}'; 
data = JSON.parse(raw); 

sankey.nodes(data.nodes) 
    .links(data.links) 
    .layout(32); 

var link = svg.append("g") 
      .selectAll(".link") 
      .data(data.links) 
      .enter().append("path") 
      .attr("class", "link") 
      .attr("d", path) 
      .style("stroke-width", function(d) { return Math.max(1, d.dy); }) 
      .sort(function(a, b) { return b.dy - a.dy; }); 

var nodes = data.nodes; 

var node = svg.append("g").selectAll(".node") 
    .data(nodes) 
    .enter().append("g") 
    .attr("class", "node") 
    .attr("transform", function(d) { 
     return "translate(" + d.x + "," + d.y + ")"; }) 
    .call(d3.behavior.drag() 
    .origin(function(d) { return d; }) 
    .on("dragstart", function() { this.parentNode.appendChild(this); }) 
    .on("drag", dragmove)); 

sankey.relayout(); 

node.filter(function(d) { return d.value != 0; }) // append text only if node value is not zero 
    .append("rect") 
    .attr("height", function(d) { return d.dy; }) 
    .attr("width", sankey.nodeWidth()) 
    .style("fill", function(d) { return d.color = color(d.name.replace(/ .*/, "")); }) 
    .style("stroke", function(d) { return d3.rgb(d.color).darker(2); }) 
    .append("title") 
    .text(function(d) { return d.name + "\n" + format(d.value); }); 

node.filter(function(d) { return d.value != 0; }) // append text only if node value is not zero 
    .append("text") 
    .attr("x", -6) 
    .attr("y", function(d) { return d.dy/2; }) 
    .attr("dy", ".35em") 
    .attr("text-anchor", "end") 
    .attr("transform", null) 
    .text(function(d) { return d.name; }) 
    .filter(function(d) { return d.x == 0; }) // at first column append text after column 
    .attr("x", 6 + sankey.nodeWidth()) 
    .attr("text-anchor", "start"); 

function dragmove(d) { 
    d3.select(this).attr("transform", "translate(" + d.x + "," + (d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))) + ")"); 
    sankey.relayout(); 
    link.attr("d", path); 
} 

Was muss ich dies zu erreichen, ändern?

Antwort

10

Hinweis Um ehrlich zu sein, habe ich dieses Plugin nie verwendet. Ich sehe keine Option, um das gewünschte Verhalten direkt zu erreichen - also habe ich mir die Quelle von sankey.js angesehen, um die Anpassungen vorzunehmen. Im Folgenden werde ich zeigen, wie ich ändern würde - Sie können es gründlicher

Idee

Mit Blick auf den Code von sankey.js :) tun möchten, sehen Sie, dass die Knoten (y-Richtung angeordnet sind,) unter Verwendung der center Funktion:

function center(node) { 
    return 0; 
} 
:

function center(node) { 
    return node.y + node.dy/2; 
} 

Da ich keinen Parameter sehen, um dieses Verhalten zu ändern, können Sie es ändernWenn Sie dann zufällt auch die Sortierreihenfolge:

function ascendingDepth(a, b) { 
    return b.y - a.y; 
} 

Sie folgendes Bild:

enter image description here

+0

Es wirkt wie ein Zauber! Vielen Dank! Ich hoffe, ich werde herausfinden, wie man auch Knoten 14 nach oben bewegt :). – tomazzlender

+2

Nicht zu schnell zu akzeptieren :) vielleicht andere Leute haben unterschiedliche Ansätze. Vielleicht möchten Sie auch mit der Sortierfunktion spielen (vielleicht basierend auf einem anderen Attribut), um andere Effekte zu erhalten. Viel Glück! (Ich habe meine Antwort absichtlich offen gehalten :)) –

+0

Ihre Lösung ist gut genug für den Moment, aber Sie haben Recht, dass andere unterschiedliche Lösungen beitragen könnten. :) – tomazzlender

Verwandte Themen