Add RenderPriority to objects and edges

This commit is contained in:
Júlio César Batista 2022-11-29 14:21:23 -08:00
parent e509fbbc2f
commit e7b72b4365
No known key found for this signature in database
GPG key ID: 10C4B861BF314878
4 changed files with 56 additions and 17 deletions

View file

@ -8,6 +8,7 @@ import (
"oss.terrastruct.com/d2/d2target"
"oss.terrastruct.com/d2/d2themes"
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
"oss.terrastruct.com/d2/lib/go2"
)
func Export(ctx context.Context, g *d2graph.Graph, themeID int64) (*d2target.Diagram, error) {
@ -16,13 +17,16 @@ func Export(ctx context.Context, g *d2graph.Graph, themeID int64) (*d2target.Dia
diagram := d2target.NewDiagram()
diagram.Shapes = make([]d2target.Shape, len(g.Objects))
highestObjectPriority := 0
for i := range g.Objects {
diagram.Shapes[i] = toShape(g.Objects[i], &theme)
highestObjectPriority = go2.IntMax(highestObjectPriority, diagram.Shapes[i].RenderPriority)
}
edgeDefaultRenderPriority := highestObjectPriority + 1
diagram.Connections = make([]d2target.Connection, len(g.Edges))
for i := range g.Edges {
diagram.Connections[i] = toConnection(g.Edges[i], &theme)
diagram.Connections[i] = toConnection(g.Edges[i], &theme, edgeDefaultRenderPriority)
}
return diagram, nil
@ -88,13 +92,17 @@ func toShape(obj *d2graph.Object, theme *d2themes.Theme) d2target.Shape {
shape := d2target.BaseShape()
shape.SetType(obj.Attributes.Shape.Value)
shape.ID = obj.AbsID()
if obj.RenderPriority == nil {
shape.RenderPriority = int(obj.Level())
} else {
shape.RenderPriority = *obj.RenderPriority
}
shape.Pos = d2target.NewPoint(int(obj.TopLeft.X), int(obj.TopLeft.Y))
shape.Width = int(obj.Width)
shape.Height = int(obj.Height)
text := obj.Text()
shape.FontSize = text.FontSize
shape.Level = int(obj.Level())
applyStyles(shape, obj)
applyTheme(shape, obj, theme)
@ -130,9 +138,14 @@ func toShape(obj *d2graph.Object, theme *d2themes.Theme) d2target.Shape {
return *shape
}
func toConnection(edge *d2graph.Edge, theme *d2themes.Theme) d2target.Connection {
func toConnection(edge *d2graph.Edge, theme *d2themes.Theme, defaultRenderPriotity int) d2target.Connection {
connection := d2target.BaseConnection()
connection.ID = edge.AbsID()
if edge.RenderPriority == nil {
connection.RenderPriority = defaultRenderPriotity
} else {
connection.RenderPriority = *edge.RenderPriority
}
// edge.Edge.ID = go2.StringToIntHash(connection.ID)
text := edge.Text()

View file

@ -78,6 +78,8 @@ type Object struct {
ChildrenArray []*Object `json:"-"`
Attributes Attributes `json:"attributes"`
RenderPriority *int `json:"renderPriority",omitempty`
}
type Attributes struct {
@ -630,6 +632,8 @@ type Edge struct {
References []EdgeReference `json:"references,omitempty"`
Attributes Attributes `json:"attributes"`
RenderPriority *int `json:"renderPriority,omitempty"`
}
type EdgeReference struct {

View file

@ -10,6 +10,7 @@ import (
"fmt"
"hash/fnv"
"io"
"sort"
"strings"
"math"
@ -983,25 +984,31 @@ func Render(diagram *d2target.Diagram) ([]byte, error) {
// SVG has no notion of z-index. The z-index is effectively the order it's drawn.
// So draw from the least nested to most nested
idToShape := make(map[string]d2target.Shape)
highest := 1
allObjects := make([]d2target.DiagramObject, 0, len(diagram.Shapes)+len(diagram.Connections))
for _, s := range diagram.Shapes {
highest = go2.Max(highest, s.Level)
idToShape[s.ID] = s
allObjects = append(allObjects, s)
}
for i := 1; i <= highest; i++ {
for _, s := range diagram.Shapes {
if s.Level == i {
err := drawShape(buf, s)
if err != nil {
return nil, err
}
}
}
for _, c := range diagram.Connections {
allObjects = append(allObjects, c)
}
sort.SliceStable(allObjects, func(i, j int) bool {
return allObjects[i].GetPriority() < allObjects[j].GetPriority()
})
markers := map[string]struct{}{}
for _, c := range diagram.Connections {
drawConnection(buf, c, markers, idToShape)
for _, obj := range allObjects {
if c, is := obj.(d2target.Connection); is {
drawConnection(buf, c, markers, idToShape)
} else if s, is := obj.(d2target.Shape); is {
err := drawShape(buf, s)
if err != nil {
return nil, err
}
} else {
return nil, fmt.Errorf("unknow object of type %t", obj)
}
}
embedFonts(buf)

View file

@ -17,6 +17,10 @@ const (
MAX_ICON_SIZE = 64
)
type DiagramObject interface {
GetPriority() int
}
type Diagram struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
@ -91,7 +95,6 @@ type Shape struct {
Pos Point `json:"pos"`
Width int `json:"width"`
Height int `json:"height"`
Level int `json:"level"`
Opacity float64 `json:"opacity"`
StrokeDash float64 `json:"strokeDash"`
@ -117,6 +120,8 @@ type Shape struct {
Text
LabelPosition string `json:"labelPosition,omitempty"`
RenderPriority int `json:"renderPriority"`
}
func (s *Shape) SetType(t string) {
@ -130,6 +135,10 @@ func (s *Shape) SetType(t string) {
s.Type = strings.ToLower(t)
}
func (s Shape) GetPriority() int {
return s.RenderPriority
}
type Text struct {
Label string `json:"label"`
FontSize int `json:"fontSize"`
@ -183,6 +192,8 @@ type Connection struct {
Animated bool `json:"animated"`
Tooltip string `json:"tooltip"`
Icon *url.URL `json:"icon"`
RenderPriority int `json:"renderPriority"`
}
func BaseConnection() *Connection {
@ -210,6 +221,10 @@ func (c *Connection) GetLabelTopLeft() *geo.Point {
)
}
func (c Connection) GetPriority() int {
return c.RenderPriority
}
type Arrowhead string
const (