func (sg *SubGraph) Dotty(labels *digraph.Labels, highlightVertices, highlightEdges map[int]bool) string { V := make([]string, 0, len(sg.V)) E := make([]string, 0, len(sg.E)) for vidx, v := range sg.V { highlight := "" if highlightVertices[vidx] { highlight = " color=red" } V = append(V, fmt.Sprintf( "n%v [label=\"%v\"%v];", vidx, labels.Label(v.Color), highlight, )) } for eidx, e := range sg.E { highlight := "" if highlightEdges[eidx] { highlight = " color=red" } E = append(E, fmt.Sprintf( "n%v->n%v [label=\"%v\"%v]", e.Src, e.Targ, labels.Label(e.Color), highlight, )) } return fmt.Sprintf("digraph{\n%v\n%v\n}", strings.Join(V, "\n"), strings.Join(E, "\n")) }
func (v *VegLoader) loadVertex(labels *digraph.Labels, b *baseLoader, data []byte) (err error) { obj, err := parseJson(data) if err != nil { return err } _id, err := obj["id"].(json.Number).Int64() if err != nil { return err } label := strings.TrimSpace(obj["label"].(string)) id := int32(_id) return b.addVertex(id, labels.Color(label), label, obj) }
func (emb *Embedding) Dotty(labels *digraph.Labels, attrs map[int]map[string]interface{}) string { V := make([]string, 0, len(emb.SG.V)) E := make([]string, 0, len(emb.SG.E)) // TODO: Replace this with strconv.Quote safeStr := func(i interface{}) string { s := fmt.Sprint(i) s = strings.Replace(s, "\n", "\\n", -1) s = strings.Replace(s, "\"", "\\\"", -1) return s } renderAttrs := func(color, id int) string { a := attrs[id] label := labels.Label(color) strs := make([]string, 0, len(a)+1) strs = append(strs, fmt.Sprintf(`idx="%v"`, id)) if line, has := a["start_line"]; has { strs = append(strs, fmt.Sprintf(`label="%v\n[line: %v]"`, safeStr(label), safeStr(line))) } else { strs = append(strs, fmt.Sprintf(`label="%v"`, safeStr(label))) } for name, value := range a { if name == "label" || name == "id" { continue } strs = append(strs, fmt.Sprintf("%v=\"%v\"", name, safeStr(value))) } return strings.Join(strs, ",") } for idx, id := range emb.Ids { V = append(V, fmt.Sprintf( "%v [%v];", id, renderAttrs(emb.SG.V[idx].Color, id), )) } for idx := range emb.SG.E { e := &emb.SG.E[idx] E = append(E, fmt.Sprintf( "%v -> %v [label=\"%v\"];", emb.Ids[e.Src], emb.Ids[e.Targ], safeStr(labels.Label(e.Color)), )) } return fmt.Sprintf( `digraph { %v %v } `, strings.Join(V, "\n "), strings.Join(E, "\n ")) }
func (v *VegLoader) loadEdge(labels *digraph.Labels, b *baseLoader, data []byte) (err error) { obj, err := parseJson(data) if err != nil { return err } _src, err := obj["src"].(json.Number).Int64() if err != nil { return err } _targ, err := obj["targ"].(json.Number).Int64() if err != nil { return err } src := int32(_src) targ := int32(_targ) label := strings.TrimSpace(obj["label"].(string)) return b.addEdge(src, targ, labels.Color(label), label) }
func (sg *SubGraph) Pretty(labels *digraph.Labels) string { V := make([]string, 0, len(sg.V)) E := make([]string, 0, len(sg.E)) for _, v := range sg.V { V = append(V, fmt.Sprintf( "(%v)", labels.Label(v.Color), )) } for _, e := range sg.E { E = append(E, fmt.Sprintf( "[%v->%v:%v]", e.Src, e.Targ, labels.Label(e.Color), )) } return fmt.Sprintf("{%v:%v}%v%v", len(sg.E), len(sg.V), strings.Join(V, ""), strings.Join(E, "")) }
func ParsePretty(str string, labels *digraph.Labels) (*SubGraph, error) { size := regexp.MustCompile(`^\{([0-9]+):([0-9]+)\}`) edge := regexp.MustCompile(`^\[([0-9]+)->([0-9]+):`) matches := size.FindStringSubmatch(str) E, err := strconv.ParseInt(matches[1], 10, 64) if err != nil { return nil, err } V, err := strconv.ParseInt(matches[2], 10, 64) if err != nil { return nil, err } idx := len(matches[0]) vertices := make(Vertices, V) for i := range vertices { if str[idx] != '(' { return nil, errors.Errorf("expected ( got %v", str[idx:idx+1]) } idx++ parens := 1 labelc := make([]byte, 0, 10) for ; idx < len(str); idx++ { if str[idx] == '\\' { continue } else if str[idx-1] == '\\' { labelc = append(labelc, str[idx]) } else if str[idx] == '(' { parens += 1 labelc = append(labelc, str[idx]) } else if str[idx] == ')' { parens -= 1 if parens > 0 { labelc = append(labelc, str[idx]) } else { idx++ break } } else { labelc = append(labelc, str[idx]) } } label := string(labelc) vertices[i].Idx = i vertices[i].Color = labels.Color(label) } edges := make(Edges, E) for i := range edges { matches := edge.FindStringSubmatch(str[idx:]) src, err := strconv.ParseInt(matches[1], 10, 64) if err != nil { return nil, err } targ, err := strconv.ParseInt(matches[2], 10, 64) if err != nil { return nil, err } labelc := make([]byte, 0, 10) idx += len(matches[0]) for ; idx < len(str); idx++ { if str[idx] == '\\' { continue } else if str[idx-1] == '\\' { labelc = append(labelc, str[idx]) } else if str[idx] == ']' { idx++ break } else { labelc = append(labelc, str[idx]) } } label := string(labelc) edges[i].Src = int(src) edges[i].Targ = int(targ) edges[i].Color = labels.Color(label) } sg := &Builder{V: vertices, E: edges} return sg.Build(), nil }