user-specified label/icon positions

This commit is contained in:
Gavin Nishizawa 2023-06-22 13:24:24 -07:00
parent cffac6bfde
commit af32907a8a
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD
4 changed files with 83 additions and 4 deletions

View file

@ -26,6 +26,7 @@ import (
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
"oss.terrastruct.com/d2/lib/color"
"oss.terrastruct.com/d2/lib/geo"
"oss.terrastruct.com/d2/lib/label"
"oss.terrastruct.com/d2/lib/shape"
"oss.terrastruct.com/d2/lib/textmeasure"
)
@ -1381,6 +1382,18 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
for _, obj := range g.Objects {
obj.Box = &geo.Box{}
// user-specified label/icon positions
if obj.HasLabel() && obj.Attributes.LabelPosition != nil {
scalar := *obj.Attributes.LabelPosition
position := LabelPositionsMapping[scalar.Value]
obj.LabelPosition = go2.Pointer(string(position))
}
if obj.Icon != nil && obj.Attributes.IconPosition != nil {
scalar := *obj.Attributes.IconPosition
position := LabelPositionsMapping[scalar.Value]
obj.IconPosition = go2.Pointer(string(position))
}
var desiredWidth int
var desiredHeight int
if obj.WidthAttr != nil {
@ -1734,6 +1747,37 @@ var LabelPositionsArray = []string{
}
var LabelPositions map[string]struct{}
// convert to label.Position
var LabelPositionsMapping = map[string]label.Position{
"top-left": label.InsideTopLeft,
"top-center": label.InsideTopCenter,
"top-right": label.InsideTopRight,
"center-left": label.InsideMiddleLeft,
"center-center": label.InsideMiddleCenter,
"center-right": label.InsideMiddleRight,
"bottom-left": label.InsideBottomLeft,
"bottom-center": label.InsideBottomCenter,
"bottom-right": label.InsideBottomRight,
"outside-top-left": label.OutsideTopLeft,
"outside-top-center": label.OutsideTopCenter,
"outside-top-right": label.OutsideTopRight,
"outside-left-top": label.OutsideLeftTop,
"outside-left-center": label.OutsideLeftMiddle,
"outside-left-bottom": label.OutsideLeftBottom,
"outside-right-top": label.OutsideRightTop,
"outside-right-center": label.OutsideRightMiddle,
"outside-right-bottom": label.OutsideRightBottom,
"outside-bottom-left": label.OutsideBottomLeft,
"outside-bottom-center": label.OutsideBottomCenter,
"outside-bottom-right": label.OutsideBottomRight,
}
var FillPatterns = []string{
"dots",
"lines",

View file

@ -236,7 +236,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
obj.Width = math.Ceil(dn.Width)
obj.Height = math.Ceil(dn.Height)
if obj.HasLabel() && obj.LabelPosition == nil {
hasLabelPosition := obj.LabelPosition != nil
if obj.HasLabel() && !hasLabelPosition {
if len(obj.ChildrenArray) > 0 {
obj.LabelPosition = go2.Pointer(string(label.OutsideTopCenter))
} else if obj.HasOutsideBottomLabel() {
@ -252,7 +253,10 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
if obj.Icon != nil && obj.IconPosition == nil {
if len(obj.ChildrenArray) > 0 {
obj.IconPosition = go2.Pointer(string(label.OutsideTopLeft))
obj.LabelPosition = go2.Pointer(string(label.OutsideTopRight))
if !hasLabelPosition {
// overwrite LabelPosition if we just set it above
obj.LabelPosition = go2.Pointer(string(label.OutsideTopRight))
}
} else {
obj.IconPosition = go2.Pointer(string(label.InsideMiddleCenter))
}

View file

@ -407,7 +407,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
obj.Width = math.Ceil(n.Width)
obj.Height = math.Ceil(n.Height)
if obj.HasLabel() && obj.LabelPosition == nil {
hasLabelPosition := obj.LabelPosition != nil
if obj.HasLabel() && !hasLabelPosition {
if len(obj.ChildrenArray) > 0 {
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
} else if obj.HasOutsideBottomLabel() {
@ -422,7 +423,9 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
if obj.Icon != nil && obj.IconPosition == nil {
if len(obj.ChildrenArray) > 0 {
obj.IconPosition = go2.Pointer(string(label.InsideTopLeft))
obj.LabelPosition = go2.Pointer(string(label.InsideTopRight))
if !hasLabelPosition {
obj.LabelPosition = go2.Pointer(string(label.InsideTopRight))
}
} else {
obj.IconPosition = go2.Pointer(string(label.InsideMiddleCenter))
}

View file

@ -50,6 +50,34 @@ const (
UnlockedBottom Position = "UNLOCKED_BOTTOM"
)
func (position Position) IsShapePosition() bool {
switch position {
case OutsideTopLeft, OutsideTopCenter, OutsideTopRight,
OutsideBottomLeft, OutsideBottomCenter, OutsideBottomRight,
OutsideLeftTop, OutsideLeftMiddle, OutsideLeftBottom,
OutsideRightTop, OutsideRightMiddle, OutsideRightBottom,
InsideTopLeft, InsideTopCenter, InsideTopRight,
InsideMiddleLeft, InsideMiddleCenter, InsideMiddleRight,
InsideBottomLeft, InsideBottomCenter, InsideBottomRight:
return true
default:
return false
}
}
func (position Position) IsEdgePosition() bool {
switch position {
case OutsideTopLeft, OutsideTopCenter, OutsideTopRight,
InsideMiddleLeft, InsideMiddleCenter, InsideMiddleRight,
OutsideBottomLeft, OutsideBottomCenter, OutsideBottomRight,
UnlockedTop, UnlockedMiddle, UnlockedBottom:
return true
default:
return false
}
}
func (position Position) IsOutside() bool {
switch position {
case OutsideTopLeft, OutsideTopCenter, OutsideTopRight,