Search code examples
graphvizdot

Set pre-defined node styles?


I've been googling around for the last 15 minutes trying to find an answer to this. But I can't seem to figure it out.

I was tasked with building some small flowcharts for some applications I've developed at work. They don't need anything fancy because they are going to convert it into their preferred format in vizio. They even said we could do it pen and paper. So I figured I would play around with graphviz/dot.

They have 6 pre-defined shapes/colors that they like to use, so I figured I would use them. I've already built them all in dot...but if I plan to re-use them many times, I'd like to find a way to save them as a sort of template.

Is that possible?

For example...These are the predefined shapes.

digraph G {
    node [color="#4271C6"]

    process [
        shape=Mrecord,
        style=filled, fillcolor="#E1F4FF",
        label="{1. Process\l | Description}"];

    subprocess [
        shape=record,
        style=filled, color="#FFFFFF", fillcolor="#A5A5A5",
        label="| Sub-Process |"];

    database [
        shape=cylinder, color="#18589A",
        label="Database"];

    inputoutput [
        shape=polygon,
        style=filled, fontcolor=white,
        fixedsize=true, skew=0.3, margin=0,
        width=2, label="Input / Output"];

    file [
        shape=folder,
        label="File"];

    external [
        shape=box3d,
        label="External entity"];
}

Nodes produced from above code


Solution

  • Okay, so I figured it out. I didn't realize you could do this...but apparently you can break up a node definition into multiple parts...so this is what I came up with, which solves my problem...

    I have a "Styles" section that goes at the top. Here I can define each node style. I use comments as a way of naming them. And I don't need to copy paste, because I can just define multiple nodes as a comma separated list.

    I also found that you can put them into subgraphs as well, like subgraph style_file {...}. But it seemed simpler to just use a comment as a way to name the style.

    digraph G {
        newrank=true;
    
        ///////////////////////////////////////////////////////////
        // Styles
        ///////////////////////////////////////////////////////////
            node [color="#4271C6"];
            edge [color="#4271C6"];
    
            //process
                createfile, uploadfile
                [shape=Mrecord, style=filled, fillcolor="#E1F4FF"];
            //subprocess
                exportfile, wait
                [shape=record, style=filled, color="#FFFFFF", fillcolor="#A5A5A5"];
            //external
                ftp
                [shape=box3d];
            //datastore
                database
                [shape=cylinder, color="#18589A"];
            //io
                exportproc
                [shape=polygon, style=filled, fontcolor=white, margin=0, width=3.1, fixedsize=true, skew=0.3];
            //file
                workfile
                [shape=folder];
    
        ///////////////////////////////////////////////////////////
        // Clusters
        ///////////////////////////////////////////////////////////
            subgraph cluster_0 {
                createfile  [label="{1. Process\l | Create file}"];
                exportfile  [label="|Export Data\nfrom DB|"];
                database    [label="Database"];
                exportproc  [label="Export Data"];
                workfile    [label="Generated file\n(Archived on server)"];
            }
    
            subgraph cluster_1 {
                uploadfile  [label="{2. Process\l | Upload file}"];
                ftp         [label="FTP Server"];
                wait        [label="|Wait for\nresponse file|"];
            }
    
        ///////////////////////////////////////////////////////////
        // Relationships
        ///////////////////////////////////////////////////////////
            {
                rank=same;
                createfile;
                uploadfile;
            }
    
        ///////////////////////////////////////////////////////////
        // Relationships
        ///////////////////////////////////////////////////////////
            # cluster_0
            createfile -> exportfile;
            exportfile -> database;
            database   -> exportproc;
            exportproc -> workfile [style=dashed];
    
            workfile -> uploadfile;
    
            # cluster_1
            uploadfile -> ftp [style=dashed];
            ftp -> wait;
    }
    

    Which produces this:

    enter image description here