Reputation: 2139
I'm having some troubles with d3 library.
I have some nodes with enabled force.drag() function. I want them to stay inside some squire. I have been trying this approach:
var force = d3.layout.force()
.size([w, h])
.charge(-40)
.linkDistance(getLinkDistance)
.gravity(0.01);
var drag = force.drag()
.on("dragstart", onDragStart)
.on("drag", onDrag);
function onDragStart(d) {
d.fixed = true;
}
function onDrag(d) {
if (d.x < 0)
d.x = 0;
if (d.x > w)
d.x = w;
if (d.y < 0)
d.y = 0;
if (d.y > h)
d.y = h;
}
var newNodes = gnodes.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.call(drag);
Unfortunately, the drag function seems to ignore this, and object still is able to exit the boundaries and become invisible. How can I prevent drag function to move objects outside my limits? To clarify, only dragging object must stay inside the squire, the rest can flay whatever they want.
Update:
I have partly solved the problem by adding dragend event and releasing the node there, if coordinates is wrong. Now the node will comeback from the outside of the screen at least. Still I can't manipulate it coordinates.
var drag = force.drag()
.on("dragstart", onDragStart)
.on("dragend", onDragEnd);
function onDragStart(d) {
d.fixed = true;
}
function onDragEnd(d) {
if (d.x < 0 || d.x > w || d.y < 0 || d.y > h)
d.fixed = false;
}
Upvotes: 1
Views: 2339
Reputation: 2139
Just solved that. Appears, the px and py coordinates need to be fixed:
var drag = force.drag()
.on("dragstart", onDragStart)
.on("drag", onDrag);
function validate(x, a, b) {
if (x < a) x = a;
if (x > b) x = b;
return x;
}
function onDragStart(d) {
d.fixed = true;
}
function onDrag(d) {
d.px = validate(d.px, 0, w);
d.py = validate(d.py, 0, h);
}
Upvotes: 3