Viewer/explorer that can collapse clusters?

Is there a viewer/explorer software that allows you to collapse and expand clusters? I.e., you have this graph before, and via collapsing, it gets displayed as this graph afterwards? I’d prefer an open source product.

Would you be open to using a script that creates your desired collapsed graph? Or do you really want the toggling action to be available inside the editor?

Note that I don’t know how to create such a script. I’m just starting to learn about Graphviz and dot. But if you are open to a scriptable approach, that might help others answer your question.

No, I need this functionality in an editor or viewer. I want to be able to quickly explore a large graph without the hassle of calling the script and reloading many times. A script may only help if an editor or viewer has a hook for calling it upon clicking a cluster/node.

Questions, but no immediate answers:

  • I assume that “collapse” means “convert to a node” What am I missing?
  • if there are nested clusters, would you want the ability to collapse mid-level clusters, or do you only want the ability to collapse top-level clusters (and all lower-level contents)?
  • your after image shows both clusters collapsed. would all clusters be collapsed at one click, or just one cluster collapsed per click?
  • what labelling happens at time of collapse if the cluster itself is not labelled?
  • should the graph go through a re-layout after a collapse? the result could significantly rearrange the result, making it hard to follow the changes as clusters are collapsed.
  • any guesses how many clusters might be in a graph?
  • would you share an example input to experiment with?

I assume that “collapse” means “convert to a node” What am I missing?

Yes.

if there are nested clusters, would you want the ability to collapse mid-level clusters, or do you only want the ability to collapse top-level clusters (and all lower-level contents)?

Upon clicking any cluster (top- or mid-level), all of its content (clusters and nodes) should be collapsed.

your after image shows both clusters collapsed. would all clusters be collapsed at one click, or just one cluster collapsed per click?

Just the one that was clicked.

what labelling happens at time of collapse if the cluster itself is not labelled?

It would be OK to assume all clusters are labelled. If not, no node label or an autogenerated node label would be fine.

should the graph go through a re-layout after a collapse? the result could significantly rearrange the result, making it hard to follow the changes as clusters are collapsed.

That’s a difficult question to answer. I think there is value in both, re-layout and no re-layout.

any guesses how many clusters might be in a graph?

Dozens.

would you share an example input to experiment with?

I don’t have one except for the mini examples I have linked above.

I’m trying to find out whether GraphViz would be a good tool for exploring software design and project management items.

For software architecture, nodes could be classes, clusters namespaces/packages and edges dependencies. Maybe even different types of dependencies, e.g. inheritance or association etc. I have once used such an explorer at work in a very expensive edition of Visual Studio. I have not found such a great tool for other languages that was affordable for personal use. jQAssistant may be what I am looking for. It is an open source tool that allows creating neo4j (graph database) graphs for Java (and AFAIK any language if writng an extension). And AFAIK, neo4j graphs can be exported as GraphViz.

For project management, nodes/clusters could be parent and child issues, and edges could be relationships like “blocks” or “relates to”. Apparently there is an extension for jQAssistant that can do that for the project management software Jira.

For both use cases, the collapse feature is quite vital, because a graph with hundreds of nodes and edges does not aid understanding.

As a side note for this question, custom arrangement of node positions would also be important. AFAIK that should be possible in at least some editors, because I have seen that some GraphViz layout engines support an attribute for a node’s position.

I’ve spent a fair amount of time over the years looking for something similar.

The closest thing that I ever found was yEd by yWorks. Here is an example of a graph with collapse/expand functionality: Folding With Layout Demo [yFiles for HTML]. It has been several years since I’ve researched down this path so there may be other products that do similar things at this point. One thing to note in the demo is that re-layout is important when collapsing and expanding nodes as the diagram will often change pretty significantly.

