I want to make a decision tree in D3.js and to add text on the link.
<!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 margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
rect_width = 90,
rect_height = 20;
var tree = d3.layout.tree()
.size([height * 2, width / 2]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.x, d.y]; });
var svg = d3.select("body").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 + ")");
d3.json("../data/ID3.json", function(error, root) {
var nodes = tree.nodes(root),
links = tree.links(nodes);
var link = svg.selectAll(".link")
.data(links)
.enter().append("g")
.attr("calss", "link")
.attr("fill", "none");
link.append("path")
.attr("d", diagonal)
.attr("stroke", "lightsteelblue");
link.append("text")
.data(nodes)
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.attr("y", -85)
.attr("text-anchor", "middle")
.attr("fill", "black")
.text(function(d) { return d.rule; });
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.append("rect")
.attr("transform", "translate(-42,-8)")
.attr("width", rect_width)
.attr("height", rect_height)
.style("fill", "lightsteelblue");
node.append("text")
.attr("dy", ".31em")
.attr("text-anchor", "middle")
.attr("transform", function(d) { return "translate(" + d.x / 128 + "," + d.y / 128 + ")"; })
.text(function(d) { return d.name; });
});
</script>
There is no text on the link at the bottom right. I think to was due to use 'nodes' data. so, I tried in to use 'root' data. but, I don't come out of nothing if I use 'root' data.
I think that this part is problem.
link.append("text") .data(nodes)
How should I revise??
my data.
{ "name" : "0", "rule" : "null",
"children" : [{ "name" : "2", "rule" : "sunny",
"children" : [{ "name" : "no(3/100%)", "rule" : "high" },
{ "name" : "yes(2/100%)", "rule" : "normal" }]},
{ "name" : "yes(4/100%)", "rule" : "overcast" },
{ "name" : "3", "rule" : "rainy",
"children" : [{ "name" : "no(2/100%)", "rule" : "TRUE" },
{ "name" : "yes(3/100%)", "rule" : "FALSE" }]}]}
For links, one can't access d.x
, d.y
, d.rule
, or similar fields, since link is not associated with a single data point, but it has its source and target. This means the data should be accessed like this: d.source.x
, d.target.y
, and so on.
The key code segment should look like this:
var link = svg.selectAll(".link")
.data(links)
.enter()
.append("g")
.attr("class", "link");
link.append("path")
.attr("fill", "none")
.attr("stroke", "#ff8888")
.attr("stroke-width", "1.5px")
.attr("d", diagonal);
link.append("text")
.attr("font-family", "Arial, Helvetica, sans-serif")
.attr("fill", "Black")
.style("font", "normal 12px Arial")
.attr("transform", function(d) {
return "translate(" +
((d.source.y + d.target.y)/2) + "," +
((d.source.x + d.target.x)/2) + ")";
})
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d) {
console.log(d.target.rule);
return d.target.rule;
});
Here is working example: jsfiddle
Of course, you can change text color, position, etc. to suit your needs.
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