Add RenderPriority to objects and edges
This commit is contained in:
parent
e509fbbc2f
commit
e7b72b4365
4 changed files with 56 additions and 17 deletions
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"oss.terrastruct.com/d2/d2target"
|
"oss.terrastruct.com/d2/d2target"
|
||||||
"oss.terrastruct.com/d2/d2themes"
|
"oss.terrastruct.com/d2/d2themes"
|
||||||
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
|
"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) {
|
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 := d2target.NewDiagram()
|
||||||
|
|
||||||
diagram.Shapes = make([]d2target.Shape, len(g.Objects))
|
diagram.Shapes = make([]d2target.Shape, len(g.Objects))
|
||||||
|
highestObjectPriority := 0
|
||||||
for i := range g.Objects {
|
for i := range g.Objects {
|
||||||
diagram.Shapes[i] = toShape(g.Objects[i], &theme)
|
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))
|
diagram.Connections = make([]d2target.Connection, len(g.Edges))
|
||||||
for i := range 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
|
return diagram, nil
|
||||||
|
|
@ -88,13 +92,17 @@ func toShape(obj *d2graph.Object, theme *d2themes.Theme) d2target.Shape {
|
||||||
shape := d2target.BaseShape()
|
shape := d2target.BaseShape()
|
||||||
shape.SetType(obj.Attributes.Shape.Value)
|
shape.SetType(obj.Attributes.Shape.Value)
|
||||||
shape.ID = obj.AbsID()
|
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.Pos = d2target.NewPoint(int(obj.TopLeft.X), int(obj.TopLeft.Y))
|
||||||
shape.Width = int(obj.Width)
|
shape.Width = int(obj.Width)
|
||||||
shape.Height = int(obj.Height)
|
shape.Height = int(obj.Height)
|
||||||
|
|
||||||
text := obj.Text()
|
text := obj.Text()
|
||||||
shape.FontSize = text.FontSize
|
shape.FontSize = text.FontSize
|
||||||
shape.Level = int(obj.Level())
|
|
||||||
|
|
||||||
applyStyles(shape, obj)
|
applyStyles(shape, obj)
|
||||||
applyTheme(shape, obj, theme)
|
applyTheme(shape, obj, theme)
|
||||||
|
|
@ -130,9 +138,14 @@ func toShape(obj *d2graph.Object, theme *d2themes.Theme) d2target.Shape {
|
||||||
return *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 := d2target.BaseConnection()
|
||||||
connection.ID = edge.AbsID()
|
connection.ID = edge.AbsID()
|
||||||
|
if edge.RenderPriority == nil {
|
||||||
|
connection.RenderPriority = defaultRenderPriotity
|
||||||
|
} else {
|
||||||
|
connection.RenderPriority = *edge.RenderPriority
|
||||||
|
}
|
||||||
// edge.Edge.ID = go2.StringToIntHash(connection.ID)
|
// edge.Edge.ID = go2.StringToIntHash(connection.ID)
|
||||||
text := edge.Text()
|
text := edge.Text()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,8 @@ type Object struct {
|
||||||
ChildrenArray []*Object `json:"-"`
|
ChildrenArray []*Object `json:"-"`
|
||||||
|
|
||||||
Attributes Attributes `json:"attributes"`
|
Attributes Attributes `json:"attributes"`
|
||||||
|
|
||||||
|
RenderPriority *int `json:"renderPriority",omitempty`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Attributes struct {
|
type Attributes struct {
|
||||||
|
|
@ -630,6 +632,8 @@ type Edge struct {
|
||||||
|
|
||||||
References []EdgeReference `json:"references,omitempty"`
|
References []EdgeReference `json:"references,omitempty"`
|
||||||
Attributes Attributes `json:"attributes"`
|
Attributes Attributes `json:"attributes"`
|
||||||
|
|
||||||
|
RenderPriority *int `json:"renderPriority,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type EdgeReference struct {
|
type EdgeReference struct {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"io"
|
"io"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"math"
|
"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.
|
// 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
|
// So draw from the least nested to most nested
|
||||||
idToShape := make(map[string]d2target.Shape)
|
idToShape := make(map[string]d2target.Shape)
|
||||||
highest := 1
|
allObjects := make([]d2target.DiagramObject, 0, len(diagram.Shapes)+len(diagram.Connections))
|
||||||
for _, s := range diagram.Shapes {
|
for _, s := range diagram.Shapes {
|
||||||
highest = go2.Max(highest, s.Level)
|
|
||||||
idToShape[s.ID] = s
|
idToShape[s.ID] = s
|
||||||
|
allObjects = append(allObjects, s)
|
||||||
}
|
}
|
||||||
for i := 1; i <= highest; i++ {
|
for _, c := range diagram.Connections {
|
||||||
for _, s := range diagram.Shapes {
|
allObjects = append(allObjects, c)
|
||||||
if s.Level == i {
|
|
||||||
err := drawShape(buf, s)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sort.SliceStable(allObjects, func(i, j int) bool {
|
||||||
|
return allObjects[i].GetPriority() < allObjects[j].GetPriority()
|
||||||
|
})
|
||||||
|
|
||||||
markers := map[string]struct{}{}
|
markers := map[string]struct{}{}
|
||||||
for _, c := range diagram.Connections {
|
for _, obj := range allObjects {
|
||||||
drawConnection(buf, c, markers, idToShape)
|
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)
|
embedFonts(buf)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@ const (
|
||||||
MAX_ICON_SIZE = 64
|
MAX_ICON_SIZE = 64
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type DiagramObject interface {
|
||||||
|
GetPriority() int
|
||||||
|
}
|
||||||
|
|
||||||
type Diagram struct {
|
type Diagram struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
|
|
@ -91,7 +95,6 @@ type Shape struct {
|
||||||
Pos Point `json:"pos"`
|
Pos Point `json:"pos"`
|
||||||
Width int `json:"width"`
|
Width int `json:"width"`
|
||||||
Height int `json:"height"`
|
Height int `json:"height"`
|
||||||
Level int `json:"level"`
|
|
||||||
|
|
||||||
Opacity float64 `json:"opacity"`
|
Opacity float64 `json:"opacity"`
|
||||||
StrokeDash float64 `json:"strokeDash"`
|
StrokeDash float64 `json:"strokeDash"`
|
||||||
|
|
@ -117,6 +120,8 @@ type Shape struct {
|
||||||
Text
|
Text
|
||||||
|
|
||||||
LabelPosition string `json:"labelPosition,omitempty"`
|
LabelPosition string `json:"labelPosition,omitempty"`
|
||||||
|
|
||||||
|
RenderPriority int `json:"renderPriority"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Shape) SetType(t string) {
|
func (s *Shape) SetType(t string) {
|
||||||
|
|
@ -130,6 +135,10 @@ func (s *Shape) SetType(t string) {
|
||||||
s.Type = strings.ToLower(t)
|
s.Type = strings.ToLower(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s Shape) GetPriority() int {
|
||||||
|
return s.RenderPriority
|
||||||
|
}
|
||||||
|
|
||||||
type Text struct {
|
type Text struct {
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
FontSize int `json:"fontSize"`
|
FontSize int `json:"fontSize"`
|
||||||
|
|
@ -183,6 +192,8 @@ type Connection struct {
|
||||||
Animated bool `json:"animated"`
|
Animated bool `json:"animated"`
|
||||||
Tooltip string `json:"tooltip"`
|
Tooltip string `json:"tooltip"`
|
||||||
Icon *url.URL `json:"icon"`
|
Icon *url.URL `json:"icon"`
|
||||||
|
|
||||||
|
RenderPriority int `json:"renderPriority"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func BaseConnection() *Connection {
|
func BaseConnection() *Connection {
|
||||||
|
|
@ -210,6 +221,10 @@ func (c *Connection) GetLabelTopLeft() *geo.Point {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Connection) GetPriority() int {
|
||||||
|
return c.RenderPriority
|
||||||
|
}
|
||||||
|
|
||||||
type Arrowhead string
|
type Arrowhead string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue