package d2grid
import (
"fmt"
"strconv"
"github.com/pancsta/d2/d2graph"
"github.com/pancsta/d2/lib/geo"
)
type gridDiagram struct {
objects []*d2graph .Object
edges []*d2graph .Edge
rows int
columns int
rowDirected bool
width float64
height float64
verticalGap int
horizontalGap int
}
func newGridDiagram(root *d2graph .Object ) (*gridDiagram , error ) {
gd := gridDiagram {
objects : root .ChildrenArray ,
verticalGap : DEFAULT_GAP ,
horizontalGap : DEFAULT_GAP ,
}
if root .GridRows != nil {
var err error
gd .rows , err = strconv .Atoi (root .GridRows .Value )
if err != nil || gd .rows <= 0 {
return nil , fmt .Errorf ("invalid grid-rows %q" , root .GridRows .Value )
}
if gd .rows > d2graph .MaxGridDimension {
return nil , fmt .Errorf ("grid-rows %d exceeds the maximum of %d" , gd .rows , d2graph .MaxGridDimension )
}
}
if root .GridColumns != nil {
var err error
gd .columns , err = strconv .Atoi (root .GridColumns .Value )
if err != nil || gd .columns <= 0 {
return nil , fmt .Errorf ("invalid grid-columns %q" , root .GridColumns .Value )
}
if gd .columns > d2graph .MaxGridDimension {
return nil , fmt .Errorf ("grid-columns %d exceeds the maximum of %d" , gd .columns , d2graph .MaxGridDimension )
}
}
if len (gd .objects ) > d2graph .MaxGridCells {
return nil , fmt .Errorf ("grid object count %d exceeds the limit of %d cells" , len (gd .objects ), d2graph .MaxGridCells )
}
if gd .rows != 0 && gd .columns != 0 {
capacity , err := d2graph .GridCapacity (gd .rows , gd .columns )
if err != nil {
return nil , err
}
if root .GridRows .MapKey == nil || root .GridColumns .MapKey == nil || root .GridRows .MapKey .Range .Before (root .GridColumns .MapKey .Range ) {
gd .rowDirected = true
}
if capacity < len (gd .objects ) {
if gd .rowDirected {
gd .rows = divideRoundUp (len (gd .objects ), gd .columns )
} else {
gd .columns = divideRoundUp (len (gd .objects ), gd .rows )
}
if _ , err := d2graph .GridCapacity (gd .rows , gd .columns ); err != nil {
return nil , fmt .Errorf ("expanded grid: %w" , err )
}
}
} else if gd .columns == 0 {
gd .rowDirected = true
if len (gd .objects ) < gd .rows {
gd .rows = len (gd .objects )
}
} else {
if len (gd .objects ) < gd .columns {
gd .columns = len (gd .objects )
}
}
if root .GridGap != nil {
gd .verticalGap , _ = strconv .Atoi (root .GridGap .Value )
gd .horizontalGap = gd .verticalGap
}
if root .VerticalGap != nil {
gd .verticalGap , _ = strconv .Atoi (root .VerticalGap .Value )
}
if root .HorizontalGap != nil {
gd .horizontalGap , _ = strconv .Atoi (root .HorizontalGap .Value )
}
for _ , o := range gd .objects {
o .TopLeft = geo .NewPoint (0 , 0 )
}
return &gd , nil
}
func divideRoundUp(numerator , denominator int ) int {
quotient := numerator / denominator
if numerator %denominator != 0 {
quotient ++
}
return quotient
}
func (gd *gridDiagram ) shift (dx , dy float64 ) {
for _ , obj := range gd .objects {
obj .MoveWithDescendants (dx , dy )
}
for _ , e := range gd .edges {
e .Move (dx , dy )
}
}
The pages are generated with Golds v0.8.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .