refactor LabelWidth and LabelHeight to LabelDimensions

This commit is contained in:
Gavin Nishizawa 2023-04-13 15:20:12 -07:00
parent ab09193128
commit 882df2fac9
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD
6 changed files with 61 additions and 75 deletions

View file

@ -98,8 +98,6 @@ type Object struct {
*geo.Box `json:"box,omitempty"` *geo.Box `json:"box,omitempty"`
LabelPosition *string `json:"labelPosition,omitempty"` LabelPosition *string `json:"labelPosition,omitempty"`
LabelWidth *int `json:"labelWidth,omitempty"`
LabelHeight *int `json:"labelHeight,omitempty"`
IconPosition *string `json:"iconPosition,omitempty"` IconPosition *string `json:"iconPosition,omitempty"`
Class *d2target.Class `json:"class,omitempty"` Class *d2target.Class `json:"class,omitempty"`
@ -531,6 +529,18 @@ func (obj *Object) HasOutsideBottomLabel() bool {
} }
} }
func (obj *Object) HasLabel() bool {
if obj == nil || obj.Attributes == nil {
return false
}
switch obj.Attributes.Shape.Value {
case d2target.ShapeText, d2target.ShapeClass, d2target.ShapeSQLTable, d2target.ShapeCode:
return false
default:
return obj.Attributes.Label.Value != ""
}
}
func (obj *Object) AbsID() string { func (obj *Object) AbsID() string {
if obj.Parent != nil && obj.Parent.ID != "" { if obj.Parent != nil && obj.Parent.ID != "" {
return obj.Parent.AbsID() + "." + obj.ID return obj.Parent.AbsID() + "." + obj.ID
@ -1382,16 +1392,6 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
} }
obj.LabelDimensions = *labelDims obj.LabelDimensions = *labelDims
switch dslShape {
case d2target.ShapeText, d2target.ShapeClass, d2target.ShapeSQLTable, d2target.ShapeCode:
// no labels
default:
if obj.Attributes.Label.Value != "" {
obj.LabelWidth = go2.Pointer(labelDims.Width)
obj.LabelHeight = go2.Pointer(labelDims.Height)
}
}
// if there is a desired width or height, fit to content box without inner label padding for smallest minimum size // if there is a desired width or height, fit to content box without inner label padding for smallest minimum size
withInnerLabelPadding := desiredWidth == 0 && desiredHeight == 0 && withInnerLabelPadding := desiredWidth == 0 && desiredHeight == 0 &&
dslShape != d2target.ShapeText && obj.Attributes.Label.Value != "" dslShape != d2target.ShapeText && obj.Attributes.Label.Value != ""

View file

@ -334,35 +334,21 @@ func CompareSerializedObject(obj, other *Object) error {
} }
} }
if obj.LabelWidth != nil { if obj.LabelDimensions.Width != other.LabelDimensions.Width {
if other.LabelWidth == nil {
return fmt.Errorf("other does not have a label width")
}
if *obj.LabelWidth != *other.LabelWidth {
return fmt.Errorf( return fmt.Errorf(
"label widths differ: obj=%d, other=%d", "label width differs: obj=%d, other=%d",
*obj.LabelWidth, obj.LabelDimensions.Width,
*other.LabelWidth, other.LabelDimensions.Width,
) )
} }
} else if other.LabelWidth != nil {
return fmt.Errorf("other should not have label width")
}
if obj.LabelHeight != nil { if obj.LabelDimensions.Height != other.LabelDimensions.Height {
if other.LabelHeight == nil {
return fmt.Errorf("other does not have a label height")
}
if *obj.LabelHeight != *other.LabelHeight {
return fmt.Errorf( return fmt.Errorf(
"label heights differ: obj=%d, other=%d", "label height differs: obj=%d, other=%d",
*obj.LabelHeight, obj.LabelDimensions.Height,
*other.LabelHeight, other.LabelDimensions.Height,
) )
} }
} else if other.LabelHeight != nil {
return fmt.Errorf("other should not have label height")
}
return nil return nil
} }

View file

