2017-09-05 105 views
0

我对D3.js是全新的,所以这可能是一个简单的问题。我有一个简单的D3树形图,在我的treeData json中,每个节点都有一个“日期”组件。如何在树形图下面粘贴时间线,以便每个节点都对应于时间轴中的日期?把时间线放到D3.js树图

下面是完整的代码。我试图找到一个有效的例子,找不到任何东西。这里找到一个例子,但它不工作: d3.js - Having a tree layout, how to change the X-axis to use a time scale in D3?

var treeData = [{ 
 
    "name": "Top Level", 
 
    "date": "12-Jan-15", 
 
    "parent": "null", 
 
    "children": [{ 
 
     "name": "Level 2: A", 
 
     "date": "13-Mar-16", 
 
     "parent": "Top Level", 
 
     "children": [{ 
 
      "name": "Son of A", 
 
      "date": "1-Aug-16", 
 
      "parent": "Level 2: A" 
 
     }, { 
 
      "name": "Daughter of A", 
 
      "date": "5-Sep-16", 
 
      "parent": "Level 2: A" 
 
     }] 
 
    }, { 
 
     "name": "Level 2: B", 
 
     "date": "12-Jan-17", 
 
     "parent": "Top Level" 
 
    }] 
 
}]; 
 

 
// ************** Generate the tree diagram ***************** 
 
var margin = { 
 
     top: 20, 
 
     right: 120, 
 
     bottom: 20, 
 
     left: 120 
 
    }, 
 
    width = 960 - margin.right - margin.left, 
 
    height = 500 - margin.top - margin.bottom; 
 

 
var i = 0; 
 

 
var tree = d3.layout.tree() 
 
    .size([height, width]); 
 

 
var diagonal = d3.svg.diagonal() 
 
    .projection(function(d) { 
 
     return [d.y, d.x]; 
 
    }); 
 

 
var svg = d3.select("#tree").append("svg") 
 
    .attr("width", width + margin.right + margin.left) 
 
    .attr("height", height + margin.top + margin.bottom) 
 
    .append("g") 
 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
root = treeData[0]; 
 

 
update(root); 
 

 
function update(source) { 
 

 
    // Compute the new tree layout. 
 
    var nodes = tree.nodes(root).reverse(), 
 
     links = tree.links(nodes); 
 

 
    // Normalize for fixed-depth. 
 
    nodes.forEach(function(d) { 
 
     d.y = d.depth * 180; 
 
    }); 
 

 
    // Declare the nodes 
 
    var node = svg.selectAll("g.node") 
 
     .data(nodes, function(d) { 
 
      return d.id || (d.id = ++i); 
 
     }); 
 

 
    // Enter the nodes. 
 
    var nodeEnter = node.enter().append("g") 
 
     .attr("class", "node") 
 
     .attr("transform", function(d) { 
 
      return "translate(" + d.y + "," + d.x + ")"; 
 
     }); 
 

 
    nodeEnter.append("circle") 
 
     .attr("r", 10) 
 
     .style("fill", "#fff"); 
 

 
    nodeEnter.append("text") 
 
     .attr("x", function(d) { 
 
      return d.children || d._children ? -13 : 13; 
 
     }) 
 
     .attr("dy", ".35em") 
 
     .attr("text-anchor", function(d) { 
 
      return d.children || d._children ? "end" : "start"; 
 
     }) 
 
     .text(function(d) { 
 
      return d.name; 
 
     }) 
 
     .style("fill-opacity", 1); 
 

 
    // Declare the links 
 
    var link = svg.selectAll("path.link") 
 
     .data(links, function(d) { 
 
      return d.target.id; 
 
     }); 
 

 
    // Enter the links. 
 
    link.enter().insert("path", "g") 
 
     .attr("class", "link") 
 
     .attr("d", diagonal); 
 

 
}
.node circle { 
 
    fill: #fff; 
 
    stroke: steelblue; 
 
    stroke-width: 3px; 
 
} 
 

 
.node text { 
 
    font: 12px sans-serif; 
 
} 
 

 
.link { 
 
    fill: none; 
 
    stroke: #ccc; 
 
    stroke-width: 2px; 
 
}
<script src="https://d3js.org/d3.v3.min.js"></script> 
 
<div id="tree"> 
 

 
</div> 
 
<div id="time"> 
 

 
</div>

回答

0

这里是一个可以在创建时间轴以D3树图时可以使用的答案。代码有评论,应该清楚它做了什么。将它保存为.html,它应该在浏览器中工作。

<!DOCTYPE html> 
<html lang="en"> 

<head> 
    <meta charset="utf-8"> 
    <title>Simple Tree Example</title> 

    <style> 
     .node circle { 
      fill: steelblue; 
      stroke: grey; 
      stroke-width: 3px; 
     } 

     .node text { 
      font: 12px sans-serif; 
     } 
     /* link is for the lines */ 

     .link { 
      fill: none; 
      stroke: #ccc; 
      stroke-width: 2px; 
      z-index: -1; 
     } 
     .axis path, 
     .axis line { 
      fill: none; 
      stroke: slategray; 
      shape-rendering: crispEdges; 
     } 
     .x.axis line, 
     .x.axis path { 
      fill: none; 
      stroke: #000; 
     } 
    </style> 
