For my flowchart, I have a vertical chart detailing the data flow. However on the downward arrows, I want to add side arrows to describe where the missing data is going. How do I do this? I can't see it in any of the documentation and examples because it tends to be about far more complex things, and I know this is a very basic task!
library(DiagrammeR)
grViz("digraph flowchart {
# node definitions with substituted label text
node [fontname = Helvetica, shape = rectangle, fixedsize = false, width = 1]
1 [label = 'data (100%)']
2 [label = 'data (90.4%)']
3 [label = 'data \\ndata (83.3%)']
4 [label = 'data (66%)']
7 [label = 'data (100%)']
8 [label = 'data (74.4%)']
9 [label = 'data (69.6%)']
10 [label = 'data (55.4%)']
1 -> 2 -> 3 -> 4;
7 -> 8 -> 9 -> 10
} ")
This gives me two side by side panels, but I want arrows coming off the downward arrows where I can put the n for missing data.
The standard trick is to create invisible dummy nodes, then break up each edge into two parts: 1) source -> dummy, and 2) dummy -> target:
library(DiagrammeR)
grViz("digraph flowchart {
# node definitions with substituted label text
node [fontname = Helvetica, shape = rectangle, fixedsize = false, width = 1]
1 [label = 'data (100%)']
2 [label = 'data (74.4%)']
3 [label = 'data (69.6%)']
4 [label = 'data (55.4%)']
m1 [label = 'missing (25.6%)']
m2 [label = 'missing (4.8%)']
node [shape=none, width=0, height=0, label='']
p1 -> 2; p2 -> 3 -> 4;
{rank=same; p1 -> m1}
{rank=same; p2 -> m2}
edge [dir=none]
1 -> p1; 2 -> p2;
}")
I shortened your example for demonstration purposes. In the above, p1 and p2 are invisible dummy nodes. There are three sets of edges:
Downward directed edges from dummy nodes to targets (e.g., p1 -> 2)
Horizontal directed edges from dummy nodes to "missing" nodes. Edge direction is imposed through rank=same.
Undirected edges from source to the dummy nodes
Related
I'm trying to make an Entity-relationship diagram using the Graphviz DOT language. In my model I have a self-referencing relationship and here I would like the edges to be orthogonal, i.e. consist only of vertical and horizontal lines. Currently I have this diagram:
digraph G {
edge [arrowhead = none]
Entity [shape = box]
Relationship [shape = diamond]
Entity -> Relationship [headport = w, tailport = w]
Relationship -> Entity [headport = e, tailport = e]
}
I tried adding graph [splines = ortho] but then the diagram renders like this:
Any ideas? I'm using version 2.43.0 of DOT.
The ortho implementation is rather flawed, Here is a DIY version. It adds invisible point-shaped nodes to each side of the two ER nodes and then draws edges to connect everything to look "ortho".
digraph G {
splines=false
edge [arrowhead = none]
{ rank=same
Entity [shape = box]
node [shape=point label="" style=invis]
x1 [group=G1]
x2 [group=g2]
x1 -> Entity [tailclip=false]
Entity -> x2 [headclip=false]
}
{ rank=same
Relationship [shape = diamond]
node [shape=point label="" style=invis]
y1 [group=G1]
y2 [group=g2]
y1 -> Relationship [tailclip=false]
Relationship -> y2 [headclip=false]
}
x1 -> y1 [headclip=false tailclip=false]
x2 -> y2 [headclip=false tailclip=false]
}
Giving:
I am trying to plot a regular graph with grViz in R like the below:
using the following code:
grViz("
graph {
# a graph statement
graph [layout = circo]
# a node statement
node [shape = circle,
style = filled,
color = grey,
fillcolor = orange];
nodesep=4
A; B; C; D; E; F; G; H;
# an edge statement
edge [color = grey]
A -- B
B -- C
C -- D
D -- E
E -- F
F -- G
G -- H
H -- A
A -- D
H -- E
B -- G
C -- F
}")
However, I cannot place the nodes in sequential order despite trying the different options for rankdir:
I am currently trying to create a flowchart using DiagrammeR
library(DiagrammeR)
grViz("
digraph g {
subgraph cluster_0 {
style=filled;
color=lightgrey;
label= To_Accrue
node [shape = rectangle, style = filled, fillcolor = Linen]
A
B
C
A->B->C
}
subgraph cluster_1 {
style=filled;
color=crimson;
label= Y
node [style=filled,color=blue, shape=folder]
1
2
3
1->2->3
}
}
")
Please refer to the link File to see what it currently generates (Tab-Sheet1). I was wondering if there is a way to achieve the desired output (Tab-Desired Output).
Thank you in advance.
The trick here is to use a blank node (called bnode here), groups (g1 in this example), and ranks (rank=same ...) to force the positioning and appearance you want. Nodes with the same group should appear in the same vertical plane, and nodes with the same rank will appear in the same horizontal plane.
library(DiagrammeR)
grViz("
digraph g {
subgraph cluster_0 {
style=filled;
color=lightgrey;
label= To_Accrue
node [shape = rectangle, style = filled, fillcolor = Linen]
bnode [style = invis, shape=point, width = 0, group=g1]
A [group=g1]
B
C [group=g1]
edge [arrowhead='none']
A->bnode
edge [arrowhead='normal']
B->bnode
bnode->C
{rank=same B bnode}
}
subgraph cluster_1 {
style=filled;
color=crimson;
label= Y
node [style=filled,color=blue, shape=folder]
1
2
3
1->2->3
}
}
")
I also edited the original code to generate the following to approach a rotational scenario.
enter image description here
library(DiagrammeR)
grViz("
digraph g {
subgraph cluster_0 {
style=filled;
color=lightgrey;
label= To_Accrue
node [shape = rectangle, style = filled, fillcolor = Linen]
a1 [style = invis, shape=point, width = 0, group=g1]
a2 [style = invis, shape=point, width = 0, group=g2]
a3 [style = invis, shape=point, width = 0, group=g3]
A [group=g1]
B
C [group=g1]
C [group=g2]
D
E [group=g2]
edge [arrowhead='none']
A->a1
C->a2
E->a3
edge [arrowhead='normal']
B->a1 {rank=same B a1}
a1->C
D->a2 {rank=same D a2}
a2->E
F->a3 {rank=same F a3}
a3->G
}
subgraph cluster_1 {
style=filled;
color=crimson;
label= Y
node [style=filled,color=blue, shape=folder]
1
2
3
1->2->3
}
}
")
The reason why Google didn't provide me the answer is I don't know the right name of the list elements in this case (*). Here I have some input data:
edges = ReadList["some\\external\\data\\source\\1"]
(* edges = { 0 -> 1, 1 -> 2, 2 -> 3 } *)
labels = ReadList["some\\external\\data\\source\\2"]
(* labels = { 0 -> A, 1 -> B, 2 -> A, 3 -> B } *)
I want to create a new list styles from labels with replaced A to Red and B to Green so I can get:
styles = { 0 -> Red, 1 -> Green, 2 -> Red, 3 -> Green }
I'm using it for drawing a graph:
Graph [ edges, VertexLabels -> labels, VertexStyle -> styles ]
(*) tried list of pairs, list of transitions, list of edges, but found that RightArrow operator has a general meaning...
I think you want this:
edges = {0 -> 1, 1 -> 2, 2 -> 3}
labels = {0 -> A, 1 -> B, 2 -> A, 3 -> B}
styles = labels /. {A -> Red, B -> Green}
Graph[edges, VertexLabels -> labels, VertexStyle -> styles]
How about starting with a "database":
edges[0] = 1; edges[1] = 2; edges[2] = 3;
labels[0] = "A"; labels[1] = "B"; labels[2] = "A"; labels[3] = "B";
and then some replacement rules:
s["A"] = "Red"; s["B"] = "Green";
which lets your define your new labels function:
styles[e_] := s[labels[e]]
which gives
In[9]:= Table[styles[i], {i, 0, 3}]
Out[9]= {"Red", "Green", "Red", "Green"}
etc...
I have to draw a small finite state machine that has some reflexive transitions (meaning the start and the end state of the transition are equal.
The problem is that rendering that in Graphviz has ugly results.
digraph finite_state_machine {
edge [fontsize=11];
S0 -> S0 [label = "td=1\n-/e2"];
S0 -> S1 [label = "td=3 \n-/e3" ];
S1 -> S0 [label = "td=3\n-/-\nt=0"];
S0 -> S2 [label = "P:i1/e4"];
S2 -> S0 [label = "td=0\n-/-" ];
S0 -> S0 [label = "i1/e1\ntd+=1"];
}
Is there a way to make this look a little better?
BTW: I tried head/tailport but they don't work on my version of Graphviz (1.13 on Mac OS X)
I am not limited to the dot engine, I only want a nice looking graph and don't care about the renderer/language.
Thanks a lot
So, if found a workaround, but not really an answer to my problem.
The trick is to have an invisible node that connections to the starting state. the starting state is then not the top of the hierarchy and one has a little bit more freedom in placing the nodes. Also then the head/tailport attributes work as they should.
The result is - if not a pretty as I would like it to be - ok to look at.
digraph finite_state_machine {
edge [fontsize=7];
fontsize = 11;
rankdir=LR;
{rank = same;null}
{rank = same; S0}
{rank = same; S1 S2}
nodesep = 1;
ranksep = 1;
null [shape = plaintext label=""];
null -> S0;
S0 -> S0 [label = "td=1\n-/e2", tailport = n, headport = n];
S0 -> S1 [label = "td=3 \n-/e3" ];
S1 -> S0 [label = "td=3\n-/-\nt=0"];
S0 -> S2 [label = "P:i1/e4"];
S2 -> S0 [label = "td=0\n-/-" ];
S0 -> S0 [label = "i1/e1\ntd+=1" headport = s tailport = s];
}
a rendering of the state machine http://img532.imageshack.us/img532/4083/previewd.png
While this works (for this particular example) I would still very much like some advice on dot/Graphviz or an alternative for rendering finite state machines in a pleasing way.