dhotson / springy

A force directed graph layout algorithm in JavaScript
http://getspringy.com
MIT License
1.88k stars 240 forks source link

return absolute x,y position of each node #81

Open brucejcw opened 8 years ago

brucejcw commented 8 years ago

Is there any API can return absolute x,y position of each node? I couldn't find it in layout

var layout = new Springy.Layout.ForceDirected(
  graph,
  400.0, // Spring stiffness
  400.0, // Node repulsion
  0.5 // Damping
);
dhotson commented 8 years ago

I'd suggest looking at the layout.eachNode function. Usage looks something like this:

layout.eachNode(function(node, point) {
  console.log(node); // Original graph node
  // The "point" is what the layout uses to track position/velocity/mass of a node
  console.log(point.p.x); 
  console.log(point.p.y);
});

Point properties: https://github.com/dhotson/springy/blob/559a40033116192a6b5b6ff645c78f1d11c2903c/springy.js#L611-L617

Also, I usually transform the underlying "world" coordinates to screen coordinates separately to the layout algorithm.

e.g. here's how it's done in springyui.js: https://github.com/dhotson/springy/blob/559a40033116192a6b5b6ff645c78f1d11c2903c/springyui.js#L63-L69

brucejcw commented 8 years ago

That's so kind of you. thanks, let me try first

brucejcw commented 8 years ago

@dhotson Does the springyui.js depends on springy.js? I didn't found Graph definition in springyui.js

dhotson commented 8 years ago

Yep, that's right—you need to include springy.js first.

brucejcw commented 8 years ago

hi, dhotson, I've tried to using your toScreen algorithm, but seems the screen x,y not looks like the point one.

toScreen = (p)->
    size = currentBB.topright.subtract(currentBB.bottomleft);
    sx = p.subtract(currentBB.bottomleft).divide(size.x).x * 1000;
    sy = p.subtract(currentBB.bottomleft).divide(size.y).y * 1000;
    return new Springy.Vector(sx, sy);
layout = new Springy.Layout.ForceDirected graph, 1000, 1000
currentBB = layout.getBoundingBox();
j = 0
layout.eachNode (node, point)->
    console.log node, point
    list[j].position = toScreen point.p
    console.log list[j].position
    j++
<canvas id="my_canvas" width="1000" height="1000" />

2016-03-30 10 19 52

dhotson commented 8 years ago

Hey sorry, I'm not quite sure I'm following what you mean—what are you expecting to see here?

brucejcw commented 8 years ago

Ok, I may not explain well.
The screenshot shows two graphs, one is springy, the other one is html div
and the absolute position of each div is using toScreen method which picked from springyui.js.
see 2016-03-30 15 14 03

What I mean is I'm converting canvas coordinate to window's using toScreen method, but the result shows the two graphs are not the same