From 0311a3f7d7da9262f162914f98ae5927f7f92222 Mon Sep 17 00:00:00 2001 From: Gavin Nishizawa Date: Mon, 23 Jan 2023 10:32:12 -0800 Subject: [PATCH] use paddingX and paddingY in GetDimensionsToFit --- d2graph/d2graph.go | 45 ++++++++++++-------------------- lib/shape/shape.go | 13 ++++++--- lib/shape/shape_callout.go | 6 ++--- lib/shape/shape_circle.go | 4 +-- lib/shape/shape_class.go | 5 ++++ lib/shape/shape_cloud.go | 11 +++++--- lib/shape/shape_code.go | 4 +++ lib/shape/shape_cylinder.go | 6 ++--- lib/shape/shape_diamond.go | 6 ++--- lib/shape/shape_document.go | 6 ++--- lib/shape/shape_hexagon.go | 6 ++--- lib/shape/shape_image.go | 4 +++ lib/shape/shape_oval.go | 6 ++--- lib/shape/shape_package.go | 6 ++--- lib/shape/shape_page.go | 6 ++--- lib/shape/shape_parallelogram.go | 6 ++--- lib/shape/shape_person.go | 6 ++--- lib/shape/shape_queue.go | 6 ++--- lib/shape/shape_real_square.go | 4 +-- lib/shape/shape_step.go | 6 ++--- lib/shape/shape_stored_data.go | 6 ++--- lib/shape/shape_table.go | 4 +++ lib/shape/shape_text.go | 4 +++ 23 files changed, 98 insertions(+), 78 deletions(-) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index c90ee7607..65f60cdb9 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -23,7 +23,7 @@ import ( ) const INNER_LABEL_PADDING int = 5 -const DEFAULT_SHAPE_PADDING = 100. +const DEFAULT_SHAPE_SIZE = 100. // TODO: Refactor with a light abstract layer on top of AST implementing scenarios, // variables, imports, substitutions and then a final set of structures representing @@ -827,21 +827,6 @@ func (obj *Object) GetDefaultSize(mtexts []*d2target.MText, ruler *textmeasure.R return &dims, nil } -func (obj *Object) GetPadding() (x, y float64) { - switch strings.ToLower(obj.Attributes.Shape.Value) { - case d2target.ShapeImage, - d2target.ShapeSQLTable, - d2target.ShapeText, - d2target.ShapeCode: - return 0., 0. - case d2target.ShapeClass: - // TODO fix class row width measurements (see SQL table) - return 100., 0. - default: - return DEFAULT_SHAPE_PADDING, DEFAULT_SHAPE_PADDING - } -} - type Edge struct { Index int `json:"index"` @@ -1107,8 +1092,8 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler obj.Attributes.Shape.Value != d2target.ShapeImage && obj.Attributes.Shape.Value != d2target.ShapeSQLTable && obj.Attributes.Shape.Value != d2target.ShapeClass { - obj.Width = DEFAULT_SHAPE_PADDING - obj.Height = DEFAULT_SHAPE_PADDING + obj.Width = DEFAULT_SHAPE_SIZE + obj.Height = DEFAULT_SHAPE_SIZE if desiredWidth != 0 { obj.Width = float64(desiredWidth) } @@ -1149,10 +1134,13 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler obj.Width = float64(go2.Max(defaultDims.Width, desiredWidth)) obj.Height = float64(go2.Max(defaultDims.Height, desiredHeight)) - paddingX, paddingY := obj.GetPadding() + shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape] + contentBox := geo.NewBox(geo.NewPoint(0, 0), float64(defaultDims.Width), float64(defaultDims.Height)) + s := shape.NewShape(shapeType, contentBox) - switch dslShape { - case d2target.ShapeSquare, d2target.ShapeCircle: + paddingX, paddingY := s.GetDefaultPadding() + + if s.AspectRatio1() { if desiredWidth != 0 || desiredHeight != 0 { paddingX = 0. paddingY = 0. @@ -1161,8 +1149,7 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler sideLength := math.Max(obj.Width+paddingX, obj.Height+paddingY) obj.Width = sideLength obj.Height = sideLength - - default: + } else { if desiredWidth == 0 { obj.Width += float64(paddingX) } @@ -1170,12 +1157,12 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler obj.Height += float64(paddingY) } } - contentBox := geo.NewBox(geo.NewPoint(0, 0), float64(defaultDims.Width), float64(defaultDims.Height)) - shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape] - s := shape.NewShape(shapeType, contentBox) - newWidth, newHeight := s.GetDimensionsToFit(contentBox.Width, contentBox.Height, paddingX/2) - obj.Width = newWidth - obj.Height = newHeight + + if desiredWidth == 0 && desiredHeight == 0 { + newWidth, newHeight := s.GetDimensionsToFit(contentBox.Width, contentBox.Height, paddingX, paddingY) + obj.Width = newWidth + obj.Height = newHeight + } } for _, edge := range g.Edges { endpointLabels := []string{} diff --git a/lib/shape/shape.go b/lib/shape/shape.go index 1585bad7b..705d209e3 100644 --- a/lib/shape/shape.go +++ b/lib/shape/shape.go @@ -46,7 +46,10 @@ type Shape interface { // placing a rectangle of the given size and padding inside the shape, return the position relative to the shape's TopLeft GetInsidePlacement(width, height, padding float64) geo.Point - GetDimensionsToFit(width, height, padding float64) (float64, float64) + // TODO note change to interface + GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) + + GetDefaultPadding() (paddingX, paddingY float64) // Perimeter returns a slice of geo.Intersectables that together constitute the shape border Perimeter() []geo.Intersectable @@ -93,8 +96,12 @@ func (s baseShape) GetInnerTopLeft(_, _, padding float64) geo.Point { // return the minimum shape dimensions needed to fit content (width x height) // in the shape's innerBox with padding -func (s baseShape) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - return width + padding*2, height + padding*2 +func (s baseShape) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + return width + paddingX, height + paddingY +} + +func (s baseShape) GetDefaultPadding() (paddingX, paddingY float64) { + return 100., 100. } func (s baseShape) Perimeter() []geo.Intersectable { diff --git a/lib/shape/shape_callout.go b/lib/shape/shape_callout.go index fccd8d5bc..fec727fd1 100644 --- a/lib/shape/shape_callout.go +++ b/lib/shape/shape_callout.go @@ -71,14 +71,14 @@ func (s shapeCallout) GetSVGPathData() []string { } } -func (s shapeCallout) GetDimensionsToFit(width, height, padding float64) (float64, float64) { +func (s shapeCallout) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { // return the minimum shape dimensions needed to fit content (width x height) // in the shape's innerBox with padding - baseHeight := height + padding*2 + baseHeight := height + paddingY if baseHeight < defaultTipHeight { baseHeight *= 2 } else { baseHeight += defaultTipHeight } - return width + padding*2, baseHeight + return width + paddingX, baseHeight } diff --git a/lib/shape/shape_circle.go b/lib/shape/shape_circle.go index 54d981099..ef759f196 100644 --- a/lib/shape/shape_circle.go +++ b/lib/shape/shape_circle.go @@ -33,8 +33,8 @@ func (s shapeCircle) AspectRatio1() bool { return true } -func (s shapeCircle) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - diameter := math.Ceil(math.Sqrt(2 * math.Pow(math.Max(width, height)+2*padding, 2))) +func (s shapeCircle) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + diameter := math.Ceil(math.Sqrt(2 * math.Pow(math.Max(width+paddingX, height+paddingY), 2))) return diameter, diameter } diff --git a/lib/shape/shape_class.go b/lib/shape/shape_class.go index ac481eadb..4b9bafc19 100644 --- a/lib/shape/shape_class.go +++ b/lib/shape/shape_class.go @@ -19,3 +19,8 @@ func NewClass(box *geo.Box) Shape { }, } } + +func (s shapeClass) GetDefaultPadding() (paddingX, paddingY float64) { + // TODO fix class row width measurements (see SQL table) + return 100, 0 +} diff --git a/lib/shape/shape_cloud.go b/lib/shape/shape_cloud.go index 634098cdb..548d65310 100644 --- a/lib/shape/shape_cloud.go +++ b/lib/shape/shape_cloud.go @@ -58,9 +58,10 @@ func (s shapeCloud) GetInnerBox() *geo.Box { return geo.NewBox(&insideTL, width, height) } -func (s shapeCloud) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - width += padding - height += padding +func (s shapeCloud) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + // TODO /2? + width += paddingX + height += paddingY aspectRatio := width / height // use the inner box with the closest aspect ratio (wide, tall, or square box) if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY { @@ -116,3 +117,7 @@ func (s shapeCloud) GetSVGPathData() []string { cloudPath(s.Box).PathData(), } } + +func (s shapeCloud) GetDefaultPadding() (paddingX, paddingY float64) { + return 50, 50 +} diff --git a/lib/shape/shape_code.go b/lib/shape/shape_code.go index 83fe728e9..2c0f4b1e1 100644 --- a/lib/shape/shape_code.go +++ b/lib/shape/shape_code.go @@ -18,3 +18,7 @@ func NewCode(box *geo.Box) Shape { }, } } + +func (s shapeCode) GetDefaultPadding() (paddingX, paddingY float64) { + return 0, 0 +} diff --git a/lib/shape/shape_cylinder.go b/lib/shape/shape_cylinder.go index 0e97bbd89..4273b49dd 100644 --- a/lib/shape/shape_cylinder.go +++ b/lib/shape/shape_cylinder.go @@ -77,8 +77,8 @@ func (s shapeCylinder) GetSVGPathData() []string { } } -func (s shapeCylinder) GetDimensionsToFit(width, height, padding float64) (float64, float64) { +func (s shapeCylinder) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { // 2 arcs top, height + padding, 1 arc bottom - totalHeight := height + padding*2 + 3*defaultArcDepth - return width + padding*2, totalHeight + totalHeight := height + paddingY + 3*defaultArcDepth + return width + paddingX, totalHeight } diff --git a/lib/shape/shape_diamond.go b/lib/shape/shape_diamond.go index 6c7951955..ef1853679 100644 --- a/lib/shape/shape_diamond.go +++ b/lib/shape/shape_diamond.go @@ -55,8 +55,8 @@ func (s shapeDiamond) GetSVGPathData() []string { } } -func (s shapeDiamond) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - totalWidth := 2 * (width + 2*padding) - totalHeight := 2 * (height + 2*padding) +func (s shapeDiamond) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + totalWidth := 2 * (width + paddingX) + totalHeight := 2 * (height + paddingY) return totalWidth, totalHeight } diff --git a/lib/shape/shape_document.go b/lib/shape/shape_document.go index 36ffeafcf..81e65f9aa 100644 --- a/lib/shape/shape_document.go +++ b/lib/shape/shape_document.go @@ -52,7 +52,7 @@ func (s shapeDocument) GetSVGPathData() []string { } } -func (s shapeDocument) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - baseHeight := (height + padding*2) * docPathHeight / docPathInnerBottom - return width + padding*2, baseHeight +func (s shapeDocument) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + baseHeight := (height + paddingX) * docPathHeight / docPathInnerBottom + return width + paddingY, baseHeight } diff --git a/lib/shape/shape_hexagon.go b/lib/shape/shape_hexagon.go index 60aeb26df..0009426c7 100644 --- a/lib/shape/shape_hexagon.go +++ b/lib/shape/shape_hexagon.go @@ -49,7 +49,7 @@ func (s shapeHexagon) GetSVGPathData() []string { } } -func (s shapeHexagon) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - totalWidth := 2 * (width + 2*padding) - return totalWidth, height + 2*padding +func (s shapeHexagon) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + totalWidth := 2 * (width + paddingX) + return totalWidth, height + paddingY } diff --git a/lib/shape/shape_image.go b/lib/shape/shape_image.go index 7ba782ae5..ae3923298 100644 --- a/lib/shape/shape_image.go +++ b/lib/shape/shape_image.go @@ -20,3 +20,7 @@ func NewImage(box *geo.Box) Shape { func (s shapeImage) IsRectangular() bool { return true } + +func (s shapeImage) GetDefaultPadding() (paddingX, paddingY float64) { + return 0, 0 +} diff --git a/lib/shape/shape_oval.go b/lib/shape/shape_oval.go index 608fd4a38..77ee82fc7 100644 --- a/lib/shape/shape_oval.go +++ b/lib/shape/shape_oval.go @@ -29,11 +29,11 @@ func (s shapeOval) GetInnerBox() *geo.Box { return geo.NewBox(&insideTL, width, height) } -func (s shapeOval) GetDimensionsToFit(width, height, padding float64) (float64, float64) { +func (s shapeOval) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { theta := math.Atan2(height, width) // add padding in direction of diagonal so there is padding distance between top left and border - paddedWidth := width + 2*padding*math.Cos(theta) - paddedHeight := height + 2*padding*math.Sin(theta) + paddedWidth := width + paddingX*math.Cos(theta) + paddedHeight := height + paddingY*math.Sin(theta) // see https://stackoverflow.com/questions/433371/ellipse-bounding-a-rectangle return math.Ceil(math.Sqrt2 * paddedWidth), math.Ceil(math.Sqrt2 * paddedHeight) } diff --git a/lib/shape/shape_package.go b/lib/shape/shape_package.go index 3181dcc7e..e0201c260 100644 --- a/lib/shape/shape_package.go +++ b/lib/shape/shape_package.go @@ -72,13 +72,13 @@ func (s shapePackage) GetSVGPathData() []string { } } -func (s shapePackage) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - innerHeight := height + padding*2 +func (s shapePackage) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + innerHeight := height + paddingY // We want to compute what the topHeight will be to add to inner height; // topHeight=(verticalScalar * totalHeight) and totalHeight=(topHeight + innerHeight) // so solving for topHeight we get: topHeight=innerHeight * (verticalScalar/(1-verticalScalar)) topHeight := innerHeight * packageVerticalScalar / (1. - packageVerticalScalar) totalHeight := innerHeight + math.Min(topHeight, packageTopMaxHeight) - return width + padding*2, totalHeight + return width + paddingX, totalHeight } diff --git a/lib/shape/shape_page.go b/lib/shape/shape_page.go index a355f02ed..4e7609d2f 100644 --- a/lib/shape/shape_page.go +++ b/lib/shape/shape_page.go @@ -86,9 +86,9 @@ func (s shapePage) GetSVGPathData() []string { } } -func (s shapePage) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - totalWidth := width + padding*2 - totalHeight := height + padding*2 +func (s shapePage) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + totalWidth := width + paddingX + totalHeight := height + paddingY // add space for corner with short pages if totalHeight < 3*pageCornerHeight { totalWidth += pageCornerWidth diff --git a/lib/shape/shape_parallelogram.go b/lib/shape/shape_parallelogram.go index 916a943a9..4666853f6 100644 --- a/lib/shape/shape_parallelogram.go +++ b/lib/shape/shape_parallelogram.go @@ -54,7 +54,7 @@ func (s shapeParallelogram) GetSVGPathData() []string { } } -func (s shapeParallelogram) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - totalWidth := width + padding*2 + parallelWedgeWidth*2 - return totalWidth, height + padding*2 +func (s shapeParallelogram) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + totalWidth := width + paddingX + parallelWedgeWidth*2 + return totalWidth, height + paddingY } diff --git a/lib/shape/shape_person.go b/lib/shape/shape_person.go index 1be86ebaa..68cf06ab8 100644 --- a/lib/shape/shape_person.go +++ b/lib/shape/shape_person.go @@ -66,11 +66,11 @@ func (s shapePerson) GetSVGPathData() []string { } } -func (s shapePerson) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - totalWidth := width + padding*2 +func (s shapePerson) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + totalWidth := width + paddingX // see shapePackage shoulderWidth := totalWidth * personShoulderWidthFactor / (1 - 2*personShoulderWidthFactor) totalWidth += 2 * shoulderWidth - totalHeight := height + padding*2 + totalHeight := height + paddingY return totalWidth, totalHeight } diff --git a/lib/shape/shape_queue.go b/lib/shape/shape_queue.go index 0ddaa683d..d5685fbb2 100644 --- a/lib/shape/shape_queue.go +++ b/lib/shape/shape_queue.go @@ -73,8 +73,8 @@ func (s shapeQueue) GetSVGPathData() []string { } } -func (s shapeQueue) GetDimensionsToFit(width, height, padding float64) (float64, float64) { +func (s shapeQueue) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { // 1 arc left, width+ padding, 2 arcs right - totalWidth := 3*defaultArcDepth + width + padding*2 - return totalWidth, height + padding*2 + totalWidth := 3*defaultArcDepth + width + paddingX + return totalWidth, height + paddingY } diff --git a/lib/shape/shape_real_square.go b/lib/shape/shape_real_square.go index 3f2ea71cb..76f3ccbde 100644 --- a/lib/shape/shape_real_square.go +++ b/lib/shape/shape_real_square.go @@ -27,7 +27,7 @@ func (s shapeRealSquare) IsRectangular() bool { return true } -func (s shapeRealSquare) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - sideLength := math.Max(width+padding*2, height+padding*2) +func (s shapeRealSquare) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + sideLength := math.Max(width+paddingX, height+paddingY) return sideLength, sideLength } diff --git a/lib/shape/shape_step.go b/lib/shape/shape_step.go index 6eb892869..481de7ed8 100644 --- a/lib/shape/shape_step.go +++ b/lib/shape/shape_step.go @@ -54,7 +54,7 @@ func (s shapeStep) GetSVGPathData() []string { } } -func (s shapeStep) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - totalWidth := width + padding*2 + 2*STEP_WEDGE_WIDTH - return totalWidth, height + padding*2 +func (s shapeStep) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + totalWidth := width + paddingX + 2*STEP_WEDGE_WIDTH + return totalWidth, height + paddingY } diff --git a/lib/shape/shape_stored_data.go b/lib/shape/shape_stored_data.go index e30c7896f..f5961c590 100644 --- a/lib/shape/shape_stored_data.go +++ b/lib/shape/shape_stored_data.go @@ -56,7 +56,7 @@ func (s shapeStoredData) GetSVGPathData() []string { } } -func (s shapeStoredData) GetDimensionsToFit(width, height, padding float64) (float64, float64) { - totalWidth := width + padding*2 + 2*storedDataWedgeWidth - return totalWidth, height + padding*2 +func (s shapeStoredData) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { + totalWidth := width + paddingX + 2*storedDataWedgeWidth + return totalWidth, height + paddingY } diff --git a/lib/shape/shape_table.go b/lib/shape/shape_table.go index 6a9ad8044..6d66b9a43 100644 --- a/lib/shape/shape_table.go +++ b/lib/shape/shape_table.go @@ -19,3 +19,7 @@ func NewTable(box *geo.Box) Shape { }, } } + +func (s shapeTable) GetDefaultPadding() (paddingX, paddingY float64) { + return 0, 0 +} diff --git a/lib/shape/shape_text.go b/lib/shape/shape_text.go index 18343205f..078609e0b 100644 --- a/lib/shape/shape_text.go +++ b/lib/shape/shape_text.go @@ -19,3 +19,7 @@ func NewText(box *geo.Box) Shape { }, } } + +func (s shapeText) GetDefaultPadding() (paddingX, paddingY float64) { + return 0, 0 +}