AutoLayout ForceDirected

Hi,
I have run in to a little problem that I would like to ask some people about to see if they have any experience. I am using Go Diagram 2.2.1 Web, and GoLayout 2.2.1.
The problem is with GoLayout, we are using a subclassed instance of Force Directed Algorithm. We overload the Spring Length and Spring Stiffness depending on the node type. Generally the output is acceptable, we have a lot of link crossings (but that is not a problem because of the way the data is structured). There is one slight issue, more often than not the “minmum energy” of the system tends to produce a square (i.e the data fits perfectly in to a square go diagram view). Our GoView is not square in shape it is more of a horiztonal A4 size, (much like a wide screen tv).
If the layout fits into a square, it won’t resize to fit optimally in our “widescreen view”. i.e our goview has alot of space on the righthand side after layout.
I though a solution would be to alter:

protected override float ElectricalFieldX(PointF xy) {<?:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

float border = 50;

float min = 0;

float max = Document.Size.Width;

if (xy.X <= 0)

return 300;

if (xy.X < min + border) {

return (300 / ((min - xy.X) * (min - xy.X)));

}

return 0;

}

The inital logic would be that this would spread the nodes out infavor of the X axis. So we can get our widescreen layout. Unfortunaltly this doesn't work :(

I have also have tried,

protected override float ElectricalFieldX(PointF xy) {

float min = 0;

return (1/ ((min - xy.X) * (min - xy.X)));

}

which I thought would set electrical fields proportional to the center of the document however it doesn't have any effect. :(

Does any one have any ideas on how to solve this problem.

Thanks,

Paul

What happens?
Could you just set the GoDocument.Size beforehand, with the original definition of ElectricalFieldX?

With the overrided electricalfieldX set to the new way it really does nothing, I think it is because as you get futher away from the origin the effect is reduced close to zero.
I am not to sure how setting the document size will help, I need the output to be scaled to fit the screen but the output is square rather then “wide screen” so the zoom level is less than optimal. If you change the document size is this like putting that “elctrical border” that is described in the docs.
Would a screen shot help, I can’t upload it anywhere so I would have to email it.
All that I am really trying to achieve is to get the algorithm to spread out width ways rather than height ways. At the moment (on average all the nodes are spread out roughly equal in both directions.
Paul

You’ll note that the original definition depended on the GoDocument.Size to decide where to place the field. You can either change the GoDocument.Size, or you can modify that code to use a different X position.

Is it correct to say the layout algorithm won’t change the size of the document? even if the best placement of nodes would mean that the document should be bigger.
Or are you talking about:

protected override float ElectricalFieldX(PointF xy) {<?:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

float border = 50;

float min = 0;

float max = Document.Size.Width;

if (xy.X <= 0)

return 300;

if (xy.X < min + border) {

return (300 / ((min - xy.X) * (min - xy.X)));

}

return 0;

}

protected override float ElectricalFieldY(PointF xy) {

float border = 50;

float min = 0;

float max = Document.Size.Height;

if (xy.Y <= 300)

return 300;

if (xy.Y < min + border) {

return (300 / ((min - xy.Y) * (min - xy.Y)));

}

return 0;

} because I don't see anywhere where the "max" variable is used. I also tried the following:

protected override float ElectricalFieldX(PointF xy) {

float border = 50;

float min = 0;

float max = Document.Size.Width;

if (xy.X <= 0)

return 400;

if (xy.X < min + border) {

return (400 / ((min - xy.X) * (min - xy.X)));

}

return 0;

}

protected override float ElectricalFieldY(PointF xy) {

float border = 50;

float min = 0;

float max = Document.Size.Height;

if (xy.Y <= 300)

return 300;

if (xy.Y < min + border) {

return (300 / ((min - xy.Y) * (min - xy.Y)));

}

return 0;

} Which I though would give it a 400:300 (4:3) ration on the screen, it did produce some results but when I rescaled to fit the screen there was about 200 pixels of white space above the top most node in the view. I'll try and find somewhere to upload the pictures of my examples to so that they make more sense.

You’re right–I saw the declaration of “max” and assumed it was used. That’s how the example was defined a long time ago, but it was changed to not place a field at the upper bounds, i.e. not to limit the maximum X and Y coordinates. The code you have is at least two years old, because it hasn’t been that way since 2.0 came out.
Here’s a definition that does impose a field at both sides along the X dimension; you can do the same for the Y.
protected override float ElectricalFieldX(PointF p) {
float max = Math.Max(500, this.Document.Size.Width);
float border = Math.Min(100, max/3);
if (p.X < 0) return 300;
else if (p.X < border) return border-p.X;
else if (p.X > max) return -300;
else if (p.X > max-border) return (max-border)-p.X;
else return 0.0f;
}

Ah, Cool.
Thanks for that, the next plan of attack was to look into allowing negative numbers in override.
I just adjusted
float max = Math.Max(500, this.Document.Size.Width);

to be
float max = Math.Max(500, this.Document.Size.Width * 4);
to get a bit more space and now the graph fills outwards very well.
Cheers for the help
Paul
ps, just out of curiosity, why is
if (p.X < 0) return 300;
defined to return 300, is 300 a particularly stong force? and thus stopping the nodes from travelling too far out?

Yes, that’s right, although I can imagine that 300 wouldn’t be enough in certain circumstances. Getting the desired balance of forces can be tricky.