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"`
LabelPosition *string `json:"labelPosition,omitempty"`
LabelWidth *int `json:"labelWidth,omitempty"`
LabelHeight *int `json:"labelHeight,omitempty"`
IconPosition *string `json:"iconPosition,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 {
if obj.Parent != nil && obj.Parent.ID != "" {
return obj.Parent.AbsID() + "." + obj.ID
@ -1382,16 +1392,6 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
}
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
withInnerLabelPadding := desiredWidth == 0 && desiredHeight == 0 &&
dslShape != d2target.ShapeText && obj.Attributes.Label.Value != ""

View file

@ -334,34 +334,20 @@ func CompareSerializedObject(obj, other *Object) error {
}
}
if obj.LabelWidth != nil {
if other.LabelWidth == nil {
return fmt.Errorf("other does not have a label width")
}
if *obj.LabelWidth != *other.LabelWidth {
return fmt.Errorf(
"label widths differ: obj=%d, other=%d",
*obj.LabelWidth,
*other.LabelWidth,
)
}
} else if other.LabelWidth != nil {
return fmt.Errorf("other should not have label width")
if obj.LabelDimensions.Width != other.LabelDimensions.Width {
return fmt.Errorf(
"label width differs: obj=%d, other=%d",
obj.LabelDimensions.Width,
other.LabelDimensions.Width,
)
}
if obj.LabelHeight != nil {
if other.LabelHeight == nil {
return fmt.Errorf("other does not have a label height")
}
if *obj.LabelHeight != *other.LabelHeight {
return fmt.Errorf(
"label heights differ: obj=%d, other=%d",
*obj.LabelHeight,
*other.LabelHeight,
)
}
} else if other.LabelHeight != nil {
return fmt.Errorf("other should not have label height")
if obj.LabelDimensions.Height != other.LabelDimensions.Height {
return fmt.Errorf(
"label height differs: obj=%d, other=%d",
obj.LabelDimensions.Height,
other.LabelDimensions.Height,
)
}
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 {
continue
}
if obj.LabelHeight != nil {
maxContainerLabelHeight = go2.Max(maxContainerLabelHeight, *obj.LabelHeight+label.PADDING)
if obj.HasLabel() {
maxContainerLabelHeight = go2.Max(maxContainerLabelHeight, obj.LabelDimensions.Height+label.PADDING)
}
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
height := obj.Height
if obj.LabelWidth != nil && obj.LabelHeight != nil {
if obj.HasLabel() {
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 {
height += float64(*obj.LabelHeight) + label.PADDING
height += float64(obj.LabelDimensions.Height) + label.PADDING
}
}
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.Height = dn.Height
if obj.LabelWidth != nil && obj.LabelHeight != nil {
if obj.HasLabel() {
if len(obj.ChildrenArray) > 0 {
obj.LabelPosition = go2.Pointer(string(label.OutsideTopCenter))
} else if obj.HasOutsideBottomLabel() {
obj.LabelPosition = go2.Pointer(string(label.OutsideBottomCenter))
// 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 {
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
} else {
@ -307,14 +307,14 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
}
for _, obj := range g.Objects {
if obj.LabelHeight == nil || len(obj.ChildrenArray) == 0 {
if !obj.HasLabel() || len(obj.ChildrenArray) == 0 {
continue
}
// 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
// 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
@ -373,7 +373,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
// 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) {
// 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
}
}
@ -463,8 +463,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
overlapsContainerLabel := false
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
labelWidth := float64(*edge.Dst.LabelWidth)
labelHeight := float64(*edge.Dst.LabelHeight)
labelWidth := float64(edge.Dst.LabelDimensions.Width)
labelHeight := float64(edge.Dst.LabelDimensions.Height)
labelTL := label.Position(*edge.Dst.LabelPosition).
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
width := obj.Width
if obj.LabelWidth != nil && obj.LabelHeight != nil {
if obj.HasLabel() {
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{
@ -249,8 +249,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
if n.LayoutOptions.Padding == DefaultOpts.Padding {
labelHeight := 0
if obj.LabelHeight != nil {
labelHeight = *obj.LabelHeight + label.PADDING
if obj.HasLabel() {
labelHeight = obj.LabelDimensions.Height + label.PADDING
}
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{
Text: obj.Attributes.Label.Value,
Width: float64(*obj.LabelWidth),
Height: float64(*obj.LabelHeight),
Width: float64(obj.LabelDimensions.Width),
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.Height = n.Height
if obj.LabelWidth != nil && obj.LabelHeight != nil {
if obj.HasLabel() {
if len(obj.ChildrenArray) > 0 {
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
} else if obj.HasOutsideBottomLabel() {
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 {
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
} else {

View file

@ -111,22 +111,22 @@ func place(obj *d2graph.Object) (float64, float64) {
if strings.Contains(*obj.LabelPosition, "_TOP_") {
// label is on the top, and container is placed on the bottom
if strings.Contains(nearKeyStr, "bottom") {
y += float64(*obj.LabelHeight)
y += float64(obj.LabelDimensions.Height)
}
} else if strings.Contains(*obj.LabelPosition, "_LEFT_") {
// label is on the left, and container is placed on the right
if strings.Contains(nearKeyStr, "right") {
x += float64(*obj.LabelWidth)
x += float64(obj.LabelDimensions.Width)
}
} else if strings.Contains(*obj.LabelPosition, "_RIGHT_") {
// label is on the right, and container is placed on the left
if strings.Contains(nearKeyStr, "left") {
x -= float64(*obj.LabelWidth)
x -= float64(obj.LabelDimensions.Width)
}
} else if strings.Contains(*obj.LabelPosition, "_BOTTOM_") {
// label is on the bottom, and container is placed on the 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 {
labelPosition := label.Position(*obj.LabelPosition)
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)
y1 = math.Min(y1, labelTL.Y)
x2 = math.Max(x2, labelTL.X+float64(*obj.LabelWidth))
y2 = math.Max(y2, labelTL.Y+float64(*obj.LabelHeight))
x2 = math.Max(x2, labelTL.X+float64(obj.LabelDimensions.Width))
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.maxActorHeight += VERTICAL_PAD
if sd.root.LabelHeight != nil {
sd.maxActorHeight += float64(*sd.root.LabelHeight)
if sd.root.HasLabel() {
sd.maxActorHeight += float64(sd.root.LabelDimensions.Height)
}
return sd, nil
@ -282,11 +282,11 @@ func (sd *sequenceDiagram) placeGroup(group *d2graph.Object) {
}
func (sd *sequenceDiagram) adjustGroupLabel(group *d2graph.Object) {
if group.LabelHeight == nil {
if !group.HasLabel() {
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 {
return
}
@ -339,8 +339,8 @@ func (sd *sequenceDiagram) placeActors() {
if actor.HasOutsideBottomLabel() {
actor.LabelPosition = go2.Pointer(string(label.OutsideBottomCenter))
yOffset = sd.maxActorHeight - actor.Height
if actor.LabelHeight != nil {
yOffset -= float64(*actor.LabelHeight)
if actor.HasLabel() {
yOffset -= float64(actor.LabelDimensions.Height)
}
} else {
actor.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter))
@ -381,8 +381,8 @@ func (sd *sequenceDiagram) addLifelineEdges() {
for _, actor := range sd.actors {
actorBottom := actor.Center()
actorBottom.Y = actor.TopLeft.Y + actor.Height
if *actor.LabelPosition == string(label.OutsideBottomCenter) && actor.LabelHeight != nil {
actorBottom.Y += float64(*actor.LabelHeight) + LIFELINE_LABEL_PAD
if *actor.LabelPosition == string(label.OutsideBottomCenter) && actor.HasLabel() {
actorBottom.Y += float64(actor.LabelDimensions.Height) + LIFELINE_LABEL_PAD
}
actorLifelineEnd := actor.Center()
actorLifelineEnd.Y = endY