diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index fc9b4a91e..3add3eaf5 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -5,12 +5,13 @@ import ( "context" "fmt" "math" - "strconv" + "cdr.dev/slog" "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/log" "oss.terrastruct.com/util-go/go2" ) @@ -69,7 +70,6 @@ func Layout(ctx context.Context, g *d2graph.Graph) error { labelHeight = float64(obj.LabelDimensions.Height) + 2*label.PADDING } - var dx, dy float64 if labelWidth > 0 { switch labelPosition { case label.OutsideTopLeft, label.OutsideTopCenter, label.OutsideTopRight, @@ -112,67 +112,71 @@ func Layout(ctx context.Context, g *d2graph.Graph) error { } } - overflowTop := padding.Top - float64(verticalPadding) - if overflowTop > 0 { - contentHeight += overflowTop - dy += overflowTop - } - overflowBottom := padding.Bottom - float64(verticalPadding) - if overflowBottom > 0 { - contentHeight += overflowBottom - } - overflowLeft := padding.Left - float64(horizontalPadding) - if overflowLeft > 0 { - contentWidth += overflowLeft - dx += overflowLeft - } - overflowRight := padding.Right - float64(horizontalPadding) - if overflowRight > 0 { - contentWidth += overflowRight - } + padding.Top = math.Max(padding.Top, float64(verticalPadding)) + padding.Bottom = math.Max(padding.Bottom, float64(verticalPadding)) + padding.Left = math.Max(padding.Left, float64(horizontalPadding)) + padding.Right = math.Max(padding.Right, float64(horizontalPadding)) - // manually handle desiredWidth/Height so we can center the grid - var desiredWidth, desiredHeight int - var originalWidthAttr, originalHeightAttr *d2graph.Scalar - if obj.WidthAttr != nil { - desiredWidth, _ = strconv.Atoi(obj.WidthAttr.Value) - // SizeToContent without desired width - originalWidthAttr = obj.WidthAttr - obj.WidthAttr = nil - } - if obj.HeightAttr != nil { - desiredHeight, _ = strconv.Atoi(obj.HeightAttr.Value) - originalHeightAttr = obj.HeightAttr - obj.HeightAttr = nil - } - // size shape according to grid - obj.SizeToContent(contentWidth, contentHeight, float64(2*horizontalPadding), float64(2*verticalPadding)) - if originalWidthAttr != nil { - obj.WidthAttr = originalWidthAttr - } - if originalHeightAttr != nil { - obj.HeightAttr = originalHeightAttr - } + // TODO: rethink how this works with shapes and padding + // // manually handle desiredWidth/Height so we can center the grid + // var desiredWidth, desiredHeight int + // var originalWidthAttr, originalHeightAttr *d2graph.Scalar + // if obj.WidthAttr != nil { + // desiredWidth, _ = strconv.Atoi(obj.WidthAttr.Value) + // // SizeToContent without desired width + // originalWidthAttr = obj.WidthAttr + // obj.WidthAttr = nil + // } + // if obj.HeightAttr != nil { + // desiredHeight, _ = strconv.Atoi(obj.HeightAttr.Value) + // originalHeightAttr = obj.HeightAttr + // obj.HeightAttr = nil + // } - if desiredWidth > 0 { - ddx := float64(desiredWidth) - obj.Width - if ddx > 0 { - dx += ddx / 2 - obj.Width = float64(desiredWidth) - } - } - if desiredHeight > 0 { - ddy := float64(desiredHeight) - obj.Height - if ddy > 0 { - dy += ddy / 2 - obj.Height = float64(desiredHeight) - } - } + totalWidth := padding.Left + contentWidth + padding.Right + totalHeight := padding.Top + contentHeight + padding.Bottom + obj.SizeToContent(totalWidth, totalHeight, 0, 0) + + // if originalWidthAttr != nil { + // obj.WidthAttr = originalWidthAttr + // } + // if originalHeightAttr != nil { + // obj.HeightAttr = originalHeightAttr + // } + + // var offsetX, offsetY float64 + // if desiredWidth > 0 { + // ddx := float64(desiredWidth) - obj.Width + // if ddx > 0 { + // offsetX = ddx / 2 + // obj.Width = float64(desiredWidth) + // } + // } + // if desiredHeight > 0 { + // ddy := float64(desiredHeight) - obj.Height + // if ddy > 0 { + // offsetY = ddy / 2 + // obj.Height = float64(desiredHeight) + // } + // } // compute where the grid should be placed inside shape - innerBox := obj.ToShape().GetInnerBox() - dx = innerBox.TopLeft.X + dx - dy = innerBox.TopLeft.Y + dy + s := obj.ToShape() + innerTL := s.GetInsidePlacement(totalWidth, totalHeight, 0, 0) + + log.Warn(ctx, obj.Shape.Value, + slog.F("box", obj.Box.ToString()), + slog.F("innerTL", innerTL.ToString()), + slog.F("contentWidth", contentWidth), + slog.F("contentHeight", contentHeight), + slog.F("labelWidth", labelWidth), + slog.F("labelHeight", labelHeight), + slog.F("padding", padding), + ) + + // move from horizontalPadding,verticalPadding to innerTL.X+padding.Left, innerTL.Y+padding.Top + dx := -float64(horizontalPadding) + innerTL.X + padding.Left + dy := -float64(verticalPadding) + innerTL.Y + padding.Top if dx != 0 || dy != 0 { gd.shift(dx, dy) }