layout nested grids
This commit is contained in:
parent
939eb500da
commit
aff2c5c68e
11 changed files with 4517 additions and 80 deletions
|
|
@ -841,13 +841,6 @@ func (c *compiler) validateKey(obj *d2graph.Object, f *d2ir.Field) {
|
||||||
if !in && arrowheadIn {
|
if !in && arrowheadIn {
|
||||||
c.errorf(f.LastPrimaryKey(), fmt.Sprintf(`invalid shape, can only set "%s" for arrowheads`, obj.Shape.Value))
|
c.errorf(f.LastPrimaryKey(), fmt.Sprintf(`invalid shape, can only set "%s" for arrowheads`, obj.Shape.Value))
|
||||||
}
|
}
|
||||||
case "grid-rows", "grid-columns", "grid-gap", "vertical-gap", "horizontal-gap":
|
|
||||||
for _, child := range obj.ChildrenArray {
|
|
||||||
if child.IsContainer() {
|
|
||||||
c.errorf(f.LastPrimaryKey(),
|
|
||||||
fmt.Sprintf(`%#v can only be used on containers with one level of nesting right now. (%#v has nested %#v)`, keyword, child.AbsID(), child.ChildrenArray[0].ID))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package d2graph
|
package d2graph
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -1823,3 +1824,96 @@ func (obj *Object) MoveWithDescendants(dx, dy float64) {
|
||||||
child.MoveWithDescendants(dx, dy)
|
child.MoveWithDescendants(dx, dy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (obj *Object) MoveWithDescendantsTo(x, y float64) {
|
||||||
|
dx := x - obj.TopLeft.X
|
||||||
|
dy := y - obj.TopLeft.Y
|
||||||
|
obj.MoveWithDescendants(dx, dy)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (parent *Object) removeChild(child *Object) {
|
||||||
|
delete(parent.Children, strings.ToLower(child.ID))
|
||||||
|
for i := 0; i < len(parent.ChildrenArray); i++ {
|
||||||
|
if parent.ChildrenArray[i] == child {
|
||||||
|
parent.ChildrenArray = append(parent.ChildrenArray[:i], parent.ChildrenArray[i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove obj and all descendants from graph, as a new Graph
|
||||||
|
func (g *Graph) ExtractAsNestedGraph(obj *Object) *Graph {
|
||||||
|
descendantObjects, edges := pluckObjAndEdges(g, obj)
|
||||||
|
|
||||||
|
tempGraph := NewGraph()
|
||||||
|
tempGraph.Root.ChildrenArray = []*Object{obj}
|
||||||
|
tempGraph.Root.Children[strings.ToLower(obj.ID)] = obj
|
||||||
|
|
||||||
|
for _, descendantObj := range descendantObjects {
|
||||||
|
descendantObj.Graph = tempGraph
|
||||||
|
}
|
||||||
|
tempGraph.Objects = descendantObjects
|
||||||
|
tempGraph.Edges = edges
|
||||||
|
|
||||||
|
obj.Parent.removeChild(obj)
|
||||||
|
obj.Parent = tempGraph.Root
|
||||||
|
|
||||||
|
return tempGraph
|
||||||
|
}
|
||||||
|
|
||||||
|
func pluckObjAndEdges(g *Graph, obj *Object) (descendantsObjects []*Object, edges []*Edge) {
|
||||||
|
for i := 0; i < len(g.Edges); i++ {
|
||||||
|
edge := g.Edges[i]
|
||||||
|
if edge.Src == obj || edge.Dst == obj {
|
||||||
|
edges = append(edges, edge)
|
||||||
|
g.Edges = append(g.Edges[:i], g.Edges[i+1:]...)
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(g.Objects); i++ {
|
||||||
|
temp := g.Objects[i]
|
||||||
|
if temp.AbsID() == obj.AbsID() {
|
||||||
|
descendantsObjects = append(descendantsObjects, obj)
|
||||||
|
g.Objects = append(g.Objects[:i], g.Objects[i+1:]...)
|
||||||
|
for _, child := range obj.ChildrenArray {
|
||||||
|
subObjects, subEdges := pluckObjAndEdges(g, child)
|
||||||
|
descendantsObjects = append(descendantsObjects, subObjects...)
|
||||||
|
edges = append(edges, subEdges...)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return descendantsObjects, edges
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Graph) InjectNestedGraph(tempGraph *Graph, parent *Object) {
|
||||||
|
obj := tempGraph.Root.ChildrenArray[0]
|
||||||
|
obj.MoveWithDescendantsTo(0, 0)
|
||||||
|
obj.Parent = parent
|
||||||
|
for _, obj := range tempGraph.Objects {
|
||||||
|
obj.Graph = g
|
||||||
|
}
|
||||||
|
g.Objects = append(g.Objects, tempGraph.Objects...)
|
||||||
|
parent.Children[strings.ToLower(obj.ID)] = obj
|
||||||
|
parent.ChildrenArray = append(parent.ChildrenArray, obj)
|
||||||
|
g.Edges = append(g.Edges, tempGraph.Edges...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Graph) PrintString() string {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
fmt.Fprint(buf, "Objects: [")
|
||||||
|
for _, obj := range g.Objects {
|
||||||
|
fmt.Fprintf(buf, "%#v @(%v)", obj.AbsID(), obj.TopLeft.ToString())
|
||||||
|
}
|
||||||
|
fmt.Fprint(buf, "]")
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (obj *Object) IterDescendants(apply func(parent, child *Object)) {
|
||||||
|
for _, c := range obj.ChildrenArray {
|
||||||
|
apply(obj, c)
|
||||||
|
c.IterDescendants(apply)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2graph"
|
"oss.terrastruct.com/d2/d2graph"
|
||||||
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
)
|
)
|
||||||
|
|
||||||
type gridDiagram struct {
|
type gridDiagram struct {
|
||||||
|
|
@ -95,6 +96,10 @@ func newGridDiagram(root *d2graph.Object) *gridDiagram {
|
||||||
gd.horizontalGap, _ = strconv.Atoi(root.HorizontalGap.Value)
|
gd.horizontalGap, _ = strconv.Atoi(root.HorizontalGap.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, o := range gd.objects {
|
||||||
|
o.TopLeft = geo.NewPoint(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
return &gd
|
return &gd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,9 +112,15 @@ func (gd *gridDiagram) shift(dx, dy float64) {
|
||||||
func (gd *gridDiagram) cleanup(obj *d2graph.Object, graph *d2graph.Graph) {
|
func (gd *gridDiagram) cleanup(obj *d2graph.Object, graph *d2graph.Graph) {
|
||||||
obj.Children = make(map[string]*d2graph.Object)
|
obj.Children = make(map[string]*d2graph.Object)
|
||||||
obj.ChildrenArray = make([]*d2graph.Object, 0)
|
obj.ChildrenArray = make([]*d2graph.Object, 0)
|
||||||
|
|
||||||
|
restore := func(parent, child *d2graph.Object) {
|
||||||
|
// fmt.Printf("restore %v's %v\n", parent.AbsID(), child.AbsID())
|
||||||
|
parent.Children[strings.ToLower(child.ID)] = child
|
||||||
|
parent.ChildrenArray = append(parent.ChildrenArray, child)
|
||||||
|
graph.Objects = append(graph.Objects, child)
|
||||||
|
}
|
||||||
for _, child := range gd.objects {
|
for _, child := range gd.objects {
|
||||||
obj.Children[strings.ToLower(child.ID)] = child
|
restore(obj, child)
|
||||||
obj.ChildrenArray = append(obj.ChildrenArray, child)
|
child.IterDescendants(restore)
|
||||||
}
|
}
|
||||||
graph.Objects = append(graph.Objects, gd.objects...)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const (
|
||||||
// 7. Put grid children back in correct location
|
// 7. Put grid children back in correct location
|
||||||
func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d2graph.LayoutGraph {
|
func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d2graph.LayoutGraph {
|
||||||
return func(ctx context.Context, g *d2graph.Graph) error {
|
return func(ctx context.Context, g *d2graph.Graph) error {
|
||||||
gridDiagrams, objectOrder, err := withoutGridDiagrams(ctx, g)
|
gridDiagrams, objectOrder, err := withoutGridDiagrams(ctx, g, layout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -49,18 +49,42 @@ func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph) (gridDiagrams map[string]*gridDiagram, objectOrder map[string]int, err error) {
|
func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) (gridDiagrams map[string]*gridDiagram, objectOrder map[string]int, err error) {
|
||||||
toRemove := make(map[*d2graph.Object]struct{})
|
toRemove := make(map[*d2graph.Object]struct{})
|
||||||
gridDiagrams = make(map[string]*gridDiagram)
|
gridDiagrams = make(map[string]*gridDiagram)
|
||||||
|
|
||||||
|
objectOrder = make(map[string]int)
|
||||||
|
for i, obj := range g.Objects {
|
||||||
|
objectOrder[obj.AbsID()] = i
|
||||||
|
}
|
||||||
|
|
||||||
var processGrid func(obj *d2graph.Object) error
|
var processGrid func(obj *d2graph.Object) error
|
||||||
processGrid = func(obj *d2graph.Object) error {
|
processGrid = func(obj *d2graph.Object) error {
|
||||||
// layout any nested grids first
|
|
||||||
for _, child := range obj.ChildrenArray {
|
for _, child := range obj.ChildrenArray {
|
||||||
if child.IsGridDiagram() {
|
if child.IsGridDiagram() {
|
||||||
if err := processGrid(child); err != nil {
|
if err := processGrid(child); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else if len(child.ChildrenArray) > 0 {
|
||||||
|
tempGraph := g.ExtractAsNestedGraph(child)
|
||||||
|
if err := layout(ctx, tempGraph); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
g.InjectNestedGraph(tempGraph, obj)
|
||||||
|
|
||||||
|
sort.SliceStable(g.Objects, func(i, j int) bool {
|
||||||
|
return objectOrder[g.Objects[i].AbsID()] < objectOrder[g.Objects[j].AbsID()]
|
||||||
|
})
|
||||||
|
sort.SliceStable(child.ChildrenArray, func(i, j int) bool {
|
||||||
|
return objectOrder[child.ChildrenArray[i].AbsID()] < objectOrder[child.ChildrenArray[j].AbsID()]
|
||||||
|
})
|
||||||
|
sort.SliceStable(obj.ChildrenArray, func(i, j int) bool {
|
||||||
|
return objectOrder[obj.ChildrenArray[i].AbsID()] < objectOrder[obj.ChildrenArray[j].AbsID()]
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, o := range tempGraph.Objects {
|
||||||
|
toRemove[o] = struct{}{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,10 +156,8 @@ func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph) (gridDiagrams ma
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
objectOrder = make(map[string]int)
|
|
||||||
layoutObjects := make([]*d2graph.Object, 0, len(toRemove))
|
layoutObjects := make([]*d2graph.Object, 0, len(toRemove))
|
||||||
for i, obj := range g.Objects {
|
for _, obj := range g.Objects {
|
||||||
objectOrder[obj.AbsID()] = i
|
|
||||||
if _, exists := toRemove[obj]; !exists {
|
if _, exists := toRemove[obj]; !exists {
|
||||||
layoutObjects = append(layoutObjects, obj)
|
layoutObjects = append(layoutObjects, obj)
|
||||||
}
|
}
|
||||||
|
|
@ -223,7 +245,7 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) {
|
||||||
}
|
}
|
||||||
o.Width = colWidths[j]
|
o.Width = colWidths[j]
|
||||||
o.Height = rowHeights[i]
|
o.Height = rowHeights[i]
|
||||||
o.TopLeft = cursor.Copy()
|
o.MoveWithDescendantsTo(cursor.X, cursor.Y)
|
||||||
cursor.X += o.Width + horizontalGap
|
cursor.X += o.Width + horizontalGap
|
||||||
}
|
}
|
||||||
cursor.X = 0
|
cursor.X = 0
|
||||||
|
|
@ -238,7 +260,7 @@ func (gd *gridDiagram) layoutEvenly(g *d2graph.Graph, obj *d2graph.Object) {
|
||||||
}
|
}
|
||||||
o.Width = colWidths[j]
|
o.Width = colWidths[j]
|
||||||
o.Height = rowHeights[i]
|
o.Height = rowHeights[i]
|
||||||
o.TopLeft = cursor.Copy()
|
o.MoveWithDescendantsTo(cursor.X, cursor.Y)
|
||||||
cursor.Y += o.Height + verticalGap
|
cursor.Y += o.Height + verticalGap
|
||||||
}
|
}
|
||||||
cursor.X += colWidths[j] + horizontalGap
|
cursor.X += colWidths[j] + horizontalGap
|
||||||
|
|
@ -374,7 +396,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) {
|
||||||
for _, row := range layout {
|
for _, row := range layout {
|
||||||
rowHeight := 0.
|
rowHeight := 0.
|
||||||
for _, o := range row {
|
for _, o := range row {
|
||||||
o.TopLeft = cursor.Copy()
|
o.MoveWithDescendantsTo(cursor.X, cursor.Y)
|
||||||
cursor.X += o.Width + horizontalGap
|
cursor.X += o.Width + horizontalGap
|
||||||
rowHeight = math.Max(rowHeight, o.Height)
|
rowHeight = math.Max(rowHeight, o.Height)
|
||||||
}
|
}
|
||||||
|
|
@ -462,7 +484,7 @@ func (gd *gridDiagram) layoutDynamic(g *d2graph.Graph, obj *d2graph.Object) {
|
||||||
for _, column := range layout {
|
for _, column := range layout {
|
||||||
colWidth := 0.
|
colWidth := 0.
|
||||||
for _, o := range column {
|
for _, o := range column {
|
||||||
o.TopLeft = cursor.Copy()
|
o.MoveWithDescendantsTo(cursor.X, cursor.Y)
|
||||||
cursor.Y += o.Height + verticalGap
|
cursor.Y += o.Height + verticalGap
|
||||||
colWidth = math.Max(colWidth, o.Width)
|
colWidth = math.Max(colWidth, o.Width)
|
||||||
}
|
}
|
||||||
|
|
@ -834,18 +856,11 @@ func cleanup(graph *d2graph.Graph, gridDiagrams map[string]*gridDiagram, objects
|
||||||
})
|
})
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if graph.Root.IsGridDiagram() {
|
var restore func(obj *d2graph.Object)
|
||||||
gd, exists := gridDiagrams[graph.Root.AbsID()]
|
restore = func(obj *d2graph.Object) {
|
||||||
if exists {
|
|
||||||
gd.cleanup(graph.Root, graph)
|
|
||||||
// return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, obj := range graph.Objects {
|
|
||||||
gd, exists := gridDiagrams[obj.AbsID()]
|
gd, exists := gridDiagrams[obj.AbsID()]
|
||||||
if !exists {
|
if !exists {
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
|
obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter))
|
||||||
// shift the grid from (0, 0)
|
// shift the grid from (0, 0)
|
||||||
|
|
@ -854,5 +869,20 @@ func cleanup(graph *d2graph.Graph, gridDiagrams map[string]*gridDiagram, objects
|
||||||
obj.TopLeft.Y+CONTAINER_PADDING,
|
obj.TopLeft.Y+CONTAINER_PADDING,
|
||||||
)
|
)
|
||||||
gd.cleanup(obj, graph)
|
gd.cleanup(obj, graph)
|
||||||
|
|
||||||
|
for _, child := range obj.ChildrenArray {
|
||||||
|
restore(child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if graph.Root.IsGridDiagram() {
|
||||||
|
gd, exists := gridDiagrams[graph.Root.AbsID()]
|
||||||
|
if exists {
|
||||||
|
gd.cleanup(graph.Root, graph)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, obj := range graph.Objects {
|
||||||
|
restore(obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,62 +148,14 @@ func WithoutConstantNears(ctx context.Context, g *d2graph.Graph) (constantNearGr
|
||||||
}
|
}
|
||||||
_, isConst := d2graph.NearConstants[d2graph.Key(obj.NearKey)[0]]
|
_, isConst := d2graph.NearConstants[d2graph.Key(obj.NearKey)[0]]
|
||||||
if isConst {
|
if isConst {
|
||||||
descendantObjects, edges := pluckObjAndEdges(g, obj)
|
tempGraph := g.ExtractAsNestedGraph(obj)
|
||||||
|
|
||||||
tempGraph := d2graph.NewGraph()
|
|
||||||
tempGraph.Root.ChildrenArray = []*d2graph.Object{obj}
|
|
||||||
tempGraph.Root.Children[strings.ToLower(obj.ID)] = obj
|
|
||||||
|
|
||||||
for _, descendantObj := range descendantObjects {
|
|
||||||
descendantObj.Graph = tempGraph
|
|
||||||
}
|
|
||||||
tempGraph.Objects = descendantObjects
|
|
||||||
tempGraph.Edges = edges
|
|
||||||
|
|
||||||
constantNearGraphs = append(constantNearGraphs, tempGraph)
|
constantNearGraphs = append(constantNearGraphs, tempGraph)
|
||||||
|
|
||||||
i--
|
i--
|
||||||
delete(obj.Parent.Children, strings.ToLower(obj.ID))
|
|
||||||
for i := 0; i < len(obj.Parent.ChildrenArray); i++ {
|
|
||||||
if obj.Parent.ChildrenArray[i] == obj {
|
|
||||||
obj.Parent.ChildrenArray = append(obj.Parent.ChildrenArray[:i], obj.Parent.ChildrenArray[i+1:]...)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.Parent = tempGraph.Root
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return constantNearGraphs
|
return constantNearGraphs
|
||||||
}
|
}
|
||||||
|
|
||||||
func pluckObjAndEdges(g *d2graph.Graph, obj *d2graph.Object) (descendantsObjects []*d2graph.Object, edges []*d2graph.Edge) {
|
|
||||||
for i := 0; i < len(g.Edges); i++ {
|
|
||||||
edge := g.Edges[i]
|
|
||||||
if edge.Src == obj || edge.Dst == obj {
|
|
||||||
edges = append(edges, edge)
|
|
||||||
g.Edges = append(g.Edges[:i], g.Edges[i+1:]...)
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < len(g.Objects); i++ {
|
|
||||||
temp := g.Objects[i]
|
|
||||||
if temp.AbsID() == obj.AbsID() {
|
|
||||||
descendantsObjects = append(descendantsObjects, obj)
|
|
||||||
g.Objects = append(g.Objects[:i], g.Objects[i+1:]...)
|
|
||||||
for _, child := range obj.ChildrenArray {
|
|
||||||
subObjects, subEdges := pluckObjAndEdges(g, child)
|
|
||||||
descendantsObjects = append(descendantsObjects, subObjects...)
|
|
||||||
edges = append(edges, subEdges...)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return descendantsObjects, edges
|
|
||||||
}
|
|
||||||
|
|
||||||
// boundingBox gets the center of the graph as defined by shapes
|
// boundingBox gets the center of the graph as defined by shapes
|
||||||
// The bounds taking into consideration only shapes gives more of a feeling of true center
|
// The bounds taking into consideration only shapes gives more of a feeling of true center
|
||||||
// It differs from d2target.BoundingBox which needs to include every visible thing
|
// It differs from d2target.BoundingBox which needs to include every visible thing
|
||||||
|
|
|
||||||
|
|
@ -2721,6 +2721,7 @@ scenarios: {
|
||||||
loadFromFile(t, "ent2d2_basic"),
|
loadFromFile(t, "ent2d2_basic"),
|
||||||
loadFromFile(t, "ent2d2_right"),
|
loadFromFile(t, "ent2d2_right"),
|
||||||
loadFromFile(t, "grid_large_checkered"),
|
loadFromFile(t, "grid_large_checkered"),
|
||||||
|
loadFromFile(t, "grid_nested"),
|
||||||
}
|
}
|
||||||
|
|
||||||
runa(t, tcs)
|
runa(t, tcs)
|
||||||
|
|
|
||||||
96
e2etests/testdata/files/grid_nested.d2
vendored
Normal file
96
e2etests/testdata/files/grid_nested.d2
vendored
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
classes: {
|
||||||
|
2x2: {
|
||||||
|
grid-rows: 2
|
||||||
|
grid-columns: 2
|
||||||
|
}
|
||||||
|
gap0: {
|
||||||
|
vertical-gap: 0
|
||||||
|
horizontal-gap: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grid w/ container: {
|
||||||
|
class: 2x2
|
||||||
|
|
||||||
|
a
|
||||||
|
b: {
|
||||||
|
b child
|
||||||
|
}
|
||||||
|
c
|
||||||
|
d
|
||||||
|
}
|
||||||
|
|
||||||
|
grid w/ nested containers: {
|
||||||
|
class: 2x2
|
||||||
|
|
||||||
|
a
|
||||||
|
b: {
|
||||||
|
b 1: {
|
||||||
|
b 2: {
|
||||||
|
b 3: {
|
||||||
|
b 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b 2a: {
|
||||||
|
b 3a: {
|
||||||
|
b 3a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c
|
||||||
|
d
|
||||||
|
}
|
||||||
|
|
||||||
|
grid in grid: {
|
||||||
|
class: 2x2
|
||||||
|
|
||||||
|
a
|
||||||
|
b: {
|
||||||
|
class: 2x2
|
||||||
|
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
d
|
||||||
|
}
|
||||||
|
c
|
||||||
|
d
|
||||||
|
}
|
||||||
|
|
||||||
|
grid w/ grid w/ grid: {
|
||||||
|
class: [2x2; gap0]
|
||||||
|
|
||||||
|
a
|
||||||
|
b: {
|
||||||
|
class: [2x2; gap0]
|
||||||
|
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c: {
|
||||||
|
class: [2x2; gap0]
|
||||||
|
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
d: {
|
||||||
|
class: [2x2; gap0]
|
||||||
|
|
||||||
|
a: {
|
||||||
|
class: [2x2; gap0]
|
||||||
|
|
||||||
|
a
|
||||||
|
b
|
||||||
|
c
|
||||||
|
d
|
||||||
|
}
|
||||||
|
b
|
||||||
|
c
|
||||||
|
d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d
|
||||||
|
}
|
||||||
|
c
|
||||||
|
d
|
||||||
|
}
|
||||||
2028
e2etests/testdata/stable/grid_nested/dagre/board.exp.json
generated
vendored
Normal file
2028
e2etests/testdata/stable/grid_nested/dagre/board.exp.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
102
e2etests/testdata/stable/grid_nested/dagre/sketch.exp.svg
vendored
Normal file
102
e2etests/testdata/stable/grid_nested/dagre/sketch.exp.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 28 KiB |
2028
e2etests/testdata/stable/grid_nested/elk/board.exp.json
generated
vendored
Normal file
2028
e2etests/testdata/stable/grid_nested/elk/board.exp.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
102
e2etests/testdata/stable/grid_nested/elk/sketch.exp.svg
vendored
Normal file
102
e2etests/testdata/stable/grid_nested/elk/sketch.exp.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 28 KiB |
Loading…
Reference in a new issue