Another option you might want to consider, especially for the software architecture piece, is Simon Brown’s C4 Model (c4model.com) and his Structurizr tooling (https://structurizr.com/) to support the C4 Model.

In the end, because I’ve got budget constraints, I ended up building my own web-based “viewer” application which allows me to interact with the nodes (click on them) and navigate up and down my hierarchy. I’ve got a database which has all the relationships for the different architecture levels and a C# application which builds the Graphviz / dot code which is rendered as SVG and pushed to the browser. Each node has a different URL endpoint and each click goes to the server and renders the new view.

Even before building the app, the bigger challenge was actually deciding what needed to be built or what to show in each diagram. The C4 Model concepts really helped me focus on having specific diagrams at a specific level and not trying to overload the diagrams to do too much.

Here is a brief view of the interaction as an animated GIF. Hopefully it renders properly here (looks like you may have to click it to get it to start the animation). And the resolution is intentionally small to make the image smaller and to avoid exposing too much from my side.
chrome_Mte5NnjTp7

While this is pretty cool, it has taken me quite a while over the past 2-3 years to build out the functionality. Although, the basic interactions and navigation weren’t terribly complicated. It is all the details around what I’m trying to display.

Hope that gives you some ideas!

2 Likes

yFiles is totally out of reach financially. I couldn’t find a price for yEd. I’ll definitely have a closer look at the C4 model and Structurizr. Looks like the important features are available for free.

Have you considered making your project available as open source or commercializing it?

It gets complicated. I’m building it for work and there are complexities around open sourcing it. In addition, what I’m building is very narrowly tailored to my needs. And trying to support something like this right now is not something I can take on.

But happy to give some pointers…

Here is a snippet from my RenderClusterOpen() method:

            sb.AppendLine($"{pad}subgraph cluster_{level}_{id} {{");
            sb.AppendLine($"{pad}    fillcolor = \"{fillcolor}\"");
            sb.AppendLine($"{pad}    label = {label}");
            sb.AppendLine($"{pad}    style = \"{style}\"");
            sb.AppendLine($"{pad}    tooltip = \"{name}\"");
            sb.AppendLine($"{pad}    URL = \"{url}\"");

And a snippet from my RenderNodeOpen() method:

            sb.AppendLine($"{pad}{level}_{id}_ [");
            sb.AppendLine($"{pad}    fillcolor = \"{fillcolor}\"");
            sb.AppendLine($"{pad}    label = {label}");
            sb.AppendLine($"{pad}    id = \"{nodeId}_\"");
            sb.AppendLine($"{pad}    shape = \"{shape}\"");
            sb.AppendLine($"{pad}    style = \"{style}\"");
            sb.AppendLine($"{pad}    tooltip = \"{name}\"");
            sb.AppendLine($"{pad}    URL = \"{url}\"");
            sb.AppendLine($"{pad}]");

Once the Graphviz dot code has been generated as a string, I use this GitHub - JamieDixon/GraphViz-C-Sharp-Wrapper: GraphViz C# Wrapper to render the SVG output and pass it to my view:

            // Note that I just followed his instructions for this code...
            var getStartProcessQuery = new GetStartProcessQuery();
            var getProcessStartInfoQuery = new GetProcessStartInfoQuery();
            var registerLayoutPluginCommand = new RegisterLayoutPluginCommand(getProcessStartInfoQuery, getStartProcessQuery);

            // GraphGeneration can be injected via the IGraphGeneration interface
            var wrapper = new GraphGeneration(getStartProcessQuery,
                                              getProcessStartInfoQuery,
                                              registerLayoutPluginCommand);

            wrapper.RenderingEngine = Enums.RenderingEngine.Dot;

            byte[] interactiveSvg = wrapper.GenerateGraph(diagBuilder.ToString(), Enums.GraphReturnType.Svg);

            ViewData["interactiveDiagram"] = Encoding.ASCII.GetString(interactiveSvg);

My view has a placeholder for the SVG:

        <div id="interactive" class="tab-pane active">
            <div>@Html.Raw(ViewData["interactiveDiagram"])</div>
        </div>

In theory, once you get the SVG rendering to the client, there isn’t much else to do. The fact that the clusters and nodes support the URL attribute takes care of making them clickable links. You obviously do need to have some mechanism to make them different urls or parameters so that you can pull the next set of data properly.

And since it is SVG, it was fairly easy to use jQuery to highlight / un-highlight the nodes during mouse-over events.

I don’t know what kind of platform you run on, but regardless of what it is, the main trick is to get the Graphviz engine to render the output as SVG and send it to the browser. In my case I sent it down as bytes along with the page, but I very easily could have saved the diagram to a file and used an img tag to link to it. And actually, that is what I also do. It isn’t visible in the gif above, but I have four tabs: one with the interactive SVG, one with a PNG to make it easier to copy and use elsewhere, one with the Graphviz dot output that I can copy and troubleshoot in gvedit, and one tab to render a slightly different version of code to try to use in our wiki (work in progress).

As I mentioned previously, the biggest challenge is deciding what you want to render. I have hundreds of applications that roll up into 70-80 systems which run on a dozen different platforms with one or more tiers. I’m basically doing something similar to the C4 Model but with different names and up a level or two. He goes does into the class and code levels which I can’t / won’t get to.

Hope that gives you something to think about!

1 Like

FWIW the approach I have taken in some products is to represent the graph in two panes:

  • On the LHS a multi select tree of the clusters and nodes
  • On the RHS the graph which is generated based on the LHS selection

Here is a snapshot (with a bunch of selections in the “tree” - not the best example as its more a list - but you get the idea…):

While the above is “open source”, it is a bit too integrated to be usefull, but here are some pieces of note:

HTH