Graph.centerNode() works to some extent, for example it's used to react on mouseclicks (see GraphPanel.nodeClicked()). It doesn't work yet during the creation of the layout. I hope I can solve this asap.
Nevertheless, there is a second way to center a node, which might be useful for you :
The usual tree layout (hypergraph.visualnet.TreeLayout) takes the first node it gets that has a minimal in-degree (the number of edges pointing to this node; i.e. the number of edges where edge.getTarget() == node). This node is always centered by the TreeLayout and it's used as the root of the tree.
Maybe you can change your graph so that the node you want to center in the layout is the root of the tree.
Regards,
Jens.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks for the response. I'm actually using the GenericNDSLayout (or something like that) and have resorted to rebuilding the whole graph everytime I want to recenter it. Unfortunately, it doesn't recenter it in the actual center, so this is a less-than-ideal solution.
The first placed I looked for centering was the mouse events in GraphPanel, but for some reason, nothing works for me When I actually click on a node, it centers just fine, but when try to center it programmatically, nothing happens.
My case is this: the user navigates through a huge graph not using the graph itself for movement. To keep decent performance, I have to re-create the graph and nodes 2 hops out at every step. Initially, I was hoping to keep the whole graph (could be 10k+ nodes) in memory, but just center on movement, but it seems to eat up too many CPU cycles.
If you have an idea why even why I re-create the graph at every movement, it is centered somewhere else, I'd appreciate it. I'd still like to re-center the graph once it is created. Thanks.
Don
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The GenericMDSLayout starts with a random layout and tries to minimize the energy of the system, where edges are behaving as springs and nodes are always repulsing (spring layout, force directed layout). The algorithm to do this is of order O(N^3), that's why it's not usable for 10k+ nodes.
When you add/remove nodes or re-create the graph completely, the "forces" move all nodes, so even if you center a node, this node will be moved in the next iteration a few milliiseconds later.
So, what solutions are there ?
1. Create another Thread that calls centerNode() every 0.1 seconds or so.
2. Add some state to the Layouts like "invalid", "in progress" , "finished" and use Events to inform listeners. You could wait until the layout has finished the optimization and use centerNode() then.
3. Add a functionality to the layouts of fixing the node position for one or more nodes. You would fix the node you are interested in, center it using centerNode and then the layout must not change the node position anymore.
None of the three methods is implemented, nor tested. Number one would be a quick and dirty solution.
Regards,
Jens.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hmm..perhaps TreeLayout would be better. Initially, I was just facinated by the growing, adapting tree, but having used it for a while, I suppose it is a bit annoying waiting for it to settle. I'm still confused why clicking on a node centered it right, but I couldn't do it programmatically. Ah well, it doesn't matter anyways if I use TreeLayout. Could TreeLayout support 10k nodes in a 200x200 window with decent performance?
Don
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok, I'm going with three hops from the center node and treelayout, and things seem to be pretty quick and responsive. If I haven't mentioned it yet, thanks a bunch for all the hard work that went into this great project. I'm using it for a MUD-type game client - http://www.twdata.org/kokua - and first used it as a tool to help me debug my genetic algorithm engine. Very useful and easy to develop with, thanks again.
As for the centering issue, I've tried centering it right after creating a new tree and centering an existing tree with no luck. I looked at the source for GraphPanel and its parent, and even copy/pasted most all of it, but to no avail. Quite strange. I can say TreeLayout's centering ability works fine though :)
Don
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ah, thanks. Yeah, my web server was down due to a pulled cord while vacuuming :)
The switch to TreeLayout worked out well, despite some NPE's I'm getting occasionally, but probably due to bad input. My next task is to try to modify edge rendering to include some notion of direction.
Don
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Is it possible to programmatically center the graph on a node? The graph.centerNode() doesn't seem to do anything. Thanks.
Don
Hi Don,
Graph.centerNode() works to some extent, for example it's used to react on mouseclicks (see GraphPanel.nodeClicked()). It doesn't work yet during the creation of the layout. I hope I can solve this asap.
Nevertheless, there is a second way to center a node, which might be useful for you :
The usual tree layout (hypergraph.visualnet.TreeLayout) takes the first node it gets that has a minimal in-degree (the number of edges pointing to this node; i.e. the number of edges where edge.getTarget() == node). This node is always centered by the TreeLayout and it's used as the root of the tree.
Maybe you can change your graph so that the node you want to center in the layout is the root of the tree.
Regards,
Jens.
Thanks for the response. I'm actually using the GenericNDSLayout (or something like that) and have resorted to rebuilding the whole graph everytime I want to recenter it. Unfortunately, it doesn't recenter it in the actual center, so this is a less-than-ideal solution.
The first placed I looked for centering was the mouse events in GraphPanel, but for some reason, nothing works for me When I actually click on a node, it centers just fine, but when try to center it programmatically, nothing happens.
My case is this: the user navigates through a huge graph not using the graph itself for movement. To keep decent performance, I have to re-create the graph and nodes 2 hops out at every step. Initially, I was hoping to keep the whole graph (could be 10k+ nodes) in memory, but just center on movement, but it seems to eat up too many CPU cycles.
If you have an idea why even why I re-create the graph at every movement, it is centered somewhere else, I'd appreciate it. I'd still like to re-center the graph once it is created. Thanks.
Don
The GenericMDSLayout starts with a random layout and tries to minimize the energy of the system, where edges are behaving as springs and nodes are always repulsing (spring layout, force directed layout). The algorithm to do this is of order O(N^3), that's why it's not usable for 10k+ nodes.
When you add/remove nodes or re-create the graph completely, the "forces" move all nodes, so even if you center a node, this node will be moved in the next iteration a few milliiseconds later.
So, what solutions are there ?
1. Create another Thread that calls centerNode() every 0.1 seconds or so.
2. Add some state to the Layouts like "invalid", "in progress" , "finished" and use Events to inform listeners. You could wait until the layout has finished the optimization and use centerNode() then.
3. Add a functionality to the layouts of fixing the node position for one or more nodes. You would fix the node you are interested in, center it using centerNode and then the layout must not change the node position anymore.
None of the three methods is implemented, nor tested. Number one would be a quick and dirty solution.
Regards,
Jens.
Hmm..perhaps TreeLayout would be better. Initially, I was just facinated by the growing, adapting tree, but having used it for a while, I suppose it is a bit annoying waiting for it to settle. I'm still confused why clicking on a node centered it right, but I couldn't do it programmatically. Ah well, it doesn't matter anyways if I use TreeLayout. Could TreeLayout support 10k nodes in a 200x200 window with decent performance?
Don
10k nodes in 200x200 is of course a lot. The TreeLayout itself works fast enough, but navigating is pretty slow.
The centering issue bothers me a bit. Has the GraphPanel already the correct size at the time you try to center a node ?
Jens.
Ok, I'm going with three hops from the center node and treelayout, and things seem to be pretty quick and responsive. If I haven't mentioned it yet, thanks a bunch for all the hard work that went into this great project. I'm using it for a MUD-type game client - http://www.twdata.org/kokua - and first used it as a tool to help me debug my genetic algorithm engine. Very useful and easy to develop with, thanks again.
As for the centering issue, I've tried centering it right after creating a new tree and centering an existing tree with no luck. I looked at the source for GraphPanel and its parent, and even copy/pasted most all of it, but to no avail. Quite strange. I can say TreeLayout's centering ability works fine though :)
Don
I think I found the problem with the centering. Try this one:
Replace hyperbolic.PoincareProjector.inversMap with (or refresh this class from CVS) :
public ModelPoint inversMap(Point p, JComponent c) {
Complex z = new Complex();
if (c.getWidth() != 0)
z.real = p.getX() * 2 / (double) c.getWidth() - 1;
if (c.getHeight() != 0)
z.imag = 1 - p.getY() * 2 / (double) c.getHeight();
if (z.norm2() < 1.0)
return z;
else
return null;
}
That's all (I think).
I tested it using
Node n = (Node) graph.getNodes().toArray()[5];
graphPanel.centerNode(n);
right before the GraphPanel is added to the contentplane.
Since I'm curious, I wanted to try out kokua, but the operation timed out. Is your server down or so ?
Oh, and thanks for the flowers ;-)
Jens.
Ah, thanks. Yeah, my web server was down due to a pulled cord while vacuuming :)
The switch to TreeLayout worked out well, despite some NPE's I'm getting occasionally, but probably due to bad input. My next task is to try to modify edge rendering to include some notion of direction.
Don