func DotTrie(name string, json bool) (string, error) { var err error Zk = datamodel.Zk.Conn ZC := zCfg{map[string]Pool{}, map[string]Rule{}, map[string]Trie{}} Edges := Edges{map[string]bool{}, map[string]bool{}, map[string]bool{}} graph := ggv.NewGraph() graph.SetName(graphName) graph.SetDir(true) result := zkGraph{graph, &ZC, &Edges} if name == "all" { err = ZC.ParseAllTrie() } else { err = ZC.ParseWholeTrie(name) } if err != nil { return "{}", err } str, err := ZC.ToJSON() if err != nil { return "{}", err } if json { return str, nil } str = result.JSONtoDot(str) return str, nil }
// Graph returns a graphiz graph for the expression. // This depends on the "code.google.com/p/gographviz" module. func (e Expr) Graph(name string) *gv.Graph { g := gv.NewGraph() g.SetName(name) g.Attrs.Add("dpi", GraphDPI) // add nodes for i, op := range e { attrs := NodeAttrs.Copy() attrs.Add("label", `"`+op.String()+`"`) g.AddNode(name, strconv.Itoa(i), attrs) } // recursively find edges starting from top var getChild func() string pos := 0 getChild = func() string { op := e[pos] arity := op.Arity() if arity == 0 { return strconv.Itoa(pos) } parent := strconv.Itoa(pos) for i := 0; i < arity; i++ { pos++ g.AddEdge(parent, "", getChild(), "", false, nil) } return parent } getChild() return g }
func parse2graph(filename string) *gographviz.Graph { f, err := os.Open(filename) checkError(err) all, err := ioutil.ReadAll(f) checkError(err) g, err := gographviz.Parse(all) // *ast.Graph checkError(err) //fmt.Printf("Parsed: %v\n", g) //ag := gographviz.NewAnalysedGraph(g) // *gographviz.Graph ag := gographviz.NewGraph() // *gographviz.Graph cluster.Read(g, ag) //fmt.Printf("Analysed: %v\n", ag) //fmt.Printf("Written: %v\n", ag.String()) return ag }
func (svc *dflowsvc) dumpgraph() error { var err error g := gographviz.NewGraph() gname := "dataflow" g.SetName(gname) g.SetDir(true) quote := func(s string) string { return fmt.Sprintf("%q", s) } for name, typ := range svc.edges { typename := typ.String() attrdata := map[string]string{ `"node"`: `"data"`, `"type"`: quote(typename), } g.AddNode(gname, quote(name), attrdata) } attrtask := map[string]string{ `"node"`: `"task"`, `"shape"`: `"component"`, } for name, node := range svc.nodes { g.AddNode(gname, quote(name), attrtask) for in := range node.in { g.AddEdge(quote(in), quote(name), true, nil) } for out := range node.out { g.AddEdge(quote(name), quote(out), true, nil) } } err = ioutil.WriteFile(svc.dotfile, []byte(g.String()), 0644) if err != nil { return Error(err) } return err }
func graph(page *crawler.Page) *ast.Graph { var f func(page *crawler.Page) visited := make(map[*crawler.Page]bool) g := graphiz.NewGraph() graphName := `"` + page.Path + `"` g.SetName(graphName) g.SetDir(true) g.AddNode(graphName, quote(page.Path), nil) f = func(page *crawler.Page) { visited[page] = true g.AddNode(graphName, quote(page.Path), nil) for _, l := range page.Links { if !visited[l] { g.AddNode(graphName, quote(l.Path), nil) f(l) } g.AddEdge(quote(page.Path), "", quote(l.Path), "", true, nil) } } f(page) return g.WriteAst() }
func aptlyGraph(cmd *commander.Command, args []string) error { var err error graph := gographviz.NewGraph() graph.SetDir(true) graph.SetName("aptly") existingNodes := map[string]bool{} fmt.Printf("Loading mirrors...\n") err = context.CollectionFactory().RemoteRepoCollection().ForEach(func(repo *deb.RemoteRepo) error { err := context.CollectionFactory().RemoteRepoCollection().LoadComplete(repo) if err != nil { return err } graph.AddNode("aptly", graphvizEscape(repo.UUID), map[string]string{ "shape": "Mrecord", "style": "filled", "fillcolor": "darkgoldenrod1", "label": graphvizEscape(fmt.Sprintf("{Mirror %s|url: %s|dist: %s|comp: %s|arch: %s|pkgs: %d}", repo.Name, repo.ArchiveRoot, repo.Distribution, strings.Join(repo.Components, ", "), strings.Join(repo.Architectures, ", "), repo.NumPackages())), }) existingNodes[repo.UUID] = true return nil }) if err != nil { return err } fmt.Printf("Loading local repos...\n") err = context.CollectionFactory().LocalRepoCollection().ForEach(func(repo *deb.LocalRepo) error { err := context.CollectionFactory().LocalRepoCollection().LoadComplete(repo) if err != nil { return err } graph.AddNode("aptly", graphvizEscape(repo.UUID), map[string]string{ "shape": "Mrecord", "style": "filled", "fillcolor": "mediumseagreen", "label": graphvizEscape(fmt.Sprintf("{Repo %s|comment: %s|pkgs: %d}", repo.Name, repo.Comment, repo.NumPackages())), }) existingNodes[repo.UUID] = true return nil }) if err != nil { return err } fmt.Printf("Loading snapshots...\n") context.CollectionFactory().SnapshotCollection().ForEach(func(snapshot *deb.Snapshot) error { existingNodes[snapshot.UUID] = true return nil }) err = context.CollectionFactory().SnapshotCollection().ForEach(func(snapshot *deb.Snapshot) error { err := context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot) if err != nil { return err } description := snapshot.Description if snapshot.SourceKind == "repo" { description = "Snapshot from repo" } graph.AddNode("aptly", graphvizEscape(snapshot.UUID), map[string]string{ "shape": "Mrecord", "style": "filled", "fillcolor": "cadetblue1", "label": graphvizEscape(fmt.Sprintf("{Snapshot %s|%s|pkgs: %d}", snapshot.Name, description, snapshot.NumPackages())), }) if snapshot.SourceKind == "repo" || snapshot.SourceKind == "local" || snapshot.SourceKind == "snapshot" { for _, uuid := range snapshot.SourceIDs { _, exists := existingNodes[uuid] if exists { graph.AddEdge(graphvizEscape(uuid), "", graphvizEscape(snapshot.UUID), "", true, nil) } } } return nil }) if err != nil { return err } fmt.Printf("Loading published repos...\n") context.CollectionFactory().PublishedRepoCollection().ForEach(func(repo *deb.PublishedRepo) error { graph.AddNode("aptly", graphvizEscape(repo.UUID), map[string]string{ "shape": "Mrecord", "style": "filled", "fillcolor": "darkolivegreen1", "label": graphvizEscape(fmt.Sprintf("{Published %s/%s|comp: %s|arch: %s}", repo.Prefix, repo.Distribution, repo.Component, strings.Join(repo.Architectures, ", "))), }) _, exists := existingNodes[repo.SourceUUID] if exists { graph.AddEdge(graphvizEscape(repo.SourceUUID), "", graphvizEscape(repo.UUID), "", true, nil) } return nil }) fmt.Printf("Generating graph...\n") buf := bytes.NewBufferString(graph.String()) tempfile, err := ioutil.TempFile("", "aptly-graph") if err != nil { return err } tempfile.Close() os.Remove(tempfile.Name()) tempfilename := tempfile.Name() + ".png" command := exec.Command("dot", "-Tpng", "-o"+tempfilename) command.Stderr = os.Stderr stdin, err := command.StdinPipe() if err != nil { return err } err = command.Start() if err != nil { return fmt.Errorf("unable to execute dot: %s (is graphviz package installed?)", err) } _, err = io.Copy(stdin, buf) if err != nil { return err } err = stdin.Close() if err != nil { return err } err = command.Wait() if err != nil { return err } err = exec.Command("open", tempfilename).Run() if err != nil { fmt.Printf("Rendered to PNG file: %s\n", tempfilename) err = nil } return err }
// Cluster break down the given Graph into clusters and returns all the sub-graphs. func (this *Graph) Cluster() []*Graph { /* Algorithm synopsis: Loop over the Starters, for each unvisited Starter, define an empty sub-graph and, put it into the toVisit set Loop over the toVisit node set, for each node in it, skip if already visited add the node to the sub-graph remove the nodes into the hasVisited node set put all its incoming and outgoing edge into the the toWalk set while stop at the hub nodes (edges from the hub nodes are not put in the toWalk set) then iterate through the toWalk edge set skip if already walked add the edge to the sub-graph put its connected nodes into the toVisit node set remove the edge from the toWalk edge set into the hasWalked edge set */ // sub-graph index sgNdx := -1 sgRet := make([]*Graph, 0) toVisit := make(nodeSet) hasVisited := make(nodeSet) toWalk := make(edgeSet) hasWalked := make(edgeSet) for starter := range *this.Starters() { // define an empty sub-graph and, put it into the toVisit set sgRet = append(sgRet, NewGraph(gographviz.NewGraph())) sgNdx++ sgRet[sgNdx].Attrs = this.Attrs sgRet[sgNdx].SetDir(this.Directed) graphName := fmt.Sprintf("%s_%03d\n", this.Name, sgNdx) sgRet[sgNdx].SetName(graphName) toVisit.Add(starter) hubVisited := make(nodeSet) for len(toVisit) > 0 { for nodep := range toVisit { toVisit.Del(nodep) //print("O ") if this.IsHub(nodep) && hasVisited.Has(nodep) && !hubVisited.Has(nodep) { // add the already-visited but not-in-this-graph hub node to the sub-graph sgRet[sgNdx].AddNode(nodep) hubVisited.Add(nodep) continue } if hasVisited.Has(nodep) { continue } //spew.Dump("toVisit", nodep) // add the node to the sub-graph sgRet[sgNdx].AddNode(nodep) // remove the nodes into the hasVisited node set hasVisited.Add(nodep) // stop at the hub nodes if this.IsHub(nodep) { continue } // put all its incoming and outgoing edge into the the toWalk set noden := nodep.Name for _, ep := range this.EdgesToParents(noden) { toWalk.Add(ep) } for _, ep := range this.EdgesToChildren(noden) { toWalk.Add(ep) } for edgep := range toWalk { toWalk.Del(edgep) //print("- ") if hasWalked.Has(edgep) { continue } //spew.Dump("toWalk", edgep) sgRet[sgNdx].Edges.Add(edgep) // put its connected nodes into the toVisit node set toVisit.Add(this.Lookup(edgep.Src)) toVisit.Add(this.Lookup(edgep.Dst)) // remove the edge into the hasWalked edge set hasWalked.Add(edgep) } } } //spew.Dump(sgNdx) } return sgRet }