2017-01-03 1 views
0

In Mike Bostocks Beispiel zur hierarchischen Kantenbündelung (https://bl.ocks.org/mbostock/7607999), wie fügt man dem Diagramm eine quantitative Dimension hinzu?d3js: Hinzufügen der quantitativen Bemaßung zur hierarchischen Kantenbündelung

Was ich will, ist zu erreichen, zum Beispiel die Verbindung zwischen „Visualisierungen“ (um 12 Uhr) und „SpanningTree“ (um 1 Uhr) eine Transparenz von 50% bzw. die Verbindung zwischen "Visualisierung" und "AspectRatioBanker" (auch 1 Uhr) zu 0% Transparenz haben. mit dieser Steigung Farbskala Lassen Sie uns „SpanningTree“ annehmen ist eine weniger wichtige Import von „Visualisierung“ als „AspectRatiobanker“ und ich möchte diesen Aspekt sichtbar zu machen.

Unter Berücksichtigung der Daten muss jedes Element im Array "imports" einen numerischen Wert haben, der die "Wichtigkeit" dieses Elements angibt.

In Anbetracht von d3 muss jeder Link basierend auf diesem numerischen Wert farbig sein.

Gibt es eine Möglichkeit, eine solche Funktion hinzuzufügen, ohne zu viel von dem Beispielcode zu ändern?

+1

Ich denke, das ist die falsche Art von Frage für Stapelüberlauf. Du hast kein definiertes Problem, hast etwas versucht und kannst es nicht zur Arbeit bringen, sondern eher eine Idee von dem, was du gerne tun würdest und jemanden suchen, der es für dich macht? Wenn im Allgemeinen jeder Import einen numerischen Wert hat, können Sie Farbe und Deckkraft auf diesen Wert beziehen. In der Praxis wird das im Beispielcode funktionieren und verstehen, was passiert. Um Ihre Frage zu beantworten, ist es möglich, aber ohne zu viel Code zu ändern? Ich weiß es nicht, wahrscheinlich nicht. Was ist zu viel? Hast du versucht, das Beispiel zu ändern? – Craicerjack

+0

Wenn Sie sagen, dass jeder Link basierend auf diesem numerischen Wert farbig sein soll, meinen Sie eine Farbe basierend auf Wert oder eine Deckkraft basierend auf Wert oder beides? – Mark

+0

Keine Sorge, ich habe Sie, Sie sagen, dass es derzeit wichtig ist, Opazität zu verwenden, und Sie würden es lieber auf Farbe machen ... – Mark

Antwort

2

Wenn ich Ihre Frage richtig verstanden möchten Sie mit Daten beginnen wie:

[ 
    { 
    "name": "flare.analytics.cluster.AgglomerativeCluster", 
    "size": 3938, 
    "imports": [ 
     { 
     "link": "flare.animate.Transitioner", 
     "value": 47.194114234125514 
     }, 
     { 
     "link": "flare.vis.data.DataList", 
     "value": 66.57002100495298 
     }, 
     { 
     "link": "flare.util.math.IMatrix", 
     "value": 5.987508739765435 
     }, 
     { 
     "link": "flare.analytics.cluster.MergeEdge", 
     "value": 31.750046370493678 
     }, 
     { 
     "link": "flare.analytics.cluster.HierarchicalCluster", 
     "value": 10.186873728884827 
     }, 
     { 
     "link": "flare.vis.data.Data", 
     "value": 28.60757703865271 
     } 
    ] 
    }, 
    ... 

Und dann die Links Farbe auf der Grundlage der value Eigenschaft in den Importen.

Um diese gegeben zu tun das verknüpfte Beispiel, ändern Sie die packageImports Funktion den Wert Eigenschaft in der links Sammlung zu behalten:

// Return a list of imports for the given array of nodes. 
function packageImports(nodes) { 
    var map = {}, 
     imports = []; 

    // Compute a map from name to node. 
    nodes.forEach(function(d) { 
    map[d.name] = d; 
    }); 

    // For each import, construct a link from the source to target node. 
    nodes.forEach(function(d) { 
    if (d.imports) d.imports.forEach(function(i) { 
     var target = map[i.link]; // find the target 
     target.value = i.value; // retain the value 
     imports.push({source: map[d.name], target: target}); 
    }); 
    }); 
    return imports; 
} 

Dann die Farbe hinzufügen, wenn Sie die Knoten anhängen:

var colorScale = d3.scale.quantize() 
    .range(["#2c7bb6", "#00a6ca","#00ccbc","#90eb9d","#ffff8c","#f9d057","#f29e2e","#e76818","#d7191c"]) 
    .domain([0,100]); 

... 

link = link 
    .data(bundle(links)) 
    .enter().append("path") 
    .each(function(d) { d.source = d[0], d.target = d[d.length - 1]; }) 
    .attr("class", "link") 
    .attr("d", line) 
    .style("stroke", function(d){ 
    return colorScale(d.target.value); //<-- add color 
    }); 

Voller laufender Code:

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 
<style> 
 

 
.node { 
 
    font: 300 11px "Helvetica Neue", Helvetica, Arial, sans-serif; 
 
    fill: #bbb; 
 
} 
 

 
.node:hover { 
 
    fill: #000; 
 
} 
 

 
.link { 
 
    fill: none; 
 
    pointer-events: none; 
 
} 
 

 
.node:hover, 
 
.node--source, 
 
.node--target { 
 
    font-weight: 700; 
 
} 
 

 
.link--source, 
 
.link--target { 
 
    stroke-opacity: 1; 
 
    stroke-width: 2px; 
 
} 
 

 
.link--source { 
 
    stroke: #d62728; 
 
} 
 

 
.link--target { 
 
    stroke: #2ca02c; 
 
} 
 

 
</style> 
 
<body> 
 
<script src="//d3js.org/d3.v3.min.js"></script> 
 
<script> 
 

 
var diameter = 960, 
 
    radius = diameter/2, 
 
    innerRadius = radius - 120; 
 

 
var cluster = d3.layout.cluster() 
 
    .size([360, innerRadius]) 
 
    .sort(null) 
 
    .value(function(d) { return d.size; }); 
 

 
var bundle = d3.layout.bundle(); 
 

 
var line = d3.svg.line.radial() 
 
    .interpolate("bundle") 
 
    .tension(.85) 
 
    .radius(function(d) { return d.y; }) 
 
    .angle(function(d) { return d.x/180 * Math.PI; }); 
 

 
var svg = d3.select("body").append("svg") 
 
    .attr("width", diameter) 
 
    .attr("height", diameter) 
 
    .append("g") 
 
    .attr("transform", "translate(" + radius + "," + radius + ")"); 
 

 
var link = svg.append("g").selectAll(".link"), 
 
    node = svg.append("g").selectAll(".node"); 
 

 
d3.json("https://jsonblob.com/api/851bd2f2-d85d-11e6-b16a-ad927fd57221", function(error, classes) { 
 
    if (error) throw error; 
 
    
 
    var nodes = cluster.nodes(packageHierarchy(classes)), 
 
     links = packageImports(nodes); 
 
     
 
    var colorScale = d3.scale.quantize() 
 
    .range(["#2c7bb6", "#00a6ca","#00ccbc","#90eb9d","#ffff8c","#f9d057","#f29e2e","#e76818","#d7191c"]) 
 
    .domain([0,100]); 
 

 
    link = link 
 
     .data(bundle(links)) 
 
    .enter().append("path") 
 
     .each(function(d) { d.source = d[0], d.target = d[d.length - 1]; }) 
 
     .attr("class", "link") 
 
     .attr("d", line) 
 
     .style("stroke", function(d){ 
 
     return colorScale(d.target.value); 
 
     }) 
 

 
    node = node 
 
     .data(nodes.filter(function(n) { return !n.children; })) 
 
    .enter().append("text") 
 
     .attr("class", "node") 
 
     .attr("dy", ".31em") 
 
     .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); }) 
 
     .style("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; }) 
 
     .text(function(d) { return d.key; }) 
 
     //.on("mouseover", mouseovered) 
 
     //.on("mouseout", mouseouted); 
 
}); 
 

 
/* 
 
function mouseovered(d) { 
 
    node 
 
     .each(function(n) { n.target = n.source = false; }); 
 

 
    link 
 
     .classed("link--target", function(l) { if (l.target === d) return l.source.source = true; }) 
 
     .classed("link--source", function(l) { if (l.source === d) return l.target.target = true; }) 
 
    .filter(function(l) { return l.target === d || l.source === d; }) 
 
     .each(function() { this.parentNode.appendChild(this); }); 
 

 
    node 
 
     .classed("node--target", function(n) { return n.target; }) 
 
     .classed("node--source", function(n) { return n.source; }); 
 
} 
 

 
function mouseouted(d) { 
 
    link 
 
     .classed("link--target", false) 
 
     .classed("link--source", false); 
 

 
    node 
 
     .classed("node--target", false) 
 
     .classed("node--source", false); 
 
} 
 
*/ 
 

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

 
// Lazily construct the package hierarchy from class names. 
 
