create dagre object mapper to manage ids for dagre to use
This commit is contained in:
parent
fa297e1e3f
commit
412ad4a6db
1 changed files with 42 additions and 16 deletions
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"cdr.dev/slog"
|
"cdr.dev/slog"
|
||||||
|
|
@ -140,17 +141,13 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapper := NewObjectMapper()
|
||||||
loadScript := ""
|
loadScript := ""
|
||||||
idToObj := make(map[string]*d2graph.Object)
|
|
||||||
for _, obj := range g.Objects {
|
for _, obj := range g.Objects {
|
||||||
id := obj.AbsID()
|
mapper.Register(obj)
|
||||||
idToObj[id] = obj
|
loadScript += mapper.generateAddNodeLine(obj, int(obj.Width), int(obj.Height))
|
||||||
|
|
||||||
width, height := obj.Width, obj.Height
|
|
||||||
|
|
||||||
loadScript += generateAddNodeLine(id, int(width), int(height))
|
|
||||||
if obj.Parent != g.Root {
|
if obj.Parent != g.Root {
|
||||||
loadScript += generateAddParentLine(id, obj.Parent.AbsID())
|
loadScript += mapper.generateAddParentLine(obj, obj.Parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,7 +175,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadScript += generateAddEdgeLine(src.AbsID(), dst.AbsID(), edge.AbsID(), width, height)
|
loadScript += mapper.generateAddEdgeLine(src, dst, edge.AbsID(), width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
if debugJS {
|
if debugJS {
|
||||||
|
|
@ -209,7 +206,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
|
||||||
log.Debug(ctx, "graph", slog.F("json", dn))
|
log.Debug(ctx, "graph", slog.F("json", dn))
|
||||||
}
|
}
|
||||||
|
|
||||||
obj := idToObj[dn.ID]
|
obj := mapper.ToObj(dn.ID)
|
||||||
|
|
||||||
// dagre gives center of node
|
// dagre gives center of node
|
||||||
obj.TopLeft = geo.NewPoint(math.Round(dn.X-dn.Width/2), math.Round(dn.Y-dn.Height/2))
|
obj.TopLeft = geo.NewPoint(math.Round(dn.X-dn.Width/2), math.Round(dn.Y-dn.Height/2))
|
||||||
|
|
@ -415,6 +412,32 @@ func setGraphAttrs(attrs dagreOpts) string {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type objectMapper struct {
|
||||||
|
objToID map[*d2graph.Object]string
|
||||||
|
idToObj map[string]*d2graph.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewObjectMapper() *objectMapper {
|
||||||
|
return &objectMapper{
|
||||||
|
objToID: make(map[*d2graph.Object]string),
|
||||||
|
idToObj: make(map[string]*d2graph.Object),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *objectMapper) Register(obj *d2graph.Object) {
|
||||||
|
id := strconv.Itoa(len(c.idToObj))
|
||||||
|
c.idToObj[id] = obj
|
||||||
|
c.objToID[obj] = id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *objectMapper) ToID(obj *d2graph.Object) string {
|
||||||
|
return c.objToID[obj]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *objectMapper) ToObj(id string) *d2graph.Object {
|
||||||
|
return c.idToObj[id]
|
||||||
|
}
|
||||||
|
|
||||||
func escapeID(id string) string {
|
func escapeID(id string) string {
|
||||||
// fixes \\
|
// fixes \\
|
||||||
id = strings.ReplaceAll(id, "\\", `\\`)
|
id = strings.ReplaceAll(id, "\\", `\\`)
|
||||||
|
|
@ -426,17 +449,20 @@ func escapeID(id string) string {
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateAddNodeLine(id string, width, height int) string {
|
func (c objectMapper) generateAddNodeLine(obj *d2graph.Object, width, height int) string {
|
||||||
id = escapeID(id)
|
id := c.ToID(obj)
|
||||||
return fmt.Sprintf("g.setNode(`%s`, { id: `%s`, width: %d, height: %d });\n", id, id, width, height)
|
return fmt.Sprintf("g.setNode(`%s`, { id: `%s`, width: %d, height: %d });\n", id, id, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateAddParentLine(childID, parentID string) string {
|
func (c objectMapper) generateAddParentLine(child, parent *d2graph.Object) string {
|
||||||
return fmt.Sprintf("g.setParent(`%s`, `%s`);\n", escapeID(childID), escapeID(parentID))
|
return fmt.Sprintf("g.setParent(`%s`, `%s`);\n", c.ToID(child), c.ToID(parent))
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateAddEdgeLine(fromID, toID, edgeID string, width, height int) string {
|
func (c objectMapper) generateAddEdgeLine(from, to *d2graph.Object, edgeID string, width, height int) string {
|
||||||
return fmt.Sprintf("g.setEdge({v:`%s`, w:`%s`, name:`%s`}, { width:%d, height:%d, labelpos: `c` });\n", escapeID(fromID), escapeID(toID), escapeID(edgeID), width, height)
|
return fmt.Sprintf(
|
||||||
|
"g.setEdge({v:`%s`, w:`%s`, name:`%s`}, { width:%d, height:%d, labelpos: `c` });\n",
|
||||||
|
c.ToID(from), c.ToID(to), escapeID(edgeID), width, height,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getLongestEdgeChainHead finds the longest chain in a container and gets its head
|
// getLongestEdgeChainHead finds the longest chain in a container and gets its head
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue