Skip to content

Commit

Permalink
create object_mapper.go
Browse files Browse the repository at this point in the history
  • Loading branch information
gavin-ts committed Sep 25, 2023
1 parent c2a9a95 commit 451f0e0
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 55 deletions.
55 changes: 0 additions & 55 deletions d2layouts/d2dagrelayout/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import (
"encoding/json"
"fmt"
"math"
"regexp"
"sort"
"strconv"
"strings"

"cdr.dev/slog"
Expand Down Expand Up @@ -412,59 +410,6 @@ 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 {
// fixes \\
id = strings.ReplaceAll(id, "\\", `\\`)
// replaces \n with \\n whenever \n is not preceded by \ (does not replace \\n)
re := regexp.MustCompile(`[^\\]\n`)
id = re.ReplaceAllString(id, `\\n`)
// avoid an unescaped \r becoming a \n in the layout result
id = strings.ReplaceAll(id, "\r", `\r`)
return id
}

func (c objectMapper) generateAddNodeLine(obj *d2graph.Object, width, height int) string {
id := c.ToID(obj)
return fmt.Sprintf("g.setNode(`%s`, { id: `%s`, width: %d, height: %d });\n", id, id, width, height)
}

func (c objectMapper) generateAddParentLine(child, parent *d2graph.Object) string {
return fmt.Sprintf("g.setParent(`%s`, `%s`);\n", c.ToID(child), c.ToID(parent))
}

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",
c.ToID(from), c.ToID(to), escapeID(edgeID), width, height,
)
}

// getLongestEdgeChainHead finds the longest chain in a container and gets its head
// If there are multiple chains of the same length, get the head closest to the center
func getLongestEdgeChainHead(g *d2graph.Graph, container *d2graph.Object) *d2graph.Object {
Expand Down
63 changes: 63 additions & 0 deletions d2layouts/d2dagrelayout/object_mapper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package d2dagrelayout

import (
"fmt"
"regexp"
"strconv"
"strings"

"oss.terrastruct.com/d2/d2graph"
)

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 (c objectMapper) generateAddNodeLine(obj *d2graph.Object, width, height int) string {
id := c.ToID(obj)
return fmt.Sprintf("g.setNode(`%s`, { id: `%s`, width: %d, height: %d });\n", id, id, width, height)
}

func (c objectMapper) generateAddParentLine(child, parent *d2graph.Object) string {
return fmt.Sprintf("g.setParent(`%s`, `%s`);\n", c.ToID(child), c.ToID(parent))
}

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",
c.ToID(from), c.ToID(to), escapeID(edgeID), width, height,
)
}

func escapeID(id string) string {
// fixes \\
id = strings.ReplaceAll(id, "\\", `\\`)
// replaces \n with \\n whenever \n is not preceded by \ (does not replace \\n)
re := regexp.MustCompile(`[^\\]\n`)
id = re.ReplaceAllString(id, `\\n`)
// avoid an unescaped \r becoming a \n in the layout result
id = strings.ReplaceAll(id, "\r", `\r`)
return id
}

0 comments on commit 451f0e0

Please sign in to comment.