Can graphviz create automatic group/cluster outlines? - graphviz

I am creating a network graph from some data. Not all the data is connected, leading to individual groups (or clusters? I'm not sure of the right terminology).
Below is an example of what it looks like. (I was using 'neato' here).
Is it possible to get graphviz to detect and draw lines around the individual groups?
I have looked at a number of dot examples with subgraphs. However, that would require me to know up-front which nodes belong in the same group, which means I would have to traverse each node to find all the connected nodes so I can include them in respective subgraphs.
I was hoping the framework can somehow do this for me automatically.

I believe that ccomps (http://www.graphviz.org/pdf/ccomps.1.pdf) (a Graphviz program) can identify disconnected subsets and create a subgraph for each subset. The following (Linux) command will identify these subsets and create a cluster around each.
ccomps -x myfile.gv | sed -e '/digraph .*_cc_/s/digraph /subgraph cluster/' -e '1idigraph N {' -e '$a}'

Related

How to add edge weights in ent?

I'm trying to use ent to build a recommendation engine (https://entgo.io/docs/schema-def/) by essentially treating ent over MySQL the same a Gremlin over a GraphDB.
I cannot figure out if there is a canonical way to add edge weights to the pre-generated schemas in ent. I think I could roll my own by modifying the generated code, but I feel like there must be a builtin way to generate edge weights, its not exactly an uncommon requirement.
How can I add weights or, generally, value data to edges in ent?

How to allow edges to overlap nodes?

I'm looking for a way to disable edge routing during rendering of dot graphs.
Ideally this would be a per-edge option, but disabling routing altogether would be helpful as well.
The graphs I'm generating represent syntax trees with additional edges from the usage of an identifier to its declaration as shown below.
Simple DAST
Now, this is still mostly readable, but with larger graphs the blue edges get very confusing very quickly, since dot seems to love routing them all over the place.
Complex DAST
I would prefer if they just went in a straight (or curved) line between the two nodes, ignoring all overlap with nodes and other edges.
Unfortunately I've been unable to find a way to achieve this effect and honestly I doubt it is even possible.
A similar question has been asked before, but I decided to open a new one anyway due to the following reasons:
I don't require the nodes to stay in a fixed position
Apart from the blue edges, my graph is always a tree (no edge overlap to worry about)
Running dot in multiple passes is unfortunately not an option for me
The other question is over 6 years old, so maybe a feature was added since then
My attempts so far:
Added "overlap=true" to the graph settings
Added "overlap=true" to individual edges
Neither of these seems to have any effect whatsoever.
The file layout is pretty simple (excerpt):
digraph {
node [shape=Mrecord];
graph [ordering=out, overlap=true, nodesep=0.3, ranksep=1];
...
# ReferenceLiteral rec
node0 -> node40 [style=dashed, color=blue, constraint=false]
node0 [shape=box style=filled label="rec" fillcolor="#cccccc"]
...
# PortNode Record
node28:p0:s -> node40:n
node28:p1_0:s -> node7:n
node28 [label="{Record|{<p0>Name|{Elements|{<p1_0>1}}}}"]
...
# DeclarationLiteral rec
node40 [shape=box style=filled label="rec" fillcolor="#cccccc"]
...
}

DFS strongly connected components dilemma

Question: Divide the set of vertices of the graph in Problem 1 into strongly connected components
(SCC). Namely, specify which vertices are in the first strongly connected component, which
in the second, and so on.
is any one able to confirm ive done this correctly? namely when i reach vertex 4 i have the option to make the first SCC either 1,7,2,4,3 (as shown) or 1,7,2,4,6,5 depending on which way i choose to travel. Is there a method to this, or can i simply just choose?
order:
1,2,7,3,4,5,8,6
SCC:
1,7,2,4,3
5
8
6
The strongly connected component is {1,2,3,4,5,6,7}. If you don't get that, your algorithm (or your implementation) has a bug. There is a definition of Strongly Connected Component, and several well-known algorithms; both can be found easily in Wikipedia (and many other internet resources) and, most likely, in your textbook and/or course notes. (If you don't have course notes, you'll easily find some for similar courses.)
you can add 5 and 6 to 1,7,2,4,3 since both are reachable from others via 4
In DFS
you have to continue visting node and creating tree while the stack is not empty
if so, then restsrt with the lowest id which is still white

Generating a directed acyclic graph from predefined elements with connection requirements

I am working on a system, when given a bank of different types of elements will create a directed acyclic graph connecting some or all the elements. Each element has some input A and an output B. When building the Graph, the system will need to make sure, the output of the previous node, matches the input of the current one.
The input and output of the nodes are to make sure only certain types of elements are connected
The elements would look like this
ElementName : Input -> Output
Possibly with multiple inputs/output, or with no outputs(See below).
One : X -> Y
Two : Y -> Z,F
Three : Y, Z -> W
Four : Z -> F
Five : F -> NULL
Note:
We are talking about a lot of different elements, 30 or so now, but the plan is to add more as time goes on.
This is part of a project to do a procedural generated narrative. The nodes are individual quests. The inputs are what you need to start the quest. The outputs are how the story state is effected.
Problem:
I have seen several different approaches to generating a random DAG, not one for making a DAG from some preset connection requirements(with rules on connecting them).
I also want some way of limiting complexity of the graph. i.e limit the number of branches they can have.
Idea of what I want:
You have a bunch of different types of legos in a bin, say 30. You have rules on connecting the Legos.
Blue -> Red
Blue -> White
Red -> Yellow
Yellow -> Green/Brown
Brown -> Blue
As you all know, in addition to a color each lego had a shape.So 2 blue legos may not be the same type of lego. So The goal is to build a large structure that fits our rules. Even with our rules, we can still connect the legos in a bunch of different structures.
P.S. I am hoping this is not to general of a question. If it is, please make a note and I will try to make it more specific.
It sounds like an L-system (aka Lindenmayer system) approach would work:
Your collection of Legos is analogous to an alphabet of symbols
Your connection rules correspond to a collection of production rules that expand each symbol into some larger string of symbols
Your starting Lego represents the the initial "axiom" string from which to begin construction
The resulting geometric structures is your DAG
The simplest approach would be something like: given a Lego, randomly select a valid connection rule & add a new Lego to the DAG. From there you could add in more complexity as needed. If you need to skew the random selection to favor certain rules, you're essentially building a stochastic grammar. If the selection of a rule depends on previously generated parts of the DAG it's a type of context sensitive grammar.
Graph rewriting, algorithmically creating a new graph out of base graph, might be a more literal solution, but I personally find that L-systems easier to internalize & that researching them yields results that are not overly academic/theoretical in nature.
L-systems themselves are a category of formal grammars. It might be worth checking into some of those related ideas, but it's pretty easy (for me at least) to get side tracked by theoretical stuff at the expense of core development.

Using Graphviz's dot or neato to layout clusters

I'm trying to draw a deployment diagram of services and servers in our enterprise using dot. For the first iteration, I used neato to draw each service as a box and Prevent overlapping records using graphviz and neato , plus allowing splines, allowed me to get a decent layout with the edges as dependencies.
Now I need to place physical servers inside each of these boxes. First I made each service a subgraph with a name beginning with cluster and then placed the nodes representing the physical servers inside each box. Again, with the help of GraphViz - How to connect subgraphs? I faked out the edges to connect the clusters rather than the nodes. The problem is, that only works in dot. When I use neato to do the layout, it doesn't understand the edges are between clusters, so it moves only the node of the cluster I used to anchor the edge. The result is the cluster boxes are enormous and overlapping.
I hope that makes sense. Is there any way to force neato to keep the nodes in a cluster grouped?
I rethought what I was doing, and instead of using a subgraph for each service with subnodes for each server, I used a record format instead. Each node now looks like
+------------------------------+
| Service name |
+------------------------------+
| server1 | server2 | server 3 |
+------------------------------+
and it's much easier to lay those out :)

Resources