* digraph G { subgraph cluster0 { node [style=filled,color=white]; style=filled; color=lightgrey; a0 -> a1 -> a2 -> a3; label = "process #1"; } subgraph cluster1 { node [style=filled]; b0 -> b1 -> b2 -> b3; label = "process #2"; color=blue } start -> a0; start -> b0; a1 -> b
()
| 50 | } |
| 51 | */ |
| 52 | func (fg *FlowGraph) plot() { |
| 53 | fg.println("digraph glow {") |
| 54 | prefix := " " |
| 55 | for _, tg := range fg.taskGroups { |
| 56 | fg.printTaskGroup(tg, prefix) |
| 57 | } |
| 58 | hasStart, hasEnd := false, false |
| 59 | for _, tg := range fg.taskGroups { |
| 60 | firstTask, lastTask := tg.Tasks[0], tg.Tasks[len(tg.Tasks)-1] |
| 61 | if firstTask.Inputs == nil { |
| 62 | ds := firstTask.Outputs[0].Parent |
| 63 | if len(ds.ExternalInputChans) == 0 { |
| 64 | fg.w(prefix).w("start -> ").t(firstTask).println(";") |
| 65 | hasStart = true |
| 66 | } else { |
| 67 | for i, _ := range ds.ExternalInputChans { |
| 68 | fg.w(prefix).input(firstTask, i, len(ds.ExternalInputChans)).println(" [shape=doublecircle];") |
| 69 | fg.w(prefix).input(firstTask, i, len(ds.ExternalInputChans)).w(" -> ").t(firstTask).println(";") |
| 70 | } |
| 71 | } |
| 72 | } else { |
| 73 | for _, dss := range firstTask.Inputs { |
| 74 | fg.w(prefix).d(dss).w(" -> ").t(firstTask).println(";") |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | if lastTask.Outputs == nil { |
| 79 | hasEnd = true |
| 80 | fg.w(prefix).t(lastTask).println(" -> end;") |
| 81 | } else { |
| 82 | for _, dss := range lastTask.Outputs { |
| 83 | fg.w(prefix).t(lastTask).w(" -> ").d(dss).println(";") |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | for _, ds := range fg.flowContext.Datasets { |
| 89 | if len(ds.ExternalOutputChans) > 0 { |
| 90 | fg.w(prefix).output(ds).println(" [shape=doublecircle];") |
| 91 | for _, dss := range ds.Shards { |
| 92 | fg.w(prefix).d(dss).w(" -> ").output(ds).println(";") |
| 93 | } |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | fg.w(prefix).println("center=true;") |
| 98 | fg.w(prefix).println("compound=true;") |
| 99 | if hasStart { |
| 100 | fg.w(prefix).println("start [shape=Mdiamond];") |
| 101 | } |
| 102 | if hasEnd { |
| 103 | fg.w(prefix).println("end [shape=Msquare];") |
| 104 | } |
| 105 | |
| 106 | fg.println("}") |
| 107 | } |
| 108 | |
| 109 | func (fg *FlowGraph) println(t string) *FlowGraph { |