Friday, April 6, 2012

Postscript flowchart symbols for graphviz

I've been wanting a more complete set of flowchart symbols for graphviz for a long time. Since today is a holiday and the kids are out of town I had some time to finally hack up some postscript flowchart shapes that graphviz can use. Some shapes are already available but others have been missing. With the above shape file, you have to use the postscript driver to have access to a more complete set of flowchart shapes. But once you've generated postscript, you can convert the output to other image formats with something like ghostview. Here is an example - a student registration process as a flow chart. This example was proposed as a swimlane flowchart and originally from an article in CA magazine.
Graphviz flowchart example: A Student registration process
The graphviz input file for that looks like this.
digraph apply {
  rankdir=BT; fontname=Helvetica
  node[peripheries=0, style=filled, fillcolor=blue, fontcolor=white,fontname=Helvetica,fixedsize=true,width=1.8,height=0.8]
  edge[fontname=Helvetica,fontsize=12,fontcolor=blue,labeldistance=1.8]

  subgraph cluster_student {
    label="Student";
    style=filled; fillcolor=grey92
    submit [shape=record, style="filled,rounded",label="Submit\nRegistration\n"]
    letter [shape=fdoc,peripheries=0, label="Letter"]
  }
  subgraph cluster_admin {
    label="Admin"
    style=filled; fillcolor=grey92
    complete  [shape=diamond,height=1,label="Application\nComplete?"]
    admreject [shape=record,label="Write Rejection\nLetter\n"]
  }
  subgraph cluster_registrar {
    label="Registrar"
    style=filled; fillcolor=grey92
    min [shape=diamond,height=1,label="Minimum\nStandard\nMet?"]
  }
  subgraph cluster_faculty {
    label="Faculty"
    style=filled; fillcolor=grey92
    {rank=same;
    suitable  [shape=diamond, height=1,label="Suitable for\nProgram?\n"]
    facaccept [shape=record,  label="Write Acceptance\nLetter\n"]
    }
  }

  submit -> complete
  complete -> submit     [headlabel="no"]
  complete -> min        [headlabel="yes"]
  min -> admreject       [headlabel="no"]
  min -> suitable        [headlabel="yes"]
  suitable -> admreject  [headlabel="no"]
  suitable -> facaccept  [headlabel="yes"]
  admreject -> letter
  facaccept -> letter
}
And the command for producing it looks like this.
dot -Teps -Gsplines=ortho -l flow.ps apply.dot | epstopdf --filter | pdftoppm | pamscale -width 800 | ppmtojpeg > apply.jpg
The detour through epstopdf is because the bounding box generated by graphviz is not really what you would expect. You need my flow.ps graphviz postscript shape file to provide as input to the dot command. For reference, here is a list of flow chart symbols that are now available.
Flowchart symbols for Graphviz (many from my postscript shape file)
It was produced with this command:
unflatten -c4 symbols.dot | dot -Teps -l flow.ps | epstopdf --filter | pdftoppm | pamscale -width 800 | ppmtojpeg > symbols.jpg
And here is the graphviz input file:
digraph symbols {

  node [peripheries=0,style=filled,fillcolor="antiquewhite4",fontname=Helvetica,fontcolor=white,fixedsize=true,width=1.8,height=0.6]

 data    [shape=fdata,       label="Data\nSymbol"]
 dec     [shape=diamond,     label="Decision\nSymbol", height=0.8]
 disk    [shape=fdisk,       label="Disk\nSymbol"]
 disp    [shape=fdisplay,    label="Display\nSymbol"]
 doc     [shape=fdoc,        label="Document\nSymbol"]
 extr    [shape=triangle,    label="Extract\nSymbol",  height=0.8]
 manin   [shape=fmanualin,   label="Manual Input\nSymbol"]
 manop   [shape=invtrapezium,label="Manual Operation\nSymbol"]
 merge   [shape=invtriangle, label="Merge\nSymbol",   height=0.8]
 multido [shape=fmultidoc,   label="Multi Document\nSymbol"]
 preproc [shape=fpreproc,    label="Predefined Process\nSymbol"]
 prep    [shape=hexagon,     label="Preparation\nSymbol"]
 proc    [shape=record,      label="Process\nSymbol"]
 term    [shape=record,      label="Terminator\nSymbol",style="rounded,filled"]
}

10 comments:

Alfredo Díaz said...

Very useful and interesting. Thanks

Alfredo Díaz said...
This comment has been removed by the author.
Kifty said...

Thanks so much for this! I was surprised GraphViz didn't include these shapes by default. You saved me a ton of effort with these.

Unknown said...

Is there possible to add also Transaction file symbol?

Where can I find full set of shapes (as in Dia -> Flow chart)?

Evan said...

What is that symbol looks like a rectangle and not complete. Is it a standard flowchart symbol?

Creately

Scum said...

Thanks a bunch for this.
Unfortunately this method does not work with Cairo renderer (i.e. when you specify -Tps:cairo instead of just -Tps).
And I really need Cairo, because the horribly obsolete built-in Postscript renderer does not support UTF-8.

So I either can't use UTF-8, or proper flowchart shapes.

Any ideas on this?

Jason Brazile said...

Unknown #1, I did a quick and dirty symbol for what you called the "Transaction file" symbol to the linked flow.ps file. According to wikipedia, it seems to be "online storage" so use it with shape=fonline.

Shalin - can you provide a link to the symbol? I am not sure which one you mean.

Unknown #2, thanks for the hint about using -Tps:cairo. However I tried it with some unicode examples from here and it seems to work for me even on an old fedora distribution e.g. with this result

Dotan Cohen said...

Hi Jason. The shapes are terrific, not that I'm having an issue with the fdata shape which is exactly the shape that I am interested in. The parallelogram shows the original containing rectangle within. That is, for the following code:
digraph {
node[shape="fdata"]
test_jason_code
}

I get a result like this:
https://ibin.co/3CGZRfLjlHuF.png

Have you any idea what might cause that? Note that I am using the PDF directly from epstopdf, I cannot install pdftoppm but for my purposes the PDF is even better anyway.

Thank you!

Jason Brazile said...

Hi Dotan

You need to set peripheries=0 [0] e.g.

digraph {
node [peripheries=0]

test_jason_code [shape="fdata"]
}

[0]
http://www.graphviz.org/doc/schema/attributes.xml#d:peripheries

Dotan Cohen said...

Thank you, I will give that a try.