I want to distinguish the link by the thickness.
I have the data.
The variable "value
" means "thickness
".
The range of "value" is 0~1.
{"nodes":[{"name":"A", "group":1},
{"name":"B", "group":1},
{"name":"C", "group":1},
{"name":"D", "group":1},
{"name":"E", "group":1}],
"links":[{"source":0,"target":1,"value":0.9},
{"source":0,"target":2,"value":0.8},
{"source":0,"target":3,"value":0.7},
{"source":1,"target":2,"value":0.7},
{"source":2,"target":4,"value":0.2},
{"source":0,"target":4,"value":0.5}]}
And my d3.js graph code is
<!DOCTYPE html>
<meta charset="utf-8">
<body><script src="../d3-master/d3.min.js"></script>
<head><link rel="stylesheet" type="text/css" href="../D3css/D3css.css"></head>
<script>
var width = 960,
height = 500
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var force = d3.layout.force()
.gravity(.05)
.distance(100)
.charge(-100)
.size([width, height]);
d3.json("../data/cor_test.json", function(error, json) {
force
.nodes(json.nodes)
.links(json.links)
.start();
var link = svg.selectAll(".link")
.data(json.links)
.enter().append("line")
.attr("class", "link");
var node = svg.selectAll(".node")
.data(json.nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("circle")
.attr("r", 5);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) { return d.name });
force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});
});
</script>
I changed the code like this.
but it doesn't work.
var link = svg.selectAll(".link")
.data(json.links)
.enter().append("line")
.attr("class", "link")
.attr("stroke-width", function(d) { return d.value; });
More simply change : .attr("stroke-width", "5px");
doesn't work too.
The link didn't show.
What should I do?
You need to specify the 'stroke'
attribute first, because:
The default value for the stroke attribute is none which means that the outline is never drawn.
See the documentation for stroke
. Below is an example of how it might be done:
selection
.attr('stroke', 'red')
.attr('stroke-width', 5);
Here's a jsfiddle demonstrating how it works.
I believe @Oleg 's answer is complete and right on, however, I just want to bring to your attention an example that makes extensive use of link thicknesses, and other related svg attributes:
2013 Budget Visualization
Relevant code is here:
// Enter any new links at the parent's previous position.
link.enter().insert("svg:path", "g")
.attr("class", "link")
.attr("d", function(d) {
if (Number(d.target[spendField]) > 0) {
var o = {x: source.x0, y: source.y0};
return diagonal({source: o, target: o});
}
else {
null;
}
})
.style("stroke",function (d,i) {
if (d.source.depth==0) {
rootCounter++;
return (d.source.children[rootCounter-1].linkColor);
}
else {
return (d.source) ? d.source.linkColor : d.linkColor;
}
})
.style("stroke-width", function (d,i) {
if (d.source.depth==0) {
var ret = level1Radius(d.target[spendField]) * 2;
return (isNaN(ret) ? 4 : ret);
}
else if (d.source.depth==1) {
var ret = level2Radius(d.target[spendField]) * 2;
return (isNaN(ret) ? 4 : ret);
}
else if (d.source.depth==2) {
var ret = level3Radius(d.target[spendField]) * 2;
return (isNaN(ret) ? 4 : ret);
}
else if (d.source.depth==3) {
var ret = level4Radius(d.target[spendField]) * 2;
return (isNaN(ret) ? 4 : ret);
}
})
.style("stroke-opacity", function(d){
var ret = ((d.source.depth+1)/4.5)
if (d.target[spendField] <= 0) ret=.1;
return ret;
})
.style("stroke-linecap","round")
.transition()
.duration(duration);
// .attr("d", diagonal);
// Transition links to their new position.
var linkUpdate = link.transition()
.duration(duration)
.attr("d", diagonal);
linkUpdate
.style("stroke-width", function (d,i) {
if (d.source.depth==0) {
var ret = level1Radius(Number(d.target[spendField])) * 2;
return (isNaN(ret) ? 4 : ret);
}
else if (d.source.depth==1) {
var ret = level2Radius(Number(d.target[spendField])) * 2;
return (isNaN(ret) ? 4 : ret);
}
else if (d.source.depth==2) {
var ret = level3Radius(Number(d.target[spendField])) * 2;
return (isNaN(ret) ? 4 : ret);
}
else if (d.source.depth==3) {
var ret = level4Radius(Number(d.target[spendField])) * 2;
return (isNaN(ret) ? 4 : ret);
}
})
// .style("stroke-dasharray", function(d) {
// var ret=(d.target[spendField] > 0) ? "" : "5,8";
// return ret;
// })
.style("stroke-opacity", function(d){
var ret = ((d.source.depth+1)/4.5)
if (d.target[spendField] <= 0) ret=.1;
return ret;
})
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", diagonal)
.remove();
Besides usage of stroke
, stroke-width
, you can notice usage of stroke-opacity
, stroke-linecap
, and general enter/update/exit pattern.
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With