2017-01-03 50 views
0

鉴于Mike Bostock在层次边捆绑(https://bl.ocks.org/mbostock/7607999)上的示例,如何为图添加定量维?d3js:将定量维添加到分层边捆绑

我想要实现的是,例如,间“可视化”(在12点)和“SpanningTree”(在1点钟方向)的链接具有50%的透明度和“可视化”“AspectRatioBanker”(也是1点)之间的链接具有0%的透明度。让我们假设“SpanningTree”是一个不太重要的进口“可视化”“AspectRatiobanker”并且我想用这个渐变色标表示这个方面。

考虑到数据,"imports"数组中的每个元素都必须有一个数值,表示该元素的“重要性”。

考虑到d3,每个链接都必须根据此数值进行着色。

有没有可能在不改变太多示例代码的情况下添加这样的功能?

+1

我认为这是堆栈溢出的错误类型的问题。你没有确定的问题尝试过某些东西,但无法让它起作用,但是更多地了解你想要做什么并寻找某个人为你做到这一点?一般来说,如果每个导入都有一个数值,那么您可以在该值上使用颜色和不透明度。在实际中,这将需要工作,并了解示例代码中发生了什么。 要回答你的问题,它的可能,但没有改变太多的代码?我不知道,可能不是。什么太多了?你有没有试过改变这个例子? – Craicerjack

+0

当你说'每个链接都必须根据此数值进行着色“时,是指基于值的颜色还是基于值或两者的不透明度? – Mark

+0

不要紧,我得到你,你说它是目前使用不透明度重要,你宁愿在颜色上做... – Mark

回答

2

如果我正确理解你的问题,你要开始像数据:

[ 
    { 
    "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 
     } 
    ] 
    }, 
    ... 

然后颜色基于进口value属性的链接。

要做到这一点给出链接的例子,修改packageImports功能保留值属性links集合中:

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

// 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; 
} 

然后,当你追加节点添加颜色全面运行代码:

<!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

感谢您的努力!我会接受你的答案,因为它通常回答我的问题。我想要的颜色只出现'.on(mousover)',但这似乎是一个微不足道的任务,我不需要任何帮助。 –