size grid container according to shape
This commit is contained in:
parent
b8c41226cc
commit
d116f7d918
2 changed files with 63 additions and 41 deletions
|
|
@ -1052,6 +1052,34 @@ func (obj *Object) GetDefaultSize(mtexts []*d2target.MText, ruler *textmeasure.R
|
||||||
return &dims, nil
|
return &dims, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (obj *Object) SizeToContent(contentBox *geo.Box, paddingX, paddingY, desiredWidth, desiredHeight float64, labelDims d2target.TextDimensions) {
|
||||||
|
dslShape := strings.ToLower(obj.Shape.Value)
|
||||||
|
shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape]
|
||||||
|
s := shape.NewShape(shapeType, contentBox)
|
||||||
|
|
||||||
|
var fitWidth, fitHeight float64
|
||||||
|
if shapeType == shape.PERSON_TYPE {
|
||||||
|
fitWidth = contentBox.Width + paddingX
|
||||||
|
fitHeight = contentBox.Height + paddingY
|
||||||
|
} else {
|
||||||
|
fitWidth, fitHeight = s.GetDimensionsToFit(contentBox.Width, contentBox.Height, paddingX, paddingY)
|
||||||
|
}
|
||||||
|
obj.Width = math.Max(float64(desiredWidth), fitWidth)
|
||||||
|
obj.Height = math.Max(float64(desiredHeight), fitHeight)
|
||||||
|
if s.AspectRatio1() {
|
||||||
|
sideLength := math.Max(obj.Width, obj.Height)
|
||||||
|
obj.Width = sideLength
|
||||||
|
obj.Height = sideLength
|
||||||
|
} else if desiredHeight == 0 || desiredWidth == 0 {
|
||||||
|
switch s.GetType() {
|
||||||
|
case shape.PERSON_TYPE:
|
||||||
|
obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.PERSON_AR_LIMIT)
|
||||||
|
case shape.OVAL_TYPE:
|
||||||
|
obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.OVAL_AR_LIMIT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (obj *Object) OuterNearContainer() *Object {
|
func (obj *Object) OuterNearContainer() *Object {
|
||||||
for obj != nil {
|
for obj != nil {
|
||||||
if obj.NearKey != nil {
|
if obj.NearKey != nil {
|
||||||
|
|
@ -1435,7 +1463,6 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
|
||||||
contentBox := geo.NewBox(geo.NewPoint(0, 0), float64(defaultDims.Width), float64(defaultDims.Height))
|
contentBox := geo.NewBox(geo.NewPoint(0, 0), float64(defaultDims.Width), float64(defaultDims.Height))
|
||||||
shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape]
|
shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape]
|
||||||
s := shape.NewShape(shapeType, contentBox)
|
s := shape.NewShape(shapeType, contentBox)
|
||||||
|
|
||||||
paddingX, paddingY := s.GetDefaultPadding()
|
paddingX, paddingY := s.GetDefaultPadding()
|
||||||
if desiredWidth != 0 {
|
if desiredWidth != 0 {
|
||||||
paddingX = 0.
|
paddingX = 0.
|
||||||
|
|
@ -1468,27 +1495,7 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var fitWidth, fitHeight float64
|
obj.SizeToContent(contentBox, paddingX, paddingY, float64(desiredWidth), float64(desiredHeight), *labelDims)
|
||||||
if shapeType == shape.PERSON_TYPE {
|
|
||||||
fitWidth = contentBox.Width + paddingX
|
|
||||||
fitHeight = contentBox.Height + paddingY
|
|
||||||
} else {
|
|
||||||
fitWidth, fitHeight = s.GetDimensionsToFit(contentBox.Width, contentBox.Height, paddingX, paddingY)
|
|
||||||
}
|
|
||||||
obj.Width = math.Max(float64(desiredWidth), fitWidth)
|
|
||||||
obj.Height = math.Max(float64(desiredHeight), fitHeight)
|
|
||||||
if s.AspectRatio1() {
|
|
||||||
sideLength := math.Max(obj.Width, obj.Height)
|
|
||||||
obj.Width = sideLength
|
|
||||||
obj.Height = sideLength
|
|
||||||
} else if desiredHeight == 0 || desiredWidth == 0 {
|
|
||||||
switch s.GetType() {
|
|
||||||
case shape.PERSON_TYPE:
|
|
||||||
obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.PERSON_AR_LIMIT)
|
|
||||||
case shape.OVAL_TYPE:
|
|
||||||
obj.Width, obj.Height = shape.LimitAR(obj.Width, obj.Height, shape.OVAL_AR_LIMIT)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for _, edge := range g.Edges {
|
for _, edge := range g.Edges {
|
||||||
usedFont := fontFamily
|
usedFont := fontFamily
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,13 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2graph"
|
"oss.terrastruct.com/d2/d2graph"
|
||||||
|
"oss.terrastruct.com/d2/d2target"
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/label"
|
"oss.terrastruct.com/d2/lib/label"
|
||||||
|
"oss.terrastruct.com/d2/lib/shape"
|
||||||
"oss.terrastruct.com/util-go/go2"
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -70,26 +73,38 @@ func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph) (gridDiagrams ma
|
||||||
obj.Children = make(map[string]*d2graph.Object)
|
obj.Children = make(map[string]*d2graph.Object)
|
||||||
obj.ChildrenArray = nil
|
obj.ChildrenArray = nil
|
||||||
|
|
||||||
var dx, dy float64
|
if obj.Box != nil {
|
||||||
width := gd.width + 2*CONTAINER_PADDING
|
// size shape according to grid
|
||||||
labelWidth := float64(obj.LabelDimensions.Width) + 2*label.PADDING
|
contentBox := geo.NewBox(geo.NewPoint(0, 0), float64(gd.width), float64(gd.height))
|
||||||
if labelWidth > width {
|
obj.SizeToContent(contentBox, 2*CONTAINER_PADDING, 2*CONTAINER_PADDING, 0, 0, obj.LabelDimensions)
|
||||||
dx = (labelWidth - width) / 2
|
|
||||||
width = labelWidth
|
// 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))
|
||||||
|
innerBox := s.GetInnerBox()
|
||||||
|
if innerBox.TopLeft.X != 0 || innerBox.TopLeft.Y != 0 {
|
||||||
|
gd.shift(innerBox.TopLeft.X, innerBox.TopLeft.Y)
|
||||||
|
}
|
||||||
|
|
||||||
|
var dx, dy float64
|
||||||
|
labelWidth := float64(obj.LabelDimensions.Width) + 2*label.PADDING
|
||||||
|
if labelWidth > obj.Width {
|
||||||
|
dx = (labelWidth - obj.Width) / 2
|
||||||
|
obj.Width = labelWidth
|
||||||
}
|
}
|
||||||
height := gd.height + 2*CONTAINER_PADDING
|
|
||||||
labelHeight := float64(obj.LabelDimensions.Height) + 2*label.PADDING
|
labelHeight := float64(obj.LabelDimensions.Height) + 2*label.PADDING
|
||||||
if labelHeight > CONTAINER_PADDING {
|
if labelHeight > CONTAINER_PADDING {
|
||||||
// if the label doesn't fit within the padding, we need to add more
|
// if the label doesn't fit within the padding, we need to add more
|
||||||
grow := labelHeight - CONTAINER_PADDING
|
grow := labelHeight - CONTAINER_PADDING
|
||||||
dy = grow / 2
|
dy = grow / 2
|
||||||
height += grow
|
obj.Height += grow
|
||||||
}
|
}
|
||||||
// we need to center children if we have to expand to fit the container label
|
// we need to center children if we have to expand to fit the container label
|
||||||
if dx != 0 || dy != 0 {
|
if dx != 0 || dy != 0 {
|
||||||
gd.shift(dx, dy)
|
gd.shift(dx, dy)
|
||||||
}
|
}
|
||||||
obj.Box = geo.NewBox(nil, width, height)
|
}
|
||||||
|
|
||||||
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
|
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
|
||||||
gridDiagrams[obj.AbsID()] = gd
|
gridDiagrams[obj.AbsID()] = gd
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue