From a7050f3ca770e05d1db9833964fee9625727df3f Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 10 Apr 2023 20:02:54 -0700 Subject: [PATCH] use grid-gap values for layout --- d2layouts/d2grid/grid_diagram.go | 23 +++++++++++++++- d2layouts/d2grid/layout.go | 47 ++++++++++++++++---------------- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/d2layouts/d2grid/grid_diagram.go b/d2layouts/d2grid/grid_diagram.go index 264bc07cc..0cb9514e6 100644 --- a/d2layouts/d2grid/grid_diagram.go +++ b/d2layouts/d2grid/grid_diagram.go @@ -19,10 +19,19 @@ type gridDiagram struct { width float64 height float64 + + gapRows float64 + gapColumns float64 } func newGridDiagram(root *d2graph.Object) *gridDiagram { - gd := gridDiagram{root: root, objects: root.ChildrenArray} + gd := gridDiagram{ + root: root, + objects: root.ChildrenArray, + gapRows: DEFAULT_GAP, + gapColumns: DEFAULT_GAP, + } + if root.Attributes.GridRows != nil { gd.rows, _ = strconv.Atoi(root.Attributes.GridRows.Value) } @@ -66,6 +75,18 @@ func newGridDiagram(root *d2graph.Object) *gridDiagram { gd.rowDirected = true } + // grid gap sets both, but can be overridden + if root.Attributes.GridGap != nil { + gd.gapRows, _ = strconv.ParseFloat(root.Attributes.GridGap.Value, 64) + gd.gapColumns = gd.gapRows + } + if root.Attributes.GridGapRows != nil { + gd.gapRows, _ = strconv.ParseFloat(root.Attributes.GridGapRows.Value, 64) + } + if root.Attributes.GridGapColumns != nil { + gd.gapColumns, _ = strconv.ParseFloat(root.Attributes.GridGapColumns.Value, 64) + } + return &gd } diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 1edae9066..e51f70d02 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -13,8 +13,7 @@ import ( const ( CONTAINER_PADDING = 60 - HORIZONTAL_PAD = 40. - VERTICAL_PAD = 40. + DEFAULT_GAP = 40. ) // Layout runs the grid layout on containers with rows/columns @@ -189,10 +188,10 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { o.Width = colWidths[j] o.Height = rowHeights[i] o.TopLeft = cursor.Copy() - cursor.X += o.Width + HORIZONTAL_PAD + cursor.X += o.Width + gd.gapColumns } cursor.X = 0 - cursor.Y += rowHeights[i] + VERTICAL_PAD + cursor.Y += rowHeights[i] + gd.gapRows } } else { for j := 0; j < gd.columns; j++ { @@ -204,22 +203,22 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) { o.Width = colWidths[j] o.Height = rowHeights[i] o.TopLeft = cursor.Copy() - cursor.Y += o.Height + VERTICAL_PAD + cursor.Y += o.Height + gd.gapRows } - cursor.X += colWidths[j] + HORIZONTAL_PAD + cursor.X += colWidths[j] + gd.gapColumns cursor.Y = 0 } } var totalWidth, totalHeight float64 for _, w := range colWidths { - totalWidth += w + HORIZONTAL_PAD + totalWidth += w + gd.gapColumns } for _, h := range rowHeights { - totalHeight += h + VERTICAL_PAD + totalHeight += h + gd.gapRows } - totalWidth -= HORIZONTAL_PAD - totalHeight -= VERTICAL_PAD + totalWidth -= gd.gapColumns + totalHeight -= gd.gapRows gd.width = totalWidth gd.height = totalHeight } @@ -246,8 +245,8 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { totalWidth += o.Width totalHeight += o.Height } - totalWidth += HORIZONTAL_PAD * float64(len(gd.objects)-gd.rows) - totalHeight += VERTICAL_PAD * float64(len(gd.objects)-gd.columns) + totalWidth += gd.gapColumns * float64(len(gd.objects)-gd.rows) + totalHeight += gd.gapRows * float64(len(gd.objects)-gd.columns) var layout [][]*d2graph.Object if gd.rowDirected { @@ -278,10 +277,10 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { rowHeight := 0. for _, o := range row { o.TopLeft = cursor.Copy() - cursor.X += o.Width + HORIZONTAL_PAD + cursor.X += o.Width + gd.gapColumns rowHeight = math.Max(rowHeight, o.Height) } - rowWidth := cursor.X - HORIZONTAL_PAD + rowWidth := cursor.X - gd.gapColumns rowWidths = append(rowWidths, rowWidth) maxX = math.Max(maxX, rowWidth) @@ -292,9 +291,9 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // new row cursor.X = 0 - cursor.Y += rowHeight + VERTICAL_PAD + cursor.Y += rowHeight + gd.gapRows } - maxY = cursor.Y - VERTICAL_PAD + maxY = cursor.Y - gd.gapRows // then expand thinnest objects to make each row the same width // . ┌A─────────────┐ ┌B──┐ ┌C─────────┐ ┬ maxHeight(A,B,C) @@ -372,10 +371,10 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { colWidth := 0. for _, o := range column { o.TopLeft = cursor.Copy() - cursor.Y += o.Height + VERTICAL_PAD + cursor.Y += o.Height + gd.gapRows colWidth = math.Max(colWidth, o.Width) } - colHeight := cursor.Y - VERTICAL_PAD + colHeight := cursor.Y - gd.gapRows colHeights = append(colHeights, colHeight) maxY = math.Max(maxY, colHeight) // set all objects in column to the same width @@ -385,9 +384,9 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) { // new column cursor.Y = 0 - cursor.X += colWidth + HORIZONTAL_PAD + cursor.X += colWidth + gd.gapColumns } - maxX = cursor.X - HORIZONTAL_PAD + maxX = cursor.X - gd.gapColumns // then expand shortest objects to make each column the same height // . ├maxWidth(A,B)─┤ ├maxW(C,D)─┤ ├maxWidth(E)──────┤ // . ┌A─────────────┐ ┌C─────────┐ ┌E────────────────┐ @@ -479,7 +478,7 @@ func (gd *gridDiagram) getBestLayout(targetSize float64, columns bool) [][]*d2gr // of these divisions, find the layout with rows closest to the targetSize for _, division := range divisions { layout := genLayout(gd.objects, division) - dist := getDistToTarget(layout, targetSize, columns) + dist := getDistToTarget(layout, targetSize, gd.gapRows, gd.gapColumns, columns) if dist < bestDist { bestLayout = layout bestDist = dist @@ -527,15 +526,15 @@ func genLayout(objects []*d2graph.Object, cutIndices []int) [][]*d2graph.Object return layout } -func getDistToTarget(layout [][]*d2graph.Object, targetSize float64, columns bool) float64 { +func getDistToTarget(layout [][]*d2graph.Object, targetSize, gapRows, gapColumns float64, columns bool) float64 { totalDelta := 0. for _, row := range layout { rowSize := 0. for _, o := range row { if columns { - rowSize += o.Height + VERTICAL_PAD + rowSize += o.Height + gapRows } else { - rowSize += o.Width + HORIZONTAL_PAD + rowSize += o.Width + gapColumns } } totalDelta += math.Abs(rowSize - targetSize)