package graph import ( "errors" "edge-infra.dev/pkg/lib/text/drawing" ) var errUnsupportedDotNodeType = errors.New("unsupported type for dot node") // Creates a dot graph representation of the graph from its root node func (g *graph) toDot() (*drawing.Digraph, error) { // as nodes are traversed depth-first, the last node is the root root := g.keys[len(g.keys)-1] rootNode := g.nodes[root] rootDotNode, dotNodes, err := rootNode.toDot() if err != nil { return nil, err } dt := &drawing.DotTree{ Root: rootDotNode, Nodes: dotNodes, Attributes: map[string]string{ "rankdir": "TB", }, } return &drawing.Digraph{ Title: rootNode.name, Subgraphs: []drawing.Subgraph{ &palletLegend{}, dt, }, }, nil } // Creates a dot representation of the node and its dependencies, returning the root node and a map of all nodes func (n *node) toDot() (rootNode *drawing.DotNode, nodes map[string]*drawing.DotNode, err error) { children := []*drawing.DotNode{} for _, dep := range n.deps { var child *drawing.DotNode child, nodes, err = dep.toDot() if err != nil { return nil, nil, err } children = append(children, child) } rootNode, err = dotNodeByType(n.label(), n.nodeType) if err != nil { return nil, nil, err } rootNode.Children = children if n.nodeType == objectsNode { rootNode.Data = n.data } if nodes == nil { nodes = map[string]*drawing.DotNode{} } nodes[n.digest.String()] = rootNode return rootNode, nodes, err }