Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write custom arrowheads in Graphviz

Tags:

graphviz

I use Graphviz (mainly dot and fdp) to automatically generate some diagrams that I need. For these diagrams I need some special arrowheads that are not a part of the standard collection of arrows: A small black triangle inside a large white triangle, and the same with the black triangle pointing downwards.

What is the best way to add such arrowheads? I don't mind hacking the source code, if necessary. Where should I start?

like image 685
Little Bobby Tables Avatar asked Jul 05 '10 11:07

Little Bobby Tables


1 Answers

You have to change to source code for that. Take a look at "lib/common/arrows.c". You will find that you have to:

  • Add a #define like ARR_TYPE_YOURARROWNAME
  • add a entry in Arrownames[] with the name you will use in the code for your arrow and the define.
  • write the prototype of your arrow function (see around row 115), read the points below
  • add your function in the Arrowtypes[] array an entry with the define you wrote previously, the pen width, the name of your arrow function which will be something like arrow_type_yourarrowname
  • write your own arrow function.

In order to write your function take a look at arrow_type_normal(), it takes 6 parameters: job (you don't have to care about this, just use it like in this function), two points ('p' and 'u'), arrowsize, penwidth and flag. If you don't care about making different versions of your arrowhead, or if you wish to ignore the modifiers (inverted arrows and the like) ignore the flag parameter.

Then, the function basically takes the two points p and u (which are structures with 'x' and 'y' attributes in them) and combines them creating an array called a[] passed to gvrender_polygon() which will finally render your arrow shape. arrow_type_normal() also mess with the penwidth and arrowwidth.

Summarizing: prepare graphviz to accept your arrow name doing the first steps then create a function that will create the arrow shape and that will call gvrender_polygon or gvrender_polyline (if you wish).

I didn't try yet, but it should work.

like image 59
David Costa Avatar answered Dec 17 '22 23:12

David Costa