diff --git a/d2layouts/d2elklayout/layout.go b/d2layouts/d2elklayout/layout.go index 6fbe5268f..d9eab2212 100644 --- a/d2layouts/d2elklayout/layout.go +++ b/d2layouts/d2elklayout/layout.go @@ -41,10 +41,38 @@ type ELKNode struct { Width float64 `json:"width"` Height float64 `json:"height"` Children []*ELKNode `json:"children,omitempty"` + Ports []*ELKPort `json:"ports,omitempty"` Labels []*ELKLabel `json:"labels,omitempty"` LayoutOptions *elkOpts `json:"layoutOptions,omitempty"` } +type PortSide string + +const ( + South PortSide = "SOUTH" + North PortSide = "NORTH" + East PortSide = "EAST" + West PortSide = "WEST" +) + +type Direction string + +const ( + Down Direction = "DOWN" + Up Direction = "UP" + Right Direction = "RIGHT" + Left Direction = "LEFT" +) + +type ELKPort struct { + ID string `json:"id"` + X float64 `json:"x"` + Y float64 `json:"y"` + Width float64 `json:"width"` + Height float64 `json:"height"` + LayoutOptions *elkOpts `json:"layoutOptions,omitempty"` +} + type ELKLabel struct { Text string `json:"text"` X float64 `json:"x"` @@ -101,16 +129,16 @@ var port_spacing = 40. var edge_node_spacing = 40 type elkOpts struct { - EdgeNode int `json:"elk.spacing.edgeNode,omitempty"` - FixedAlignment string `json:"elk.layered.nodePlacement.bk.fixedAlignment,omitempty"` - Thoroughness int `json:"elk.layered.thoroughness,omitempty"` - EdgeEdgeBetweenLayersSpacing int `json:"elk.layered.spacing.edgeEdgeBetweenLayers,omitempty"` - Direction string `json:"elk.direction"` - HierarchyHandling string `json:"elk.hierarchyHandling,omitempty"` - InlineEdgeLabels bool `json:"elk.edgeLabels.inline,omitempty"` - ForceNodeModelOrder bool `json:"elk.layered.crossingMinimization.forceNodeModelOrder,omitempty"` - ConsiderModelOrder string `json:"elk.layered.considerModelOrder.strategy,omitempty"` - CycleBreakingStrategy string `json:"elk.layered.cycleBreaking.strategy,omitempty"` + EdgeNode int `json:"elk.spacing.edgeNode,omitempty"` + FixedAlignment string `json:"elk.layered.nodePlacement.bk.fixedAlignment,omitempty"` + Thoroughness int `json:"elk.layered.thoroughness,omitempty"` + EdgeEdgeBetweenLayersSpacing int `json:"elk.layered.spacing.edgeEdgeBetweenLayers,omitempty"` + Direction Direction `json:"elk.direction"` + HierarchyHandling string `json:"elk.hierarchyHandling,omitempty"` + InlineEdgeLabels bool `json:"elk.edgeLabels.inline,omitempty"` + ForceNodeModelOrder bool `json:"elk.layered.crossingMinimization.forceNodeModelOrder,omitempty"` + ConsiderModelOrder string `json:"elk.layered.considerModelOrder.strategy,omitempty"` + CycleBreakingStrategy string `json:"elk.layered.cycleBreaking.strategy,omitempty"` SelfLoopDistribution string `json:"elk.layered.edgeRouting.selfLoopDistribution,omitempty"` @@ -118,6 +146,9 @@ type elkOpts struct { ContentAlignment string `json:"elk.contentAlignment,omitempty"` NodeSizeMinimum string `json:"elk.nodeSize.minimum,omitempty"` + PortSide PortSide `json:"elk.port.side,omitempty"` + PortConstraints string `json:"elk.portConstraints,omitempty"` + ConfigurableOpts } @@ -171,15 +202,15 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } switch g.Root.Direction.Value { case "down": - elkGraph.LayoutOptions.Direction = "DOWN" + elkGraph.LayoutOptions.Direction = Down case "up": - elkGraph.LayoutOptions.Direction = "UP" + elkGraph.LayoutOptions.Direction = Up case "right": - elkGraph.LayoutOptions.Direction = "RIGHT" + elkGraph.LayoutOptions.Direction = Right case "left": - elkGraph.LayoutOptions.Direction = "LEFT" + elkGraph.LayoutOptions.Direction = Left default: - elkGraph.LayoutOptions.Direction = "DOWN" + elkGraph.LayoutOptions.Direction = Down } // set label and icon positions for ELK @@ -257,9 +288,9 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } switch elkGraph.LayoutOptions.Direction { - case "DOWN", "UP": + case Down, Up: n.LayoutOptions.NodeSizeMinimum = fmt.Sprintf("(%d, %d)", int(math.Ceil(height)), int(math.Ceil(width))) - case "RIGHT", "LEFT": + case Right, Left: n.LayoutOptions.NodeSizeMinimum = fmt.Sprintf("(%d, %d)", int(math.Ceil(width)), int(math.Ceil(height))) } } else { @@ -287,6 +318,33 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } else { elkNodes[parent].Children = append(elkNodes[parent].Children, n) } + + if obj.SQLTable != nil { + n.LayoutOptions.PortConstraints = "FIXED_POS" + columns := obj.SQLTable.Columns + colHeight := n.Height / float64(len(columns)+1) + n.Ports = make([]*ELKPort, 0, len(columns)*2) + var srcSide, dstSide PortSide + switch elkGraph.LayoutOptions.Direction { + case Left: + srcSide, dstSide = West, East + default: + srcSide, dstSide = East, West + } + for i, col := range columns { + n.Ports = append(n.Ports, &ELKPort{ + ID: srcPortID(obj, col.Name.Label), + Y: float64(i+1)*colHeight + colHeight/2, + LayoutOptions: &elkOpts{PortSide: srcSide}, + }) + n.Ports = append(n.Ports, &ELKPort{ + ID: dstPortID(obj, col.Name.Label), + Y: float64(i+1)*colHeight + colHeight/2, + LayoutOptions: &elkOpts{PortSide: dstSide}, + }) + } + } + elkNodes[obj] = n }) @@ -325,11 +383,64 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } } - for _, edge := range g.Edges { + var srcSide, dstSide PortSide + switch elkGraph.LayoutOptions.Direction { + case Up: + srcSide, dstSide = North, South + default: + srcSide, dstSide = South, North + } + + ports := map[struct { + obj *d2graph.Object + side PortSide + }][]*ELKPort{} + + for ei, edge := range g.Edges { + var src, dst string + + switch { + case edge.SrcTableColumnIndex != nil: + src = srcPortID(edge.Src, edge.Src.SQLTable.Columns[*edge.SrcTableColumnIndex].Name.Label) + case edge.Src.SQLTable != nil: + p := &ELKPort{ + ID: fmt.Sprintf("%s.%d", srcPortID(edge.Src, "__root__"), ei), + LayoutOptions: &elkOpts{PortSide: srcSide}, + } + src = p.ID + elkNodes[edge.Src].Ports = append(elkNodes[edge.Src].Ports, p) + k := struct { + obj *d2graph.Object + side PortSide + }{edge.Src, srcSide} + ports[k] = append(ports[k], p) + default: + src = edge.Src.AbsID() + } + + switch { + case edge.DstTableColumnIndex != nil: + dst = dstPortID(edge.Dst, edge.Dst.SQLTable.Columns[*edge.DstTableColumnIndex].Name.Label) + case edge.Dst.SQLTable != nil: + p := &ELKPort{ + ID: fmt.Sprintf("%s.%d", dstPortID(edge.Dst, "__root__"), ei), + LayoutOptions: &elkOpts{PortSide: dstSide}, + } + dst = p.ID + elkNodes[edge.Dst].Ports = append(elkNodes[edge.Dst].Ports, p) + k := struct { + obj *d2graph.Object + side PortSide + }{edge.Dst, dstSide} + ports[k] = append(ports[k], p) + default: + dst = edge.Dst.AbsID() + } + e := &ELKEdge{ ID: edge.AbsID(), - Sources: []string{edge.Src.AbsID()}, - Targets: []string{edge.Dst.AbsID()}, + Sources: []string{src}, + Targets: []string{dst}, } if edge.Label.Value != "" { e.Labels = append(e.Labels, &ELKLabel{ @@ -345,6 +456,14 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err elkEdges[edge] = e } + for k, ports := range ports { + width := elkNodes[k.obj].Width + spacing := width / float64(len(ports)+1) + for i, p := range ports { + p.X = float64(i+1) * spacing + } + } + raw, err := json.Marshal(elkGraph) if err != nil { return err @@ -507,6 +626,14 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err return nil } +func srcPortID(obj *d2graph.Object, column string) string { + return fmt.Sprintf("%s.%s.src", obj.AbsID(), column) +} + +func dstPortID(obj *d2graph.Object, column string) string { + return fmt.Sprintf("%s.%s.dst", obj.AbsID(), column) +} + // deleteBends is a shim for ELK to delete unnecessary bends // see https://github.com/terrastruct/d2/issues/1030 func deleteBends(g *d2graph.Graph) { @@ -525,30 +652,40 @@ func deleteBends(g *d2graph.Graph) { var corner *geo.Point var end *geo.Point + var columnIndex *int if isSource { start = e.Route[0] corner = e.Route[1] end = e.Route[2] endpoint = e.Src + columnIndex = e.SrcTableColumnIndex } else { start = e.Route[len(e.Route)-1] corner = e.Route[len(e.Route)-2] end = e.Route[len(e.Route)-3] endpoint = e.Dst + columnIndex = e.DstTableColumnIndex } isHorizontal := math.Ceil(start.Y) == math.Ceil(corner.Y) dx, dy := endpoint.GetModifierElementAdjustments() // Make sure it's still attached - if isHorizontal { + switch { + case columnIndex != nil: + maxRowOffset := endpoint.Height / float64(len(endpoint.SQLTable.Columns)+1) / 3 + rowCenter := endpoint.TopLeft.Y + maxRowOffset*float64(*columnIndex+1)*2 + maxRowOffset + if math.Abs(end.Y-rowCenter) > maxRowOffset { + continue + } + case isHorizontal: if end.Y <= endpoint.TopLeft.Y+10-dy { continue } if end.Y >= endpoint.TopLeft.Y+endpoint.Height-10 { continue } - } else { + default: if end.X <= endpoint.TopLeft.X+10 { continue } @@ -610,12 +747,21 @@ func deleteBends(g *d2graph.Graph) { } } } + // Get rid of ladders // ELK likes to do these for some reason // . ┌─ // . ┌─┘ // . │ // We want to transform these into L-shapes + + points := map[geo.Point]int{} + for _, e := range g.Edges { + for _, p := range e.Route { + points[*p]++ + } + } + for ei, e := range g.Edges { if len(e.Route) < 6 { continue @@ -631,6 +777,11 @@ func deleteBends(g *d2graph.Graph) { end := e.Route[i+2] after := e.Route[i+3] + if c, _ := points[*corner]; c > 1 { + // If corner is shared with another edge, they merge + continue + } + // S-shape on sources only concerned one segment, since the other was just along the bound of endpoint // These concern two segments diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go index c9fdfc0dc..c62d1d625 100644 --- a/e2etests/stable_test.go +++ b/e2etests/stable_test.go @@ -1190,18 +1190,21 @@ a -> md -> b `, }, { name: "sql_tables", - script: `users: { + script: ` +direction: left + +users: { shape: sql_table - id: int + id: int { constraint: primary_key } name: string email: string password: string - last_login: datetime { constraint: primary_key } + last_login: datetime } products: { shape: sql_table - id: int + id: int { constraint: primary_key } price: decimal sku: string name: string @@ -1209,22 +1212,41 @@ products: { orders: { shape: sql_table - id: int - user_id: int - product_id: int + id: int { constraint: primary_key } + user_id: int { constraint: foreign_key } + product_id: int { constraint: foreign_key } } shipments: { shape: sql_table - id: int - order_id: int + id: int { constraint: primary_key } + order_id: int { constraint: foreign_key } tracking_number: string status: string } -users.id <-> orders.user_id -products.id <-> orders.product_id -shipments.order_id <-> orders.id`, +orders.user_id -> users.id +orders.product_id -> products.id +shipments.order_id -> orders.id`, + }, { + name: "sql_table_row_connections", + script: ` +direction: left + +a: { + shape: sql_table + id: int { constraint: primary_key } +} + +b: { + shape: sql_table + id: int { constraint: primary_key } + a_1: int { constraint: foreign_key } + a_2: int { constraint: foreign_key } +} + +b.a_1 -> a.id +b.a_2 -> a.id`, }, { name: "images", script: `a: { @@ -2364,20 +2386,27 @@ a -> b { name: "sql_table_tooltip_animated", script: ` +direction: left + x: { shape: sql_table - y + y { constraint: primary_key } tooltip: I like turtles } a: { shape: sql_table - b + b { constraint: foreign_key } } -x.y -> a.b: { +a.b <-> x.y: { style.animated: true - target-arrowhead.shape: cf-many + source-arrowhead: { + shape: cf-many + } + target-arrowhead: { + shape: cf-one + } } `, }, diff --git a/e2etests/testdata/stable/ent2d2_basic/elk/board.exp.json b/e2etests/testdata/stable/ent2d2_basic/elk/board.exp.json index 9fd0bdcae..296c132a9 100644 --- a/e2etests/testdata/stable/ent2d2_basic/elk/board.exp.json +++ b/e2etests/testdata/stable/ent2d2_basic/elk/board.exp.json @@ -7,8 +7,8 @@ "id": "User", "type": "sql_table", "pos": { - "x": 411, - "y": 12 + "x": 376, + "y": 110 }, "width": 280, "height": 144, @@ -142,7 +142,7 @@ "type": "sql_table", "pos": { "x": 12, - "y": 377 + "y": 573 }, "width": 194, "height": 108, @@ -246,7 +246,7 @@ "type": "sql_table", "pos": { "x": 226, - "y": 377 + "y": 573 }, "width": 194, "height": 108, @@ -350,7 +350,7 @@ "type": "sql_table", "pos": { "x": 440, - "y": 377 + "y": 573 }, "width": 222, "height": 144, @@ -482,7 +482,7 @@ "type": "sql_table", "pos": { "x": 682, - "y": 377 + "y": 573 }, "width": 146, "height": 108, @@ -584,7 +584,7 @@ "type": "sql_table", "pos": { "x": 848, - "y": 377 + "y": 573 }, "width": 308, "height": 108, @@ -709,19 +709,27 @@ "route": [ { "x": 411, - "y": 60 - }, - { - "x": 323, - "y": 60 - }, - { - "x": 323, - "y": 108 + "y": 254 }, { "x": 411, - "y": 108 + "y": 342 + }, + { + "x": 288, + "y": 342 + }, + { + "x": 288, + "y": 22 + }, + { + "x": 469.3330078125, + "y": 22 + }, + { + "x": 469.3330078125, + "y": 110 } ], "animated": false, @@ -754,20 +762,28 @@ "labelPercentage": 0, "route": [ { - "x": 691, - "y": 108 + "x": 446, + "y": 254 }, { - "x": 779, - "y": 108 + "x": 446, + "y": 352 }, { - "x": 779, - "y": 60 + "x": 228, + "y": 352 }, { - "x": 691, - "y": 60 + "x": 228, + "y": 12 + }, + { + "x": 562.666015625, + "y": 12 + }, + { + "x": 562.666015625, + "y": 110 } ], "animated": false, @@ -800,20 +816,20 @@ "labelPercentage": 0, "route": [ { - "x": 457.6659851074219, - "y": 156 + "x": 481, + "y": 254 }, { - "x": 457.6659851074219, - "y": 196 + "x": 481, + "y": 392 }, { "x": 109, - "y": 196 + "y": 392 }, { "x": 109, - "y": 377 + "y": 573 } ], "animated": false, @@ -846,20 +862,20 @@ "labelPercentage": 0, "route": [ { - "x": 504.3330078125, - "y": 156 + "x": 516, + "y": 254 }, { - "x": 504.3330078125, - "y": 246 + "x": 516, + "y": 442 }, { "x": 323, - "y": 246 + "y": 442 }, { "x": 323, - "y": 377 + "y": 573 } ], "animated": false, @@ -893,11 +909,11 @@ "route": [ { "x": 551, - "y": 156 + "y": 254 }, { "x": 551, - "y": 377 + "y": 573 } ], "animated": false, @@ -930,20 +946,20 @@ "labelPercentage": 0, "route": [ { - "x": 597.666015625, - "y": 156 + "x": 586, + "y": 254 }, { - "x": 597.666015625, - "y": 246 + "x": 586, + "y": 442 }, { "x": 755, - "y": 246 + "y": 442 }, { "x": 755, - "y": 377 + "y": 573 } ], "animated": false, @@ -976,20 +992,20 @@ "labelPercentage": 0, "route": [ { - "x": 644.3330078125, - "y": 156 + "x": 621, + "y": 254 }, { - "x": 644.3330078125, - "y": 196 + "x": 621, + "y": 392 }, { "x": 1002, - "y": 196 + "y": 392 }, { "x": 1002, - "y": 377 + "y": 573 } ], "animated": false, diff --git a/e2etests/testdata/stable/ent2d2_basic/elk/sketch.exp.svg b/e2etests/testdata/stable/ent2d2_basic/elk/sketch.exp.svg index a6d2b2cf3..42a3641ab 100644 --- a/e2etests/testdata/stable/ent2d2_basic/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/ent2d2_basic/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -UseridintPKparent_idintFKspouse_idintFKPetidintPKowner_idintFKCardidintPKowner_idintFKPostidintPKtextstringauthor_idintFKMetadataidintPKageintInfoidintPKcontentjson.RawMessage spouse children/parent/ancestorpets/ownercard/ownerposts/authormetadata/userinfo/user - - - - - - - - + .d2-362248761 .fill-N1{fill:#0A0F25;} + .d2-362248761 .fill-N2{fill:#676C7E;} + .d2-362248761 .fill-N3{fill:#9499AB;} + .d2-362248761 .fill-N4{fill:#CFD2DD;} + .d2-362248761 .fill-N5{fill:#DEE1EB;} + .d2-362248761 .fill-N6{fill:#EEF1F8;} + .d2-362248761 .fill-N7{fill:#FFFFFF;} + .d2-362248761 .fill-B1{fill:#0D32B2;} + .d2-362248761 .fill-B2{fill:#0D32B2;} + .d2-362248761 .fill-B3{fill:#E3E9FD;} + .d2-362248761 .fill-B4{fill:#E3E9FD;} + .d2-362248761 .fill-B5{fill:#EDF0FD;} + .d2-362248761 .fill-B6{fill:#F7F8FE;} + .d2-362248761 .fill-AA2{fill:#4A6FF3;} + .d2-362248761 .fill-AA4{fill:#EDF0FD;} + .d2-362248761 .fill-AA5{fill:#F7F8FE;} + .d2-362248761 .fill-AB4{fill:#EDF0FD;} + .d2-362248761 .fill-AB5{fill:#F7F8FE;} + .d2-362248761 .stroke-N1{stroke:#0A0F25;} + .d2-362248761 .stroke-N2{stroke:#676C7E;} + .d2-362248761 .stroke-N3{stroke:#9499AB;} + .d2-362248761 .stroke-N4{stroke:#CFD2DD;} + .d2-362248761 .stroke-N5{stroke:#DEE1EB;} + .d2-362248761 .stroke-N6{stroke:#EEF1F8;} + .d2-362248761 .stroke-N7{stroke:#FFFFFF;} + .d2-362248761 .stroke-B1{stroke:#0D32B2;} + .d2-362248761 .stroke-B2{stroke:#0D32B2;} + .d2-362248761 .stroke-B3{stroke:#E3E9FD;} + .d2-362248761 .stroke-B4{stroke:#E3E9FD;} + .d2-362248761 .stroke-B5{stroke:#EDF0FD;} + .d2-362248761 .stroke-B6{stroke:#F7F8FE;} + .d2-362248761 .stroke-AA2{stroke:#4A6FF3;} + .d2-362248761 .stroke-AA4{stroke:#EDF0FD;} + .d2-362248761 .stroke-AA5{stroke:#F7F8FE;} + .d2-362248761 .stroke-AB4{stroke:#EDF0FD;} + .d2-362248761 .stroke-AB5{stroke:#F7F8FE;} + .d2-362248761 .background-color-N1{background-color:#0A0F25;} + .d2-362248761 .background-color-N2{background-color:#676C7E;} + .d2-362248761 .background-color-N3{background-color:#9499AB;} + .d2-362248761 .background-color-N4{background-color:#CFD2DD;} + .d2-362248761 .background-color-N5{background-color:#DEE1EB;} + .d2-362248761 .background-color-N6{background-color:#EEF1F8;} + .d2-362248761 .background-color-N7{background-color:#FFFFFF;} + .d2-362248761 .background-color-B1{background-color:#0D32B2;} + .d2-362248761 .background-color-B2{background-color:#0D32B2;} + .d2-362248761 .background-color-B3{background-color:#E3E9FD;} + .d2-362248761 .background-color-B4{background-color:#E3E9FD;} + .d2-362248761 .background-color-B5{background-color:#EDF0FD;} + .d2-362248761 .background-color-B6{background-color:#F7F8FE;} + .d2-362248761 .background-color-AA2{background-color:#4A6FF3;} + .d2-362248761 .background-color-AA4{background-color:#EDF0FD;} + .d2-362248761 .background-color-AA5{background-color:#F7F8FE;} + .d2-362248761 .background-color-AB4{background-color:#EDF0FD;} + .d2-362248761 .background-color-AB5{background-color:#F7F8FE;} + .d2-362248761 .color-N1{color:#0A0F25;} + .d2-362248761 .color-N2{color:#676C7E;} + .d2-362248761 .color-N3{color:#9499AB;} + .d2-362248761 .color-N4{color:#CFD2DD;} + .d2-362248761 .color-N5{color:#DEE1EB;} + .d2-362248761 .color-N6{color:#EEF1F8;} + .d2-362248761 .color-N7{color:#FFFFFF;} + .d2-362248761 .color-B1{color:#0D32B2;} + .d2-362248761 .color-B2{color:#0D32B2;} + .d2-362248761 .color-B3{color:#E3E9FD;} + .d2-362248761 .color-B4{color:#E3E9FD;} + .d2-362248761 .color-B5{color:#EDF0FD;} + .d2-362248761 .color-B6{color:#F7F8FE;} + .d2-362248761 .color-AA2{color:#4A6FF3;} + .d2-362248761 .color-AA4{color:#EDF0FD;} + .d2-362248761 .color-AA5{color:#F7F8FE;} + .d2-362248761 .color-AB4{color:#EDF0FD;} + .d2-362248761 .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}]]>UseridintPKparent_idintFKspouse_idintFKPetidintPKowner_idintFKCardidintPKowner_idintFKPostidintPKtextstringauthor_idintFKMetadataidintPKageintInfoidintPKcontentjson.RawMessage spouse children/parent/ancestorpets/ownercard/ownerposts/authormetadata/userinfo/user + + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/ent2d2_right/elk/board.exp.json b/e2etests/testdata/stable/ent2d2_right/elk/board.exp.json index 31085175a..498bfb706 100644 --- a/e2etests/testdata/stable/ent2d2_right/elk/board.exp.json +++ b/e2etests/testdata/stable/ent2d2_right/elk/board.exp.json @@ -7,8 +7,8 @@ "id": "User", "type": "sql_table", "pos": { - "x": 12, - "y": 200 + "x": 72, + "y": 198 }, "width": 201, "height": 280, @@ -141,8 +141,8 @@ "id": "Pet", "type": "sql_table", "pos": { - "x": 514, - "y": 12 + "x": 571, + "y": 1406 }, "width": 194, "height": 108, @@ -245,8 +245,8 @@ "id": "Card", "type": "sql_table", "pos": { - "x": 514, - "y": 140 + "x": 571, + "y": 618 }, "width": 194, "height": 108, @@ -349,8 +349,8 @@ "id": "Post", "type": "sql_table", "pos": { - "x": 514, - "y": 268 + "x": 557, + "y": 1182 }, "width": 222, "height": 144, @@ -481,8 +481,8 @@ "id": "Metadata", "type": "sql_table", "pos": { - "x": 514, - "y": 432 + "x": 595, + "y": 806 }, "width": 146, "height": 108, @@ -584,7 +584,7 @@ "type": "sql_table", "pos": { "x": 514, - "y": 560 + "y": 994 }, "width": 308, "height": 108, @@ -708,20 +708,28 @@ "labelPercentage": 0, "route": [ { - "x": 79, - "y": 200 + "x": 97.125, + "y": 478 }, { - "x": 79, - "y": 150 + "x": 97.125, + "y": 528 }, { - "x": 146, - "y": 150 + "x": 22, + "y": 528 }, { - "x": 146, - "y": 200 + "x": 22, + "y": 148 + }, + { + "x": 139, + "y": 148 + }, + { + "x": 139, + "y": 198 } ], "animated": false, @@ -754,20 +762,28 @@ "labelPercentage": 0, "route": [ { - "x": 146, - "y": 480 + "x": 122.25, + "y": 478 }, { - "x": 146, - "y": 530 + "x": 122.25, + "y": 538 }, { - "x": 79, - "y": 530 + "x": 12, + "y": 538 }, { - "x": 79, - "y": 480 + "x": 12, + "y": 99 + }, + { + "x": 206, + "y": 99 + }, + { + "x": 206, + "y": 198 } ], "animated": false, @@ -800,20 +816,20 @@ "labelPercentage": 0, "route": [ { - "x": 213, - "y": 246.66600036621094 + "x": 147.375, + "y": 478 }, { - "x": 253, - "y": 246.66600036621094 + "x": 147.375, + "y": 1366 }, { - "x": 253, - "y": 66 + "x": 668, + "y": 1366 }, { - "x": 514, - "y": 66 + "x": 668, + "y": 1406 } ], "animated": false, @@ -846,20 +862,20 @@ "labelPercentage": 0, "route": [ { - "x": 213, - "y": 293.3330078125 + "x": 172.5, + "y": 478 }, { - "x": 303, - "y": 293.3330078125 + "x": 172.5, + "y": 578 }, { - "x": 303, - "y": 194 + "x": 668, + "y": 578 }, { - "x": 514, - "y": 194 + "x": 668, + "y": 618 } ], "animated": false, @@ -892,12 +908,20 @@ "labelPercentage": 0, "route": [ { - "x": 213, - "y": 340 + "x": 197.625, + "y": 478 }, { - "x": 514, - "y": 340 + "x": 197.625, + "y": 1142 + }, + { + "x": 668, + "y": 1142 + }, + { + "x": 668, + "y": 1182 } ], "animated": false, @@ -930,20 +954,20 @@ "labelPercentage": 0, "route": [ { - "x": 213, - "y": 386.6659851074219 + "x": 222.75, + "y": 478 }, { - "x": 303, - "y": 386.6659851074219 + "x": 222.75, + "y": 766 }, { - "x": 303, - "y": 486 + "x": 668, + "y": 766 }, { - "x": 514, - "y": 486 + "x": 668, + "y": 806 } ], "animated": false, @@ -976,20 +1000,20 @@ "labelPercentage": 0, "route": [ { - "x": 213, - "y": 433.3330078125 + "x": 247.875, + "y": 478 }, { - "x": 253, - "y": 433.3330078125 + "x": 247.875, + "y": 954 }, { - "x": 253, - "y": 614 + "x": 668, + "y": 954 }, { - "x": 514, - "y": 614 + "x": 668, + "y": 994 } ], "animated": false, diff --git a/e2etests/testdata/stable/ent2d2_right/elk/sketch.exp.svg b/e2etests/testdata/stable/ent2d2_right/elk/sketch.exp.svg index 0da128f47..518245911 100644 --- a/e2etests/testdata/stable/ent2d2_right/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/ent2d2_right/elk/sketch.exp.svg @@ -1,16 +1,16 @@ -UseridintPKparent_idintFKspouse_idintFKPetidintPKowner_idintFKCardidintPKowner_idintFKPostidintPKtextstringauthor_idintFKMetadataidintPKageintInfoidintPKcontentjson.RawMessage spousespouse childrenparentyowhoaheypets/ownercard/ownerposts/authormetadata/userinfo/user - - - - - - - - + .d2-1743102802 .fill-N1{fill:#0A0F25;} + .d2-1743102802 .fill-N2{fill:#676C7E;} + .d2-1743102802 .fill-N3{fill:#9499AB;} + .d2-1743102802 .fill-N4{fill:#CFD2DD;} + .d2-1743102802 .fill-N5{fill:#DEE1EB;} + .d2-1743102802 .fill-N6{fill:#EEF1F8;} + .d2-1743102802 .fill-N7{fill:#FFFFFF;} + .d2-1743102802 .fill-B1{fill:#0D32B2;} + .d2-1743102802 .fill-B2{fill:#0D32B2;} + .d2-1743102802 .fill-B3{fill:#E3E9FD;} + .d2-1743102802 .fill-B4{fill:#E3E9FD;} + .d2-1743102802 .fill-B5{fill:#EDF0FD;} + .d2-1743102802 .fill-B6{fill:#F7F8FE;} + .d2-1743102802 .fill-AA2{fill:#4A6FF3;} + .d2-1743102802 .fill-AA4{fill:#EDF0FD;} + .d2-1743102802 .fill-AA5{fill:#F7F8FE;} + .d2-1743102802 .fill-AB4{fill:#EDF0FD;} + .d2-1743102802 .fill-AB5{fill:#F7F8FE;} + .d2-1743102802 .stroke-N1{stroke:#0A0F25;} + .d2-1743102802 .stroke-N2{stroke:#676C7E;} + .d2-1743102802 .stroke-N3{stroke:#9499AB;} + .d2-1743102802 .stroke-N4{stroke:#CFD2DD;} + .d2-1743102802 .stroke-N5{stroke:#DEE1EB;} + .d2-1743102802 .stroke-N6{stroke:#EEF1F8;} + .d2-1743102802 .stroke-N7{stroke:#FFFFFF;} + .d2-1743102802 .stroke-B1{stroke:#0D32B2;} + .d2-1743102802 .stroke-B2{stroke:#0D32B2;} + .d2-1743102802 .stroke-B3{stroke:#E3E9FD;} + .d2-1743102802 .stroke-B4{stroke:#E3E9FD;} + .d2-1743102802 .stroke-B5{stroke:#EDF0FD;} + .d2-1743102802 .stroke-B6{stroke:#F7F8FE;} + .d2-1743102802 .stroke-AA2{stroke:#4A6FF3;} + .d2-1743102802 .stroke-AA4{stroke:#EDF0FD;} + .d2-1743102802 .stroke-AA5{stroke:#F7F8FE;} + .d2-1743102802 .stroke-AB4{stroke:#EDF0FD;} + .d2-1743102802 .stroke-AB5{stroke:#F7F8FE;} + .d2-1743102802 .background-color-N1{background-color:#0A0F25;} + .d2-1743102802 .background-color-N2{background-color:#676C7E;} + .d2-1743102802 .background-color-N3{background-color:#9499AB;} + .d2-1743102802 .background-color-N4{background-color:#CFD2DD;} + .d2-1743102802 .background-color-N5{background-color:#DEE1EB;} + .d2-1743102802 .background-color-N6{background-color:#EEF1F8;} + .d2-1743102802 .background-color-N7{background-color:#FFFFFF;} + .d2-1743102802 .background-color-B1{background-color:#0D32B2;} + .d2-1743102802 .background-color-B2{background-color:#0D32B2;} + .d2-1743102802 .background-color-B3{background-color:#E3E9FD;} + .d2-1743102802 .background-color-B4{background-color:#E3E9FD;} + .d2-1743102802 .background-color-B5{background-color:#EDF0FD;} + .d2-1743102802 .background-color-B6{background-color:#F7F8FE;} + .d2-1743102802 .background-color-AA2{background-color:#4A6FF3;} + .d2-1743102802 .background-color-AA4{background-color:#EDF0FD;} + .d2-1743102802 .background-color-AA5{background-color:#F7F8FE;} + .d2-1743102802 .background-color-AB4{background-color:#EDF0FD;} + .d2-1743102802 .background-color-AB5{background-color:#F7F8FE;} + .d2-1743102802 .color-N1{color:#0A0F25;} + .d2-1743102802 .color-N2{color:#676C7E;} + .d2-1743102802 .color-N3{color:#9499AB;} + .d2-1743102802 .color-N4{color:#CFD2DD;} + .d2-1743102802 .color-N5{color:#DEE1EB;} + .d2-1743102802 .color-N6{color:#EEF1F8;} + .d2-1743102802 .color-N7{color:#FFFFFF;} + .d2-1743102802 .color-B1{color:#0D32B2;} + .d2-1743102802 .color-B2{color:#0D32B2;} + .d2-1743102802 .color-B3{color:#E3E9FD;} + .d2-1743102802 .color-B4{color:#E3E9FD;} + .d2-1743102802 .color-B5{color:#EDF0FD;} + .d2-1743102802 .color-B6{color:#F7F8FE;} + .d2-1743102802 .color-AA2{color:#4A6FF3;} + .d2-1743102802 .color-AA4{color:#EDF0FD;} + .d2-1743102802 .color-AA5{color:#F7F8FE;} + .d2-1743102802 .color-AB4{color:#EDF0FD;} + .d2-1743102802 .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}]]>UseridintPKparent_idintFKspouse_idintFKPetidintPKowner_idintFKCardidintPKowner_idintFKPostidintPKtextstringauthor_idintFKMetadataidintPKageintInfoidintPKcontentjson.RawMessage spousespouse childrenparentyowhoaheypets/ownercard/ownerposts/authormetadata/userinfo/user + + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/sql_table_row_connections/dagre/board.exp.json b/e2etests/testdata/stable/sql_table_row_connections/dagre/board.exp.json new file mode 100644 index 000000000..e9050aa8e --- /dev/null +++ b/e2etests/testdata/stable/sql_table_row_connections/dagre/board.exp.json @@ -0,0 +1,351 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "sql_table", + "pos": { + "x": 0, + "y": 36 + }, + "width": 131, + "height": 72, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N1", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": [ + { + "name": { + "label": "id", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 15, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": [ + "primary_key" + ], + "reference": "" + } + ], + "label": "a", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + }, + { + "id": "b", + "type": "sql_table", + "pos": { + "x": 231, + "y": 0 + }, + "width": 146, + "height": 144, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N1", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": [ + { + "name": { + "label": "id", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 15, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": [ + "primary_key" + ], + "reference": "" + }, + { + "name": { + "label": "a_1", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 29, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": [ + "foreign_key" + ], + "reference": "" + }, + { + "name": { + "label": "a_2", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 30, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": [ + "foreign_key" + ], + "reference": "" + } + ], + "label": "b", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 12, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + } + ], + "connections": [ + { + "id": "(b -> a)[0]", + "src": "b", + "srcArrow": "none", + "dst": "a", + "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": 231, + "y": 66 + }, + { + "x": 191, + "y": 62.79999923706055 + }, + { + "x": 171, + "y": 62.79999923706055 + }, + { + "x": 131, + "y": 66 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(b -> a)[1]", + "src": "b", + "srcArrow": "none", + "dst": "a", + "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": 231, + "y": 78 + }, + { + "x": 191, + "y": 81.19999694824219 + }, + { + "x": 171, + "y": 81.19999694824219 + }, + { + "x": 131, + "y": 78 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ], + "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/sql_table_row_connections/dagre/sketch.exp.svg b/e2etests/testdata/stable/sql_table_row_connections/dagre/sketch.exp.svg new file mode 100644 index 000000000..3ea05b0f9 --- /dev/null +++ b/e2etests/testdata/stable/sql_table_row_connections/dagre/sketch.exp.svg @@ -0,0 +1,95 @@ +aidintPKbidintPKa_1intFKa_2intFK + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/sql_table_row_connections/elk/board.exp.json b/e2etests/testdata/stable/sql_table_row_connections/elk/board.exp.json new file mode 100644 index 000000000..d6757f931 --- /dev/null +++ b/e2etests/testdata/stable/sql_table_row_connections/elk/board.exp.json @@ -0,0 +1,341 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "sql_table", + "pos": { + "x": 12, + "y": 42 + }, + "width": 131, + "height": 80, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N1", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": [ + { + "name": { + "label": "id", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 15, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": [ + "primary_key" + ], + "reference": "" + } + ], + "label": "a", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + }, + { + "id": "b", + "type": "sql_table", + "pos": { + "x": 223, + "y": 12 + }, + "width": 146, + "height": 144, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "N1", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": [ + { + "name": { + "label": "id", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 15, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": [ + "primary_key" + ], + "reference": "" + }, + { + "name": { + "label": "a_1", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 29, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": [ + "foreign_key" + ], + "reference": "" + }, + { + "name": { + "label": "a_2", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 30, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": [ + "foreign_key" + ], + "reference": "" + } + ], + "label": "b", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 12, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + } + ], + "connections": [ + { + "id": "(b -> a)[0]", + "src": "b", + "srcArrow": "none", + "dst": "a", + "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": 223, + "y": 102 + }, + { + "x": 143, + "y": 102 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(b -> a)[1]", + "src": "b", + "srcArrow": "none", + "dst": "a", + "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": 223, + "y": 138 + }, + { + "x": 183, + "y": 138 + }, + { + "x": 183, + "y": 102 + }, + { + "x": 143, + "y": 102 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ], + "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/sql_table_row_connections/elk/sketch.exp.svg b/e2etests/testdata/stable/sql_table_row_connections/elk/sketch.exp.svg new file mode 100644 index 000000000..56d388b65 --- /dev/null +++ b/e2etests/testdata/stable/sql_table_row_connections/elk/sketch.exp.svg @@ -0,0 +1,95 @@ +aidintPKbidintPKa_1intFKa_2intFK + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/board.exp.json b/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/board.exp.json index 9e4967a4c..f64da567a 100644 --- a/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/board.exp.json +++ b/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/board.exp.json @@ -10,7 +10,7 @@ "x": 0, "y": 0 }, - "width": 60, + "width": 103, "height": 72, "opacity": 1, "strokeDash": 0, @@ -55,7 +55,9 @@ "labelWidth": 0, "labelHeight": 0 }, - "constraint": null, + "constraint": [ + "primary_key" + ], "reference": "" } ], @@ -79,10 +81,10 @@ "id": "a", "type": "sql_table", "pos": { - "x": 0, - "y": 172 + "x": 203, + "y": 0 }, - "width": 60, + "width": 101, "height": 72, "opacity": 1, "strokeDash": 0, @@ -127,7 +129,9 @@ "labelWidth": 0, "labelHeight": 0 }, - "constraint": null, + "constraint": [ + "foreign_key" + ], "reference": "" } ], @@ -150,11 +154,11 @@ ], "connections": [ { - "id": "(x -> a)[0]", - "src": "x", - "srcArrow": "none", - "dst": "a", - "dstArrow": "cf-many", + "id": "(a <-> x)[0]", + "src": "a", + "srcArrow": "cf-many", + "dst": "x", + "dstArrow": "cf-one", "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -174,20 +178,20 @@ "labelPercentage": 0, "route": [ { - "x": 30, - "y": 72 + "x": 203, + "y": 36 }, { - "x": 30, - "y": 112 + "x": 163, + "y": 36 }, { - "x": 30, - "y": 132 + "x": 143, + "y": 36 }, { - "x": 30, - "y": 172 + "x": 103, + "y": 36 } ], "isCurve": true, diff --git a/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/sketch.exp.svg b/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/sketch.exp.svg index ef9161f73..d4eb1e2bf 100644 --- a/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/sql_table_tooltip_animated/dagre/sketch.exp.svg @@ -1,10 +1,10 @@ -xyab I like turtles + .d2-3096218097 .fill-N1{fill:#0A0F25;} + .d2-3096218097 .fill-N2{fill:#676C7E;} + .d2-3096218097 .fill-N3{fill:#9499AB;} + .d2-3096218097 .fill-N4{fill:#CFD2DD;} + .d2-3096218097 .fill-N5{fill:#DEE1EB;} + .d2-3096218097 .fill-N6{fill:#EEF1F8;} + .d2-3096218097 .fill-N7{fill:#FFFFFF;} + .d2-3096218097 .fill-B1{fill:#0D32B2;} + .d2-3096218097 .fill-B2{fill:#0D32B2;} + .d2-3096218097 .fill-B3{fill:#E3E9FD;} + .d2-3096218097 .fill-B4{fill:#E3E9FD;} + .d2-3096218097 .fill-B5{fill:#EDF0FD;} + .d2-3096218097 .fill-B6{fill:#F7F8FE;} + .d2-3096218097 .fill-AA2{fill:#4A6FF3;} + .d2-3096218097 .fill-AA4{fill:#EDF0FD;} + .d2-3096218097 .fill-AA5{fill:#F7F8FE;} + .d2-3096218097 .fill-AB4{fill:#EDF0FD;} + .d2-3096218097 .fill-AB5{fill:#F7F8FE;} + .d2-3096218097 .stroke-N1{stroke:#0A0F25;} + .d2-3096218097 .stroke-N2{stroke:#676C7E;} + .d2-3096218097 .stroke-N3{stroke:#9499AB;} + .d2-3096218097 .stroke-N4{stroke:#CFD2DD;} + .d2-3096218097 .stroke-N5{stroke:#DEE1EB;} + .d2-3096218097 .stroke-N6{stroke:#EEF1F8;} + .d2-3096218097 .stroke-N7{stroke:#FFFFFF;} + .d2-3096218097 .stroke-B1{stroke:#0D32B2;} + .d2-3096218097 .stroke-B2{stroke:#0D32B2;} + .d2-3096218097 .stroke-B3{stroke:#E3E9FD;} + .d2-3096218097 .stroke-B4{stroke:#E3E9FD;} + .d2-3096218097 .stroke-B5{stroke:#EDF0FD;} + .d2-3096218097 .stroke-B6{stroke:#F7F8FE;} + .d2-3096218097 .stroke-AA2{stroke:#4A6FF3;} + .d2-3096218097 .stroke-AA4{stroke:#EDF0FD;} + .d2-3096218097 .stroke-AA5{stroke:#F7F8FE;} + .d2-3096218097 .stroke-AB4{stroke:#EDF0FD;} + .d2-3096218097 .stroke-AB5{stroke:#F7F8FE;} + .d2-3096218097 .background-color-N1{background-color:#0A0F25;} + .d2-3096218097 .background-color-N2{background-color:#676C7E;} + .d2-3096218097 .background-color-N3{background-color:#9499AB;} + .d2-3096218097 .background-color-N4{background-color:#CFD2DD;} + .d2-3096218097 .background-color-N5{background-color:#DEE1EB;} + .d2-3096218097 .background-color-N6{background-color:#EEF1F8;} + .d2-3096218097 .background-color-N7{background-color:#FFFFFF;} + .d2-3096218097 .background-color-B1{background-color:#0D32B2;} + .d2-3096218097 .background-color-B2{background-color:#0D32B2;} + .d2-3096218097 .background-color-B3{background-color:#E3E9FD;} + .d2-3096218097 .background-color-B4{background-color:#E3E9FD;} + .d2-3096218097 .background-color-B5{background-color:#EDF0FD;} + .d2-3096218097 .background-color-B6{background-color:#F7F8FE;} + .d2-3096218097 .background-color-AA2{background-color:#4A6FF3;} + .d2-3096218097 .background-color-AA4{background-color:#EDF0FD;} + .d2-3096218097 .background-color-AA5{background-color:#F7F8FE;} + .d2-3096218097 .background-color-AB4{background-color:#EDF0FD;} + .d2-3096218097 .background-color-AB5{background-color:#F7F8FE;} + .d2-3096218097 .color-N1{color:#0A0F25;} + .d2-3096218097 .color-N2{color:#676C7E;} + .d2-3096218097 .color-N3{color:#9499AB;} + .d2-3096218097 .color-N4{color:#CFD2DD;} + .d2-3096218097 .color-N5{color:#DEE1EB;} + .d2-3096218097 .color-N6{color:#EEF1F8;} + .d2-3096218097 .color-N7{color:#FFFFFF;} + .d2-3096218097 .color-B1{color:#0D32B2;} + .d2-3096218097 .color-B2{color:#0D32B2;} + .d2-3096218097 .color-B3{color:#E3E9FD;} + .d2-3096218097 .color-B4{color:#E3E9FD;} + .d2-3096218097 .color-B5{color:#EDF0FD;} + .d2-3096218097 .color-B6{color:#F7F8FE;} + .d2-3096218097 .color-AA2{color:#4A6FF3;} + .d2-3096218097 .color-AA4{color:#EDF0FD;} + .d2-3096218097 .color-AA5{color:#F7F8FE;} + .d2-3096218097 .color-AB4{color:#EDF0FD;} + .d2-3096218097 .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}]]>xyPKabFK I like turtles @@ -111,7 +111,7 @@ - - + + \ No newline at end of file diff --git a/e2etests/testdata/stable/sql_table_tooltip_animated/elk/board.exp.json b/e2etests/testdata/stable/sql_table_tooltip_animated/elk/board.exp.json index 613062453..17929a530 100644 --- a/e2etests/testdata/stable/sql_table_tooltip_animated/elk/board.exp.json +++ b/e2etests/testdata/stable/sql_table_tooltip_animated/elk/board.exp.json @@ -10,7 +10,7 @@ "x": 12, "y": 12 }, - "width": 60, + "width": 103, "height": 72, "opacity": 1, "strokeDash": 0, @@ -55,7 +55,9 @@ "labelWidth": 0, "labelHeight": 0 }, - "constraint": null, + "constraint": [ + "primary_key" + ], "reference": "" } ], @@ -79,10 +81,10 @@ "id": "a", "type": "sql_table", "pos": { - "x": 12, - "y": 154 + "x": 185, + "y": 12 }, - "width": 60, + "width": 101, "height": 72, "opacity": 1, "strokeDash": 0, @@ -127,7 +129,9 @@ "labelWidth": 0, "labelHeight": 0 }, - "constraint": null, + "constraint": [ + "foreign_key" + ], "reference": "" } ], @@ -150,11 +154,11 @@ ], "connections": [ { - "id": "(x -> a)[0]", - "src": "x", - "srcArrow": "none", - "dst": "a", - "dstArrow": "cf-many", + "id": "(a <-> x)[0]", + "src": "a", + "srcArrow": "cf-many", + "dst": "x", + "dstArrow": "cf-one", "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -174,12 +178,12 @@ "labelPercentage": 0, "route": [ { - "x": 42, - "y": 84 + "x": 185, + "y": 66 }, { - "x": 42, - "y": 154 + "x": 115, + "y": 66 } ], "animated": true, diff --git a/e2etests/testdata/stable/sql_table_tooltip_animated/elk/sketch.exp.svg b/e2etests/testdata/stable/sql_table_tooltip_animated/elk/sketch.exp.svg index 33df82d73..3f7f76b1a 100644 --- a/e2etests/testdata/stable/sql_table_tooltip_animated/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/sql_table_tooltip_animated/elk/sketch.exp.svg @@ -1,10 +1,10 @@ -xyab I like turtles + .d2-3579465052 .fill-N1{fill:#0A0F25;} + .d2-3579465052 .fill-N2{fill:#676C7E;} + .d2-3579465052 .fill-N3{fill:#9499AB;} + .d2-3579465052 .fill-N4{fill:#CFD2DD;} + .d2-3579465052 .fill-N5{fill:#DEE1EB;} + .d2-3579465052 .fill-N6{fill:#EEF1F8;} + .d2-3579465052 .fill-N7{fill:#FFFFFF;} + .d2-3579465052 .fill-B1{fill:#0D32B2;} + .d2-3579465052 .fill-B2{fill:#0D32B2;} + .d2-3579465052 .fill-B3{fill:#E3E9FD;} + .d2-3579465052 .fill-B4{fill:#E3E9FD;} + .d2-3579465052 .fill-B5{fill:#EDF0FD;} + .d2-3579465052 .fill-B6{fill:#F7F8FE;} + .d2-3579465052 .fill-AA2{fill:#4A6FF3;} + .d2-3579465052 .fill-AA4{fill:#EDF0FD;} + .d2-3579465052 .fill-AA5{fill:#F7F8FE;} + .d2-3579465052 .fill-AB4{fill:#EDF0FD;} + .d2-3579465052 .fill-AB5{fill:#F7F8FE;} + .d2-3579465052 .stroke-N1{stroke:#0A0F25;} + .d2-3579465052 .stroke-N2{stroke:#676C7E;} + .d2-3579465052 .stroke-N3{stroke:#9499AB;} + .d2-3579465052 .stroke-N4{stroke:#CFD2DD;} + .d2-3579465052 .stroke-N5{stroke:#DEE1EB;} + .d2-3579465052 .stroke-N6{stroke:#EEF1F8;} + .d2-3579465052 .stroke-N7{stroke:#FFFFFF;} + .d2-3579465052 .stroke-B1{stroke:#0D32B2;} + .d2-3579465052 .stroke-B2{stroke:#0D32B2;} + .d2-3579465052 .stroke-B3{stroke:#E3E9FD;} + .d2-3579465052 .stroke-B4{stroke:#E3E9FD;} + .d2-3579465052 .stroke-B5{stroke:#EDF0FD;} + .d2-3579465052 .stroke-B6{stroke:#F7F8FE;} + .d2-3579465052 .stroke-AA2{stroke:#4A6FF3;} + .d2-3579465052 .stroke-AA4{stroke:#EDF0FD;} + .d2-3579465052 .stroke-AA5{stroke:#F7F8FE;} + .d2-3579465052 .stroke-AB4{stroke:#EDF0FD;} + .d2-3579465052 .stroke-AB5{stroke:#F7F8FE;} + .d2-3579465052 .background-color-N1{background-color:#0A0F25;} + .d2-3579465052 .background-color-N2{background-color:#676C7E;} + .d2-3579465052 .background-color-N3{background-color:#9499AB;} + .d2-3579465052 .background-color-N4{background-color:#CFD2DD;} + .d2-3579465052 .background-color-N5{background-color:#DEE1EB;} + .d2-3579465052 .background-color-N6{background-color:#EEF1F8;} + .d2-3579465052 .background-color-N7{background-color:#FFFFFF;} + .d2-3579465052 .background-color-B1{background-color:#0D32B2;} + .d2-3579465052 .background-color-B2{background-color:#0D32B2;} + .d2-3579465052 .background-color-B3{background-color:#E3E9FD;} + .d2-3579465052 .background-color-B4{background-color:#E3E9FD;} + .d2-3579465052 .background-color-B5{background-color:#EDF0FD;} + .d2-3579465052 .background-color-B6{background-color:#F7F8FE;} + .d2-3579465052 .background-color-AA2{background-color:#4A6FF3;} + .d2-3579465052 .background-color-AA4{background-color:#EDF0FD;} + .d2-3579465052 .background-color-AA5{background-color:#F7F8FE;} + .d2-3579465052 .background-color-AB4{background-color:#EDF0FD;} + .d2-3579465052 .background-color-AB5{background-color:#F7F8FE;} + .d2-3579465052 .color-N1{color:#0A0F25;} + .d2-3579465052 .color-N2{color:#676C7E;} + .d2-3579465052 .color-N3{color:#9499AB;} + .d2-3579465052 .color-N4{color:#CFD2DD;} + .d2-3579465052 .color-N5{color:#DEE1EB;} + .d2-3579465052 .color-N6{color:#EEF1F8;} + .d2-3579465052 .color-N7{color:#FFFFFF;} + .d2-3579465052 .color-B1{color:#0D32B2;} + .d2-3579465052 .color-B2{color:#0D32B2;} + .d2-3579465052 .color-B3{color:#E3E9FD;} + .d2-3579465052 .color-B4{color:#E3E9FD;} + .d2-3579465052 .color-B5{color:#EDF0FD;} + .d2-3579465052 .color-B6{color:#F7F8FE;} + .d2-3579465052 .color-AA2{color:#4A6FF3;} + .d2-3579465052 .color-AA4{color:#EDF0FD;} + .d2-3579465052 .color-AA5{color:#F7F8FE;} + .d2-3579465052 .color-AB4{color:#EDF0FD;} + .d2-3579465052 .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}]]>xyPKabFK I like turtles @@ -111,7 +111,7 @@ - - + + \ No newline at end of file diff --git a/e2etests/testdata/stable/sql_tables/dagre/board.exp.json b/e2etests/testdata/stable/sql_tables/dagre/board.exp.json index c400a4c67..51aa78d86 100644 --- a/e2etests/testdata/stable/sql_tables/dagre/board.exp.json +++ b/e2etests/testdata/stable/sql_tables/dagre/board.exp.json @@ -55,7 +55,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "primary_key" + ], "reference": "" }, { @@ -167,9 +169,7 @@ "labelWidth": 77, "labelHeight": 26 }, - "constraint": [ - "primary_key" - ], + "constraint": null, "reference": "" } ], @@ -193,10 +193,10 @@ "id": "products", "type": "sql_table", "pos": { - "x": 311, - "y": 18 + "x": 22, + "y": 276 }, - "width": 164, + "width": 207, "height": 180, "opacity": 1, "strokeDash": 0, @@ -241,7 +241,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "primary_key" + ], "reference": "" }, { @@ -349,10 +351,10 @@ "id": "orders", "type": "sql_table", "pos": { - "x": 311, - "y": 316 + "x": 351, + "y": 165 }, - "width": 164, + "width": 207, "height": 144, "opacity": 1, "strokeDash": 0, @@ -397,7 +399,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "primary_key" + ], "reference": "" }, { @@ -425,7 +429,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "foreign_key" + ], "reference": "" }, { @@ -453,7 +459,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "foreign_key" + ], "reference": "" } ], @@ -477,10 +485,10 @@ "id": "shipments", "type": "sql_table", "pos": { - "x": 535, - "y": 18 + "x": 658, + "y": 147 }, - "width": 244, + "width": 287, "height": 180, "opacity": 1, "strokeDash": 0, @@ -525,7 +533,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "primary_key" + ], "reference": "" }, { @@ -553,7 +563,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "foreign_key" + ], "reference": "" }, { @@ -632,10 +644,10 @@ ], "connections": [ { - "id": "(users <-> orders)[0]", - "src": "users", - "srcArrow": "triangle", - "dst": "orders", + "id": "(orders -> users)[0]", + "src": "orders", + "srcArrow": "none", + "dst": "users", "dstArrow": "triangle", "opacity": 1, "strokeDash": 0, @@ -656,20 +668,20 @@ "labelPercentage": 0, "route": [ { - "x": 125.5, - "y": 216 + "x": 369, + "y": 165 }, { - "x": 125.5, - "y": 256 + "x": 314.6000061035156, + "y": 119.4000015258789 }, { - "x": 162.6999969482422, - "y": 283 + "x": 291, + "y": 108 }, { - "x": 311.5, - "y": 351 + "x": 251, + "y": 108 } ], "isCurve": true, @@ -679,10 +691,10 @@ "zIndex": 0 }, { - "id": "(products <-> orders)[0]", - "src": "products", - "srcArrow": "triangle", - "dst": "orders", + "id": "(orders -> products)[0]", + "src": "orders", + "srcArrow": "none", + "dst": "products", "dstArrow": "triangle", "opacity": 1, "strokeDash": 0, @@ -703,20 +715,20 @@ "labelPercentage": 0, "route": [ { - "x": 393, - "y": 198 + "x": 369, + "y": 309 }, { - "x": 393, - "y": 252.39999389648438 + "x": 314.6000061035156, + "y": 354.6000061035156 }, { - "x": 393, - "y": 276 + "x": 286.6000061035156, + "y": 366 }, { - "x": 393, - "y": 316 + "x": 229, + "y": 366 } ], "isCurve": true, @@ -726,9 +738,9 @@ "zIndex": 0 }, { - "id": "(shipments <-> orders)[0]", + "id": "(shipments -> orders)[0]", "src": "shipments", - "srcArrow": "triangle", + "srcArrow": "none", "dst": "orders", "dstArrow": "triangle", "opacity": 1, @@ -750,20 +762,20 @@ "labelPercentage": 0, "route": [ { - "x": 657, - "y": 198 + "x": 658, + "y": 237 }, { - "x": 657, - "y": 252.39999389648438 + "x": 618, + "y": 237 }, { - "x": 620.5999755859375, - "y": 282.79998779296875 + "x": 598, + "y": 237 }, { - "x": 475, - "y": 350 + "x": 558, + "y": 237 } ], "isCurve": true, diff --git a/e2etests/testdata/stable/sql_tables/dagre/sketch.exp.svg b/e2etests/testdata/stable/sql_tables/dagre/sketch.exp.svg index fb4818f76..393a9e13c 100644 --- a/e2etests/testdata/stable/sql_tables/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/sql_tables/dagre/sketch.exp.svg @@ -1,10 +1,10 @@ -usersidintnamestringemailstringpasswordstringlast_logindatetimePKproductsidintpricedecimalskustringnamestringordersidintuser_idintproduct_idintshipmentsidintorder_idinttracking_numberstringstatusstring - + .d2-1770468726 .fill-N1{fill:#0A0F25;} + .d2-1770468726 .fill-N2{fill:#676C7E;} + .d2-1770468726 .fill-N3{fill:#9499AB;} + .d2-1770468726 .fill-N4{fill:#CFD2DD;} + .d2-1770468726 .fill-N5{fill:#DEE1EB;} + .d2-1770468726 .fill-N6{fill:#EEF1F8;} + .d2-1770468726 .fill-N7{fill:#FFFFFF;} + .d2-1770468726 .fill-B1{fill:#0D32B2;} + .d2-1770468726 .fill-B2{fill:#0D32B2;} + .d2-1770468726 .fill-B3{fill:#E3E9FD;} + .d2-1770468726 .fill-B4{fill:#E3E9FD;} + .d2-1770468726 .fill-B5{fill:#EDF0FD;} + .d2-1770468726 .fill-B6{fill:#F7F8FE;} + .d2-1770468726 .fill-AA2{fill:#4A6FF3;} + .d2-1770468726 .fill-AA4{fill:#EDF0FD;} + .d2-1770468726 .fill-AA5{fill:#F7F8FE;} + .d2-1770468726 .fill-AB4{fill:#EDF0FD;} + .d2-1770468726 .fill-AB5{fill:#F7F8FE;} + .d2-1770468726 .stroke-N1{stroke:#0A0F25;} + .d2-1770468726 .stroke-N2{stroke:#676C7E;} + .d2-1770468726 .stroke-N3{stroke:#9499AB;} + .d2-1770468726 .stroke-N4{stroke:#CFD2DD;} + .d2-1770468726 .stroke-N5{stroke:#DEE1EB;} + .d2-1770468726 .stroke-N6{stroke:#EEF1F8;} + .d2-1770468726 .stroke-N7{stroke:#FFFFFF;} + .d2-1770468726 .stroke-B1{stroke:#0D32B2;} + .d2-1770468726 .stroke-B2{stroke:#0D32B2;} + .d2-1770468726 .stroke-B3{stroke:#E3E9FD;} + .d2-1770468726 .stroke-B4{stroke:#E3E9FD;} + .d2-1770468726 .stroke-B5{stroke:#EDF0FD;} + .d2-1770468726 .stroke-B6{stroke:#F7F8FE;} + .d2-1770468726 .stroke-AA2{stroke:#4A6FF3;} + .d2-1770468726 .stroke-AA4{stroke:#EDF0FD;} + .d2-1770468726 .stroke-AA5{stroke:#F7F8FE;} + .d2-1770468726 .stroke-AB4{stroke:#EDF0FD;} + .d2-1770468726 .stroke-AB5{stroke:#F7F8FE;} + .d2-1770468726 .background-color-N1{background-color:#0A0F25;} + .d2-1770468726 .background-color-N2{background-color:#676C7E;} + .d2-1770468726 .background-color-N3{background-color:#9499AB;} + .d2-1770468726 .background-color-N4{background-color:#CFD2DD;} + .d2-1770468726 .background-color-N5{background-color:#DEE1EB;} + .d2-1770468726 .background-color-N6{background-color:#EEF1F8;} + .d2-1770468726 .background-color-N7{background-color:#FFFFFF;} + .d2-1770468726 .background-color-B1{background-color:#0D32B2;} + .d2-1770468726 .background-color-B2{background-color:#0D32B2;} + .d2-1770468726 .background-color-B3{background-color:#E3E9FD;} + .d2-1770468726 .background-color-B4{background-color:#E3E9FD;} + .d2-1770468726 .background-color-B5{background-color:#EDF0FD;} + .d2-1770468726 .background-color-B6{background-color:#F7F8FE;} + .d2-1770468726 .background-color-AA2{background-color:#4A6FF3;} + .d2-1770468726 .background-color-AA4{background-color:#EDF0FD;} + .d2-1770468726 .background-color-AA5{background-color:#F7F8FE;} + .d2-1770468726 .background-color-AB4{background-color:#EDF0FD;} + .d2-1770468726 .background-color-AB5{background-color:#F7F8FE;} + .d2-1770468726 .color-N1{color:#0A0F25;} + .d2-1770468726 .color-N2{color:#676C7E;} + .d2-1770468726 .color-N3{color:#9499AB;} + .d2-1770468726 .color-N4{color:#CFD2DD;} + .d2-1770468726 .color-N5{color:#DEE1EB;} + .d2-1770468726 .color-N6{color:#EEF1F8;} + .d2-1770468726 .color-N7{color:#FFFFFF;} + .d2-1770468726 .color-B1{color:#0D32B2;} + .d2-1770468726 .color-B2{color:#0D32B2;} + .d2-1770468726 .color-B3{color:#E3E9FD;} + .d2-1770468726 .color-B4{color:#E3E9FD;} + .d2-1770468726 .color-B5{color:#EDF0FD;} + .d2-1770468726 .color-B6{color:#F7F8FE;} + .d2-1770468726 .color-AA2{color:#4A6FF3;} + .d2-1770468726 .color-AA4{color:#EDF0FD;} + .d2-1770468726 .color-AA5{color:#F7F8FE;} + .d2-1770468726 .color-AB4{color:#EDF0FD;} + .d2-1770468726 .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}]]>usersidintPKnamestringemailstringpasswordstringlast_logindatetimeproductsidintPKpricedecimalskustringnamestringordersidintPKuser_idintFKproduct_idintFKshipmentsidintPKorder_idintFKtracking_numberstringstatusstring + \ No newline at end of file diff --git a/e2etests/testdata/stable/sql_tables/elk/board.exp.json b/e2etests/testdata/stable/sql_tables/elk/board.exp.json index fece8e814..6592421bd 100644 --- a/e2etests/testdata/stable/sql_tables/elk/board.exp.json +++ b/e2etests/testdata/stable/sql_tables/elk/board.exp.json @@ -55,7 +55,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "primary_key" + ], "reference": "" }, { @@ -167,9 +169,7 @@ "labelWidth": 77, "labelHeight": 26 }, - "constraint": [ - "primary_key" - ], + "constraint": null, "reference": "" } ], @@ -193,10 +193,10 @@ "id": "products", "type": "sql_table", "pos": { - "x": 283, - "y": 48 + "x": 56, + "y": 248 }, - "width": 164, + "width": 207, "height": 180, "opacity": 1, "strokeDash": 0, @@ -241,7 +241,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "primary_key" + ], "reference": "" }, { @@ -349,10 +351,10 @@ "id": "orders", "type": "sql_table", "pos": { - "x": 283, - "y": 308 + "x": 343, + "y": 76 }, - "width": 164, + "width": 207, "height": 144, "opacity": 1, "strokeDash": 0, @@ -397,7 +399,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "primary_key" + ], "reference": "" }, { @@ -425,7 +429,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "foreign_key" + ], "reference": "" }, { @@ -453,7 +459,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "foreign_key" + ], "reference": "" } ], @@ -477,10 +485,10 @@ "id": "shipments", "type": "sql_table", "pos": { - "x": 467, - "y": 48 + "x": 620, + "y": 40 }, - "width": 244, + "width": 287, "height": 180, "opacity": 1, "strokeDash": 0, @@ -525,7 +533,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "primary_key" + ], "reference": "" }, { @@ -553,7 +563,9 @@ "labelWidth": 23, "labelHeight": 26 }, - "constraint": null, + "constraint": [ + "foreign_key" + ], "reference": "" }, { @@ -632,10 +644,10 @@ ], "connections": [ { - "id": "(users <-> orders)[0]", - "src": "users", - "srcArrow": "triangle", - "dst": "orders", + "id": "(orders -> users)[0]", + "src": "orders", + "srcArrow": "none", + "dst": "users", "dstArrow": "triangle", "opacity": 1, "strokeDash": 0, @@ -656,20 +668,20 @@ "labelPercentage": 0, "route": [ { - "x": 137.5, - "y": 228 + "x": 343, + "y": 166 }, { - "x": 137.5, - "y": 268 + "x": 303, + "y": 166 }, { - "x": 324, - "y": 268 + "x": 303, + "y": 66 }, { - "x": 324, - "y": 308 + "x": 263, + "y": 66 } ], "animated": false, @@ -678,10 +690,10 @@ "zIndex": 0 }, { - "id": "(products <-> orders)[0]", - "src": "products", - "srcArrow": "triangle", - "dst": "orders", + "id": "(orders -> products)[0]", + "src": "orders", + "srcArrow": "none", + "dst": "products", "dstArrow": "triangle", "opacity": 1, "strokeDash": 0, @@ -702,12 +714,20 @@ "labelPercentage": 0, "route": [ { - "x": 365, - "y": 228 + "x": 343, + "y": 202 }, { - "x": 365, - "y": 308 + "x": 303, + "y": 202 + }, + { + "x": 303, + "y": 302 + }, + { + "x": 263, + "y": 302 } ], "animated": false, @@ -716,9 +736,9 @@ "zIndex": 0 }, { - "id": "(shipments <-> orders)[0]", + "id": "(shipments -> orders)[0]", "src": "shipments", - "srcArrow": "triangle", + "srcArrow": "none", "dst": "orders", "dstArrow": "triangle", "opacity": 1, @@ -740,20 +760,12 @@ "labelPercentage": 0, "route": [ { - "x": 589, - "y": 228 + "x": 620, + "y": 130 }, { - "x": 589, - "y": 268 - }, - { - "x": 406, - "y": 268 - }, - { - "x": 406, - "y": 308 + "x": 550, + "y": 130 } ], "animated": false, diff --git a/e2etests/testdata/stable/sql_tables/elk/sketch.exp.svg b/e2etests/testdata/stable/sql_tables/elk/sketch.exp.svg index 30dfab403..bcc2129f1 100644 --- a/e2etests/testdata/stable/sql_tables/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/sql_tables/elk/sketch.exp.svg @@ -1,10 +1,10 @@ -usersidintnamestringemailstringpasswordstringlast_logindatetimePKproductsidintpricedecimalskustringnamestringordersidintuser_idintproduct_idintshipmentsidintorder_idinttracking_numberstringstatusstring - + .d2-2764772137 .fill-N1{fill:#0A0F25;} + .d2-2764772137 .fill-N2{fill:#676C7E;} + .d2-2764772137 .fill-N3{fill:#9499AB;} + .d2-2764772137 .fill-N4{fill:#CFD2DD;} + .d2-2764772137 .fill-N5{fill:#DEE1EB;} + .d2-2764772137 .fill-N6{fill:#EEF1F8;} + .d2-2764772137 .fill-N7{fill:#FFFFFF;} + .d2-2764772137 .fill-B1{fill:#0D32B2;} + .d2-2764772137 .fill-B2{fill:#0D32B2;} + .d2-2764772137 .fill-B3{fill:#E3E9FD;} + .d2-2764772137 .fill-B4{fill:#E3E9FD;} + .d2-2764772137 .fill-B5{fill:#EDF0FD;} + .d2-2764772137 .fill-B6{fill:#F7F8FE;} + .d2-2764772137 .fill-AA2{fill:#4A6FF3;} + .d2-2764772137 .fill-AA4{fill:#EDF0FD;} + .d2-2764772137 .fill-AA5{fill:#F7F8FE;} + .d2-2764772137 .fill-AB4{fill:#EDF0FD;} + .d2-2764772137 .fill-AB5{fill:#F7F8FE;} + .d2-2764772137 .stroke-N1{stroke:#0A0F25;} + .d2-2764772137 .stroke-N2{stroke:#676C7E;} + .d2-2764772137 .stroke-N3{stroke:#9499AB;} + .d2-2764772137 .stroke-N4{stroke:#CFD2DD;} + .d2-2764772137 .stroke-N5{stroke:#DEE1EB;} + .d2-2764772137 .stroke-N6{stroke:#EEF1F8;} + .d2-2764772137 .stroke-N7{stroke:#FFFFFF;} + .d2-2764772137 .stroke-B1{stroke:#0D32B2;} + .d2-2764772137 .stroke-B2{stroke:#0D32B2;} + .d2-2764772137 .stroke-B3{stroke:#E3E9FD;} + .d2-2764772137 .stroke-B4{stroke:#E3E9FD;} + .d2-2764772137 .stroke-B5{stroke:#EDF0FD;} + .d2-2764772137 .stroke-B6{stroke:#F7F8FE;} + .d2-2764772137 .stroke-AA2{stroke:#4A6FF3;} + .d2-2764772137 .stroke-AA4{stroke:#EDF0FD;} + .d2-2764772137 .stroke-AA5{stroke:#F7F8FE;} + .d2-2764772137 .stroke-AB4{stroke:#EDF0FD;} + .d2-2764772137 .stroke-AB5{stroke:#F7F8FE;} + .d2-2764772137 .background-color-N1{background-color:#0A0F25;} + .d2-2764772137 .background-color-N2{background-color:#676C7E;} + .d2-2764772137 .background-color-N3{background-color:#9499AB;} + .d2-2764772137 .background-color-N4{background-color:#CFD2DD;} + .d2-2764772137 .background-color-N5{background-color:#DEE1EB;} + .d2-2764772137 .background-color-N6{background-color:#EEF1F8;} + .d2-2764772137 .background-color-N7{background-color:#FFFFFF;} + .d2-2764772137 .background-color-B1{background-color:#0D32B2;} + .d2-2764772137 .background-color-B2{background-color:#0D32B2;} + .d2-2764772137 .background-color-B3{background-color:#E3E9FD;} + .d2-2764772137 .background-color-B4{background-color:#E3E9FD;} + .d2-2764772137 .background-color-B5{background-color:#EDF0FD;} + .d2-2764772137 .background-color-B6{background-color:#F7F8FE;} + .d2-2764772137 .background-color-AA2{background-color:#4A6FF3;} + .d2-2764772137 .background-color-AA4{background-color:#EDF0FD;} + .d2-2764772137 .background-color-AA5{background-color:#F7F8FE;} + .d2-2764772137 .background-color-AB4{background-color:#EDF0FD;} + .d2-2764772137 .background-color-AB5{background-color:#F7F8FE;} + .d2-2764772137 .color-N1{color:#0A0F25;} + .d2-2764772137 .color-N2{color:#676C7E;} + .d2-2764772137 .color-N3{color:#9499AB;} + .d2-2764772137 .color-N4{color:#CFD2DD;} + .d2-2764772137 .color-N5{color:#DEE1EB;} + .d2-2764772137 .color-N6{color:#EEF1F8;} + .d2-2764772137 .color-N7{color:#FFFFFF;} + .d2-2764772137 .color-B1{color:#0D32B2;} + .d2-2764772137 .color-B2{color:#0D32B2;} + .d2-2764772137 .color-B3{color:#E3E9FD;} + .d2-2764772137 .color-B4{color:#E3E9FD;} + .d2-2764772137 .color-B5{color:#EDF0FD;} + .d2-2764772137 .color-B6{color:#F7F8FE;} + .d2-2764772137 .color-AA2{color:#4A6FF3;} + .d2-2764772137 .color-AA4{color:#EDF0FD;} + .d2-2764772137 .color-AA5{color:#F7F8FE;} + .d2-2764772137 .color-AB4{color:#EDF0FD;} + .d2-2764772137 .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}]]>usersidintPKnamestringemailstringpasswordstringlast_logindatetimeproductsidintPKpricedecimalskustringnamestringordersidintPKuser_idintFKproduct_idintFKshipmentsidintPKorder_idintFKtracking_numberstringstatusstring + \ No newline at end of file