add maximum attempts

This commit is contained in:
Gavin Nishizawa 2023-04-26 11:31:27 -07:00
parent 203cc5e4af
commit 917b262773
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD

View file

@ -472,32 +472,46 @@ func (gd *gridDiagram) getBestLayout(targetSize float64, columns bool) [][]*d2gr
// . A │ B C │ D E ┌E───────────┐ // . A │ B C │ D E ┌E───────────┐
// . A │ B │ C D E └────────────┘ // . A │ B │ C D E └────────────┘
// of these divisions, find the layout with rows closest to the targetSize // of these divisions, find the layout with rows closest to the targetSize
iterDivisions(gd.objects, nCuts, func(division []int) { count := 0
iterDivisions(gd.objects, nCuts, func(division []int) bool {
layout := genLayout(gd.objects, division) layout := genLayout(gd.objects, division)
dist := getDistToTarget(layout, targetSize, float64(gd.horizontalGap), float64(gd.verticalGap), columns) dist := getDistToTarget(layout, targetSize, float64(gd.horizontalGap), float64(gd.verticalGap), columns)
if dist < bestDist { if dist < bestDist {
bestLayout = layout bestLayout = layout
bestDist = dist bestDist = dist
} }
count++
if count > 1_000_000 {
return true
}
return false
}) })
return bestLayout return bestLayout
} }
// process current division, return true to stop iterating
type iterDivision func(division []int) (done bool)
// get all possible divisions of objects by the number of cuts // get all possible divisions of objects by the number of cuts
func iterDivisions(objects []*d2graph.Object, nCuts int, f func([]int)) { func iterDivisions(objects []*d2graph.Object, nCuts int, f iterDivision) {
if len(objects) < 2 || nCuts == 0 { if len(objects) < 2 || nCuts == 0 {
return return
} }
done := false
// we go in this order to prefer extra objects in starting rows rather than later ones // we go in this order to prefer extra objects in starting rows rather than later ones
lastObj := len(objects) - 1 lastObj := len(objects) - 1
for index := lastObj; index >= nCuts; index-- { for index := lastObj; index >= nCuts; index-- {
if nCuts > 1 { if nCuts > 1 {
iterDivisions(objects[:index], nCuts-1, func(inner []int) { iterDivisions(objects[:index], nCuts-1, func(inner []int) bool {
f(append(inner, index-1)) done = f(append(inner, index-1))
return done
}) })
} else { } else {
f([]int{index - 1}) done = f([]int{index - 1})
}
if done {
return
} }
} }
} }