function packageHierarchy(classes) { 
 
    var map = {}; 
 

 
    function find(name, data) { 
 
    var node = map[name], i; 
 
    if (!node) { 
 
     node = map[name] = data || {name: name, children: []}; 
 
     if (name.length) { 
 
     node.parent = find(name.substring(0, i = name.lastIndexOf("."))); 
 
     node.parent.children.push(node); 
 
     node.key = name.substring(i + 1); 
 
     } 
 
    } 
 
    return node; 
 
    } 
 

 
    classes.forEach(function(d) { 
 
    find(d.name, d); 
 
    }); 
 

 
    return map[""]; 
 
} 
 

 
// Return a list of imports for the given array of nodes. 
 
function packageImports(nodes) { 
 
    var map = {}, 
 
     imports = []; 
 

 
    // Compute a map from name to node. 
 
    nodes.forEach(function(d) { 
 
    map[d.name] = d; 
 
    }); 
 

 
    // For each import, construct a link from the source to target node. 
 
    nodes.forEach(function(d) { 
 
    if (d.imports) d.imports.forEach(function(i) { 
 
     var target = map[i.link]; 
 
     target.value = i.value; 
 
     imports.push({source: map[d.name], target: target}); 
 
    }); 
 
    }); 
 
    return imports; 
 
} 
 

 
</script>

+1

Danke für die Mühe! Ich werde deine Antwort akzeptieren, weil sie allgemein meine Frage beantwortet. Ich möchte, dass die Farben nur "on (mousover)" erscheinen, aber das scheint eine triviale Aufgabe zu sein, mit der ich keine Hilfe brauche. –

Verwandte Themen