| 1 | module dotgraph |
| 2 | |
| 3 | import strings |
| 4 | |
| 5 | @[heap] |
| 6 | pub struct DotGraph { |
| 7 | mut: |
| 8 | sb strings.Builder |
| 9 | } |
| 10 | |
| 11 | pub fn new(name string, label string, color string) &DotGraph { |
| 12 | mut res := &DotGraph{ |
| 13 | sb: strings.new_builder(1024) |
| 14 | } |
| 15 | res.writeln(' subgraph cluster_${name} {') |
| 16 | res.writeln('\tedge [fontname="Helvetica",fontsize="10",labelfontname="Helvetica",labelfontsize="10",style="solid",color="black"];') |
| 17 | res.writeln('\tnode [fontname="Helvetica",fontsize="10",style="filled",fontcolor="black",fillcolor="white",color="black",shape="box"];') |
| 18 | res.writeln('\trankdir="LR";') |
| 19 | res.writeln('\tcolor="${color}";') |
| 20 | res.writeln('\tlabel="${label}";') |
| 21 | // Node14 [shape="box",label="PrivateBase",URL="$classPrivateBase.html"]; |
| 22 | // Node15 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid"]; |
| 23 | return res |
| 24 | } |
| 25 | |
| 26 | pub fn (mut d DotGraph) writeln(line string) { |
| 27 | d.sb.writeln(line) |
| 28 | } |
| 29 | |
| 30 | pub fn (mut d DotGraph) finish() { |
| 31 | d.sb.writeln(' }') |
| 32 | println(d.sb.str()) |
| 33 | } |
| 34 | |
| 35 | // |
| 36 | |
| 37 | pub struct NewNodeConfig { |
| 38 | pub: |
| 39 | node_name string |
| 40 | should_highlight bool |
| 41 | tooltip string |
| 42 | ctx voidptr = unsafe { nil } |
| 43 | name2node_fn FnLabel2NodeName = node_name |
| 44 | } |
| 45 | |
| 46 | pub fn (mut d DotGraph) new_node(nlabel string, cfg NewNodeConfig) { |
| 47 | mut nname := cfg.name2node_fn(nlabel, cfg.ctx) |
| 48 | if cfg.node_name != '' { |
| 49 | nname = cfg.node_name |
| 50 | } |
| 51 | if cfg.should_highlight { |
| 52 | d.writeln('\t${nname} [label="${nlabel}",color="blue",height=0.2,width=0.4,fillcolor="#00FF00",tooltip="${cfg.tooltip}",shape=oval];') |
| 53 | } else { |
| 54 | d.writeln('\t${nname} [shape="box",label="${nlabel}"];') |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | // |
| 59 | |
| 60 | pub struct NewEdgeConfig { |
| 61 | pub: |
| 62 | should_highlight bool |
| 63 | ctx voidptr = unsafe { nil } |
| 64 | name2node_fn FnLabel2NodeName = node_name |
| 65 | } |
| 66 | |
| 67 | pub fn (mut d DotGraph) new_edge(source string, target string, cfg NewEdgeConfig) { |
| 68 | nsource := cfg.name2node_fn(source, cfg.ctx) |
| 69 | ntarget := cfg.name2node_fn(target, cfg.ctx) |
| 70 | if cfg.should_highlight { |
| 71 | d.writeln('\t${nsource} -> ${ntarget} [color="blue"];') |
| 72 | } else { |
| 73 | d.writeln('\t${nsource} -> ${ntarget};') |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | // |
| 78 | |
| 79 | pub type FnLabel2NodeName = fn (string, voidptr) string |
| 80 | |
| 81 | pub fn node_name(name string, context voidptr) string { |
| 82 | return name.replace('.', '_') |
| 83 | } |
| 84 | |