From 9ac8f3421668bc9540ecaec96fdc15497afe91e3 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 18 Sep 2023 21:18:56 -0700 Subject: [PATCH] fix scenario with only center nears --- d2layouts/d2near/layout.go | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/d2layouts/d2near/layout.go b/d2layouts/d2near/layout.go index 12cabf793..190317542 100644 --- a/d2layouts/d2near/layout.go +++ b/d2layouts/d2near/layout.go @@ -14,12 +14,22 @@ import ( const pad = 20 -var CenterNearConstants = map[string]struct{}{ +type set map[string]struct{} + +var HorizontalCenterNears = set{ + "center-left": {}, + "center-right": {}, +} +var VerticalCenterNears = set{ "top-center": {}, - "center-left": {}, - "center-right": {}, "bottom-center": {}, } +var NonCenterNears = set{ + "top-left": {}, + "top-right": {}, + "bottom-left": {}, + "bottom-right": {}, +} // Layout finds the shapes which are assigned constant near keywords and places them. func Layout(ctx context.Context, g *d2graph.Graph, constantNearGraphs []*d2graph.Graph) error { @@ -37,11 +47,11 @@ func Layout(ctx context.Context, g *d2graph.Graph, constantNearGraphs []*d2graph // Imagine the graph has two long texts, one at top center and one at top left. // Top left should go left enough to not collide with center. // So place the center ones first, then the later ones will consider them for bounding box - for _, processCenters := range []bool{true, false} { + for _, currentSet := range []set{VerticalCenterNears, HorizontalCenterNears, NonCenterNears} { for _, tempGraph := range constantNearGraphs { obj := tempGraph.Root.ChildrenArray[0] - _, isCenterConstant := CenterNearConstants[d2graph.Key(obj.NearKey)[0]] - if processCenters == isCenterConstant { + _, in := currentSet[d2graph.Key(obj.NearKey)[0]] + if in { prevX, prevY := obj.TopLeft.X, obj.TopLeft.Y obj.TopLeft = geo.NewPoint(place(obj)) dx, dy := obj.TopLeft.X-prevX, obj.TopLeft.Y-prevY @@ -64,8 +74,8 @@ func Layout(ctx context.Context, g *d2graph.Graph, constantNearGraphs []*d2graph } for _, tempGraph := range constantNearGraphs { obj := tempGraph.Root.ChildrenArray[0] - _, isCenterConstant := CenterNearConstants[d2graph.Key(obj.NearKey)[0]] - if processCenters == isCenterConstant { + _, in := currentSet[d2graph.Key(obj.NearKey)[0]] + if in { // The z-index for constant nears does not matter, as it will not collide g.Objects = append(g.Objects, tempGraph.Objects...) if obj.Parent.Children == nil { @@ -92,28 +102,20 @@ func place(obj *d2graph.Object) (float64, float64) { switch nearKeyStr { case "top-left": x, y = tl.X-obj.Width-pad, tl.Y-obj.Height-pad - break case "top-center": x, y = tl.X+w/2-obj.Width/2, tl.Y-obj.Height-pad - break case "top-right": x, y = br.X+pad, tl.Y-obj.Height-pad - break case "center-left": x, y = tl.X-obj.Width-pad, tl.Y+h/2-obj.Height/2 - break case "center-right": x, y = br.X+pad, tl.Y+h/2-obj.Height/2 - break case "bottom-left": x, y = tl.X-obj.Width-pad, br.Y+pad - break case "bottom-center": x, y = br.X-w/2-obj.Width/2, br.Y+pad - break case "bottom-right": x, y = br.X+pad, br.Y+pad - break } if obj.LabelPosition != nil && !strings.Contains(*obj.LabelPosition, "INSIDE") {