@ -114,8 +114,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
if len(obj.ChildrenArray) == 0 || obj.Parent == g.Root { if len(obj.ChildrenArray) == 0 || obj.Parent == g.Root {
continue continue
} }
if obj.LabelHeight != nil { if obj.HasLabel() {
maxContainerLabelHeight = go2.Max(maxContainerLabelHeight, *obj.LabelHeight+label.PADDING) maxContainerLabelHeight = go2.Max(maxContainerLabelHeight, obj.LabelDimensions.Height+label.PADDING)
} }
if obj.Attributes.Icon != nil && obj.Attributes.Shape.Value != d2target.ShapeImage { if obj.Attributes.Icon != nil && obj.Attributes.Shape.Value != d2target.ShapeImage {
@ -160,12 +160,12 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
idToObj[id] = obj idToObj[id] = obj
height := obj.Height height := obj.Height
if obj.LabelWidth != nil && obj.LabelHeight != nil { if obj.HasLabel() {
if obj.HasOutsideBottomLabel() || obj.Attributes.Icon != nil { if obj.HasOutsideBottomLabel() || obj.Attributes.Icon != nil {
height += float64(*obj.LabelHeight) + label.PADDING height += float64(obj.LabelDimensions.Height) + label.PADDING
} }
if len(obj.ChildrenArray) > 0 { if len(obj.ChildrenArray) > 0 {
height += float64(*obj.LabelHeight) + label.PADDING height += float64(obj.LabelDimensions.Height) + label.PADDING
} }
} }
loadScript += generateAddNodeLine(id, int(obj.Width), int(height)) loadScript += generateAddNodeLine(id, int(obj.Width), int(height))
@ -235,13 +235,13 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
obj.Width = dn.Width obj.Width = dn.Width
obj.Height = dn.Height obj.Height = dn.Height
if obj.LabelWidth != nil && obj.LabelHeight != nil { if obj.HasLabel() {
if len(obj.ChildrenArray) > 0 { if len(obj.ChildrenArray) > 0 {
obj.LabelPosition = go2.Pointer(string(label.OutsideTopCenter)) obj.LabelPosition = go2.Pointer(string(label.OutsideTopCenter))
} else if obj.HasOutsideBottomLabel() { } else if obj.HasOutsideBottomLabel() {
obj.LabelPosition = go2.Pointer(string(label.OutsideBottomCenter)) obj.LabelPosition = go2.Pointer(string(label.OutsideBottomCenter))
// remove the extra height we added to the node when passing to dagre // remove the extra height we added to the node when passing to dagre
obj.Height -= float64(*obj.LabelHeight) + label.PADDING obj.Height -= float64(obj.LabelDimensions.Height) + label.PADDING
} else if obj.Attributes.Icon != nil { } else if obj.Attributes.Icon != nil {
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
} else { } else {
@ -307,14 +307,14 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
} }
for _, obj := range g.Objects { for _, obj := range g.Objects {
if obj.LabelHeight == nil || len(obj.ChildrenArray) == 0 { if !obj.HasLabel() || len(obj.ChildrenArray) == 0 {
continue continue
} }
// usually you don't want to take away here more than what was added, which is the label height // usually you don't want to take away here more than what was added, which is the label height
// however, if the label height is more than the ranksep/2, we'll have no padding around children anymore // however, if the label height is more than the ranksep/2, we'll have no padding around children anymore
// so cap the amount taken off at ranksep/2 // so cap the amount taken off at ranksep/2
subtract := float64(go2.Min(rootAttrs.ranksep/2, *obj.LabelHeight+label.PADDING)) subtract := float64(go2.Min(rootAttrs.ranksep/2, obj.LabelDimensions.Height+label.PADDING))
obj.Height -= subtract obj.Height -= subtract
@ -373,7 +373,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
// Don't move src points on side of container // Don't move src points on side of container
if almostEqual(e.Route[0].X, obj.TopLeft.X) || almostEqual(e.Route[0].X, obj.TopLeft.X+obj.Width) { if almostEqual(e.Route[0].X, obj.TopLeft.X) || almostEqual(e.Route[0].X, obj.TopLeft.X+obj.Width) {
// Unless the dst is also on a container // Unless the dst is also on a container
if e.Dst.LabelHeight == nil || len(e.Dst.ChildrenArray) <= 0 { if !e.Dst.HasLabel() || len(e.Dst.ChildrenArray) <= 0 {
continue continue
} }
} }
@ -463,8 +463,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
overlapsContainerLabel := false overlapsContainerLabel := false
if edge.Dst.IsContainer() && edge.Dst.Attributes.Label.Value != "" && !dstShape.Is(shape.TEXT_TYPE) { if edge.Dst.IsContainer() && edge.Dst.Attributes.Label.Value != "" && !dstShape.Is(shape.TEXT_TYPE) {
// assumes LabelPosition, LabelWidth, LabelHeight are all set if there is a label // assumes LabelPosition, LabelWidth, LabelHeight are all set if there is a label
labelWidth := float64(*edge.Dst.LabelWidth) labelWidth := float64(edge.Dst.LabelDimensions.Width)
labelHeight := float64(*edge.Dst.LabelHeight) labelHeight := float64(edge.Dst.LabelDimensions.Height)
labelTL := label.Position(*edge.Dst.LabelPosition). labelTL := label.Position(*edge.Dst.LabelPosition).
GetPointOnBox(edge.Dst.Box, label.PADDING, labelWidth, labelHeight) GetPointOnBox(edge.Dst.Box, label.PADDING, labelWidth, labelHeight)

View file

@ -208,11 +208,11 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
height := obj.Height height := obj.Height
width := obj.Width width := obj.Width
if obj.LabelWidth != nil && obj.LabelHeight != nil { if obj.HasLabel() {
if obj.HasOutsideBottomLabel() || obj.Attributes.Icon != nil { if obj.HasOutsideBottomLabel() || obj.Attributes.Icon != nil {
height += float64(*obj.LabelHeight) + label.PADDING height += float64(obj.LabelDimensions.Height) + label.PADDING
} }
width = go2.Max(width, float64(*obj.LabelWidth)) width = go2.Max(width, float64(obj.LabelDimensions.Width))
} }
n := &ELKNode{ n := &ELKNode{
@ -249,8 +249,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
if n.LayoutOptions.Padding == DefaultOpts.Padding { if n.LayoutOptions.Padding == DefaultOpts.Padding {
labelHeight := 0 labelHeight := 0
if obj.LabelHeight != nil { if obj.HasLabel() {
labelHeight = *obj.LabelHeight + label.PADDING labelHeight = obj.LabelDimensions.Height + label.PADDING
} }
n.Height += 100 + float64(labelHeight) n.Height += 100 + float64(labelHeight)
@ -281,11 +281,11 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
} }
} }
if obj.LabelWidth != nil && obj.LabelHeight != nil { if obj.HasLabel() {
n.Labels = append(n.Labels, &ELKLabel{ n.Labels = append(n.Labels, &ELKLabel{
Text: obj.Attributes.Label.Value, Text: obj.Attributes.Label.Value,
Width: float64(*obj.LabelWidth), Width: float64(obj.LabelDimensions.Width),
Height: float64(*obj.LabelHeight), Height: float64(obj.LabelDimensions.Height),
}) })
} }
@ -391,12 +391,12 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
obj.Width = n.Width obj.Width = n.Width
obj.Height = n.Height obj.Height = n.Height
if obj.LabelWidth != nil && obj.LabelHeight != nil { if obj.HasLabel() {
if len(obj.ChildrenArray) > 0 { if len(obj.ChildrenArray) > 0 {
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
} else if obj.HasOutsideBottomLabel() { } else if obj.HasOutsideBottomLabel() {
obj.LabelPosition = go2.Pointer(string(label.OutsideBottomCenter)) obj.LabelPosition = go2.Pointer(string(label.OutsideBottomCenter))
obj.Height -= float64(*obj.LabelHeight) + label.PADDING obj.Height -= float64(obj.LabelDimensions.Height) + label.PADDING
} else if obj.Attributes.Icon != nil { } else if obj.Attributes.Icon != nil {
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
} else { } else {

View file

@ -111,22 +111,22 @@ func place(obj *d2graph.Object) (float64, float64) {
if strings.Contains(*obj.LabelPosition, "_TOP_") { if strings.Contains(*obj.LabelPosition, "_TOP_") {
// label is on the top, and container is placed on the bottom // label is on the top, and container is placed on the bottom
if strings.Contains(nearKeyStr, "bottom") { if strings.Contains(nearKeyStr, "bottom") {
y += float64(*obj.LabelHeight) y += float64(obj.LabelDimensions.Height)
} }
} else if strings.Contains(*obj.LabelPosition, "_LEFT_") { } else if strings.Contains(*obj.LabelPosition, "_LEFT_") {
// label is on the left, and container is placed on the right // label is on the left, and container is placed on the right
if strings.Contains(nearKeyStr, "right") { if strings.Contains(nearKeyStr, "right") {
x += float64(*obj.LabelWidth) x += float64(obj.LabelDimensions.Width)
} }
} else if strings.Contains(*obj.LabelPosition, "_RIGHT_") { } else if strings.Contains(*obj.LabelPosition, "_RIGHT_") {
// label is on the right, and container is placed on the left // label is on the right, and container is placed on the left
if strings.Contains(nearKeyStr, "left") { if strings.Contains(nearKeyStr, "left") {
x -= float64(*obj.LabelWidth) x -= float64(obj.LabelDimensions.Width)
} }
} else if strings.Contains(*obj.LabelPosition, "_BOTTOM_") { } else if strings.Contains(*obj.LabelPosition, "_BOTTOM_") {
// label is on the bottom, and container is placed on the top // label is on the bottom, and container is placed on the top
if strings.Contains(nearKeyStr, "top") { if strings.Contains(nearKeyStr, "top") {
y -= float64(*obj.LabelHeight) y -= float64(obj.LabelDimensions.Height)
} }
} }
} }
@ -239,11 +239,11 @@ func boundingBox(g *d2graph.Graph) (tl, br *geo.Point) {
if obj.Attributes.Label.Value != "" && obj.LabelPosition != nil { if obj.Attributes.Label.Value != "" && obj.LabelPosition != nil {
labelPosition := label.Position(*obj.LabelPosition) labelPosition := label.Position(*obj.LabelPosition)
if labelPosition.IsOutside() { if labelPosition.IsOutside() {
labelTL := labelPosition.GetPointOnBox(obj.Box, label.PADDING, float64(*obj.LabelWidth), float64(*obj.LabelHeight)) labelTL := labelPosition.GetPointOnBox(obj.Box, label.PADDING, float64(obj.LabelDimensions.Width), float64(obj.LabelDimensions.Height))
x1 = math.Min(x1, labelTL.X) x1 = math.Min(x1, labelTL.X)
y1 = math.Min(y1, labelTL.Y) y1 = math.Min(y1, labelTL.Y)
x2 = math.Max(x2, labelTL.X+float64(*obj.LabelWidth)) x2 = math.Max(x2, labelTL.X+float64(obj.LabelDimensions.Width))
y2 = math.Max(y2, labelTL.Y+float64(*obj.LabelHeight)) y2 = math.Max(y2, labelTL.Y+float64(obj.LabelDimensions.Height))
} }
} }
} }

View file

@ -186,8 +186,8 @@ func newSequenceDiagram(objects []*d2graph.Object, messages []*d2graph.Edge) (*s
sd.yStep += VERTICAL_PAD sd.yStep += VERTICAL_PAD
sd.maxActorHeight += VERTICAL_PAD sd.maxActorHeight += VERTICAL_PAD
if sd.root.LabelHeight != nil { if sd.root.HasLabel() {
sd.maxActorHeight += float64(*sd.root.LabelHeight) sd.maxActorHeight += float64(sd.root.LabelDimensions.Height)
} }
return sd, nil return sd, nil
@ -282,11 +282,11 @@ func (sd *sequenceDiagram) placeGroup(group *d2graph.Object) {
} }
func (sd *sequenceDiagram) adjustGroupLabel(group *d2graph.Object) { func (sd *sequenceDiagram) adjustGroupLabel(group *d2graph.Object) {
if group.LabelHeight == nil { if !group.HasLabel() {
return return
} }
heightAdd := (*group.LabelHeight + EDGE_GROUP_LABEL_PADDING) - GROUP_CONTAINER_PADDING heightAdd := (group.LabelDimensions.Height + EDGE_GROUP_LABEL_PADDING) - GROUP_CONTAINER_PADDING
if heightAdd < 0 { if heightAdd < 0 {
return return
} }
@ -339,8 +339,8 @@ func (sd *sequenceDiagram) placeActors() {
if actor.HasOutsideBottomLabel() { if actor.HasOutsideBottomLabel() {
actor.LabelPosition = go2.Pointer(string(label.OutsideBottomCenter)) actor.LabelPosition = go2.Pointer(string(label.OutsideBottomCenter))
yOffset = sd.maxActorHeight - actor.Height yOffset = sd.maxActorHeight - actor.Height
if actor.LabelHeight != nil { if actor.HasLabel() {
yOffset -= float64(*actor.LabelHeight) yOffset -= float64(actor.LabelDimensions.Height)
} }
} else { } else {
actor.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) actor.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter))
@ -381,8 +381,8 @@ func (sd *sequenceDiagram) addLifelineEdges() {
for _, actor := range sd.actors { for _, actor := range sd.actors {
actorBottom := actor.Center() actorBottom := actor.Center()
actorBottom.Y = actor.TopLeft.Y + actor.Height actorBottom.Y = actor.TopLeft.Y + actor.Height
if *actor.LabelPosition == string(label.OutsideBottomCenter) && actor.LabelHeight != nil { if *actor.LabelPosition == string(label.OutsideBottomCenter) && actor.HasLabel() {
actorBottom.Y += float64(*actor.LabelHeight) + LIFELINE_LABEL_PAD actorBottom.Y += float64(actor.LabelDimensions.Height) + LIFELINE_LABEL_PAD
} }
actorLifelineEnd := actor.Center() actorLifelineEnd := actor.Center()
actorLifelineEnd.Y = endY actorLifelineEnd.Y = endY