javascript - D3 Force directed layout + All nodes to original positions -


i have created basic nodes , links create force directed graph d3. have set basic logic on drag functions when node dragged returns original starting position. worked nicely until linked them together. how of nodes in chain return original positions after dragend?

<!doctype html> <meta charset="utf-8"> <style>      .properties{         fill: yellow;         stroke: black;         stroke-width: 2px;     }     .link {     stroke: #777;     stroke-width: 2px;     }   </style> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> <script>         //most of these variables used calculate original position         var width = 960, height = 500, colors = d3.scale.category10();         var svg = null, force = null;         var circle = null, path = null;         var nodes = null, links = null;         var nodesarray = null, linkarray = null;         var count = 0;         var element = "body"; var numedges = 4, numnodes = 5;         var = 0; var l = 16, r = 12, linelimit = 10;         var d = 2 * r + l;         var r = (count - 1) * d;         var m = width / 2;         var x;          svg = d3.selectall(element).append('svg').attr('width', width).attr('height', height);          //load nodes , links original positions         nodes = d3.range(numnodes).map(function () {             x = m - (r / 2) + (i * d);             ++i;             return {                 x: x,                 y: (height) / 3,                 fx: x,                 fy: height / 3,                 id: i-1,                 reflexive: true,                 r: 12             };                    });         (var = 0; < numnodes; ++i) {             d3.select(element).append("h3").text("node " + + ": " + nodes[i].id);         }          = -1;         links = d3.range(numedges).map(function () {             i++;             return {                 //                 source: nodes[i],                 target: nodes[i+1],                 left: false,                 right: true             }         });         (var = 0; < numedges; ++i) {             d3.select(element).append("h3").text("source: " + links[i].source.id + " target: " + links[i].target.id);         }          force = d3.layout.force().size([width, height]).nodes(nodes).links(links).linkdistance(40).linkstrength(0.1).charge(-300);         var drag = force.drag()                     .on('dragstart', dragstart)                     .on('drag', drag)                     .on('dragend', dragend);         linkarray = svg.selectall('.link').data(links).enter().append('line').attr('class', 'link')             .attr('x1', function (d) {                 return nodes[d.source.id].x;             })             .attr('y1', function (d) { return nodes[d.source.id].y; })             .attr('x2', function (d) { return nodes[d.target.id].x; })             .attr('y2', function (d) { return nodes[d.target.id].y; });           var circlegroup = svg.selectall("g").data(nodes);         var groupenter = circlegroup.enter().append("g").attr("transform", function(d){return "translate("+[d.x,d.y]+")";}).call(drag);         var circle = groupenter.append("circle").attr("cx", 0).attr("cy", -4).attr("r", function(d){return d.r;}).attr("class", "properties");         var label = circlegroup.append("text").text(function(d){return d.id;}).attr({"alignment-baseline": "middle", "text-anchor": "middle" }).attr("class", "id");               force.on('tick', tick);         force.start();         var originalposition = [];         function dragstart(d) {             originalposition[0] = d.x;             originalposition[1] = d.y;             console.log("start: ", originalposition[0], originalposition[1]);         }         function drag() {             var m = d3.mouse(this);             d3.select(this)                     .attr('cx', m[0])                     .attr('cy', m[1]);         }          function dragend(d) {             console.log("end: ", d.x, d.y);             d3.select(this).transition().attr('cx', originalposition[0]).attr('cy', originalposition[1]);         }          function tick() {              circlegroup.attr('transform', function(d) {                 return 'translate(' + d.x + ',' + d.y + ')';             });              linkarray                 .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; });          }  </script> 

i did on drag start keep clone of original graph data this:

function dragstart(d) {     clone1 = json.parse(json.stringify(graph)); }  

on drag end copy stored clones x/y/px/py attributes graph node returns old position this:

function dragend(d) {     clone1.nodes.foreach(function(n,i){         graph.nodes[i].px=n.px         graph.nodes[i].py=n.py         graph.nodes[i].x=n.x         graph.nodes[i].y=n.y     });  } 

working code here.


Comments