toolkit/javascript/d3/examples/force/force-dynamic.html
changeset 47 c0b4a8b5a012
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolkit/javascript/d3/examples/force/force-dynamic.html	Thu Apr 10 14:20:23 2014 +0200
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Force-Directed Layout (Dynamic)</title>
+    <script type="text/javascript" src="../../d3.js"></script>
+    <script type="text/javascript" src="../../d3.geom.js"></script>
+    <script type="text/javascript" src="../../d3.layout.js"></script>
+    <style type="text/css">
+
+rect {
+  fill: #fff;
+}
+
+.node {
+  fill: #000;
+}
+
+.cursor {
+  fill: none;
+  stroke: brown;
+  pointer-events: none;
+}
+
+.link {
+  stroke: #999;
+}
+
+    </style>
+  </head>
+  <body>
+    <div id="chart"></div>
+    <script type="text/javascript">
+
+var w = 960,
+    h = 500,
+    fill = d3.scale.category20(),
+    nodes = [],
+    links = [];
+
+var vis = d3.select("#chart").append("svg:svg")
+    .attr("width", w)
+    .attr("height", h);
+
+vis.append("svg:rect")
+    .attr("width", w)
+    .attr("height", h);
+
+var force = d3.layout.force()
+    .distance(30)
+    .nodes(nodes)
+    .links(links)
+    .size([w, h]);
+
+var cursor = vis.append("svg:circle")
+    .attr("r", 30)
+    .attr("transform", "translate(-100,-100)")
+    .attr("class", "cursor");
+
+force.on("tick", function() {
+  vis.selectAll("line.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; });
+
+  vis.selectAll("circle.node")
+      .attr("cx", function(d) { return d.x; })
+      .attr("cy", function(d) { return d.y; });
+});
+
+vis.on("mousemove", function() {
+  cursor.attr("transform", "translate(" + d3.svg.mouse(this) + ")");
+});
+
+vis.on("mousedown", function() {
+  var point = d3.svg.mouse(this),
+      node = {x: point[0], y: point[1]},
+      n = nodes.push(node);
+
+  // add links to any nearby nodes
+  nodes.forEach(function(target) {
+    var x = target.x - node.x,
+        y = target.y - node.y;
+    if (Math.sqrt(x * x + y * y) < 30) {
+      links.push({source: node, target: target});
+    }
+  });
+
+  restart();
+});
+
+restart();
+
+function restart() {
+  force.start();
+
+  vis.selectAll("line.link")
+      .data(links)
+    .enter().insert("svg:line", "circle.node")
+      .attr("class", "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; });
+
+  vis.selectAll("circle.node")
+      .data(nodes)
+    .enter().insert("svg:circle", "circle.cursor")
+      .attr("class", "node")
+      .attr("cx", function(d) { return d.x; })
+      .attr("cy", function(d) { return d.y; })
+      .attr("r", 4.5)
+      .call(force.drag);
+}
+
+    </script>
+  </body>
+</html>