Placing boxes in diagram the optimal way (no crossing lines) - algorithm

I am doing an assignment where I have to draw a diagram on a web page with a number of boxes, some of which are to be connected by arrows. I have everything setup so that I'm able to draw the actual diagram, arrows and all but now I'm faced with the problem of placing the boxes in the optimal way. By this I mean laying out the page so that I have a minimum of lines crossing.
I have to do two types of diagrams: One is a more hierarchical diagram where I know which box to place top left and where all boxes form a hierarchy. The other is more tricky where no box needs to have a specific place and the end result is not a hierarchy. In either scenario are there more than one connection between two boxes. It's pretty much the same as laying out an E/R diagram for a database in the most readable way.
Does anyone know how to do this or where to find information about how to do this?
Thanks in advance
./CJ

Laying out an arbitrary graph with minimal crossings is an NP-hard problem, so you're left with finding a good heuristic.
What comes to mind is this:
Lay your items on the perimeter of a circle with their connecting edges.
Use simulated annealing to swap items, aiming to minimise the number of crossings.
Tidy up using, say, force directed layout.
Another option would be to find a spanning tree, render that, then add in the back links. This may well produce more crossings than the simulated annealing approach, but it has the benefit of reusing the solution to the first part of your assignment.
Best of luck!

Related

Is there a simple(-ish) algorithm for drawing force-directed graphs?

I'm trying to write a little graph visualizer in P5js but I can't find a simple(-ish) algorithm to follow.
I've found ways to do it with D3 and I've found some dense textbook snippets (like this) but I'm looking for something in between the two.
Can someone explain the simplest algorithm for drawing a graph (force-directed or otherwise) or point me to a good resource?
Thanks for your help!
I literally just started something similar.
It's fairly easy to code, you just need to think about the 3 separate forces acting on each node, add them together and divide that by the mass of the node to get the movement of each node.
Gravity, put a simple force acting towards the centre of the canvas so the nodes dont launch themselves out of frame
Node-Node replusion, You can either use coulombs force (which describes particle-particle repulsion) or use the gravitational attraction equation and just reverse it
Connection Forces, this ones a little tricky, define a connection as 2 nodes and the distance between them. when the actual distance between them is different from the defined distance, add a force in the direction of the connection multiplied by the difference between the defined and the actual distance

How to optimize a large graph for pathfinding algorithms?

