diff --git a/d2exporter/export_test.go b/d2exporter/export_test.go index 4eb1974c9..4aa862bdd 100644 --- a/d2exporter/export_test.go +++ b/d2exporter/export_test.go @@ -17,9 +17,8 @@ import ( "oss.terrastruct.com/d2/d2compiler" "oss.terrastruct.com/d2/d2exporter" "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/d2layouts" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" - "oss.terrastruct.com/d2/d2layouts/d2grid" - "oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/d2lib" "oss.terrastruct.com/d2/d2target" "oss.terrastruct.com/d2/lib/geo" @@ -235,7 +234,8 @@ func run(t *testing.T, tc testCase) { err = g.SetDimensions(nil, ruler, nil) assert.JSON(t, nil, err) - err = d2sequence.Layout(ctx, g, d2grid.Layout(ctx, g, d2dagrelayout.DefaultLayout)) + graphInfo := d2layouts.NestedGraphInfo(g.Root) + err = d2layouts.LayoutNested(ctx, g, graphInfo, d2dagrelayout.DefaultLayout) if err != nil { t.Fatal(err) } diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 1452cf4bc..36d206e41 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -1090,6 +1090,21 @@ func (obj *Object) OuterNearContainer() *Object { return nil } +func (obj *Object) IsConstantNear() bool { + if obj.NearKey == nil { + return false + } + keyPath := Key(obj.NearKey) + + // interesting if there is a shape with id=top-left, then top-left isn't treated a constant near + _, isKey := obj.Graph.Root.HasChild(keyPath) + if isKey { + return false + } + _, isConst := NearConstants[keyPath[0]] + return isConst +} + type Edge struct { Index int `json:"index"` @@ -1910,7 +1925,7 @@ 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.Fprintf(buf, "%v, ", obj.AbsID()) } fmt.Fprint(buf, "]") return buf.String() diff --git a/d2graph/layout.go b/d2graph/layout.go index 9f2702df7..8c705b713 100644 --- a/d2graph/layout.go +++ b/d2graph/layout.go @@ -26,7 +26,7 @@ func (obj *Object) MoveWithDescendantsTo(x, y float64) { obj.MoveWithDescendants(dx, dy) } -func (parent *Object) removeChild(child *Object) { +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 { @@ -51,7 +51,7 @@ func (g *Graph) ExtractAsNestedGraph(obj *Object) *Graph { tempGraph.Objects = descendantObjects tempGraph.Edges = edges - obj.Parent.removeChild(obj) + obj.Parent.RemoveChild(obj) obj.Parent = tempGraph.Root return tempGraph diff --git a/d2layouts/d2grid/layout.go b/d2layouts/d2grid/layout.go index 9e9109453..f2b01e183 100644 --- a/d2layouts/d2grid/layout.go +++ b/d2layouts/d2grid/layout.go @@ -5,7 +5,6 @@ import ( "context" "fmt" "math" - "sort" "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2target" @@ -21,257 +20,160 @@ const ( // Layout runs the grid layout on containers with rows/columns // Note: children are not allowed edges or descendants -// -// 1. Traverse graph from root, skip objects with no rows/columns -// 2. Construct a grid with the container children -// 3. Remove the children from the main graph -// 4. Run grid layout -// 5. Set the resulting dimensions to the main graph shape -// 6. Run core layouts (without grid children) -// 7. Put grid children back in correct location -func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) d2graph.LayoutGraph { - return func(ctx context.Context, g *d2graph.Graph) error { - gridDiagrams, objectOrder, edgeOrder, err := withoutGridDiagrams(ctx, g, layout) - if err != nil { - return err - } +// 1. Run grid layout on the graph root +// 2. Set the resulting dimensions to the graph root +func Layout(ctx context.Context, g *d2graph.Graph) error { + obj := g.Root - if g.Root.IsGridDiagram() && len(g.Root.ChildrenArray) != 0 { - g.Root.TopLeft = geo.NewPoint(0, 0) - } else if err := layout(ctx, g); err != nil { - return err - } - - cleanup(g, gridDiagrams, objectOrder, edgeOrder) - return nil - } -} - -func withoutGridDiagrams(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) (gridDiagrams map[string]*gridDiagram, objectOrder, edgeOrder map[string]int, err error) { - toRemove := make(map[*d2graph.Object]struct{}) - edgeToRemove := make(map[*d2graph.Edge]struct{}) - gridDiagrams = make(map[string]*gridDiagram) - - objectOrder = make(map[string]int) - for i, obj := range g.Objects { - objectOrder[obj.AbsID()] = i - } - edgeOrder = make(map[string]int) - for i, edge := range g.Edges { - edgeOrder[edge.AbsID()] = i + gd, err := layoutGrid(g, obj) + if err != nil { + return err } - var processGrid func(obj *d2graph.Object) error - processGrid = func(obj *d2graph.Object) error { - for _, child := range obj.ChildrenArray { - if len(child.ChildrenArray) == 0 { - continue - } - if child.IsGridDiagram() { - if err := processGrid(child); err != nil { - return err - } - } else { - 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()] - }) - sort.SliceStable(g.Edges, func(i, j int) bool { - return edgeOrder[g.Edges[i].AbsID()] < edgeOrder[g.Edges[j].AbsID()] - }) - - for _, o := range tempGraph.Objects { - toRemove[o] = struct{}{} - } - } + if obj.Box != nil { + // CONTAINER_PADDING is default, but use gap value if set + horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING + if obj.GridGap != nil || obj.HorizontalGap != nil { + horizontalPadding = gd.horizontalGap + } + if obj.GridGap != nil || obj.VerticalGap != nil { + verticalPadding = gd.verticalGap } - gd, err := layoutGrid(g, obj) - if err != nil { - return err - } - obj.Children = make(map[string]*d2graph.Object) - obj.ChildrenArray = nil + // size shape according to grid + obj.SizeToContent(gd.width, gd.height, float64(2*horizontalPadding), float64(2*verticalPadding)) - if obj.Box != nil { - // CONTAINER_PADDING is default, but use gap value if set - horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING - if obj.GridGap != nil || obj.HorizontalGap != nil { - horizontalPadding = gd.horizontalGap - } - if obj.GridGap != nil || obj.VerticalGap != nil { - verticalPadding = gd.verticalGap - } - - // size shape according to grid - obj.SizeToContent(gd.width, gd.height, float64(2*horizontalPadding), float64(2*verticalPadding)) - - // compute where the grid should be placed inside shape - s := obj.ToShape() - innerBox := s.GetInnerBox() - if innerBox.TopLeft.X != 0 || innerBox.TopLeft.Y != 0 { - gd.shift(innerBox.TopLeft.X, innerBox.TopLeft.Y) - } - - // compute how much space the label and icon occupy - var occupiedWidth, occupiedHeight float64 - if obj.Icon != nil { - iconSpace := float64(d2target.MAX_ICON_SIZE + 2*label.PADDING) - occupiedWidth = iconSpace - occupiedHeight = iconSpace - } - - var dx, dy float64 - if obj.LabelDimensions.Height != 0 { - occupiedHeight = math.Max( - occupiedHeight, - float64(obj.LabelDimensions.Height)+2*label.PADDING, - ) - } - if obj.LabelDimensions.Width != 0 { - // . ├────┤───────├────┤ - // . icon label icon - // with an icon in top left we need 2x the space to fit the label in the center - occupiedWidth *= 2 - occupiedWidth += float64(obj.LabelDimensions.Width) + 2*label.PADDING - if occupiedWidth > obj.Width { - dx = (occupiedWidth - obj.Width) / 2 - obj.Width = occupiedWidth - } - } - - // also check for grid cells with outside top labels or icons - // the first grid object is at the top (and always exists) - topY := gd.objects[0].TopLeft.Y - highestOutside := topY - for _, o := range gd.objects { - // we only want to compute label positions for objects at the top of the grid - if o.TopLeft.Y > topY { - if gd.rowDirected { - // if the grid is rowDirected (row1, row2, etc) we can stop after finishing the first row - break - } else { - // otherwise we continue until the next column - continue - } - } - if o.LabelPosition != nil { - labelPosition := label.Position(*o.LabelPosition) - if labelPosition.IsOutside() { - labelTL := o.GetLabelTopLeft() - if labelTL.Y < highestOutside { - highestOutside = labelTL.Y - } - } - } - if o.IconPosition != nil { - switch label.Position(*o.IconPosition) { - case label.OutsideTopLeft, label.OutsideTopCenter, label.OutsideTopRight: - iconSpace := float64(d2target.MAX_ICON_SIZE + label.PADDING) - if topY-iconSpace < highestOutside { - highestOutside = topY - iconSpace - } - } - } - } - if highestOutside < topY { - occupiedHeight += topY - highestOutside + 2*label.PADDING - } - if occupiedHeight > float64(verticalPadding) { - // if the label doesn't fit within the padding, we need to add more - dy = occupiedHeight - float64(verticalPadding) - obj.Height += dy - } - - // we need to center children if we have to expand to fit the container label - if dx != 0 || dy != 0 { - gd.shift(dx, dy) - } + // compute where the grid should be placed inside shape + s := obj.ToShape() + innerBox := s.GetInnerBox() + if innerBox.TopLeft.X != 0 || innerBox.TopLeft.Y != 0 { + gd.shift(innerBox.TopLeft.X, innerBox.TopLeft.Y) } - if obj.HasLabel() { - obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - } + // compute how much space the label and icon occupy + var occupiedWidth, occupiedHeight float64 if obj.Icon != nil { - obj.IconPosition = go2.Pointer(string(label.InsideTopLeft)) + iconSpace := float64(d2target.MAX_ICON_SIZE + 2*label.PADDING) + occupiedWidth = iconSpace + occupiedHeight = iconSpace } - gridDiagrams[obj.AbsID()] = gd + var dx, dy float64 + if obj.LabelDimensions.Height != 0 { + occupiedHeight = math.Max( + occupiedHeight, + float64(obj.LabelDimensions.Height)+2*label.PADDING, + ) + } + if obj.LabelDimensions.Width != 0 { + // . ├────┤───────├────┤ + // . icon label icon + // with an icon in top left we need 2x the space to fit the label in the center + occupiedWidth *= 2 + occupiedWidth += float64(obj.LabelDimensions.Width) + 2*label.PADDING + if occupiedWidth > obj.Width { + dx = (occupiedWidth - obj.Width) / 2 + obj.Width = occupiedWidth + } + } + + // also check for grid cells with outside top labels or icons + // the first grid object is at the top (and always exists) + topY := gd.objects[0].TopLeft.Y + highestOutside := topY for _, o := range gd.objects { - toRemove[o] = struct{}{} - } - - // simple straight line edge routing between grid objects - for i, e := range g.Edges { - edgeOrder[e.AbsID()] = i - if !e.Src.Parent.IsDescendantOf(obj) && !e.Dst.Parent.IsDescendantOf(obj) { - continue + // we only want to compute label positions for objects at the top of the grid + if o.TopLeft.Y > topY { + if gd.rowDirected { + // if the grid is rowDirected (row1, row2, etc) we can stop after finishing the first row + break + } else { + // otherwise we continue until the next column + continue + } } - // if edge is within grid, remove it from outer layout - gd.edges = append(gd.edges, e) - edgeToRemove[e] = struct{}{} - - if e.Src.Parent != obj || e.Dst.Parent != obj { - continue + if o.LabelPosition != nil { + labelPosition := label.Position(*o.LabelPosition) + if labelPosition.IsOutside() { + labelTL := o.GetLabelTopLeft() + if labelTL.Y < highestOutside { + highestOutside = labelTL.Y + } + } } - // if edge is grid child, use simple routing - e.Route = []*geo.Point{e.Src.Center(), e.Dst.Center()} - e.TraceToShape(e.Route, 0, 1) - if e.Label.Value != "" { - e.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) + if o.IconPosition != nil { + switch label.Position(*o.IconPosition) { + case label.OutsideTopLeft, label.OutsideTopCenter, label.OutsideTopRight: + iconSpace := float64(d2target.MAX_ICON_SIZE + label.PADDING) + if topY-iconSpace < highestOutside { + highestOutside = topY - iconSpace + } + } } } + if highestOutside < topY { + occupiedHeight += topY - highestOutside + 2*label.PADDING + } + if occupiedHeight > float64(verticalPadding) { + // if the label doesn't fit within the padding, we need to add more + dy = occupiedHeight - float64(verticalPadding) + obj.Height += dy + } - return nil - } - - if len(g.Objects) > 0 { - queue := make([]*d2graph.Object, 1, len(g.Objects)) - queue[0] = g.Root - for len(queue) > 0 { - obj := queue[0] - queue = queue[1:] - if len(obj.ChildrenArray) == 0 { - continue - } - if !obj.IsGridDiagram() { - queue = append(queue, obj.ChildrenArray...) - continue - } - - if err := processGrid(obj); err != nil { - return nil, nil, nil, err - } + // we need to center children if we have to expand to fit the container label + if dx != 0 || dy != 0 { + gd.shift(dx, dy) } } - layoutObjects := make([]*d2graph.Object, 0, len(toRemove)) - for _, obj := range g.Objects { - if _, exists := toRemove[obj]; !exists { - layoutObjects = append(layoutObjects, obj) - } + if obj.HasLabel() { + obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) } - g.Objects = layoutObjects - layoutEdges := make([]*d2graph.Edge, 0, len(edgeToRemove)) + if obj.Icon != nil { + obj.IconPosition = go2.Pointer(string(label.InsideTopLeft)) + } + + // simple straight line edge routing between grid objects for _, e := range g.Edges { - if _, exists := edgeToRemove[e]; !exists { - layoutEdges = append(layoutEdges, e) + if !e.Src.Parent.IsDescendantOf(obj) && !e.Dst.Parent.IsDescendantOf(obj) { + continue + } + // if edge is within grid, remove it from outer layout + gd.edges = append(gd.edges, e) + + if e.Src.Parent != obj || e.Dst.Parent != obj { + continue + } + // if edge is grid child, use simple routing + e.Route = []*geo.Point{e.Src.Center(), e.Dst.Center()} + e.TraceToShape(e.Route, 0, 1) + if e.Label.Value != "" { + e.LabelPosition = go2.Pointer(string(label.InsideMiddleCenter)) } } - g.Edges = layoutEdges - return gridDiagrams, objectOrder, edgeOrder, nil + if g.Root.IsGridDiagram() && len(g.Root.ChildrenArray) != 0 { + g.Root.TopLeft = geo.NewPoint(0, 0) + } + + obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + + if g.RootLevel > 0 { + horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING + if obj.GridGap != nil || obj.HorizontalGap != nil { + horizontalPadding = gd.horizontalGap + } + if obj.GridGap != nil || obj.VerticalGap != nil { + verticalPadding = gd.verticalGap + } + + // shift the grid from (0, 0) + gd.shift( + obj.TopLeft.X+float64(horizontalPadding), + obj.TopLeft.Y+float64(verticalPadding), + ) + } + return nil } func layoutGrid(g *d2graph.Graph, obj *d2graph.Object) (*gridDiagram, error) { @@ -969,57 +871,3 @@ func getDistToTarget(layout [][]*d2graph.Object, targetSize float64, horizontalG } return totalDelta } - -// cleanup restores the graph after the core layout engine finishes -// - translating the grid to its position placed by the core layout engine -// - restore the children of the grid -// - sorts objects to their original graph order -func cleanup(graph *d2graph.Graph, gridDiagrams map[string]*gridDiagram, objectsOrder, edgeOrder map[string]int) { - defer func() { - sort.SliceStable(graph.Objects, func(i, j int) bool { - return objectsOrder[graph.Objects[i].AbsID()] < objectsOrder[graph.Objects[j].AbsID()] - }) - sort.SliceStable(graph.Edges, func(i, j int) bool { - return edgeOrder[graph.Edges[i].AbsID()] < edgeOrder[graph.Edges[j].AbsID()] - }) - }() - - var restore func(obj *d2graph.Object) - restore = func(obj *d2graph.Object) { - gd, exists := gridDiagrams[obj.AbsID()] - if !exists { - return - } - obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - - horizontalPadding, verticalPadding := CONTAINER_PADDING, CONTAINER_PADDING - if obj.GridGap != nil || obj.HorizontalGap != nil { - horizontalPadding = gd.horizontalGap - } - if obj.GridGap != nil || obj.VerticalGap != nil { - verticalPadding = gd.verticalGap - } - - // shift the grid from (0, 0) - gd.shift( - obj.TopLeft.X+float64(horizontalPadding), - obj.TopLeft.Y+float64(verticalPadding), - ) - 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) - } -} diff --git a/d2layouts/d2layouts.go b/d2layouts/d2layouts.go new file mode 100644 index 000000000..ff00222dc --- /dev/null +++ b/d2layouts/d2layouts.go @@ -0,0 +1,362 @@ +package d2layouts + +import ( + "context" + "math" + "sort" + "strings" + + "cdr.dev/slog" + + "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/d2layouts/d2grid" + "oss.terrastruct.com/d2/d2layouts/d2near" + "oss.terrastruct.com/d2/d2layouts/d2sequence" + "oss.terrastruct.com/d2/lib/geo" + "oss.terrastruct.com/d2/lib/log" +) + +type DiagramType string + +// a grid diagram at a constant near is +const ( + DefaultGraphType DiagramType = "" + ConstantNearGraph DiagramType = "constant-near" + GridDiagram DiagramType = "grid-diagram" + SequenceDiagram DiagramType = "sequence-diagram" +) + +type GraphInfo struct { + IsConstantNear bool + DiagramType DiagramType +} + +func (gi GraphInfo) isDefault() bool { + return !gi.IsConstantNear && gi.DiagramType == DefaultGraphType +} + +func SaveChildrenOrder(container *d2graph.Object) (restoreOrder func()) { + objectOrder := make(map[string]int, len(container.ChildrenArray)) + for i, obj := range container.ChildrenArray { + objectOrder[obj.AbsID()] = i + } + return func() { + sort.SliceStable(container.ChildrenArray, func(i, j int) bool { + return objectOrder[container.ChildrenArray[i].AbsID()] < objectOrder[container.ChildrenArray[j].AbsID()] + }) + } +} + +func SaveOrder(g *d2graph.Graph) (restoreOrder func()) { + objectOrder := make(map[string]int, len(g.Objects)) + for i, obj := range g.Objects { + objectOrder[obj.AbsID()] = i + } + edgeOrder := make(map[string]int, len(g.Edges)) + for i, edge := range g.Edges { + edgeOrder[edge.AbsID()] = i + } + restoreRootOrder := SaveChildrenOrder(g.Root) + return func() { + sort.SliceStable(g.Objects, func(i, j int) bool { + return objectOrder[g.Objects[i].AbsID()] < objectOrder[g.Objects[j].AbsID()] + }) + sort.SliceStable(g.Edges, func(i, j int) bool { + iIndex, iHas := edgeOrder[g.Edges[i].AbsID()] + jIndex, jHas := edgeOrder[g.Edges[j].AbsID()] + if iHas && jHas { + return iIndex < jIndex + } + return iHas + }) + restoreRootOrder() + } +} + +func LayoutNested(ctx context.Context, g *d2graph.Graph, graphInfo GraphInfo, coreLayout d2graph.LayoutGraph) error { + g.Root.Box = &geo.Box{} + + // Before we can layout these nodes, we need to handle all nested diagrams first. + extracted := make(map[*d2graph.Object]*d2graph.Graph) + var extractedOrder []*d2graph.Object + + var constantNears []*d2graph.Graph + restoreOrder := SaveOrder(g) + defer restoreOrder() + + // Iterate top-down from Root so all nested diagrams can process their own contents + queue := make([]*d2graph.Object, 0, len(g.Root.ChildrenArray)) + queue = append(queue, g.Root.ChildrenArray...) + + for len(queue) > 0 { + curr := queue[0] + queue = queue[1:] + + isGridCellContainer := graphInfo.DiagramType == GridDiagram && + curr.IsContainer() && curr.Parent == g.Root + gi := NestedGraphInfo(curr) + + if isGridCellContainer && gi.isDefault() { + // if we are in a grid diagram, and our children have descendants + // we need to run layout on them first, even if they are not special diagram types + nestedGraph := ExtractSubgraph(curr, true) + err := LayoutNested(ctx, nestedGraph, GraphInfo{}, coreLayout) + if err != nil { + return err + } + InjectNested(g.Root, nestedGraph, false) + restoreOrder() + dx := -curr.TopLeft.X + dy := -curr.TopLeft.Y + for _, o := range nestedGraph.Objects { + o.TopLeft.X += dx + o.TopLeft.Y += dy + } + for _, e := range nestedGraph.Edges { + e.Move(dx, dy) + } + continue + } + + if !gi.isDefault() { + // empty grid or sequence can have 0 objects.. + if !gi.IsConstantNear && len(curr.Children) == 0 { + continue + } + + // There is a nested diagram here, so extract its contents and process in the same way + nestedGraph := ExtractSubgraph(curr, gi.IsConstantNear) + + log.Info(ctx, "layout nested", slog.F("level", curr.Level()), slog.F("child", curr.AbsID()), slog.F("gi", gi)) + nestedInfo := gi + nearKey := curr.NearKey + if gi.IsConstantNear { + // layout nested as a non-near + nestedInfo = GraphInfo{} + curr.NearKey = nil + } + + err := LayoutNested(ctx, nestedGraph, nestedInfo, coreLayout) + if err != nil { + return err + } + + if gi.IsConstantNear { + curr.NearKey = nearKey + } else { + FitToGraph(curr, nestedGraph, geo.Spacing{}) + curr.TopLeft = geo.NewPoint(0, 0) + } + + if gi.IsConstantNear { + // near layout will inject these nestedGraphs + constantNears = append(constantNears, nestedGraph) + } else { + // We will restore the contents after running layout with child as the placeholder + extracted[curr] = nestedGraph + extractedOrder = append(extractedOrder, curr) + } + } else if len(curr.ChildrenArray) > 0 { + queue = append(queue, curr.ChildrenArray...) + } + } + + // We can now run layout with accurate sizes of nested layout containers + // Layout according to the type of diagram + var err error + switch graphInfo.DiagramType { + case GridDiagram: + log.Debug(ctx, "layout grid", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + if err = d2grid.Layout(ctx, g); err != nil { + return err + } + + case SequenceDiagram: + log.Debug(ctx, "layout sequence", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + err = d2sequence.Layout(ctx, g, coreLayout) + if err != nil { + return err + } + default: + log.Debug(ctx, "default layout", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + err := coreLayout(ctx, g) + if err != nil { + return err + } + } + + if len(constantNears) > 0 { + err := d2near.Layout(ctx, g, constantNears) + if err != nil { + panic(err) + } + } + + // With the layout set, inject all the extracted graphs + for _, n := range extractedOrder { + nestedGraph := extracted[n] + InjectNested(n, nestedGraph, true) + PositionNested(n, nestedGraph) + } + + log.Debug(ctx, "done", slog.F("rootlevel", g.RootLevel), slog.F("shapes", g.PrintString())) + return err +} + +func NestedGraphInfo(obj *d2graph.Object) (gi GraphInfo) { + if obj.Graph.RootLevel == 0 && obj.IsConstantNear() { + gi.IsConstantNear = true + } + if obj.IsSequenceDiagram() { + gi.DiagramType = SequenceDiagram + } else if obj.IsGridDiagram() { + gi.DiagramType = GridDiagram + } + return gi +} + +func ExtractSubgraph(container *d2graph.Object, includeSelf bool) *d2graph.Graph { + // includeSelf: when we have a constant near or a grid cell that is a container, + // we want to include itself in the nested graph, not just its descendants, + nestedGraph := d2graph.NewGraph() + nestedGraph.RootLevel = int(container.Level()) + if includeSelf { + nestedGraph.RootLevel-- + } + nestedGraph.Root.Attributes = container.Attributes + nestedGraph.Root.Box = &geo.Box{} + + isNestedObject := func(obj *d2graph.Object) bool { + if includeSelf { + return obj.IsDescendantOf(container) + } + return obj.Parent.IsDescendantOf(container) + } + + // separate out nested edges + g := container.Graph + remainingEdges := make([]*d2graph.Edge, 0, len(g.Edges)) + for _, edge := range g.Edges { + if isNestedObject(edge.Src) && isNestedObject(edge.Dst) { + nestedGraph.Edges = append(nestedGraph.Edges, edge) + } else { + remainingEdges = append(remainingEdges, edge) + } + } + g.Edges = remainingEdges + + // separate out nested objects + remainingObjects := make([]*d2graph.Object, 0, len(g.Objects)) + for _, obj := range g.Objects { + if isNestedObject(obj) { + nestedGraph.Objects = append(nestedGraph.Objects, obj) + } else { + remainingObjects = append(remainingObjects, obj) + } + } + g.Objects = remainingObjects + + // update object and new root references + for _, o := range nestedGraph.Objects { + o.Graph = nestedGraph + } + + if includeSelf { + // remove container parent's references + if container.Parent != nil { + container.Parent.RemoveChild(container) + } + + // set root references + nestedGraph.Root.ChildrenArray = []*d2graph.Object{container} + container.Parent = nestedGraph.Root + nestedGraph.Root.Children[strings.ToLower(container.ID)] = container + } else { + // set root references + nestedGraph.Root.ChildrenArray = append(nestedGraph.Root.ChildrenArray, container.ChildrenArray...) + for _, child := range container.ChildrenArray { + child.Parent = nestedGraph.Root + nestedGraph.Root.Children[strings.ToLower(child.ID)] = child + } + + // remove container's references + for k := range container.Children { + delete(container.Children, k) + } + container.ChildrenArray = nil + } + + return nestedGraph +} + +func InjectNested(container *d2graph.Object, nestedGraph *d2graph.Graph, isRoot bool) { + // TODO restore order of objects + g := container.Graph + for _, obj := range nestedGraph.Root.ChildrenArray { + obj.Parent = container + container.Children[strings.ToLower(obj.ID)] = obj + container.ChildrenArray = append(container.ChildrenArray, obj) + } + for _, obj := range nestedGraph.Objects { + obj.Graph = g + } + g.Objects = append(g.Objects, nestedGraph.Objects...) + g.Edges = append(g.Edges, nestedGraph.Edges...) + + if isRoot { + if nestedGraph.Root.LabelPosition != nil { + container.LabelPosition = nestedGraph.Root.LabelPosition + } + if nestedGraph.Root.IconPosition != nil { + container.IconPosition = nestedGraph.Root.IconPosition + } + container.Attributes = nestedGraph.Root.Attributes + } +} + +func PositionNested(container *d2graph.Object, nestedGraph *d2graph.Graph) { + // tl, _ := boundingBox(nestedGraph) + // Note: assumes nestedGraph's layout has contents positioned relative to 0,0 + dx := container.TopLeft.X //- tl.X + dy := container.TopLeft.Y //- tl.Y + for _, o := range nestedGraph.Objects { + o.TopLeft.X += dx + o.TopLeft.Y += dy + } + for _, e := range nestedGraph.Edges { + e.Move(dx, dy) + } +} + +func boundingBox(g *d2graph.Graph) (tl, br *geo.Point) { + if len(g.Objects) == 0 { + return geo.NewPoint(0, 0), geo.NewPoint(0, 0) + } + tl = geo.NewPoint(math.Inf(1), math.Inf(1)) + br = geo.NewPoint(math.Inf(-1), math.Inf(-1)) + + for _, obj := range g.Objects { + if obj.TopLeft == nil { + panic(obj.AbsID()) + } + tl.X = math.Min(tl.X, obj.TopLeft.X) + tl.Y = math.Min(tl.Y, obj.TopLeft.Y) + br.X = math.Max(br.X, obj.TopLeft.X+obj.Width) + br.Y = math.Max(br.Y, obj.TopLeft.Y+obj.Height) + } + + return tl, br +} + +func FitToGraph(container *d2graph.Object, nestedGraph *d2graph.Graph, padding geo.Spacing) { + var width, height float64 + width = nestedGraph.Root.Width + height = nestedGraph.Root.Height + if width == 0 || height == 0 { + tl, br := boundingBox(nestedGraph) + width = br.X - tl.X + height = br.Y - tl.Y + } + container.Width = padding.Left + width + padding.Right + container.Height = padding.Top + height + padding.Bottom +} diff --git a/d2layouts/d2near/layout.go b/d2layouts/d2near/layout.go index 190317542..a3baaee65 100644 --- a/d2layouts/d2near/layout.go +++ b/d2layouts/d2near/layout.go @@ -145,28 +145,6 @@ func place(obj *d2graph.Object) (float64, float64) { return x, y } -// WithoutConstantNears plucks out the graph objects which have "near" set to a constant value -// This is to be called before layout engines so they don't take part in regular positioning -func WithoutConstantNears(ctx context.Context, g *d2graph.Graph) (constantNearGraphs []*d2graph.Graph) { - for i := 0; i < len(g.Objects); i++ { - obj := g.Objects[i] - if obj.NearKey == nil { - continue - } - _, isKey := g.Root.HasChild(d2graph.Key(obj.NearKey)) - if isKey { - continue - } - _, isConst := d2graph.NearConstants[d2graph.Key(obj.NearKey)[0]] - if isConst { - tempGraph := g.ExtractAsNestedGraph(obj) - constantNearGraphs = append(constantNearGraphs, tempGraph) - i-- - } - } - return constantNearGraphs -} - // 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 // It differs from d2target.BoundingBox which needs to include every visible thing diff --git a/d2layouts/d2sequence/layout.go b/d2layouts/d2sequence/layout.go index 24427914b..ccbe9df2e 100644 --- a/d2layouts/d2sequence/layout.go +++ b/d2layouts/d2sequence/layout.go @@ -2,7 +2,6 @@ package d2sequence import ( "context" - "sort" "strings" "oss.terrastruct.com/util-go/go2" @@ -15,85 +14,50 @@ import ( // Layout runs the sequence diagram layout engine on objects of shape sequence_diagram // -// 1. Traverse graph from root, skip objects with shape not `sequence_diagram` -// 2. Construct a sequence diagram from all descendant objects and edges -// 3. Remove those objects and edges from the main graph -// 4. Run layout on sequence diagrams -// 5. Set the resulting dimensions to the main graph shape -// 6. Run core layouts (still without sequence diagram innards) -// 7. Put back sequence diagram innards in correct location +// 1. Run layout on sequence diagrams +// 2. Set the resulting dimensions to the main graph shape func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) error { - sequenceDiagrams, objectOrder, edgeOrder, err := WithoutSequenceDiagrams(ctx, g) + // used in layout code + g.Root.Shape.Value = d2target.ShapeSequenceDiagram + + sd, err := layoutSequenceDiagram(g, g.Root) if err != nil { return err } + g.Root.Box = geo.NewBox(nil, sd.getWidth()+GROUP_CONTAINER_PADDING*2, sd.getHeight()+GROUP_CONTAINER_PADDING*2) - if g.Root.IsSequenceDiagram() { - // the sequence diagram is the only layout engine if the whole diagram is - // shape: sequence_diagram - g.Root.TopLeft = geo.NewPoint(0, 0) - } else if err := layout(ctx, g); err != nil { - return err + // the sequence diagram is the only layout engine if the whole diagram is + // shape: sequence_diagram + g.Root.TopLeft = geo.NewPoint(0, 0) + + obj := g.Root + + obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) + + // shift the sequence diagrams as they are always placed at (0, 0) with some padding + sd.shift( + geo.NewPoint( + obj.TopLeft.X+GROUP_CONTAINER_PADDING, + obj.TopLeft.Y+GROUP_CONTAINER_PADDING, + ), + ) + + obj.Children = make(map[string]*d2graph.Object) + obj.ChildrenArray = make([]*d2graph.Object, 0) + for _, child := range sd.actors { + obj.Children[strings.ToLower(child.ID)] = child + obj.ChildrenArray = append(obj.ChildrenArray, child) } - - cleanup(g, sequenceDiagrams, objectOrder, edgeOrder) - return nil -} - -func WithoutSequenceDiagrams(ctx context.Context, g *d2graph.Graph) (map[string]*sequenceDiagram, map[string]int, map[string]int, error) { - objectsToRemove := make(map[*d2graph.Object]struct{}) - edgesToRemove := make(map[*d2graph.Edge]struct{}) - sequenceDiagrams := make(map[string]*sequenceDiagram) - - if len(g.Objects) > 0 { - queue := make([]*d2graph.Object, 1, len(g.Objects)) - queue[0] = g.Root - for len(queue) > 0 { - obj := queue[0] - queue = queue[1:] - if len(obj.ChildrenArray) == 0 { - continue - } - if obj.Shape.Value != d2target.ShapeSequenceDiagram { - queue = append(queue, obj.ChildrenArray...) - continue - } - - sd, err := layoutSequenceDiagram(g, obj) - if err != nil { - return nil, nil, nil, err - } - obj.Children = make(map[string]*d2graph.Object) - obj.ChildrenArray = nil - obj.Box = geo.NewBox(nil, sd.getWidth()+GROUP_CONTAINER_PADDING*2, sd.getHeight()+GROUP_CONTAINER_PADDING*2) - obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - sequenceDiagrams[obj.AbsID()] = sd - - for _, edge := range sd.messages { - edgesToRemove[edge] = struct{}{} - } - for _, obj := range sd.actors { - objectsToRemove[obj] = struct{}{} - } - for _, obj := range sd.notes { - objectsToRemove[obj] = struct{}{} - } - for _, obj := range sd.groups { - objectsToRemove[obj] = struct{}{} - } - for _, obj := range sd.spans { - objectsToRemove[obj] = struct{}{} - } + for _, child := range sd.groups { + if child.Parent.AbsID() == obj.AbsID() { + obj.Children[strings.ToLower(child.ID)] = child + obj.ChildrenArray = append(obj.ChildrenArray, child) } } - layoutEdges, edgeOrder := getLayoutEdges(g, edgesToRemove) - g.Edges = layoutEdges - layoutObjects, objectOrder := getLayoutObjects(g, objectsToRemove) - // TODO this isn't a proper deletion because the objects still appear as children of the object - g.Objects = layoutObjects + g.Edges = append(g.Edges, sd.lifelines...) - return sequenceDiagrams, objectOrder, edgeOrder, nil + return nil } // layoutSequenceDiagram finds the edges inside the sequence diagram and performs the layout on the object descendants @@ -113,97 +77,3 @@ func layoutSequenceDiagram(g *d2graph.Graph, obj *d2graph.Object) (*sequenceDiag err = sd.layout() return sd, err } - -func getLayoutEdges(g *d2graph.Graph, toRemove map[*d2graph.Edge]struct{}) ([]*d2graph.Edge, map[string]int) { - edgeOrder := make(map[string]int) - layoutEdges := make([]*d2graph.Edge, 0, len(g.Edges)-len(toRemove)) - - for i, edge := range g.Edges { - edgeOrder[edge.AbsID()] = i - if _, exists := toRemove[edge]; !exists { - layoutEdges = append(layoutEdges, edge) - } - } - return layoutEdges, edgeOrder -} - -func getLayoutObjects(g *d2graph.Graph, toRemove map[*d2graph.Object]struct{}) ([]*d2graph.Object, map[string]int) { - objectOrder := make(map[string]int) - layoutObjects := make([]*d2graph.Object, 0, len(toRemove)) - for i, obj := range g.Objects { - objectOrder[obj.AbsID()] = i - if _, exists := toRemove[obj]; !exists { - layoutObjects = append(layoutObjects, obj) - } - } - return layoutObjects, objectOrder -} - -// cleanup restores the graph after the core layout engine finishes -// - translating the sequence diagram to its position placed by the core layout engine -// - restore the children of the sequence diagram graph object -// - adds the sequence diagram edges (messages) back to the graph -// - adds the sequence diagram lifelines to the graph edges -// - adds the sequence diagram descendants back to the graph objects -// - sorts edges and objects to their original graph order -func cleanup(g *d2graph.Graph, sequenceDiagrams map[string]*sequenceDiagram, objectsOrder, edgesOrder map[string]int) { - var objects []*d2graph.Object - if g.Root.IsSequenceDiagram() { - objects = []*d2graph.Object{g.Root} - } else { - objects = g.Objects - } - for _, obj := range objects { - sd, exists := sequenceDiagrams[obj.AbsID()] - if !exists { - continue - } - obj.LabelPosition = go2.Pointer(string(label.InsideTopCenter)) - - // shift the sequence diagrams as they are always placed at (0, 0) with some padding - sd.shift( - geo.NewPoint( - obj.TopLeft.X+GROUP_CONTAINER_PADDING, - obj.TopLeft.Y+GROUP_CONTAINER_PADDING, - ), - ) - - obj.Children = make(map[string]*d2graph.Object) - obj.ChildrenArray = make([]*d2graph.Object, 0) - for _, child := range sd.actors { - obj.Children[strings.ToLower(child.ID)] = child - obj.ChildrenArray = append(obj.ChildrenArray, child) - } - for _, child := range sd.groups { - if child.Parent.AbsID() == obj.AbsID() { - obj.Children[strings.ToLower(child.ID)] = child - obj.ChildrenArray = append(obj.ChildrenArray, child) - } - } - - g.Edges = append(g.Edges, sd.messages...) - g.Edges = append(g.Edges, sd.lifelines...) - g.Objects = append(g.Objects, sd.actors...) - g.Objects = append(g.Objects, sd.notes...) - g.Objects = append(g.Objects, sd.groups...) - g.Objects = append(g.Objects, sd.spans...) - } - - // no new objects, so just keep the same position - sort.SliceStable(g.Objects, func(i, j int) bool { - return objectsOrder[g.Objects[i].AbsID()] < objectsOrder[g.Objects[j].AbsID()] - }) - - // sequence diagrams add lifelines, and they must be the last ones in this slice - sort.SliceStable(g.Edges, func(i, j int) bool { - iOrder, iExists := edgesOrder[g.Edges[i].AbsID()] - jOrder, jExists := edgesOrder[g.Edges[j].AbsID()] - if iExists && jExists { - return iOrder < jOrder - } else if iExists && !jExists { - return true - } - // either both don't exist or i doesn't exist and j exists - return false - }) -} diff --git a/d2lib/d2.go b/d2lib/d2.go index c34eb9206..7115a7ffd 100644 --- a/d2lib/d2.go +++ b/d2lib/d2.go @@ -10,10 +10,8 @@ import ( "oss.terrastruct.com/d2/d2compiler" "oss.terrastruct.com/d2/d2exporter" "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/d2layouts" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" - "oss.terrastruct.com/d2/d2layouts/d2grid" - "oss.terrastruct.com/d2/d2layouts/d2near" - "oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/d2renderers/d2fonts" "oss.terrastruct.com/d2/d2renderers/d2svg" "oss.terrastruct.com/d2/d2target" @@ -84,23 +82,8 @@ func compile(ctx context.Context, g *d2graph.Graph, compileOpts *CompileOptions, return nil, err } - constantNearGraphs := d2near.WithoutConstantNears(ctx, g) - - layoutWithGrids := d2grid.Layout(ctx, g, coreLayout) - - // run core layout for constantNears - for _, tempGraph := range constantNearGraphs { - if err = layoutWithGrids(ctx, tempGraph); err != nil { - return nil, err - } - } - - err = d2sequence.Layout(ctx, g, layoutWithGrids) - if err != nil { - return nil, err - } - - err = d2near.Layout(ctx, g, constantNearGraphs) + graphInfo := d2layouts.NestedGraphInfo(g.Root) + err = d2layouts.LayoutNested(ctx, g, graphInfo, coreLayout) if err != nil { return nil, err } diff --git a/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg b/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg index 477f27ce8..8b87d6a30 100644 --- a/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg @@ -1,20 +1,20 @@ - @@ -844,20 +844,20 @@ -OEM FactoryOEM WarehouseDistributor Warehousecompany WarehouseFlow-I (Warehousing, Installation)MasterRegional-1Regional-2Regional-N

