This commit is contained in:
Gavin Nishizawa 2023-06-27 14:29:19 -07:00
parent d85c1e9f3b
commit 3ebc557ee8
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD

View file

@ -264,17 +264,11 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
} }
} }
padding, err := parsePadding(opts.Padding) if obj.IsContainer() {
if err != nil { padding := parsePadding(opts.Padding)
// TODO
panic(err)
}
if len(obj.ChildrenArray) > 0 && opts.Padding == DefaultOpts.Padding {
padding = adjustPadding(obj, width, height, padding) padding = adjustPadding(obj, width, height, padding)
}
n.LayoutOptions.Padding = padding.String() n.LayoutOptions.Padding = padding.String()
}
if obj.HasLabel() { if obj.HasLabel() {
n.Labels = append(n.Labels, &ELKLabel{ n.Labels = append(n.Labels, &ELKLabel{
@ -292,45 +286,39 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
elkNodes[obj] = n elkNodes[obj] = n
}) })
// adjust parent padding for children with outside positioned icons
for _, obj := range g.Objects { for _, obj := range g.Objects {
if !obj.IsContainer() { if !obj.IsContainer() {
continue continue
} }
var hasTop, hasBottom bool var hasTop, hasBottom bool
for _, child := range obj.ChildrenArray { for _, child := range obj.ChildrenArray {
if child.Shape.Value == d2target.ShapeImage || child.IconPosition == nil { if child.Shape.Value == d2target.ShapeImage || child.IconPosition == nil {
continue continue
} }
position := label.Position(*child.IconPosition) switch label.Position(*child.IconPosition) {
switch position {
case label.OutsideTopLeft, label.OutsideTopCenter, label.OutsideTopRight: case label.OutsideTopLeft, label.OutsideTopCenter, label.OutsideTopRight:
hasTop = true hasTop = true
case label.OutsideBottomLeft, label.OutsideBottomCenter, label.OutsideBottomRight: case label.OutsideBottomLeft, label.OutsideBottomCenter, label.OutsideBottomRight:
hasBottom = true hasBottom = true
} }
if hasTop && hasBottom {
break
}
} }
if hasTop || hasBottom { if hasTop || hasBottom {
padding, err := parsePadding(elkNodes[obj].LayoutOptions.Padding) padding := parsePadding(elkNodes[obj].LayoutOptions.Padding)
if err != nil {
// TODO add validation to plugin option
panic(err)
}
if hasTop { if hasTop {
padding.top = go2.Max(padding.top, d2target.MAX_ICON_SIZE+2*label.PADDING) padding.top = go2.Max(padding.top, d2target.MAX_ICON_SIZE+2*label.PADDING)
} }
if hasBottom { if hasBottom {
padding.bottom = go2.Max(padding.bottom, d2target.MAX_ICON_SIZE+2*label.PADDING) padding.bottom = go2.Max(padding.bottom, d2target.MAX_ICON_SIZE+2*label.PADDING)
} }
elkNodes[obj].LayoutOptions.Padding = padding.String() elkNodes[obj].LayoutOptions.Padding = padding.String()
} }
} }
for _, edge := range g.Edges { for _, edge := range g.Edges {
@ -801,99 +789,55 @@ type shapePadding struct {
} }
// parse out values from elk padding string. e.g. "[top=50,left=50,bottom=50,right=50]" // parse out values from elk padding string. e.g. "[top=50,left=50,bottom=50,right=50]"
func parsePadding(in string) (padding shapePadding, err error) { func parsePadding(in string) shapePadding {
r := regexp.MustCompile(`top=(\d+),left=(\d+),bottom=(\d+),right=(\d+)`) reTop := regexp.MustCompile(`top=(\d+)`)
submatches := r.FindStringSubmatch(in) reLeft := regexp.MustCompile(`left=(\d+)`)
reBottom := regexp.MustCompile(`bottom=(\d+)`)
reRight := regexp.MustCompile(`right=(\d+)`)
padding = shapePadding{top: 50, left: 50, right: 50, bottom: 50} padding := shapePadding{}
var i int64 submatches := reTop.FindStringSubmatch(in)
i, err = strconv.ParseInt(submatches[1], 10, 64) if len(submatches) == 2 {
if err != nil { i, err := strconv.ParseInt(submatches[1], 10, 64)
return if err == nil {
}
padding.top = int(i) padding.top = int(i)
i, err = strconv.ParseInt(submatches[2], 10, 64)
if err != nil {
return
} }
}
submatches = reLeft.FindStringSubmatch(in)
if len(submatches) == 2 {
i, err := strconv.ParseInt(submatches[1], 10, 64)
if err == nil {
padding.left = int(i) padding.left = int(i)
}
}
i, err = strconv.ParseInt(submatches[3], 10, 64) submatches = reBottom.FindStringSubmatch(in)
if len(submatches) == 2 {
i, err := strconv.ParseInt(submatches[1], 10, 64)
if err == nil {
padding.bottom = int(i) padding.bottom = int(i)
if err != nil { }
return
} }
i, err = strconv.ParseInt(submatches[4], 10, 64) submatches = reRight.FindStringSubmatch(in)
if err != nil { i, err := strconv.ParseInt(submatches[1], 10, 64)
return if len(submatches) == 2 {
} if err == nil {
padding.right = int(i) padding.right = int(i)
return padding, nil
}
func (padding shapePadding) String() string {
return fmt.Sprintf("[top=%d,left=%d,bottom=%d,right=%d]", padding.top, padding.left, padding.bottom, padding.right)
}
func (padding shapePadding) mergePadding(position label.Position, width, height int) shapePadding {
switch position {
case label.InsideTopLeft:
// TODO: consider only adding Y padding for labels in corners, and just ensure the total width fits
if height > padding.top {
padding.top = height
}
if width > padding.left {
padding.left = width
}
case label.InsideTopCenter:
if height > padding.top {
padding.top = height
}
case label.InsideTopRight:
if height > padding.top {
padding.top = height
}
if width > padding.right {
padding.right = width
}
case label.InsideBottomLeft:
if height > padding.bottom {
padding.bottom = height
}
if width > padding.left {
padding.left = width
}
case label.InsideBottomCenter:
if height > padding.bottom {
padding.bottom = height
}
case label.InsideBottomRight:
if height > padding.bottom {
padding.bottom = height
}
if width > padding.right {
padding.right = width
}
case label.InsideMiddleLeft:
if width > padding.left {
padding.left = width
}
case label.InsideMiddleRight:
if width > padding.right {
padding.right = width
} }
} }
return padding return padding
} }
func (padding shapePadding) String() string {
return fmt.Sprintf("[top=%d,left=%d,bottom=%d,right=%d]", padding.top, padding.left, padding.bottom, padding.right)
}
func adjustPadding(obj *d2graph.Object, width, height float64, padding shapePadding) shapePadding { func adjustPadding(obj *d2graph.Object, width, height float64, padding shapePadding) shapePadding {
// TODO don't need to check Icon? if !obj.IsContainer() {
if !obj.IsContainer() && obj.Icon == nil {
return padding return padding
} }
@ -904,7 +848,7 @@ func adjustPadding(obj *d2graph.Object, width, height float64, padding shapePadd
labelWidth := obj.LabelDimensions.Width + 2*label.PADDING labelWidth := obj.LabelDimensions.Width + 2*label.PADDING
switch label.Position(*obj.LabelPosition) { switch label.Position(*obj.LabelPosition) {
case label.InsideTopLeft, label.InsideTopCenter, label.InsideTopRight: case label.InsideTopLeft, label.InsideTopCenter, label.InsideTopRight:
// TODO for corners we only add height, but need to confirm there is enough width // Note: for corners we only add height
extraTop = labelHeight extraTop = labelHeight
case label.InsideBottomLeft, label.InsideBottomCenter, label.InsideBottomRight: case label.InsideBottomLeft, label.InsideBottomCenter, label.InsideBottomRight:
extraBottom = labelHeight extraBottom = labelHeight
@ -999,13 +943,12 @@ func adjustDimensions(obj *d2graph.Object) (width, height float64) {
if position.IsShapePosition() { if position.IsShapePosition() {
switch position { switch position {
case label.OutsideTopLeft, label.OutsideTopCenter, label.OutsideTopRight,
label.OutsideBottomLeft, label.OutsideBottomCenter, label.OutsideBottomRight:
// TODO labelWidth+2*label.PADDING
width = go2.Max(width, float64(obj.LabelDimensions.Width))
case label.OutsideLeftTop, label.OutsideLeftMiddle, label.OutsideLeftBottom, case label.OutsideLeftTop, label.OutsideLeftMiddle, label.OutsideLeftBottom,
label.OutsideRightTop, label.OutsideRightMiddle, label.OutsideRightBottom: label.OutsideRightTop, label.OutsideRightMiddle, label.OutsideRightBottom:
width += float64(obj.LabelDimensions.Width) + label.PADDING width += float64(obj.LabelDimensions.Width) + label.PADDING
default:
// TODO labelWidth+2*label.PADDING
width = go2.Max(width, float64(obj.LabelDimensions.Width))
} }
} }
@ -1023,12 +966,11 @@ func adjustDimensions(obj *d2graph.Object) (width, height float64) {
if position.IsShapePosition() { if position.IsShapePosition() {
switch position { switch position {
case label.OutsideTopLeft, label.OutsideTopCenter, label.OutsideTopRight,
label.OutsideBottomLeft, label.OutsideBottomCenter, label.OutsideBottomRight:
width = go2.Max(width, d2target.MAX_ICON_SIZE+2*label.PADDING)
case label.OutsideLeftTop, label.OutsideLeftMiddle, label.OutsideLeftBottom, case label.OutsideLeftTop, label.OutsideLeftMiddle, label.OutsideLeftBottom,
label.OutsideRightTop, label.OutsideRightMiddle, label.OutsideRightBottom: label.OutsideRightTop, label.OutsideRightMiddle, label.OutsideRightBottom:
width += d2target.MAX_ICON_SIZE + label.PADDING width += d2target.MAX_ICON_SIZE + label.PADDING
default:
width = go2.Max(width, d2target.MAX_ICON_SIZE+2*label.PADDING)
} }
} }
} }