I have seen this question: Is there a way to zoom into a D3 force layout graph?
But I got some unexpected behaivor from my graph - after few drags or zoom or pan all nodes just freeze and drag stop working.
I created this fiddle: http://jsfiddle.net/7gpweae9/9/
The main part of the code:
var svg = d3.select("#graph")
.append("svg:svg")
.attr("width", width)
.attr("height", height)
.attr("pointer-event", "all")
.append("svg:g")
.call(d3.behavior.zoom().on("zoom", zoom))
.append("svg:g");
svg.append("svg:rect")
.attr("width", width)
.attr("height", height)
.attr('fill', 'white');
var link = svg.selectAll(".link");
var node = svg.selectAll(".node");
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([width,height])
.linkDistance(100)
.charge(-400)
.start();
var drag = d3.behavior.drag()
.origin(function(d) { return d; })
.on("dragstart", dragstarted)
.on("drag", dragged)
.on("dragend", dragended);
node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.call(drag);
node.append("circle")
.attr("class", "node-circle")
.attr("r", 12);
node.append("text")
.attr("x", 12)
.attr("y", ".35em")
.text(function(d) { return d.word; });
link = svg.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link");
force.on("tick", function() {
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; });
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
});
function zoom() {
svg.attr("transform",
"translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
function dragstarted(d) {
d3.event.sourceEvent.stopPropagation();
d3.select(this).classed("dragging", true);
}
function dragged(d) {
d3.select(this).attr("x", d.x = d3.event.x).attr("y", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this).classed("dragging", false);
}
Perhaps I missed something, I've never used d3 before.
UPD: It seems that freezing occurs after a certain period of time.
I replaced d3.layout.force() to force.drag() and now it works almost fine.
var nodes;
var links;
prepareData();
var graph = document.querySelectorAll("#graph")[0];
var height = 500;
var width = 500;
var svg = d3.select("#graph").append("svg:svg")
.attr("width", width)
.attr("height", height)
.attr("pointer-event", "all")
.append("svg:g")
.call(d3.behavior.zoom().on("zoom", zoom))
.append("svg:g");
svg.append("svg:rect")
.attr("width", width)
.attr("height", height)
.attr('fill', 'white');
var link = svg.selectAll(".link");
var node = svg.selectAll(".node");
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([width,height])
.linkDistance(100)
.charge(-400)
.start();
var drag = force.drag()
.origin(function(d) { return d; })
.on("dragstart", dragstarted)
.on("drag", dragged)
node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.call(drag);
node.append("circle")
.attr("class", "node-circle")
.attr("r", 12);
node.append("text")
.attr("x", 12)
.attr("y", ".35em")
.text(function(d) { return d.word; });
link = svg.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link");
force.on("tick", function() {
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; });
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});
function zoom() {
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
function dragstarted(d) {
d3.event.sourceEvent.stopPropagation();
}
function dragged(d) {
d3.select(this).attr("x", d.x = d3.event.x).attr("y", d.y = d3.event.y);
}
function prepareData() {
nodes = [{"index":0,"word":"edit"},{"index":1,"word":"course","sentences":[29859]},{"index":2,"word":"needs","sentences":[29859]},{"index":3,"word":"fit","sentences":[29859]},{"index":4,"word":"slides","sentences":[29859]},{"index":5,"word":"print","sentences":[29859]},{"index":6,"word":"can","sentences":[29859]}];
links = [{"source":0,"target":1},{"source":0,"target":2},{"source":0,"target":3},{"source":0,"target":4},{"source":0,"target":5},{"source":0,"target":6}]
}
svg {
border: 1px solid black;
}
.link {
stroke: #000;
stroke-width: 1px;
}
.node-circle {
cursor: move;
fill: #ccc;
stroke: #000;
stroke-width: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body>
<div id="graph"></div>
</body>