company Warehouse

+Flow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor Warehousecompany WarehouseMasterRegional-1Regional-2Regional-N

company Warehouse

  • Asset Tagging
  • Inventory
  • Staging
  • Dispatch to Site
-
+
+ - diff --git a/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg index f6216f287..4b287519e 100644 --- a/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg +++ b/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg @@ -1,16 +1,16 @@ Chicken's plan +}]]>Chicken's plan -Approach roadChicken's plan +Chicken's planApproach road - -Approach roadCross roadChicken's plan + +Chicken's planApproach roadCross road + - -Approach roadCross roadMake you wonder whyChicken's plan +Chicken's planApproach roadCross roadMake you wonder why + - \ No newline at end of file diff --git a/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg index 8ec9e5a88..a38d833e5 100644 --- a/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg +++ b/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg @@ -1,16 +1,16 @@ CHICKEN'S PLAN +}]]>CHICKEN'S PLAN -APPROACH ROADCHICKEN'S PLAN +CHICKEN'S PLANAPPROACH ROAD - -APPROACH ROADCROSS ROADCHICKEN'S PLAN + +CHICKEN'S PLANAPPROACH ROADCROSS ROAD + - -APPROACH ROADCROSS ROADMAKE YOU WONDER WHYCHICKEN'S PLAN +CHICKEN'S PLANAPPROACH ROADCROSS ROADMAKE YOU WONDER WHY + - \ No newline at end of file diff --git a/e2etests/e2e_test.go b/e2etests/e2e_test.go index 2eaa799af..7d8a45c5d 100644 --- a/e2etests/e2e_test.go +++ b/e2etests/e2e_test.go @@ -21,8 +21,6 @@ import ( "oss.terrastruct.com/d2/d2graph" "oss.terrastruct.com/d2/d2layouts/d2dagrelayout" "oss.terrastruct.com/d2/d2layouts/d2elklayout" - "oss.terrastruct.com/d2/d2layouts/d2near" - "oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/d2lib" "oss.terrastruct.com/d2/d2plugin" "oss.terrastruct.com/d2/d2renderers/d2animate" @@ -108,8 +106,6 @@ func runa(t *testing.T, tcs []testCase) { // serde exercises serializing and deserializing the graph // We want to run all the steps leading up to serialization in the course of regular layout func serde(t *testing.T, tc testCase, ruler *textmeasure.Ruler) { - ctx := context.Background() - ctx = log.WithTB(ctx, t, nil) g, _, err := d2compiler.Compile("", strings.NewReader(tc.script), &d2compiler.CompileOptions{ UTF16Pos: false, }) @@ -117,8 +113,6 @@ func serde(t *testing.T, tc testCase, ruler *textmeasure.Ruler) { if len(g.Objects) > 0 { err = g.SetDimensions(nil, ruler, nil) trequire.Nil(t, err) - d2near.WithoutConstantNears(ctx, g) - d2sequence.WithoutSequenceDiagrams(ctx, g) } b, err := d2graph.SerializeGraph(g) trequire.Nil(t, err) diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go index 0e82cb2a6..517fd91f2 100644 --- a/e2etests/stable_test.go +++ b/e2etests/stable_test.go @@ -2835,6 +2835,7 @@ y: profits { loadFromFile(t, "dagre_spacing_right"), loadFromFile(t, "simple_grid_edges"), loadFromFile(t, "grid_nested_simple_edges"), + loadFromFile(t, "nested_diagram_types"), } runa(t, tcs) diff --git a/e2etests/testdata/files/nested_diagram_types.d2 b/e2etests/testdata/files/nested_diagram_types.d2 new file mode 100644 index 000000000..a63eacd7d --- /dev/null +++ b/e2etests/testdata/files/nested_diagram_types.d2 @@ -0,0 +1,48 @@ +a +b +c + +a: { + grid-columns: 3 + + 1 + 2 + 3 + 3: { + shape: sequence_diagram + x + y + # TODO x -> y + } + + 1 -> 2 -> 3 + + near: center-right +} + +b: { + shape: sequence_diagram + 1 -> 2 + + near: bottom-right + + 2: { + # TODO compile error grid on sequence actor? + grid-columns: 3 + x + y + z + } + + 1: { + x: { + # TODO compile error grid in sequence (group) + # grid-columns: 3 + u + v + w + } + y + z + } +} diff --git a/e2etests/testdata/regression/multiple_constant_nears/dagre/board.exp.json b/e2etests/testdata/regression/multiple_constant_nears/dagre/board.exp.json index d20cfdc39..d6231ed4b 100644 --- a/e2etests/testdata/regression/multiple_constant_nears/dagre/board.exp.json +++ b/e2etests/testdata/regression/multiple_constant_nears/dagre/board.exp.json @@ -3,47 +3,6 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "c", - "type": "rectangle", - "pos": { - "x": 0, - "y": 0 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B6", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "a", "type": "rectangle", @@ -85,6 +44,88 @@ "zIndex": 0, "level": 1 }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 73, + "y": 318 + }, + "width": 139, + "height": 292, + "opacity": 0.5, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "green", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, { "id": "a.1", "type": "rectangle", @@ -208,47 +249,6 @@ "zIndex": 0, "level": 2 }, - { - "id": "b", - "type": "rectangle", - "pos": { - "x": 73, - "y": 318 - }, - "width": 139, - "height": 292, - "opacity": 0.5, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "green", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 13, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "b.1111", "type": "rectangle", diff --git a/e2etests/testdata/regression/multiple_constant_nears/dagre/sketch.exp.svg b/e2etests/testdata/regression/multiple_constant_nears/dagre/sketch.exp.svg index 310f04aac..59453e7ae 100644 --- a/e2etests/testdata/regression/multiple_constant_nears/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/multiple_constant_nears/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -cab12311112222 + .d2-114303792 .fill-N1{fill:#0A0F25;} + .d2-114303792 .fill-N2{fill:#676C7E;} + .d2-114303792 .fill-N3{fill:#9499AB;} + .d2-114303792 .fill-N4{fill:#CFD2DD;} + .d2-114303792 .fill-N5{fill:#DEE1EB;} + .d2-114303792 .fill-N6{fill:#EEF1F8;} + .d2-114303792 .fill-N7{fill:#FFFFFF;} + .d2-114303792 .fill-B1{fill:#0D32B2;} + .d2-114303792 .fill-B2{fill:#0D32B2;} + .d2-114303792 .fill-B3{fill:#E3E9FD;} + .d2-114303792 .fill-B4{fill:#E3E9FD;} + .d2-114303792 .fill-B5{fill:#EDF0FD;} + .d2-114303792 .fill-B6{fill:#F7F8FE;} + .d2-114303792 .fill-AA2{fill:#4A6FF3;} + .d2-114303792 .fill-AA4{fill:#EDF0FD;} + .d2-114303792 .fill-AA5{fill:#F7F8FE;} + .d2-114303792 .fill-AB4{fill:#EDF0FD;} + .d2-114303792 .fill-AB5{fill:#F7F8FE;} + .d2-114303792 .stroke-N1{stroke:#0A0F25;} + .d2-114303792 .stroke-N2{stroke:#676C7E;} + .d2-114303792 .stroke-N3{stroke:#9499AB;} + .d2-114303792 .stroke-N4{stroke:#CFD2DD;} + .d2-114303792 .stroke-N5{stroke:#DEE1EB;} + .d2-114303792 .stroke-N6{stroke:#EEF1F8;} + .d2-114303792 .stroke-N7{stroke:#FFFFFF;} + .d2-114303792 .stroke-B1{stroke:#0D32B2;} + .d2-114303792 .stroke-B2{stroke:#0D32B2;} + .d2-114303792 .stroke-B3{stroke:#E3E9FD;} + .d2-114303792 .stroke-B4{stroke:#E3E9FD;} + .d2-114303792 .stroke-B5{stroke:#EDF0FD;} + .d2-114303792 .stroke-B6{stroke:#F7F8FE;} + .d2-114303792 .stroke-AA2{stroke:#4A6FF3;} + .d2-114303792 .stroke-AA4{stroke:#EDF0FD;} + .d2-114303792 .stroke-AA5{stroke:#F7F8FE;} + .d2-114303792 .stroke-AB4{stroke:#EDF0FD;} + .d2-114303792 .stroke-AB5{stroke:#F7F8FE;} + .d2-114303792 .background-color-N1{background-color:#0A0F25;} + .d2-114303792 .background-color-N2{background-color:#676C7E;} + .d2-114303792 .background-color-N3{background-color:#9499AB;} + .d2-114303792 .background-color-N4{background-color:#CFD2DD;} + .d2-114303792 .background-color-N5{background-color:#DEE1EB;} + .d2-114303792 .background-color-N6{background-color:#EEF1F8;} + .d2-114303792 .background-color-N7{background-color:#FFFFFF;} + .d2-114303792 .background-color-B1{background-color:#0D32B2;} + .d2-114303792 .background-color-B2{background-color:#0D32B2;} + .d2-114303792 .background-color-B3{background-color:#E3E9FD;} + .d2-114303792 .background-color-B4{background-color:#E3E9FD;} + .d2-114303792 .background-color-B5{background-color:#EDF0FD;} + .d2-114303792 .background-color-B6{background-color:#F7F8FE;} + .d2-114303792 .background-color-AA2{background-color:#4A6FF3;} + .d2-114303792 .background-color-AA4{background-color:#EDF0FD;} + .d2-114303792 .background-color-AA5{background-color:#F7F8FE;} + .d2-114303792 .background-color-AB4{background-color:#EDF0FD;} + .d2-114303792 .background-color-AB5{background-color:#F7F8FE;} + .d2-114303792 .color-N1{color:#0A0F25;} + .d2-114303792 .color-N2{color:#676C7E;} + .d2-114303792 .color-N3{color:#9499AB;} + .d2-114303792 .color-N4{color:#CFD2DD;} + .d2-114303792 .color-N5{color:#DEE1EB;} + .d2-114303792 .color-N6{color:#EEF1F8;} + .d2-114303792 .color-N7{color:#FFFFFF;} + .d2-114303792 .color-B1{color:#0D32B2;} + .d2-114303792 .color-B2{color:#0D32B2;} + .d2-114303792 .color-B3{color:#E3E9FD;} + .d2-114303792 .color-B4{color:#E3E9FD;} + .d2-114303792 .color-B5{color:#EDF0FD;} + .d2-114303792 .color-B6{color:#F7F8FE;} + .d2-114303792 .color-AA2{color:#4A6FF3;} + .d2-114303792 .color-AA4{color:#EDF0FD;} + .d2-114303792 .color-AA5{color:#F7F8FE;} + .d2-114303792 .color-AB4{color:#EDF0FD;} + .d2-114303792 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>abc12311112222 - + diff --git a/e2etests/testdata/regression/multiple_constant_nears/elk/board.exp.json b/e2etests/testdata/regression/multiple_constant_nears/elk/board.exp.json index d80cd5430..2ce891239 100644 --- a/e2etests/testdata/regression/multiple_constant_nears/elk/board.exp.json +++ b/e2etests/testdata/regression/multiple_constant_nears/elk/board.exp.json @@ -3,47 +3,6 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "c", - "type": "rectangle", - "pos": { - "x": 12, - "y": 12 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B6", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "a", "type": "rectangle", @@ -85,6 +44,88 @@ "zIndex": 0, "level": 1 }, + { + "id": "b", + "type": "rectangle", + "pos": { + "x": 85, + "y": 284 + }, + "width": 179, + "height": 302, + "opacity": 0.5, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "green", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, { "id": "a.1", "type": "rectangle", @@ -208,47 +249,6 @@ "zIndex": 0, "level": 2 }, - { - "id": "b", - "type": "rectangle", - "pos": { - "x": 85, - "y": 284 - }, - "width": 179, - "height": 302, - "opacity": 0.5, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "green", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 13, - "labelHeight": 36, - "labelPosition": "INSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, { "id": "b.1111", "type": "rectangle", diff --git a/e2etests/testdata/regression/multiple_constant_nears/elk/sketch.exp.svg b/e2etests/testdata/regression/multiple_constant_nears/elk/sketch.exp.svg index fa774803d..9f669ad5d 100644 --- a/e2etests/testdata/regression/multiple_constant_nears/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/multiple_constant_nears/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -cab12311112222 + .d2-1840765879 .fill-N1{fill:#0A0F25;} + .d2-1840765879 .fill-N2{fill:#676C7E;} + .d2-1840765879 .fill-N3{fill:#9499AB;} + .d2-1840765879 .fill-N4{fill:#CFD2DD;} + .d2-1840765879 .fill-N5{fill:#DEE1EB;} + .d2-1840765879 .fill-N6{fill:#EEF1F8;} + .d2-1840765879 .fill-N7{fill:#FFFFFF;} + .d2-1840765879 .fill-B1{fill:#0D32B2;} + .d2-1840765879 .fill-B2{fill:#0D32B2;} + .d2-1840765879 .fill-B3{fill:#E3E9FD;} + .d2-1840765879 .fill-B4{fill:#E3E9FD;} + .d2-1840765879 .fill-B5{fill:#EDF0FD;} + .d2-1840765879 .fill-B6{fill:#F7F8FE;} + .d2-1840765879 .fill-AA2{fill:#4A6FF3;} + .d2-1840765879 .fill-AA4{fill:#EDF0FD;} + .d2-1840765879 .fill-AA5{fill:#F7F8FE;} + .d2-1840765879 .fill-AB4{fill:#EDF0FD;} + .d2-1840765879 .fill-AB5{fill:#F7F8FE;} + .d2-1840765879 .stroke-N1{stroke:#0A0F25;} + .d2-1840765879 .stroke-N2{stroke:#676C7E;} + .d2-1840765879 .stroke-N3{stroke:#9499AB;} + .d2-1840765879 .stroke-N4{stroke:#CFD2DD;} + .d2-1840765879 .stroke-N5{stroke:#DEE1EB;} + .d2-1840765879 .stroke-N6{stroke:#EEF1F8;} + .d2-1840765879 .stroke-N7{stroke:#FFFFFF;} + .d2-1840765879 .stroke-B1{stroke:#0D32B2;} + .d2-1840765879 .stroke-B2{stroke:#0D32B2;} + .d2-1840765879 .stroke-B3{stroke:#E3E9FD;} + .d2-1840765879 .stroke-B4{stroke:#E3E9FD;} + .d2-1840765879 .stroke-B5{stroke:#EDF0FD;} + .d2-1840765879 .stroke-B6{stroke:#F7F8FE;} + .d2-1840765879 .stroke-AA2{stroke:#4A6FF3;} + .d2-1840765879 .stroke-AA4{stroke:#EDF0FD;} + .d2-1840765879 .stroke-AA5{stroke:#F7F8FE;} + .d2-1840765879 .stroke-AB4{stroke:#EDF0FD;} + .d2-1840765879 .stroke-AB5{stroke:#F7F8FE;} + .d2-1840765879 .background-color-N1{background-color:#0A0F25;} + .d2-1840765879 .background-color-N2{background-color:#676C7E;} + .d2-1840765879 .background-color-N3{background-color:#9499AB;} + .d2-1840765879 .background-color-N4{background-color:#CFD2DD;} + .d2-1840765879 .background-color-N5{background-color:#DEE1EB;} + .d2-1840765879 .background-color-N6{background-color:#EEF1F8;} + .d2-1840765879 .background-color-N7{background-color:#FFFFFF;} + .d2-1840765879 .background-color-B1{background-color:#0D32B2;} + .d2-1840765879 .background-color-B2{background-color:#0D32B2;} + .d2-1840765879 .background-color-B3{background-color:#E3E9FD;} + .d2-1840765879 .background-color-B4{background-color:#E3E9FD;} + .d2-1840765879 .background-color-B5{background-color:#EDF0FD;} + .d2-1840765879 .background-color-B6{background-color:#F7F8FE;} + .d2-1840765879 .background-color-AA2{background-color:#4A6FF3;} + .d2-1840765879 .background-color-AA4{background-color:#EDF0FD;} + .d2-1840765879 .background-color-AA5{background-color:#F7F8FE;} + .d2-1840765879 .background-color-AB4{background-color:#EDF0FD;} + .d2-1840765879 .background-color-AB5{background-color:#F7F8FE;} + .d2-1840765879 .color-N1{color:#0A0F25;} + .d2-1840765879 .color-N2{color:#676C7E;} + .d2-1840765879 .color-N3{color:#9499AB;} + .d2-1840765879 .color-N4{color:#CFD2DD;} + .d2-1840765879 .color-N5{color:#DEE1EB;} + .d2-1840765879 .color-N6{color:#EEF1F8;} + .d2-1840765879 .color-N7{color:#FFFFFF;} + .d2-1840765879 .color-B1{color:#0D32B2;} + .d2-1840765879 .color-B2{color:#0D32B2;} + .d2-1840765879 .color-B3{color:#E3E9FD;} + .d2-1840765879 .color-B4{color:#E3E9FD;} + .d2-1840765879 .color-B5{color:#EDF0FD;} + .d2-1840765879 .color-B6{color:#F7F8FE;} + .d2-1840765879 .color-AA2{color:#4A6FF3;} + .d2-1840765879 .color-AA4{color:#EDF0FD;} + .d2-1840765879 .color-AA5{color:#F7F8FE;} + .d2-1840765879 .color-AB4{color:#EDF0FD;} + .d2-1840765879 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>abc12311112222 - + diff --git a/e2etests/testdata/regression/unconnected/dagre/board.exp.json b/e2etests/testdata/regression/unconnected/dagre/board.exp.json index c247f0d23..1ab1067fa 100644 --- a/e2etests/testdata/regression/unconnected/dagre/board.exp.json +++ b/e2etests/testdata/regression/unconnected/dagre/board.exp.json @@ -3,6 +3,46 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ + { + "id": "title", + "type": "text", + "pos": { + "x": 438, + "y": -56 + }, + "width": 639, + "height": 51, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Workflow-I (Warehousing, Installation)", + "fontSize": 40, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 639, + "labelHeight": 51, + "zIndex": 0, + "level": 1 + }, { "id": "OEM Factory", "type": "rectangle", @@ -493,46 +533,6 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 - }, - { - "id": "title", - "type": "text", - "pos": { - "x": 438, - "y": -56 - }, - "width": 639, - "height": 51, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "Workflow-I (Warehousing, Installation)", - "fontSize": 40, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 639, - "labelHeight": 51, - "zIndex": 0, - "level": 1 } ], "connections": [ diff --git a/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg b/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg index 33754aad7..c861d0812 100644 --- a/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteWorkflow-I (Warehousing, Installation)MasterRegional-1Regional-2Regional-N
    +Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
    • Asset Tagging
    • Inventory
    • Staging
    • Dispatch to Site
    -
    InstallationSupport +
InstallationSupport + - diff --git a/e2etests/testdata/regression/unconnected/elk/board.exp.json b/e2etests/testdata/regression/unconnected/elk/board.exp.json index a30837f37..d45f7a548 100644 --- a/e2etests/testdata/regression/unconnected/elk/board.exp.json +++ b/e2etests/testdata/regression/unconnected/elk/board.exp.json @@ -3,6 +3,46 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ + { + "id": "title", + "type": "text", + "pos": { + "x": 482, + "y": -59 + }, + "width": 639, + "height": 51, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Workflow-I (Warehousing, Installation)", + "fontSize": 40, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 639, + "labelHeight": 51, + "zIndex": 0, + "level": 1 + }, { "id": "OEM Factory", "type": "rectangle", @@ -493,46 +533,6 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 2 - }, - { - "id": "title", - "type": "text", - "pos": { - "x": 482, - "y": -59 - }, - "width": 639, - "height": 51, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "Workflow-I (Warehousing, Installation)", - "fontSize": 40, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 639, - "labelHeight": 51, - "zIndex": 0, - "level": 1 } ], "connections": [ diff --git a/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg b/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg index 17ae95cfa..a1101fced 100644 --- a/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteWorkflow-I (Warehousing, Installation)MasterRegional-1Regional-2Regional-N
    +Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
    • Asset Tagging
    • Inventory
    • Staging
    • Dispatch to Site
    -
    InstallationSupport +
InstallationSupport + - diff --git a/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json b/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json index b81735f0e..b550af1dd 100644 --- a/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json +++ b/e2etests/testdata/stable/constant_near_stress/dagre/board.exp.json @@ -125,46 +125,6 @@ "zIndex": 0, "level": 1 }, - { - "id": "bottom", - "type": "text", - "pos": { - "x": -431, - "y": 252 - }, - "width": 917, - "height": 131, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "# Cats, no less liquid than their shadows, offer no angles to the wind.\n\nIf we can't fix it, it ain't broke.\n\nDieters live life in the fasting lane.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 917, - "labelHeight": 131, - "zIndex": 0, - "level": 1 - }, { "id": "Joe", "type": "person", @@ -247,6 +207,46 @@ "zIndex": 0, "level": 1 }, + { + "id": "bottom", + "type": "text", + "pos": { + "x": -431, + "y": 252 + }, + "width": 917, + "height": 131, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# Cats, no less liquid than their shadows, offer no angles to the wind.\n\nIf we can't fix it, it ain't broke.\n\nDieters live life in the fasting lane.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 917, + "labelHeight": 131, + "zIndex": 0, + "level": 1 + }, { "id": "i am top left", "type": "text", diff --git a/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg b/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg index 78134855a..b7b35a9ba 100644 --- a/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -xyThe top of the mountain

Cats, no less liquid than their shadows, offer no angles to the wind.

+xyThe top of the mountainJoeDonald

Cats, no less liquid than their shadows, offer no angles to the wind.

If we can't fix it, it ain't broke.

Dieters live life in the fasting lane.

-
JoeDonaldi am top lefti am top righti am bottom lefti am bottom right +
i am top lefti am top righti am bottom lefti am bottom right - + diff --git a/e2etests/testdata/stable/constant_near_stress/elk/board.exp.json b/e2etests/testdata/stable/constant_near_stress/elk/board.exp.json index d393d9216..603b35fc4 100644 --- a/e2etests/testdata/stable/constant_near_stress/elk/board.exp.json +++ b/e2etests/testdata/stable/constant_near_stress/elk/board.exp.json @@ -125,46 +125,6 @@ "zIndex": 0, "level": 1 }, - { - "id": "bottom", - "type": "text", - "pos": { - "x": -419, - "y": 234 - }, - "width": 917, - "height": 131, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "# Cats, no less liquid than their shadows, offer no angles to the wind.\n\nIf we can't fix it, it ain't broke.\n\nDieters live life in the fasting lane.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 917, - "labelHeight": 131, - "zIndex": 0, - "level": 1 - }, { "id": "Joe", "type": "person", @@ -247,6 +207,46 @@ "zIndex": 0, "level": 1 }, + { + "id": "bottom", + "type": "text", + "pos": { + "x": -419, + "y": 234 + }, + "width": 917, + "height": 131, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# Cats, no less liquid than their shadows, offer no angles to the wind.\n\nIf we can't fix it, it ain't broke.\n\nDieters live life in the fasting lane.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 917, + "labelHeight": 131, + "zIndex": 0, + "level": 1 + }, { "id": "i am top left", "type": "text", diff --git a/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg b/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg index d85bffe5b..40fe40ab2 100644 --- a/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -xyThe top of the mountain

Cats, no less liquid than their shadows, offer no angles to the wind.

+xyThe top of the mountainJoeDonald

Cats, no less liquid than their shadows, offer no angles to the wind.

If we can't fix it, it ain't broke.

Dieters live life in the fasting lane.

-
JoeDonaldi am top lefti am top righti am bottom lefti am bottom right +
i am top lefti am top righti am bottom lefti am bottom right - + diff --git a/e2etests/testdata/stable/constant_near_title/dagre/board.exp.json b/e2etests/testdata/stable/constant_near_title/dagre/board.exp.json index ac0d6e0df..62e89f006 100644 --- a/e2etests/testdata/stable/constant_near_title/dagre/board.exp.json +++ b/e2etests/testdata/stable/constant_near_title/dagre/board.exp.json @@ -3,6 +3,46 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ + { + "id": "title", + "type": "text", + "pos": { + "x": 37, + "y": -71 + }, + "width": 257, + "height": 51, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# A winning strategy", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 257, + "labelHeight": 51, + "zIndex": 0, + "level": 1 + }, { "id": "poll the people", "type": "rectangle", @@ -207,46 +247,6 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 1 - }, - { - "id": "title", - "type": "text", - "pos": { - "x": 37, - "y": -71 - }, - "width": 257, - "height": 51, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "# A winning strategy", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 257, - "labelHeight": 51, - "zIndex": 0, - "level": 1 } ], "connections": [ diff --git a/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg b/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg index 91cd0cab6..b3955e1c1 100644 --- a/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -poll the peopleresultsunfavorablefavorablewill of the people

A winning strategy

-
+

A winning strategy

+
poll the peopleresultsunfavorablefavorablewill of the people + -
\ No newline at end of file diff --git a/e2etests/testdata/stable/constant_near_title/elk/board.exp.json b/e2etests/testdata/stable/constant_near_title/elk/board.exp.json index 56d22f7ee..1eb62f0b7 100644 --- a/e2etests/testdata/stable/constant_near_title/elk/board.exp.json +++ b/e2etests/testdata/stable/constant_near_title/elk/board.exp.json @@ -3,6 +3,46 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ + { + "id": "title", + "type": "text", + "pos": { + "x": 29, + "y": -59 + }, + "width": 257, + "height": 51, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "transparent", + "stroke": "N1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# A winning strategy", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 257, + "labelHeight": 51, + "zIndex": 0, + "level": 1 + }, { "id": "poll the people", "type": "rectangle", @@ -207,46 +247,6 @@ "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 0, "level": 1 - }, - { - "id": "title", - "type": "text", - "pos": { - "x": 29, - "y": -59 - }, - "width": 257, - "height": 51, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "transparent", - "stroke": "N1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "# A winning strategy", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 257, - "labelHeight": 51, - "zIndex": 0, - "level": 1 } ], "connections": [ diff --git a/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg b/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg index 8d6e6ec78..275c532b1 100644 --- a/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -poll the peopleresultsunfavorablefavorablewill of the people

A winning strategy

-
+

A winning strategy

+
poll the peopleresultsunfavorablefavorablewill of the people + -
\ No newline at end of file diff --git a/e2etests/testdata/stable/near_keys_for_container#01/dagre/board.exp.json b/e2etests/testdata/stable/near_keys_for_container#01/dagre/board.exp.json index 0b3b174cd..f0d9f8c63 100644 --- a/e2etests/testdata/stable/near_keys_for_container#01/dagre/board.exp.json +++ b/e2etests/testdata/stable/near_keys_for_container#01/dagre/board.exp.json @@ -3,334 +3,6 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "z", - "type": "rectangle", - "pos": { - "x": -113, - "y": 56 - }, - "width": 227, - "height": 292, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "z", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "z.a", - "type": "rectangle", - "pos": { - "x": -83, - "y": 86 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.b", - "type": "rectangle", - "pos": { - "x": -83, - "y": 252 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.c", - "type": "rectangle", - "pos": { - "x": 30, - "y": 86 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.d", - "type": "rectangle", - "pos": { - "x": 29, - "y": 252 - }, - "width": 54, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "d", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 9, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a", - "type": "rectangle", - "pos": { - "x": -86, - "y": -217 - }, - "width": 173, - "height": 197, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "a.b", - "type": "rectangle", - "pos": { - "x": -56, - "y": -176 - }, - "width": 113, - "height": 126, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 24, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 31, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.b.c", - "type": "rectangle", - "pos": { - "x": -26, - "y": -146 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B6", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 - }, { "id": "x", "type": "rectangle", @@ -741,6 +413,334 @@ "zIndex": 0, "level": 2 }, + { + "id": "z", + "type": "rectangle", + "pos": { + "x": -113, + "y": 56 + }, + "width": 227, + "height": 292, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "z.a", + "type": "rectangle", + "pos": { + "x": -83, + "y": 86 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.b", + "type": "rectangle", + "pos": { + "x": -83, + "y": 252 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.c", + "type": "rectangle", + "pos": { + "x": 30, + "y": 86 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.d", + "type": "rectangle", + "pos": { + "x": 29, + "y": 252 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "d", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a", + "type": "rectangle", + "pos": { + "x": -86, + "y": -217 + }, + "width": 173, + "height": 197, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.b", + "type": "rectangle", + "pos": { + "x": -56, + "y": -176 + }, + "width": 113, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.b.c", + "type": "rectangle", + "pos": { + "x": -26, + "y": -146 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, { "id": "b", "type": "rectangle", @@ -907,100 +907,6 @@ } ], "connections": [ - { - "id": "z.(a -> b)[0]", - "src": "z.a", - "srcArrow": "none", - "dst": "z.b", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": -57, - "y": 152 - }, - { - "x": -57, - "y": 192 - }, - { - "x": -57, - "y": 212 - }, - { - "x": -57, - "y": 252 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "z.(c -> d)[0]", - "src": "z.c", - "srcArrow": "none", - "dst": "z.d", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": 56.5, - "y": 152 - }, - { - "x": 56.5, - "y": 192 - }, - { - "x": 56.5, - "y": 212 - }, - { - "x": 56.5, - "y": 252 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, { "id": "x.(a -> b)[0]", "src": "x.a", @@ -1188,6 +1094,100 @@ "tooltip": "", "icon": null, "zIndex": 0 + }, + { + "id": "z.(a -> b)[0]", + "src": "z.a", + "srcArrow": "none", + "dst": "z.b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": -57, + "y": 152 + }, + { + "x": -57, + "y": 192 + }, + { + "x": -57, + "y": 212 + }, + { + "x": -57, + "y": 252 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "z.(c -> d)[0]", + "src": "z.c", + "srcArrow": "none", + "dst": "z.d", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 56.5, + "y": 152 + }, + { + "x": 56.5, + "y": 192 + }, + { + "x": 56.5, + "y": 212 + }, + { + "x": 56.5, + "y": 252 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 } ], "root": { diff --git a/e2etests/testdata/stable/near_keys_for_container#01/dagre/sketch.exp.svg b/e2etests/testdata/stable/near_keys_for_container#01/dagre/sketch.exp.svg index 006077180..332b06d69 100644 --- a/e2etests/testdata/stable/near_keys_for_container#01/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/near_keys_for_container#01/dagre/sketch.exp.svg @@ -1,16 +1,16 @@ -zaxybabcdbabcdabcdaccd + .d2-4283156917 .fill-N1{fill:#0A0F25;} + .d2-4283156917 .fill-N2{fill:#676C7E;} + .d2-4283156917 .fill-N3{fill:#9499AB;} + .d2-4283156917 .fill-N4{fill:#CFD2DD;} + .d2-4283156917 .fill-N5{fill:#DEE1EB;} + .d2-4283156917 .fill-N6{fill:#EEF1F8;} + .d2-4283156917 .fill-N7{fill:#FFFFFF;} + .d2-4283156917 .fill-B1{fill:#0D32B2;} + .d2-4283156917 .fill-B2{fill:#0D32B2;} + .d2-4283156917 .fill-B3{fill:#E3E9FD;} + .d2-4283156917 .fill-B4{fill:#E3E9FD;} + .d2-4283156917 .fill-B5{fill:#EDF0FD;} + .d2-4283156917 .fill-B6{fill:#F7F8FE;} + .d2-4283156917 .fill-AA2{fill:#4A6FF3;} + .d2-4283156917 .fill-AA4{fill:#EDF0FD;} + .d2-4283156917 .fill-AA5{fill:#F7F8FE;} + .d2-4283156917 .fill-AB4{fill:#EDF0FD;} + .d2-4283156917 .fill-AB5{fill:#F7F8FE;} + .d2-4283156917 .stroke-N1{stroke:#0A0F25;} + .d2-4283156917 .stroke-N2{stroke:#676C7E;} + .d2-4283156917 .stroke-N3{stroke:#9499AB;} + .d2-4283156917 .stroke-N4{stroke:#CFD2DD;} + .d2-4283156917 .stroke-N5{stroke:#DEE1EB;} + .d2-4283156917 .stroke-N6{stroke:#EEF1F8;} + .d2-4283156917 .stroke-N7{stroke:#FFFFFF;} + .d2-4283156917 .stroke-B1{stroke:#0D32B2;} + .d2-4283156917 .stroke-B2{stroke:#0D32B2;} + .d2-4283156917 .stroke-B3{stroke:#E3E9FD;} + .d2-4283156917 .stroke-B4{stroke:#E3E9FD;} + .d2-4283156917 .stroke-B5{stroke:#EDF0FD;} + .d2-4283156917 .stroke-B6{stroke:#F7F8FE;} + .d2-4283156917 .stroke-AA2{stroke:#4A6FF3;} + .d2-4283156917 .stroke-AA4{stroke:#EDF0FD;} + .d2-4283156917 .stroke-AA5{stroke:#F7F8FE;} + .d2-4283156917 .stroke-AB4{stroke:#EDF0FD;} + .d2-4283156917 .stroke-AB5{stroke:#F7F8FE;} + .d2-4283156917 .background-color-N1{background-color:#0A0F25;} + .d2-4283156917 .background-color-N2{background-color:#676C7E;} + .d2-4283156917 .background-color-N3{background-color:#9499AB;} + .d2-4283156917 .background-color-N4{background-color:#CFD2DD;} + .d2-4283156917 .background-color-N5{background-color:#DEE1EB;} + .d2-4283156917 .background-color-N6{background-color:#EEF1F8;} + .d2-4283156917 .background-color-N7{background-color:#FFFFFF;} + .d2-4283156917 .background-color-B1{background-color:#0D32B2;} + .d2-4283156917 .background-color-B2{background-color:#0D32B2;} + .d2-4283156917 .background-color-B3{background-color:#E3E9FD;} + .d2-4283156917 .background-color-B4{background-color:#E3E9FD;} + .d2-4283156917 .background-color-B5{background-color:#EDF0FD;} + .d2-4283156917 .background-color-B6{background-color:#F7F8FE;} + .d2-4283156917 .background-color-AA2{background-color:#4A6FF3;} + .d2-4283156917 .background-color-AA4{background-color:#EDF0FD;} + .d2-4283156917 .background-color-AA5{background-color:#F7F8FE;} + .d2-4283156917 .background-color-AB4{background-color:#EDF0FD;} + .d2-4283156917 .background-color-AB5{background-color:#F7F8FE;} + .d2-4283156917 .color-N1{color:#0A0F25;} + .d2-4283156917 .color-N2{color:#676C7E;} + .d2-4283156917 .color-N3{color:#9499AB;} + .d2-4283156917 .color-N4{color:#CFD2DD;} + .d2-4283156917 .color-N5{color:#DEE1EB;} + .d2-4283156917 .color-N6{color:#EEF1F8;} + .d2-4283156917 .color-N7{color:#FFFFFF;} + .d2-4283156917 .color-B1{color:#0D32B2;} + .d2-4283156917 .color-B2{color:#0D32B2;} + .d2-4283156917 .color-B3{color:#E3E9FD;} + .d2-4283156917 .color-B4{color:#E3E9FD;} + .d2-4283156917 .color-B5{color:#EDF0FD;} + .d2-4283156917 .color-B6{color:#F7F8FE;} + .d2-4283156917 .color-AA2{color:#4A6FF3;} + .d2-4283156917 .color-AA4{color:#EDF0FD;} + .d2-4283156917 .color-AA5{color:#F7F8FE;} + .d2-4283156917 .color-AB4{color:#EDF0FD;} + .d2-4283156917 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>xyzababcdabcdabcdbaccd - - + + - - - - - @@ -116,6 +111,11 @@ + + + + + diff --git a/e2etests/testdata/stable/near_keys_for_container#01/elk/board.exp.json b/e2etests/testdata/stable/near_keys_for_container#01/elk/board.exp.json index c216a61ab..461bd39c7 100644 --- a/e2etests/testdata/stable/near_keys_for_container#01/elk/board.exp.json +++ b/e2etests/testdata/stable/near_keys_for_container#01/elk/board.exp.json @@ -3,334 +3,6 @@ "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ - { - "id": "z", - "type": "rectangle", - "pos": { - "x": -113, - "y": 20 - }, - "width": 227, - "height": 302, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "z", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "INSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "z.a", - "type": "rectangle", - "pos": { - "x": -63, - "y": 70 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.b", - "type": "rectangle", - "pos": { - "x": -63, - "y": 206 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.c", - "type": "rectangle", - "pos": { - "x": 10, - "y": 70 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "z.d", - "type": "rectangle", - "pos": { - "x": 9, - "y": 206 - }, - "width": 54, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "d", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 9, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a", - "type": "rectangle", - "pos": { - "x": -126, - "y": -286 - }, - "width": 253, - "height": 266, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B4", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "INSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "a.b", - "type": "rectangle", - "pos": { - "x": -76, - "y": -236 - }, - "width": 153, - "height": 166, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B5", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 24, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 31, - "labelPosition": "INSIDE_TOP_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.b.c", - "type": "rectangle", - "pos": { - "x": -26, - "y": -186 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B6", - "stroke": "B1", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 3 - }, { "id": "x", "type": "rectangle", @@ -741,6 +413,334 @@ "zIndex": 0, "level": 2 }, + { + "id": "z", + "type": "rectangle", + "pos": { + "x": -113, + "y": 20 + }, + "width": 227, + "height": 302, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "z.a", + "type": "rectangle", + "pos": { + "x": -63, + "y": 70 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.b", + "type": "rectangle", + "pos": { + "x": -63, + "y": 206 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.c", + "type": "rectangle", + "pos": { + "x": 10, + "y": 70 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "z.d", + "type": "rectangle", + "pos": { + "x": 9, + "y": 206 + }, + "width": 54, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "d", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 9, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a", + "type": "rectangle", + "pos": { + "x": -126, + "y": -286 + }, + "width": 253, + "height": 266, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.b", + "type": "rectangle", + "pos": { + "x": -76, + "y": -236 + }, + "width": 153, + "height": 166, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.b.c", + "type": "rectangle", + "pos": { + "x": -26, + "y": -186 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, { "id": "b", "type": "rectangle", @@ -907,82 +907,6 @@ } ], "connections": [ - { - "id": "z.(a -> b)[0]", - "src": "z.a", - "srcArrow": "none", - "dst": "z.b", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": -37, - "y": 136 - }, - { - "x": -37, - "y": 206 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "z.(c -> d)[0]", - "src": "z.c", - "srcArrow": "none", - "dst": "z.d", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "route": [ - { - "x": 36.5, - "y": 136 - }, - { - "x": 36.5, - "y": 206 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, { "id": "x.(a -> b)[0]", "src": "x.a", @@ -1134,6 +1058,82 @@ "tooltip": "", "icon": null, "zIndex": 0 + }, + { + "id": "z.(a -> b)[0]", + "src": "z.a", + "srcArrow": "none", + "dst": "z.b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": -37, + "y": 136 + }, + { + "x": -37, + "y": 206 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "z.(c -> d)[0]", + "src": "z.c", + "srcArrow": "none", + "dst": "z.d", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 36.5, + "y": 136 + }, + { + "x": 36.5, + "y": 206 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 } ], "root": { diff --git a/e2etests/testdata/stable/near_keys_for_container#01/elk/sketch.exp.svg b/e2etests/testdata/stable/near_keys_for_container#01/elk/sketch.exp.svg index 535aecf9d..d7853b97f 100644 --- a/e2etests/testdata/stable/near_keys_for_container#01/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/near_keys_for_container#01/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -zaxybabcdbabcdabcdaccd + .d2-355368884 .fill-N1{fill:#0A0F25;} + .d2-355368884 .fill-N2{fill:#676C7E;} + .d2-355368884 .fill-N3{fill:#9499AB;} + .d2-355368884 .fill-N4{fill:#CFD2DD;} + .d2-355368884 .fill-N5{fill:#DEE1EB;} + .d2-355368884 .fill-N6{fill:#EEF1F8;} + .d2-355368884 .fill-N7{fill:#FFFFFF;} + .d2-355368884 .fill-B1{fill:#0D32B2;} + .d2-355368884 .fill-B2{fill:#0D32B2;} + .d2-355368884 .fill-B3{fill:#E3E9FD;} + .d2-355368884 .fill-B4{fill:#E3E9FD;} + .d2-355368884 .fill-B5{fill:#EDF0FD;} + .d2-355368884 .fill-B6{fill:#F7F8FE;} + .d2-355368884 .fill-AA2{fill:#4A6FF3;} + .d2-355368884 .fill-AA4{fill:#EDF0FD;} + .d2-355368884 .fill-AA5{fill:#F7F8FE;} + .d2-355368884 .fill-AB4{fill:#EDF0FD;} + .d2-355368884 .fill-AB5{fill:#F7F8FE;} + .d2-355368884 .stroke-N1{stroke:#0A0F25;} + .d2-355368884 .stroke-N2{stroke:#676C7E;} + .d2-355368884 .stroke-N3{stroke:#9499AB;} + .d2-355368884 .stroke-N4{stroke:#CFD2DD;} + .d2-355368884 .stroke-N5{stroke:#DEE1EB;} + .d2-355368884 .stroke-N6{stroke:#EEF1F8;} + .d2-355368884 .stroke-N7{stroke:#FFFFFF;} + .d2-355368884 .stroke-B1{stroke:#0D32B2;} + .d2-355368884 .stroke-B2{stroke:#0D32B2;} + .d2-355368884 .stroke-B3{stroke:#E3E9FD;} + .d2-355368884 .stroke-B4{stroke:#E3E9FD;} + .d2-355368884 .stroke-B5{stroke:#EDF0FD;} + .d2-355368884 .stroke-B6{stroke:#F7F8FE;} + .d2-355368884 .stroke-AA2{stroke:#4A6FF3;} + .d2-355368884 .stroke-AA4{stroke:#EDF0FD;} + .d2-355368884 .stroke-AA5{stroke:#F7F8FE;} + .d2-355368884 .stroke-AB4{stroke:#EDF0FD;} + .d2-355368884 .stroke-AB5{stroke:#F7F8FE;} + .d2-355368884 .background-color-N1{background-color:#0A0F25;} + .d2-355368884 .background-color-N2{background-color:#676C7E;} + .d2-355368884 .background-color-N3{background-color:#9499AB;} + .d2-355368884 .background-color-N4{background-color:#CFD2DD;} + .d2-355368884 .background-color-N5{background-color:#DEE1EB;} + .d2-355368884 .background-color-N6{background-color:#EEF1F8;} + .d2-355368884 .background-color-N7{background-color:#FFFFFF;} + .d2-355368884 .background-color-B1{background-color:#0D32B2;} + .d2-355368884 .background-color-B2{background-color:#0D32B2;} + .d2-355368884 .background-color-B3{background-color:#E3E9FD;} + .d2-355368884 .background-color-B4{background-color:#E3E9FD;} + .d2-355368884 .background-color-B5{background-color:#EDF0FD;} + .d2-355368884 .background-color-B6{background-color:#F7F8FE;} + .d2-355368884 .background-color-AA2{background-color:#4A6FF3;} + .d2-355368884 .background-color-AA4{background-color:#EDF0FD;} + .d2-355368884 .background-color-AA5{background-color:#F7F8FE;} + .d2-355368884 .background-color-AB4{background-color:#EDF0FD;} + .d2-355368884 .background-color-AB5{background-color:#F7F8FE;} + .d2-355368884 .color-N1{color:#0A0F25;} + .d2-355368884 .color-N2{color:#676C7E;} + .d2-355368884 .color-N3{color:#9499AB;} + .d2-355368884 .color-N4{color:#CFD2DD;} + .d2-355368884 .color-N5{color:#DEE1EB;} + .d2-355368884 .color-N6{color:#EEF1F8;} + .d2-355368884 .color-N7{color:#FFFFFF;} + .d2-355368884 .color-B1{color:#0D32B2;} + .d2-355368884 .color-B2{color:#0D32B2;} + .d2-355368884 .color-B3{color:#E3E9FD;} + .d2-355368884 .color-B4{color:#E3E9FD;} + .d2-355368884 .color-B5{color:#EDF0FD;} + .d2-355368884 .color-B6{color:#F7F8FE;} + .d2-355368884 .color-AA2{color:#4A6FF3;} + .d2-355368884 .color-AA4{color:#EDF0FD;} + .d2-355368884 .color-AA5{color:#F7F8FE;} + .d2-355368884 .color-AB4{color:#EDF0FD;} + .d2-355368884 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>xyzababcdabcdabcdbaccd - - + + - - - - - @@ -116,6 +111,11 @@ + + + + + diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json new file mode 100644 index 000000000..84d833a62 --- /dev/null +++ b/e2etests/testdata/stable/nested_diagram_types/dagre/board.exp.json @@ -0,0 +1,1093 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 73, + "y": -142 + }, + "width": 579, + "height": 351, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "sequence_diagram", + "pos": { + "x": 73, + "y": 228 + }, + "width": 521, + "height": 1106, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.1", + "type": "rectangle", + "pos": { + "x": 133, + "y": -82 + }, + "width": 52, + "height": 231, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.2", + "type": "rectangle", + "pos": { + "x": 225, + "y": -82 + }, + "width": 53, + "height": 231, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.3", + "type": "sequence_diagram", + "pos": { + "x": 318, + "y": -82 + }, + "width": 274, + "height": 231, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "3", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.3.x", + "type": "rectangle", + "pos": { + "x": 330, + "y": 0 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "a.3.y", + "type": "rectangle", + "pos": { + "x": 480, + "y": 0 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.1", + "type": "rectangle", + "pos": { + "x": 85, + "y": 436 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.2", + "type": "rectangle", + "pos": { + "x": 225, + "y": 316 + }, + "width": 357, + "height": 186, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.2.x", + "type": "rectangle", + "pos": { + "x": 285, + "y": 376 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.y", + "type": "rectangle", + "pos": { + "x": 377, + "y": 376 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.z", + "type": "rectangle", + "pos": { + "x": 470, + "y": 376 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.1.x", + "type": "rectangle", + "pos": { + "x": 129, + "y": 632 + }, + "width": 12, + "height": 358, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "zIndex": 2, + "level": 3 + }, + { + "id": "b.1.x.u", + "type": "page", + "pos": { + "x": 109, + "y": 642 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "u", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.v", + "type": "page", + "pos": { + "x": 108, + "y": 778 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "v", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.w", + "type": "page", + "pos": { + "x": 106, + "y": 914 + }, + "width": 57, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "w", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.y", + "type": "page", + "pos": { + "x": 108, + "y": 1050 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.1.z", + "type": "page", + "pos": { + "x": 109, + "y": 1186 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + } + ], + "connections": [ + { + "id": "a.(1 -> 2)[0]", + "src": "a.1", + "srcArrow": "none", + "dst": "a.2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 184.5, + "y": 33 + }, + { + "x": 225.5, + "y": 33 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "a.(2 -> 3)[0]", + "src": "a.2", + "srcArrow": "none", + "dst": "a.3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 278, + "y": 33 + }, + { + "x": 318, + "y": 33 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "b.(1 -> 2)[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "b.2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 135, + "y": 572.5 + }, + { + "x": 403.5, + "y": 572.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "(a.3.x -- )[0]", + "src": "a.3.x", + "srcArrow": "none", + "dst": "x-lifeline-end-1678191278", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 380, + "y": 66.5 + }, + { + "x": 380, + "y": 136.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(a.3.y -- )[0]", + "src": "a.3.y", + "srcArrow": "none", + "dst": "y-lifeline-end-35261543", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 530, + "y": 66.5 + }, + { + "x": 530, + "y": 136.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(b.1 -- )[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "1-lifeline-end-1719232319", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 135, + "y": 502.5 + }, + { + "x": 135, + "y": 1322.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(b.2 -- )[0]", + "src": "b.2", + "srcArrow": "none", + "dst": "2-lifeline-end-1739547740", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 403.5, + "y": 502.5 + }, + { + "x": 403.5, + "y": 1322.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + } + ], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg new file mode 100644 index 000000000..393da2b08 --- /dev/null +++ b/e2etests/testdata/stable/nested_diagram_types/dagre/sketch.exp.svg @@ -0,0 +1,119 @@ +abc12312xyxyz yzuvw + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json new file mode 100644 index 000000000..2c26323ff --- /dev/null +++ b/e2etests/testdata/stable/nested_diagram_types/elk/board.exp.json @@ -0,0 +1,1093 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 85, + "y": -130 + }, + "width": 579, + "height": 351, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "sequence_diagram", + "pos": { + "x": 85, + "y": 240 + }, + "width": 521, + "height": 1106, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "a.1", + "type": "rectangle", + "pos": { + "x": 145, + "y": -70 + }, + "width": 52, + "height": 231, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.2", + "type": "rectangle", + "pos": { + "x": 237, + "y": -70 + }, + "width": 53, + "height": 231, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.3", + "type": "sequence_diagram", + "pos": { + "x": 330, + "y": -70 + }, + "width": 274, + "height": 231, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "3", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "a.3.x", + "type": "rectangle", + "pos": { + "x": 342, + "y": 12 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "a.3.y", + "type": "rectangle", + "pos": { + "x": 492, + "y": 12 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.1", + "type": "rectangle", + "pos": { + "x": 97, + "y": 448 + }, + "width": 100, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.2", + "type": "rectangle", + "pos": { + "x": 237, + "y": 328 + }, + "width": 357, + "height": 186, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "b.2.x", + "type": "rectangle", + "pos": { + "x": 297, + "y": 388 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "x", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.y", + "type": "rectangle", + "pos": { + "x": 389, + "y": 388 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.2.z", + "type": "rectangle", + "pos": { + "x": 482, + "y": 388 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "b.1.x", + "type": "rectangle", + "pos": { + "x": 141, + "y": 644 + }, + "width": 12, + "height": 358, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "zIndex": 2, + "level": 3 + }, + { + "id": "b.1.x.u", + "type": "page", + "pos": { + "x": 121, + "y": 654 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "u", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.v", + "type": "page", + "pos": { + "x": 120, + "y": 790 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "v", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.x.w", + "type": "page", + "pos": { + "x": 118, + "y": 926 + }, + "width": 57, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "w", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 4 + }, + { + "id": "b.1.y", + "type": "page", + "pos": { + "x": 120, + "y": 1062 + }, + "width": 53, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "y", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 8, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + }, + { + "id": "b.1.z", + "type": "page", + "pos": { + "x": 121, + "y": 1198 + }, + "width": 52, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N7", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "z", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 7, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 5, + "level": 3 + } + ], + "connections": [ + { + "id": "a.(1 -> 2)[0]", + "src": "a.1", + "srcArrow": "none", + "dst": "a.2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 196.5, + "y": 45 + }, + { + "x": 237.5, + "y": 45 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "a.(2 -> 3)[0]", + "src": "a.2", + "srcArrow": "none", + "dst": "a.3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 290, + "y": 45 + }, + { + "x": 330, + "y": 45 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "b.(1 -> 2)[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "b.2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 147, + "y": 584.5 + }, + { + "x": 415.5, + "y": 584.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 4 + }, + { + "id": "(a.3.x -- )[0]", + "src": "a.3.x", + "srcArrow": "none", + "dst": "x-lifeline-end-1678191278", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 392, + "y": 78.5 + }, + { + "x": 392, + "y": 148.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(a.3.y -- )[0]", + "src": "a.3.y", + "srcArrow": "none", + "dst": "y-lifeline-end-35261543", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 542, + "y": 78.5 + }, + { + "x": 542, + "y": 148.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(b.1 -- )[0]", + "src": "b.1", + "srcArrow": "none", + "dst": "1-lifeline-end-1719232319", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 147, + "y": 514.5 + }, + { + "x": 147, + "y": 1334.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(b.2 -- )[0]", + "src": "b.2", + "srcArrow": "none", + "dst": "2-lifeline-end-1739547740", + "dstArrow": "none", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 415.5, + "y": 514.5 + }, + { + "x": 415.5, + "y": 1334.5 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + } + ], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg new file mode 100644 index 000000000..562f706b3 --- /dev/null +++ b/e2etests/testdata/stable/nested_diagram_types/elk/sketch.exp.svg @@ -0,0 +1,119 @@ +abc12312xyxyz yzuvw + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/geo/spacing.go b/lib/geo/spacing.go new file mode 100644 index 000000000..2684ee582 --- /dev/null +++ b/lib/geo/spacing.go @@ -0,0 +1,5 @@ +package geo + +type Spacing struct { + Top, Bottom, Left, Right float64 +}