toolkit/javascript/d3/examples/force/force-interactive.html
changeset 47 c0b4a8b5a012
equal deleted inserted replaced
46:efd9c589177a 47:c0b4a8b5a012
       
     1 <!DOCTYPE html>
       
     2 <html>
       
     3   <head>
       
     4     <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
       
     5     <title>Force-Directed Graph</title>
       
     6     <script type="text/javascript" src="../../d3.js"></script>
       
     7     <script type="text/javascript" src="../../d3.geom.js"></script>
       
     8     <script type="text/javascript" src="../../d3.layout.js"></script>
       
     9     <style type="text/css">
       
    10 
       
    11 circle.node {
       
    12   cursor: pointer;
       
    13   stroke: #3182bd;
       
    14   stroke-width: 1.5px;
       
    15 }
       
    16 
       
    17 line.link {
       
    18   fill: none;
       
    19   stroke: #9ecae1;
       
    20   stroke-width: 1.5px;
       
    21 }
       
    22 
       
    23     </style>
       
    24   </head>
       
    25   <body>
       
    26     <div id="chart"></div>
       
    27     <script type="text/javascript">
       
    28 
       
    29 var w = 960,
       
    30     h = 500,
       
    31     node,
       
    32     link,
       
    33     root;
       
    34 
       
    35 var force = d3.layout.force()
       
    36     .on("tick", tick)
       
    37     .size([w, h]);
       
    38 
       
    39 var vis = d3.select("#chart").append("svg:svg")
       
    40     .attr("width", w)
       
    41     .attr("height", h);
       
    42 
       
    43 d3.json("../data/flare.json", function(json) {
       
    44   root = json;
       
    45   update();
       
    46 });
       
    47 
       
    48 function update() {
       
    49   var nodes = flatten(root),
       
    50       links = d3.layout.tree().links(nodes);
       
    51 
       
    52   // Restart the force layout.
       
    53   force
       
    54       .nodes(nodes)
       
    55       .links(links)
       
    56       .start();
       
    57 
       
    58   // Update the links…
       
    59   link = vis.selectAll("line.link")
       
    60       .data(links, function(d) { return d.target.id; });
       
    61 
       
    62   // Enter any new links.
       
    63   link.enter().insert("svg:line", ".node")
       
    64       .attr("class", "link")
       
    65       .attr("x1", function(d) { return d.source.x; })
       
    66       .attr("y1", function(d) { return d.source.y; })
       
    67       .attr("x2", function(d) { return d.target.x; })
       
    68       .attr("y2", function(d) { return d.target.y; });
       
    69 
       
    70   // Exit any old links.
       
    71   link.exit().remove();
       
    72 
       
    73   // Update the nodes…
       
    74   node = vis.selectAll("circle.node")
       
    75       .data(nodes, function(d) { return d.id; })
       
    76       .style("fill", color);
       
    77 
       
    78   // Enter any new nodes.
       
    79   node.enter().append("svg:circle")
       
    80       .attr("class", "node")
       
    81       .attr("cx", function(d) { return d.x; })
       
    82       .attr("cy", function(d) { return d.y; })
       
    83       .attr("r", function(d) { return Math.sqrt(d.size) / 10 || 4.5; })
       
    84       .style("fill", color)
       
    85       .on("click", click)
       
    86       .call(force.drag);
       
    87 
       
    88   // Exit any old nodes.
       
    89   node.exit().remove();
       
    90 }
       
    91 
       
    92 function tick() {
       
    93   link.attr("x1", function(d) { return d.source.x; })
       
    94       .attr("y1", function(d) { return d.source.y; })
       
    95       .attr("x2", function(d) { return d.target.x; })
       
    96       .attr("y2", function(d) { return d.target.y; });
       
    97 
       
    98   node.attr("cx", function(d) { return d.x; })
       
    99       .attr("cy", function(d) { return d.y; });
       
   100 }
       
   101 
       
   102 // Color leaf nodes orange, and packages white or blue.
       
   103 function color(d) {
       
   104   return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
       
   105 }
       
   106 
       
   107 // Toggle children on click.
       
   108 function click(d) {
       
   109   if (d.children) {
       
   110     d._children = d.children;
       
   111     d.children = null;
       
   112   } else {
       
   113     d.children = d._children;
       
   114     d._children = null;
       
   115   }
       
   116   update();
       
   117 }
       
   118 
       
   119 // Returns a list of all nodes under the root.
       
   120 function flatten(root) {
       
   121   var nodes = [], i = 0;
       
   122 
       
   123   function recurse(node) {
       
   124     if (node.children) node.children.forEach(recurse);
       
   125     if (!node.id) node.id = ++i;
       
   126     nodes.push(node);
       
   127   }
       
   128 
       
   129   recurse(root);
       
   130   return nodes;
       
   131 }
       
   132 
       
   133     </script>
       
   134   </body>
       
   135 </html>