I develop a small program where an user can create a simple diagrams with abstract blocks connected by lines, for example, flow charts or structural diagrams. One of the clause of the statement of work is that lines have to get around other blocks\lines and don't intersect them while moving.
Illustration
I tried to use pathfinding algorithms like A* or Lee's algorithm for it and consider a workspace (a window with diagram elements) like a graph - one pixel is one graph node. However, moving of blocks\lines causes the significant time delay (for example, pathfinding in the workspace with size 500x500 takes about 320-360 ms). It seems like the graph is too big for those algorithms.
Could you please tell me how to reduce the number of nodes with regard to this case? Maybe is there a way to speed up those algorithms or use something other for it?!
Don't think of this as a graph theory problem, think of it as a physics problem.
Visualize it as follows. Each block has a specified force pulling it towards the last place that it was put. Line segments, blocks, and the edge of the graph repel each other with an inverse square law (except that the end of the line you are drawing doesn't repel blocks in front of it). Under sufficient stress, a line segment can be broken into smaller line segments that have a pull towards returning to being a straight line.
The dynamics are complicated, but the number of entities is the number of objects you see on screen, not the number of pixels it is drawn on. Therefore you'll be able to do updates relatively quickly.
You'll need to play with the dynamics a bit to get a good experience, but this should be a more tractable approach.

Standard names for "stacked" versus "hanging" layered graph drawing algorithms?

Here are two different ways of drawing the same hierarchy. Notice that in the "stacked" layout, nodes are always one layer higher than their highest "child" node. (Important: See edit at bottom of question for another example)
Do these two types of layered drawing methods have specific names? I'm trying to find existing algorithms for the "stacked" one, but can't seem to surface any info because I don't know what it's called.
If they don't have names to distinguish them because they rely on the same algorithm, are there well known sets of parameters for attaining the "stacked" version of the graph with existing algorithms? Thanks!
Edit: Although the above graphs are strict "trees", the algorithm I'm looking for should be able to handle cases where nodes have more than one parent, and cases where there is more than one path from root to leaf. Here's an example, and here's another.
Edit2: In case it's useful to anyone, a hacky (and slow) force-directed approach with pre-computed node layers (y-axis contraints) seems to work all right. Here's what it looks like. That example uses cytoscape.js and cola.js, and it's upside down. It's not at all a solution to this question so I'm just putting this here as an edit.
(SO wouldn't let me submit the JSBin link without a code block...)
I don't know of any specific names for the above. It looks like the layering algorithm in both cases is the longest path algorithm that minimizes height but essentially ignores width. If you layer the graph from the bottom-up and the graph has many sinks (vertices with zero out-degree) then you will get a wide bottom layer (a "stacked" layout?). If you layer the graph from the top-down and it has many sources (vertices with zero in-degree) then you will get a wide top layer (a "hanging" layout?).

Arranging nodes-edges for 'good looking' graph layout

I came across following graph layout proposed in the paper NodeTrix :
The big blocks that are visible are nodes themselves (A sort of composite node of a sub-graph).
I see that the edges are some sort of curves which seem to not intersect too much among themselves. Also, the nodes and edges don't intersect among themselves. Paper doen't talk about it btw.
I was hoping to implement this visualization. I have following doubts:
Q1. Is this some specific algorithm to arrange Nodes-Edges so that the graph look good, as shown in this paper ? Any other algorithm in general ?
Q2. Is there some special algorithm for the curved edges shown above as well ?
It would be great if someone could figure out the exact algorithm in the above figure visually, but some general similar algorithm should also do.
One algorithm is Force-directed graph drawing. It will produce an output very different from the posted picture, but it is quite popular and might give you a place to start looking.
To be honest, I suspect that the shown graph is manually laid out.
EDIT: Answer to comment
In the example all nodes are square boxes, and the edges start/end diagonal to the sides of the boxes. A way to to this could be
Place boxes using force-direction (or likely some customized version of it, forces depend on the size of the box)
Imagine a "guide-edge" going directly between the centers of the boxes
Calculate the the places where the guide-edge intersects the boxes, and use that as the start/end points of the real, drawn edge.
Make the real edge start diagonal to the sides, and use bezier curves to draw the curve.
You probably want to represent this as some vector format, that has bezier cures built in, e.g., svg.

Circular representation of a tree structure

I have some data in a tree structure, and I want to represent them in a graphical way, with the root node in the middle of the stage, his children displaced in a circle around him, and so on for every children, around their parent.
I don't want overlapping nodes, so the question is how to arrange space in an optimal way.
Something less or more like (found via google)
What algorhythms I have to search to realize something like this?
If you don't care about how it's done, but just that you are visualizing the data, then take a look at graphviz's radial layout. Although the example doesn't look exactly what you want, it is the layout you'd need. It'll also give you some ideas on how it's done too with the loads of research papers in there. Good luck!
You could also see how easy it is to extend this paper into a circular structure.
You can do it in an emergent way by setting up a system in which each tree node tries to keep as much distance from all other nodes (except parent) as possible, but as short a distance as possible from the parent (down to some minimum distance which it must maintain). If you run that algorithm for each node repeatedly until it stabilizes, you'll have an arrangement like the one you describe. I'm sure there are a lot of optimizations you can do to it, but I'm pretty sure this is going to be the simplest approach. Trying to calculate all the layout up front would be very complex...
You are trying to draw a planar representation of a graph.
Find some buzzwords and perhaps a resource here
And in wikipedia
Ah and I forgot: You can do this the newtonian way with forces.
Simply give all nodes a repelling potential, like make them all Protons which push each other away. Give the edges the properties of newtonian springs, exerting forces that pull them together and you are all set.
Could even create nice animations that way.
This is also an official way of graph drawing, but I don't know the name.
If you want to draw the tree with a minimum of wasted space and short connections, then you're in for a computationally expensive solution. It will be hard to get this to be realtime on a tree of decent size, not to mention that making small changes to the tree might result in a radically different equilibrium.
Another approach would be to abandon the physical simulation and just build it iteratively. I've done something similar last week, but my trees are probably a lot less involved than yours.
For this tree-layout, each node object has to store an angle and an offset. These two numbers control where on the graphics surface they end up.
Here is my basic algorithm:
1) recurse over your entire tree-data and find all the Leaf nodes.
2) while you're doing this, be sure to measure the length of each branching structure, so you know which is the longest.
3) once you have all your leaf nodes, distribute them equally over a concentric circle. You can either use the entire circle, or only some part of the angle domain.
4) once all Leaf nodes have been solved, you recurse again over the tree, going from the outside in. Each node you encounter that is not a leaf node is in need of layout. Essentially, every node from here on has an angle which is the average of all it's child nodes, and the offset is the graph_radius * (depth_of_node / maximum_depth)
I found this gives me a very decent and humanly readable distribution, albeit not a very efficient one in terms of screen usage. I uploaded an animation of my tree-display here: GIF anim

Resources