save cloud innerbox aspect ratio

This commit is contained in:
Gavin Nishizawa 2023-11-16 18:08:33 -08:00
parent ade01c8c54
commit b9a5dad820
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD
8 changed files with 41 additions and 5 deletions

View file

@ -167,6 +167,10 @@ func toShape(obj *d2graph.Object, theme *d2themes.Theme) d2target.Shape {
case d2target.ShapeSQLTable:
shape.SQLTable = *obj.SQLTable
shape.FontSize -= d2target.HeaderFontAdd
case d2target.ShapeCloud:
if obj.ContentAspectRatio != nil {
shape.ContentAspectRatio = go2.Pointer(*obj.ContentAspectRatio)
}
}
shape.Label = text.Text
shape.LabelWidth = text.Dimensions.Width

View file

@ -107,6 +107,8 @@ type Object struct {
LabelPosition *string `json:"labelPosition,omitempty"`
IconPosition *string `json:"iconPosition,omitempty"`
ContentAspectRatio *float64 `json:"contentAspectRatio,omitempty"`
Class *d2target.Class `json:"class,omitempty"`
SQLTable *d2target.SQLTable `json:"sql_table,omitempty"`
@ -1068,13 +1070,17 @@ func (obj *Object) SizeToContent(contentWidth, contentHeight, paddingX, paddingY
obj.Width = sideLength
obj.Height = sideLength
} else if desiredHeight == 0 || desiredWidth == 0 {
switch s.GetType() {
switch shapeType {
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)
}
}
if shapeType == shape.CLOUD_TYPE {
innerBox := s.GetInnerBoxForContent(contentWidth, contentHeight)
obj.ContentAspectRatio = go2.Pointer(innerBox.Width / innerBox.Height)
}
}
func (obj *Object) OuterNearContainer() *Object {

View file

@ -364,7 +364,11 @@ func (obj *Object) ToShape() shape.Shape {
dslShape := strings.ToLower(obj.Shape.Value)
shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[dslShape]
contentBox := geo.NewBox(tl, obj.Width, obj.Height)
return shape.NewShape(shapeType, contentBox)
s := shape.NewShape(shapeType, contentBox)
if shapeType == shape.CLOUD_TYPE && obj.ContentAspectRatio != nil {
s.SetInnerBoxAspectRatio(*obj.ContentAspectRatio)
}
return s
}
func (obj *Object) GetLabelTopLeft() *geo.Point {

View file

@ -124,7 +124,7 @@ func Layout(ctx context.Context, g *d2graph.Graph) error {
innerTL := s.GetInsidePlacement(totalWidth, totalHeight, 0, 0)
// depending on the shape innerBox may be larger than totalWidth, totalHeight
// if this is the case, we want to center the cells within the larger innerBox
innerBox := s.GetInnerBoxForContent(totalWidth, totalHeight)
innerBox := s.GetInnerBox()
var resizeDx, resizeDy float64
if innerBox.Width > totalWidth {
resizeDx = (innerBox.Width - totalWidth) / 2

View file

@ -932,6 +932,9 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape
shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[targetShape.Type]
s := shape.NewShape(shapeType, geo.NewBox(tl, width, height))
if shapeType == shape.CLOUD_TYPE && targetShape.ContentAspectRatio != nil {
s.SetInnerBoxAspectRatio(*targetShape.ContentAspectRatio)
}
var shadowAttr string
if targetShape.Shadow {

View file

@ -469,6 +469,8 @@ type Shape struct {
Class
SQLTable
ContentAspectRatio *float64 `json:"contentAspectRatio,omitempty"`
Text
LabelPosition string `json:"labelPosition,omitempty"`

View file

@ -45,7 +45,9 @@ type Shape interface {
GetBox() *geo.Box
GetInnerBox() *geo.Box
// cloud shape has different innerBoxes depending on content's aspect ratio
GetInnerBoxForContent(width, height float64) *geo.Box
SetInnerBoxAspectRatio(aspectRatio float64)
// placing a rectangle of the given size and padding inside the shape, return the position relative to the shape's TopLeft
GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point
@ -91,7 +93,11 @@ func (s baseShape) GetInnerBox() *geo.Box {
// only cloud shape needs this right now
func (s baseShape) GetInnerBoxForContent(width, height float64) *geo.Box {
return (*s.FullShape).GetInnerBox()
return nil
}
func (s baseShape) SetInnerBoxAspectRatio(aspectRatio float64) {
// only used for cloud
}
func (s baseShape) GetInsidePlacement(_, _, paddingX, paddingY float64) geo.Point {

View file

@ -30,6 +30,7 @@ const CLOUD_SQUARE_INNER_HEIGHT = 0.663
type shapeCloud struct {
*baseShape
innerBoxAspectRatio *float64
}
func NewCloud(box *geo.Box) Shape {
@ -38,13 +39,18 @@ func NewCloud(box *geo.Box) Shape {
Type: CLOUD_TYPE,
Box: box,
},
innerBoxAspectRatio: go2.Pointer(0.),
}
shape.FullShape = go2.Pointer(Shape(shape))
return shape
}
func (s shapeCloud) GetInnerBox() *geo.Box {
return s.GetInnerBoxForContent(s.Box.Width, s.Box.Height)
if s.innerBoxAspectRatio != nil && *s.innerBoxAspectRatio != 0. {
return s.GetInnerBoxForContent(*s.innerBoxAspectRatio, 1)
} else {
return s.GetInnerBoxForContent(s.Box.Width, s.Box.Height)
}
}
// we need this since the content's aspect ratio determines which placement is used
@ -66,6 +72,11 @@ func (s shapeCloud) GetInnerBoxForContent(width, height float64) *geo.Box {
return geo.NewBox(&insideTL, width, height)
}
func (s shapeCloud) SetInnerBoxAspectRatio(aspectRatio float64) {
// only used for cloud
*s.innerBoxAspectRatio = aspectRatio
}
func (s shapeCloud) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) {
width += paddingX
height += paddingY