</head> 

<body> 
    </div> 
    <!-- load the d3.js library --> 
    <script src="http://d3js.org/d3.v3.min.js"></script> 

    <script> 
     var treeData = [{ 
      "name": "Root", 
      "date": "01-01-2017", 
      "children": [{ 
        "name": "A", 
        "date": "01-02-2017", 
        "children": [ 

         { 
          "name": "B", 
          "date": "01-05-2017", 
          "children": [{ 
           "name": "C", 
           "date": "01-06-2017", 
           "children": [{ 
            "name": "D", 
            "date": "01-07-2017", 
           }] 
          }] 


         } 
        ] 
       }    
      ] 
     }]; 

     // ************** Generate the tree diagram ***************** 
     var margin = { 
       top: 20, 
       right: 60, 
       bottom: 20, 
       left: 120 
      }, 
      width = 1000 - margin.right - margin.left, 
      height = 200 - margin.top - margin.bottom; 

     var i = 0; 

     var tree = d3.layout.tree() 
      .size([height, width]); 

     var diagonal = d3.svg.diagonal() 
      .projection(function (d) { 
       return [d.y, d.x]; 
      }); 

     var svg = d3.select("body").append("svg") 
      .attr("width", width + margin.right + margin.left) 
      .attr("height", height + margin.top + margin.bottom), 
      g = svg.append("g") 
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

     root = treeData[0]; 
     var nodes = tree.nodes(root).reverse(); 
     var maxdate = d3.max(nodes, function (d) { 
      return new Date(d.date.replace(/(\d{2})-(\d{2})-(\d{4})/, "$1/$2/$3")); 
     }); 
     var mindate = d3.min(nodes, function (d) { 
      return new Date(d.date.replace(/(\d{2})-(\d{2})-(\d{4})/, "$1/$2/$3")); 
     }); 

     mindate.setMonth(mindate.getMonth() + 1); 
     maxdate.setMonth(maxdate.getMonth() + 1); 
     maxdate.setDate(maxdate.getDate() + 5); 

     var x = d3.time.scale() 
      .domain([mindate, maxdate]) 
      .range([0, width]); 

     var xAxis = d3.svg.axis() 
      .orient("bottom") 
      .scale(x) 
      .ticks(10); 
     g.append('g') 
      .attr('transform', 'translate(0,' + height + ')') .attr("class", "axis") 
      .call(customXAxis); 
     var linksg = g.append("g"); 

     function customXAxis(g) { 
      g.call(xAxis); 
      //g.select('.domain').remove(); 
     }; 

     update(root); 

     function update(source) { 
      // Compute the new tree layout. 
      var nodes = tree.nodes(root).reverse(), 
       links = tree.links(nodes); 

      // Normalize for fixed-depth. 
      nodes.forEach(function (d) { 
       d.y = d.depth * 80; 
      }); 

      // Declare the nodes… 
      var node = g.selectAll("g.node") 
       .data(nodes, function (d) { 
        return d.id || (d.id = ++i); 
       }); 

      // Enter the nodes. 
      var nodeEnter = node.enter().append("g") 
       .attr("class", "node") 
       .attr("transform", function (d) { 
        var ddate = d.date.split("-"); 
        var t = new Date(ddate[2], ddate[0], ddate[1]); 
        return "translate(" + x(t) + "," + d.x + ")"; 
       }); 

      nodeEnter.append("circle") 
       .attr("r", 15) 
       .transition() 
       .delay(350) 
       .style("fill", "steelblue"); 


      nodeEnter.append("text") 
       .attr("x", function (d) { 
        return d.children || d._children ? -20 : 20; 
       }) 
       .attr("dy", ".35em") 
       .attr("text-anchor", function (d) { 
        return d.children || d._children ? "end" : "start"; 
       }) 
       .text(function (d) { 
         return d.name 
       }) 
       .style("fill-opacity", 1); 


      // Declare the links… 
      var link = linksg.selectAll('.link') 
       .data(nodes) 
       .enter().append('path') 
       .attr('class', 'link') 
       .attr('d', function (d) { 
        if (d.parent != undefined) { 
         var res = d.date.split("-"); 
         var nodeDate = new Date(+res[2], +res[0], +res[1]); 
         var res = d.parent.date.split("-"); 
         var parentDate = new Date(+res[2], +res[0], +res[1]); 
         return 'M' + x(nodeDate) + ',' + d.x + 
          'C' + (x(nodeDate) + x(parentDate))/2 + ',' + d.x + 
          ' ' + (x(nodeDate) + x(parentDate))/2 + ',' + d.parent.x + 
          ' ' + x(parentDate) + ',' + d.parent.x; 
        } 
       }); 
     } // end update() function 
    </script> 
</body> 

</html>.