Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I want to add text on the link in D3.js tree graph

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" }]}]}
like image 714
user3766479 Avatar asked Jun 23 '14 07:06

user3766479


1 Answers

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

enter image description here

Of course, you can change text color, position, etc. to suit your needs.

Hope this helps.

like image 66
VividD Avatar answered Oct 26 '22 22:10

VividD