I have the following model:
strict digraph graphName {
rankdir="LR";
splines="curved";
age -> intention [label="-"];
attitude -> intention [label="+"];
education -> intention [label="+"];
env_friendly -> intention [label="+"];
knowledge -> intention [label="+"];
male
negative -> intention [label="-"];
neutral
positive -> intention [label="+"];
unsafe -> intention [label="-"];
positive -> env_friendly [dir="both", label="+"];
{ rank = same; age; attitude; education; env_friendly; knowledge; male; negative; neutral; positive; unsafe; }
}
This renders OK but the edge labels are off, and the double-arrow goes into the nodes rather than to the node edge. What must I do to get the labels back with the nodes?
Just removing the the line splines = "curved"; gives you what (I guess) you want:
strict digraph graphName {
rankdir="LR";
# splines="curved";
age -> intention [label="-"];
attitude -> intention [label="+"];
education -> intention [label="+"];
env_friendly -> intention [label="+"];
knowledge -> intention [label="+"];
male
negative -> intention [label="-"];
neutral
positive -> intention [label="+"];
unsafe -> intention [label="-"];
positive -> env_friendly [dir="both", label="+"];
{ rank = same; age; attitude; education; env_friendly; knowledge; male; negative; neutral; positive; unsafe; }
}
yields
The hint was in graphviz's warning
Warning: edge labels with splines=curved not supported in dot - use xlabels
but rather than using xlabels, the key is leaving splines alone.
Related
I would like to indicate that a node should be there, but is currently lacking in the process.
Intuitively I would like to cross it out as shown in below image (now done manually in Paint):
Is there a node attribute in Graphviz that I can use for this?
I can't find an attribute or node shape to do what you want, but here are two ways to do it:
build an image outside of Graphviz (with the text and the X) and use the image attribute to use the image as the node (yes, a pain if you want to do this frequently):
b [image="myB.png"]
For every X'd out node, add 2 new edges from .ne to .sw and .nw to .se (see below) Each with this (new) attribute: straightline=1. Then run this command:
dot -Tdot Xout2.gv |gvpr -f straightline.gvpr -c | neato -n2 -Tpng >out.png
Where this is straightline.gvpr:
E[straightline==1]{
int i, n;
string pt[int];
double x1, y1, x2, y2, xI1, yI1, xI2, yI2;
n=split($.pos, pt, " ");
for (i=0;i<=1;i++){
if (match(pt[i],"e,")>=0){
print ("// BEFORE: ", pt[i]);
pt[n-1]=substr(pt[i],2);
print ("// AFTER: ", pt[i]);
pt[i]=pt[i+1];
}
}
for (i=0;i<=1;i++){
if (match(pt[i],"s,")>=0){
pt[0]=substr(pt[i],2);
}
}
sscanf (pt[0], "%f,%f", &x1, &y1);
sscanf (pt[n-1], "%f,%f", &x2, &y2);
xI1=x1+(x2-x1)*.3;
yI1=y1+(y2-y1)*.3;
xI2=x1+(x2-x1)*.7;
yI2=y1+(y2-y1)*.7;
$.pos=sprintf("%s %.3f,%.3f %.3f,%.3f %s", pt[0], xI1, yI1, xI2, yI2, pt[n-1]);
}
From this input:
digraph X{
graph [outputorder=edgefirst]
b [ label="X me"]
a -> b -> c
a -> d
d -> c
e -> f
g -> i -> k
edge [color="#ff000080" penwidth=2] // note translucent color
b:ne -> b:sw [straightline=1]
b:se -> b:nw [straightline=1]
edge [color="green" penwidth=2]
e:n -> e:s [straightline=1]
f:w -> f:se [straightline=1]
edge [color="orange" penwidth=2]
g:n -> g:se [dir=back straightline=1]
edge [color="blue" penwidth=2]
g:n -> g:sw [dir=back straightline=1]
i:e -> i:w [dir=none straightline=1]
k -> k:s [dir=both straightline=1]
}
Sorry, convoluted, but it works.
While the answer of sroush gives me the exact output I need, it requires that I understand how to introduce gvpr in my workflow which will take a bit of time.
In the meantime I came up with a dot only approach, which approximates crossing out a node sufficiently for my purpose.
In below graph I would like to cross out the node Some process:
digraph graphname {
rankdir=LR
node [fillcolor="lightblue3", style="filled"]
a
c
d
b [label="Some\nprocess"]
a -> b -> c
a -> d -> c
{rank=same a;d}
}
To do so I change:
the nodestyle of the Some process node to have a diagonal hard gradient
use a HTML-like label to strikethrough the text
Make the fontcolor and node outline a shade of gray
digraph graphname {
rankdir=LR
node [fillcolor="lightblue3", style="filled"]
a
c
d
node [fillcolor="lightblue3;0.5:white", style="filled", fontcolor="gray50", color="gray50", gradientangle=100]
b [label=<<s>Some<br/>process</s>>]
a -> b -> c
a -> d -> c
{rank=same a;d}
}
I'm using this Python project "Family Tree Maker" to generate a family tree. It works with GraphViz, creates a nice DOT file and then a PNG. "Minimum Viable Product" check. It works :D
Now I'd like to make it a bit nicer.
Is there a simple way (e.g. not having to increase the length of the edge per hand) to force the right-most vertical edge (between Father1-Mother2 and Franz) to be straight/vertical like displayed below?
Thanks!
Edit: as correctly stated by #albert in the comments, webgraphviz.com displays the correct output while viz-js.com doesn't.
PS: Here's the DOT code that generate this Graph:
digraph {
graph [splines=ortho];
node [shape=box, fontname = "calibri"];
edge [dir=none];
Father1[label="Father1",style=filled,fillcolor=azure2];
Mother1[label="Mother1",style=filled,fillcolor=bisque];
Child1[label="Child 1",style=filled,fillcolor=azure2];
Child2[label="Child 2",style=filled,fillcolor=bisque];
Child3[label="Child 3",style=filled,fillcolor=azure2];
Child4[label="Child 4",style=filled,fillcolor=azure2];
Mother2[label="Mother2",style=filled,fillcolor=bisque];
Franz[label="Franz",style=filled,fillcolor=azure2];
{ rank=same;
Mother1 -> h0 -> Father1;
h0[shape=circle,label="",height=0.01,width=0.01];
Father1 -> h1 -> Mother2;
h1[shape=circle,label="",height=0.01,width=0.01];
}
{ rank=same;
h0_0 -> h0_1 -> h0_2 -> h0_3 -> h0_4;
h0_0[shape=circle,label="",height=0.01,width=0.01];
h0_1[shape=circle,label="",height=0.01,width=0.01];
h0_2[shape=circle,label="",height=0.01,width=0.01];
h0_3[shape=circle,label="",height=0.01,width=0.01];
h0_4[shape=circle,label="",height=0.01,width=0.01];
h0_4 -> h1_0 [style=invis];
h1_0;
h1_0[shape=circle,label="",height=0.01,width=0.01];
}
h0 -> h0_2;
h0_0 -> Child1;
h0_1 -> Child2;
h0_3 -> Child3;
h0_4 -> Child4;
h1 -> h1_0;
h1_0 -> Franz;
{ rank=same;
Child1 -> Child2 [style=invis];
Child2 -> Child3 [style=invis];
Child3 -> Child4 [style=invis];
Child4 -> Franz [style=invis];
}
{ rank=same;
}
}
As expected after discussing with #Albert in the comments, using version 2.28 of GraphViz, I get the result I wanted.
I created an issue report on GraphViz's Gitlab: https://gitlab.com/graphviz/graphviz/issues/1627
I am trying to create a timeline that associates years with historical events in DOT, but somehow don't get along with the DOT User's Guide.
Here is my first take:
digraph {
ratio=0.70 ranksep=.75
{
node [shape=plaintext, fontsize=16];
past -> 1933 -> 1943 -> 1988 -> 2001 -> 2015 -> future;
node [shape=plaintext, fontsize=14];
a -> b -> c -> d -> e -> f -> g;
{rank=same past -> a }
{rank=same 1943 -> c }
{rank=same future g }
}
}
The timeline on the left is taken from the User's Guide. The line on the right was meant to contain the corresponding information on the historic event, e.g. for the year 1943 the info is c.
The output looks like this:
However, I would like to have the line on the right much closer to the left timeline. And the historic events on right should not be connected by an arrow with each other.
Somehow the connection between f and g is messed up, too.
Both the ratio and the ranksep influence the distance between the nodes. I would advise using one or the other to see what the difference is. Removing both gives a shorter distance.
To remove the arrows between the events on the right, edge style can be set to "invis".
Running the posted DOT (see the resulting image) does not show any weird connection between f and g...
Using the following DOT:
digraph {
node [shape=plaintext, fontsize=16];
past -> 1933 -> 1943 -> 1988 -> 2001 -> 2015 -> future;
{
node [fontsize=14];
edge [style=invis];
a -> b -> c -> d -> e -> f -> g;
}
{rank=same past -> a }
{rank=same 1943 -> c }
{rank=same future g }
}
Yields this result:
It took me some time to make the graph below look like it does right now, and I'm almost satisfied. The one thing that still bothers me is that the connection between D and B should be above all nodes for the sake of aesthetics.
The funny thing is, that supplying the ports for the edge doesn't impress dot which just makes the edge cross the connected nodes.
Do you have an idea on how to avoid this?
digraph {
graph [splines=ortho, nodesep=0.2, fontname="DejaVu Sans", rankdir=LR]
node [shape=box, fontsize=8]
edge [arrowsize=0.5]
subgraph cluster {
style=invis;
A -> B -> C;
A -> B -> C;
A -> B -> C -> D;
D -> E;
D:nw -> B:ne;
}
{
D -> F -> { C; E };
}
}
PS: You need the latest Graphviz version in order to get orthogonal edges.
It may be a function of the version of the engine you use. I'm not sure what version of dot the GraphViz Workspace http://graphviz-dev.appspot.com/ uses but it does run your problem connector across the top.
Need draw a graph with dot/graphviz like this image:
The texts can be above arrows, like graphviz does it. But how to achieve the T-layout? Need make a cluster for the top row?
This is one possibility using rank=same for a subgraph:
digraph g {
node[shape=point, width=0.2];
{
rank=same;
p1 -> n [label="text1"];
n -> p2 [label="text2"];
}
n -> p3 [label="text3", dir=back];
n[label="node", shape=rect, style=rounded];
}
You could also use a left-right layout instead of top-down.
An other possibility is to disable the effect of some edges using constraint=false:
digraph g {
node[shape=point, width=0.2];
p1 -> n [label="text1", constraint=false];
n -> p2 [label="text2", constraint=false];
n -> p3 [label="text3", dir=back];
n[label="node", shape=rect, style=rounded];
}
The result is the same.
dot usually layouts trees in layers. To force an edge to not be a layer separation you can add the constraint=false option. So something like:
digraph {
A [shape=point]
B [shape=point]
C [shape=point]
N [label="node"]
A -> N [label="text1", constraint=false]
N -> B [label="text2", constraint=false]
N -> C [label="text3", dir=back]
}
should work.
Note that the edge from the lower node to "node" has to be backwards, since dot layouts trees from top to bottom. Therefore the logical edge direction has to be from top to bottom, even though the display direction might be the other way round (which is the case here).