I am working on a visualization tool for an excel document containing a relatively large amount of business requirements (70 data elements).
The purpose is to show some of the internal structures of the data which is not immediately obvious when staring at the excel file. The structure looks something like this:
root-->(
(component 1)--->( sub-component a)--->(data element 1, data element 2, ..., data element 30),
(component 2)--->( sub-component a)--->(data element 1, data element 2, ..., data element 30),
(component 3)--->( sub-component a)--->(data element 2, data element 2, ..., data element 30)
)
What I'm noticing is that:
Graphs are great at showing structure, but suck at showing data. Tables are great at showing data, but suck at showing structure.
At this point I can no longer use the default autolayout of GraphStream. Due to the large number of data elements attached to a single sub component, the autolayout cannot position those elements in such a way that they don't overlap and become impossible to read. What happens is a sort of flower effect, where the data elements are are like overlapping petals around their parent.
If I disable the autolayout, I have to position the nodes myself. Graphstream says the following:
You fix the coordinates as you wish. The units you use will be called “Graph Units”. However, as you will see later, the viewer supports two other units: pixels and percents.
http://graphstream-project.org/doc/Tutorials/Graph-Visualisation/1.0/
Alright, as it turns out, either this is a difficult problem or I am slow. I have been unable to position nodes is a readable way.
Things I've tried:
- Positioning children relative to their parent: Iterate through the nodes with for loops (in retrospect it may be worth implementing this recursively to support n levels), starting with root. Determine the number of children of root divided by 2 (3/2 = 1 with integer division) call this middle. Set component 1 X position to i - middle. Set the y position to root y position - 1. In this way I can create a 'tree' structure where the parent sits centered on top of its children.
Other people's children are what's wrong with this world...
Unfortunately this doesn't work out well in practice. Any single component is ok but if there are other parents on the same level their children overlap with every other parent's children. This happens because the children are being positioned relative to their parent, and have no idea that, in fact, the position they want to go in is already being taken up by someone else's kids.
So now I don't know what to do. I can't position nodes taking into account nodes that don't exist yet. I have a few idea fragments, but they all seem convoluted.
So before I venture into hell code, I made this question because I feel like I can't possibly be the first person to have to draw a readable graph, and there probably are established ways to do this.
For reference these are the idea fragments:
Make individual graph elements responsible for their own position and have them position themselves relative to their children or lack there of.
Look into manipulating the camera in combination with some positioning solution. Limit the number of nodes that can be visible at a given time (kill other people's children if there's too many). Use zoom and panning based on which component is clicked.
Recursion. Is a word I know. Kidding aside, I have used recursion before and I feel graphs, especially graphs like mine without cyclic structures in them, practically beg for recursive solution. I actually have, in a different project used a recursive approach to draw graphs, but I ended up in the same situation. How can I be aware of the recursive paths drawing other parent's children? I should still probably brainstorm some recursive approaches.
Create a new data structure that represents relative real estate in the viewport. Segment into regions, nodes take up the relative regions, 2 nodes cannot take up the same relative region. Figure out what to do when some one try's to sit on someone else's kid. I came up with this while writing this post actually.
That's all I got, what do you guys think? Is there some well known algorithm for node positioning that already solves my issue? Which of my idea fragments sound most promising?