adjust grid for outside top labels

This commit is contained in:
Gavin Nishizawa 2023-05-26 17:47:31 -07:00
parent 297819dc35
commit 6d8dde153e
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD
4 changed files with 70 additions and 14 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"
)
@ -1989,3 +1990,36 @@ func (obj *Object) GetModifierElementAdjustments() (dx, dy float64) {
}
return dx, dy
}
func (obj *Object) ToShape() shape.Shape {
tl := obj.TopLeft
if tl == nil {
tl = geo.NewPoint(0, 0)
}
dslShape := strings.ToLower(obj.Shape.Value)
shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape]
contentBox := geo.NewBox(tl, obj.Width, obj.Height)
return shape.NewShape(shapeType, contentBox)
}
func (obj *Object) GetLabelTopLeft() *geo.Point {
if obj.LabelPosition == nil {
return nil
}
s := obj.ToShape()
labelPosition := label.Position(*obj.LabelPosition)
var box *geo.Box
if labelPosition.IsOutside() {
box = s.GetBox()
} else {
box = s.GetInnerBox()
}
labelTL := labelPosition.GetPointOnBox(box, label.PADDING,
float64(obj.LabelDimensions.Width),
float64(obj.LabelDimensions.Height),
)
return labelTL
}

View file

@ -119,9 +119,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
}
if obj.Icon != nil && obj.Shape.Value != d2target.ShapeImage {
contentBox := geo.NewBox(geo.NewPoint(0, 0), float64(obj.Width), float64(obj.Height))
shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[obj.Shape.Value]
s := shape.NewShape(shapeType, contentBox)
s := obj.ToShape()
iconSize := d2target.GetIconSize(s.GetInnerBox(), string(label.InsideTopLeft))
// Since dagre container labels are pushed up, we don't want a child container to collide
maxContainerLabelHeight = go2.Max(maxContainerLabelHeight, (iconSize+label.PADDING*2)*2)
@ -491,8 +489,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
}
}
srcShape := shape.NewShape(d2target.DSL_SHAPE_TO_SHAPE_TYPE[strings.ToLower(edge.Src.Shape.Value)], edge.Src.Box)
dstShape := shape.NewShape(d2target.DSL_SHAPE_TO_SHAPE_TYPE[strings.ToLower(edge.Dst.Shape.Value)], edge.Dst.Box)
srcShape := edge.Src.ToShape()
dstShape := edge.Dst.ToShape()
// trace the edge to the specific shape's border
points[startIndex] = shape.TraceToShapeBorder(srcShape, start, points[startIndex+1])

View file

@ -501,8 +501,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
}
}
srcShape := shape.NewShape(d2target.DSL_SHAPE_TO_SHAPE_TYPE[strings.ToLower(edge.Src.Shape.Value)], edge.Src.Box)
dstShape := shape.NewShape(d2target.DSL_SHAPE_TO_SHAPE_TYPE[strings.ToLower(edge.Dst.Shape.Value)], edge.Dst.Box)
srcShape := edge.Src.ToShape()
dstShape := edge.Dst.ToShape()
// trace the edge to the specific shape's border
points[startIndex] = shape.TraceToShapeBorder(srcShape, points[startIndex], points[startIndex+1])

View file

@ -6,13 +6,10 @@ import (
"fmt"
"math"
"sort"
"strings"
"oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2target"
"oss.terrastruct.com/d2/lib/geo"
"oss.terrastruct.com/d2/lib/label"
"oss.terrastruct.com/d2/lib/shape"
"oss.terrastruct.com/util-go/go2"
)
@ -104,13 +101,12 @@ func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.L
if obj.GridGap != nil || obj.VerticalGap != nil {
verticalPadding = gd.verticalGap
}
// size shape according to grid
obj.SizeToContent(float64(gd.width), float64(gd.height), float64(2*horizontalPadding), float64(2*verticalPadding))
obj.SizeToContent(gd.width, gd.height, float64(2*horizontalPadding), float64(2*verticalPadding))
// compute where the grid should be placed inside shape
dslShape := strings.ToLower(obj.Shape.Value)
shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape]
s := shape.NewShape(shapeType, geo.NewBox(geo.NewPoint(0, 0), obj.Width, obj.Height))
s := obj.ToShape()
innerBox := s.GetInnerBox()
if innerBox.TopLeft.X != 0 || innerBox.TopLeft.Y != 0 {
gd.shift(innerBox.TopLeft.X, innerBox.TopLeft.Y)
@ -126,6 +122,34 @@ func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.L
}
if obj.LabelDimensions.Height != 0 {
labelHeight := float64(obj.LabelDimensions.Height) + 2*label.PADDING
{
// also check for grid cells with outside top labels
topY := gd.objects[0].TopLeft.Y
highestLabel := topY
for _, o := range gd.objects {
if o.TopLeft.Y > topY {
if gd.rowDirected {
break
} else {
continue
}
}
if o.LabelPosition != nil {
labelPosition := label.Position(*o.LabelPosition)
if labelPosition.IsOutside() {
labelTL := o.GetLabelTopLeft()
if labelTL.Y < highestLabel {
highestLabel = labelTL.Y
}
}
}
}
if highestLabel < topY {
labelHeight += topY - highestLabel + 2*label.PADDING
}
}
if labelHeight > float64(verticalPadding) {
// if the label doesn't fit within the padding, we need to add more
grow := labelHeight - float64(verticalPadding)