Render the RevTree in Graphviz Dot format, which can then be used to generate a PNG diagram like http://cbmobile-bucket.s3.amazonaws.com/diagrams/example-sync-gateway-revtrees/three_branches.png using the command: dot -Tpng revtree.dot > revtree.png or an online tool such as webgraphviz.com
()
| 660 | // like http://cbmobile-bucket.s3.amazonaws.com/diagrams/example-sync-gateway-revtrees/three_branches.png |
| 661 | // using the command: dot -Tpng revtree.dot > revtree.png or an online tool such as webgraphviz.com |
| 662 | func (tree RevTree) RenderGraphvizDot() string { |
| 663 | |
| 664 | resultBuffer := bytes.Buffer{} |
| 665 | |
| 666 | // Helper func to surround graph node w/ double quotes |
| 667 | surroundWithDoubleQuotes := func(orig string) string { |
| 668 | return fmt.Sprintf(`"%s"`, orig) |
| 669 | } |
| 670 | |
| 671 | // Helper func to get the graphviz dot representation of a node |
| 672 | dotRepresentation := func(node *RevInfo) string { |
| 673 | switch node.Deleted { |
| 674 | case false: |
| 675 | return fmt.Sprintf( |
| 676 | "%s -> %s; ", |
| 677 | surroundWithDoubleQuotes(node.Parent), |
| 678 | surroundWithDoubleQuotes(node.ID), |
| 679 | ) |
| 680 | default: |
| 681 | multilineResult := bytes.Buffer{} |
| 682 | multilineResult.WriteString( |
| 683 | fmt.Sprintf( |
| 684 | `%s [fontcolor=red];`, |
| 685 | surroundWithDoubleQuotes(node.ID), |
| 686 | ), |
| 687 | ) |
| 688 | multilineResult.WriteString( |
| 689 | fmt.Sprintf( |
| 690 | `%s -> %s [label="Tombstone", fontcolor=red];`, |
| 691 | surroundWithDoubleQuotes(node.Parent), |
| 692 | surroundWithDoubleQuotes(node.ID), |
| 693 | ), |
| 694 | ) |
| 695 | |
| 696 | return multilineResult.String() |
| 697 | } |
| 698 | |
| 699 | } |
| 700 | |
| 701 | // Helper func to append node to result: parent -> child; |
| 702 | dupes := base.Set{} |
| 703 | appendNodeToResult := func(node *RevInfo) { |
| 704 | nodeAsDotText := dotRepresentation(node) |
| 705 | if dupes.Contains(nodeAsDotText) { |
| 706 | return |
| 707 | } else { |
| 708 | dupes[nodeAsDotText] = struct{}{} |
| 709 | } |
| 710 | resultBuffer.WriteString(nodeAsDotText) |
| 711 | } |
| 712 | |
| 713 | // Start graphviz dot file |
| 714 | resultBuffer.WriteString("digraph graphname{") |
| 715 | |
| 716 | // This function will be called back for every leaf node in tree |
| 717 | leafProcessor := func(leaf *RevInfo) { |
| 718 | |
| 719 | // Append the leaf to the output |