fix dagre node ordering
This commit is contained in:
parent
0d370cc600
commit
557e097a42
4 changed files with 31 additions and 27 deletions
|
|
@ -30,6 +30,7 @@ var setupJS string
|
||||||
var dagreJS string
|
var dagreJS string
|
||||||
|
|
||||||
type DagreNode struct {
|
type DagreNode struct {
|
||||||
|
ID string `json:"id"`
|
||||||
X float64 `json:"x"`
|
X float64 `json:"x"`
|
||||||
Y float64 `json:"y"`
|
Y float64 `json:"y"`
|
||||||
Width float64 `json:"width"`
|
Width float64 `json:"width"`
|
||||||
|
|
@ -49,7 +50,7 @@ type dagreGraphAttrs struct {
|
||||||
rankdir string
|
rankdir string
|
||||||
}
|
}
|
||||||
|
|
||||||
func Layout(ctx context.Context, d2graph *d2graph.Graph) (err error) {
|
func Layout(ctx context.Context, g *d2graph.Graph) (err error) {
|
||||||
defer xdefer.Errorf(&err, "failed to dagre layout")
|
defer xdefer.Errorf(&err, "failed to dagre layout")
|
||||||
|
|
||||||
debugJS := false
|
debugJS := false
|
||||||
|
|
@ -66,7 +67,7 @@ func Layout(ctx context.Context, d2graph *d2graph.Graph) (err error) {
|
||||||
edgesep: 40,
|
edgesep: 40,
|
||||||
nodesep: 60,
|
nodesep: 60,
|
||||||
}
|
}
|
||||||
switch d2graph.Root.Attributes.Direction.Value {
|
switch g.Root.Attributes.Direction.Value {
|
||||||
case "down":
|
case "down":
|
||||||
rootAttrs.rankdir = "TB"
|
rootAttrs.rankdir = "TB"
|
||||||
case "right":
|
case "right":
|
||||||
|
|
@ -84,14 +85,16 @@ func Layout(ctx context.Context, d2graph *d2graph.Graph) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadScript := ""
|
loadScript := ""
|
||||||
for _, obj := range d2graph.Objects {
|
idToObj := make(map[string]*d2graph.Object)
|
||||||
|
for _, obj := range g.Objects {
|
||||||
id := obj.AbsID()
|
id := obj.AbsID()
|
||||||
|
idToObj[id] = obj
|
||||||
loadScript += generateAddNodeLine(id, int(obj.Width), int(obj.Height))
|
loadScript += generateAddNodeLine(id, int(obj.Width), int(obj.Height))
|
||||||
if obj.Parent != d2graph.Root {
|
if obj.Parent != g.Root {
|
||||||
loadScript += generateAddParentLine(id, obj.Parent.AbsID())
|
loadScript += generateAddParentLine(id, obj.Parent.AbsID())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, edge := range d2graph.Edges {
|
for _, edge := range g.Edges {
|
||||||
// dagre doesn't work with edges to containers so we connect container edges to their first child instead (going all the way down)
|
// dagre doesn't work with edges to containers so we connect container edges to their first child instead (going all the way down)
|
||||||
// we will chop the edge where it intersects the container border so it only shows the edge from the container
|
// we will chop the edge where it intersects the container border so it only shows the edge from the container
|
||||||
src := edge.Src
|
src := edge.Src
|
||||||
|
|
@ -124,13 +127,7 @@ func Layout(ctx context.Context, d2graph *d2graph.Graph) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// val, err := v8ctx.RunScript("JSON.stringify(dagre.graphlib.json.write(g))", "q.js")
|
for i := range g.Objects {
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// log.Debug(ctx, "graph", slog.F("json", val.String()))
|
|
||||||
|
|
||||||
for i, obj := range d2graph.Objects {
|
|
||||||
val, err := v8ctx.RunScript(fmt.Sprintf("JSON.stringify(g.node(g.nodes()[%d]))", i), "value.js")
|
val, err := v8ctx.RunScript(fmt.Sprintf("JSON.stringify(g.node(g.nodes()[%d]))", i), "value.js")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -139,6 +136,11 @@ func Layout(ctx context.Context, d2graph *d2graph.Graph) (err error) {
|
||||||
if err := json.Unmarshal([]byte(val.String()), &dn); err != nil {
|
if err := json.Unmarshal([]byte(val.String()), &dn); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if debugJS {
|
||||||
|
log.Debug(ctx, "graph", slog.F("json", dn))
|
||||||
|
}
|
||||||
|
|
||||||
|
obj := idToObj[dn.ID]
|
||||||
|
|
||||||
// dagre gives center of node
|
// dagre gives center of node
|
||||||
obj.TopLeft = geo.NewPoint(math.Round(dn.X-dn.Width/2), math.Round(dn.Y-dn.Height/2))
|
obj.TopLeft = geo.NewPoint(math.Round(dn.X-dn.Width/2), math.Round(dn.Y-dn.Height/2))
|
||||||
|
|
@ -159,7 +161,7 @@ func Layout(ctx context.Context, d2graph *d2graph.Graph) (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, edge := range d2graph.Edges {
|
for i, edge := range g.Edges {
|
||||||
val, err := v8ctx.RunScript(fmt.Sprintf("JSON.stringify(g.edge(g.edges()[%d]))", i), "value.js")
|
val, err := v8ctx.RunScript(fmt.Sprintf("JSON.stringify(g.edge(g.edges()[%d]))", i), "value.js")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -168,6 +170,9 @@ func Layout(ctx context.Context, d2graph *d2graph.Graph) (err error) {
|
||||||
if err := json.Unmarshal([]byte(val.String()), &de); err != nil {
|
if err := json.Unmarshal([]byte(val.String()), &de); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if debugJS {
|
||||||
|
log.Debug(ctx, "graph", slog.F("json", de))
|
||||||
|
}
|
||||||
|
|
||||||
points := make([]*geo.Point, len(de.Points))
|
points := make([]*geo.Point, len(de.Points))
|
||||||
for i := range de.Points {
|
for i := range de.Points {
|
||||||
|
|
@ -250,7 +255,7 @@ func setGraphAttrs(attrs dagreGraphAttrs) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateAddNodeLine(id string, width, height int) string {
|
func generateAddNodeLine(id string, width, height int) string {
|
||||||
return fmt.Sprintf("g.setNode(`%s`, { width: %d, height: %d });\n", id, width, height)
|
return fmt.Sprintf("g.setNode(`%s`, { id: `%s`, width: %d, height: %d });\n", id, id, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateAddParentLine(childID, parentID string) string {
|
func generateAddParentLine(childID, parentID string) string {
|
||||||
|
|
|
||||||
|
|
@ -1213,7 +1213,6 @@ finally.sequence.scorer -> finally.sequence.itemResponse.c`,
|
||||||
{
|
{
|
||||||
name: "number_connections",
|
name: "number_connections",
|
||||||
script: `1 -> 2
|
script: `1 -> 2
|
||||||
|
|
||||||
foo baz: Foo Baz
|
foo baz: Foo Baz
|
||||||
|
|
||||||
foo baz -> hello
|
foo baz -> hello
|
||||||
|
|
|
||||||
22
e2etests/testdata/stable/number_connections/dagre/board.exp.json
generated
vendored
22
e2etests/testdata/stable/number_connections/dagre/board.exp.json
generated
vendored
|
|
@ -5,10 +5,10 @@
|
||||||
"id": "foo baz",
|
"id": "foo baz",
|
||||||
"type": "",
|
"type": "",
|
||||||
"pos": {
|
"pos": {
|
||||||
"x": 1,
|
"x": 173,
|
||||||
"y": 0
|
"y": 0
|
||||||
},
|
},
|
||||||
"width": 112,
|
"width": 159,
|
||||||
"height": 126,
|
"height": 126,
|
||||||
"opacity": 1,
|
"opacity": 1,
|
||||||
"strokeDash": 0,
|
"strokeDash": 0,
|
||||||
|
|
@ -44,10 +44,10 @@
|
||||||
"id": "1",
|
"id": "1",
|
||||||
"type": "",
|
"type": "",
|
||||||
"pos": {
|
"pos": {
|
||||||
"x": 0,
|
"x": 1,
|
||||||
"y": 226
|
"y": 0
|
||||||
},
|
},
|
||||||
"width": 113,
|
"width": 112,
|
||||||
"height": 126,
|
"height": 126,
|
||||||
"opacity": 1,
|
"opacity": 1,
|
||||||
"strokeDash": 0,
|
"strokeDash": 0,
|
||||||
|
|
@ -83,10 +83,10 @@
|
||||||
"id": "2",
|
"id": "2",
|
||||||
"type": "",
|
"type": "",
|
||||||
"pos": {
|
"pos": {
|
||||||
"x": 173,
|
"x": 0,
|
||||||
"y": 0
|
"y": 226
|
||||||
},
|
},
|
||||||
"width": 159,
|
"width": 113,
|
||||||
"height": 126,
|
"height": 126,
|
||||||
"opacity": 1,
|
"opacity": 1,
|
||||||
"strokeDash": 0,
|
"strokeDash": 0,
|
||||||
|
|
@ -186,15 +186,15 @@
|
||||||
"route": [
|
"route": [
|
||||||
{
|
{
|
||||||
"x": 56.5,
|
"x": 56.5,
|
||||||
"y": 226
|
"y": 126
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"x": 56.5,
|
"x": 56.5,
|
||||||
"y": 226
|
"y": 166
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"x": 56.5,
|
"x": 56.5,
|
||||||
"y": 226
|
"y": 186
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"x": 56.5,
|
"x": 56.5,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ width="532" height="552" viewBox="-100 -100 532 552"><style type="text/css">
|
||||||
}
|
}
|
||||||
|
|
||||||
]]>
|
]]>
|
||||||
</style><g id="foo baz"><g class="shape" ><rect x="1" y="0" width="112" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="57.000000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">Foo Baz</text></g><g id="1"><g class="shape" ><rect x="0" y="226" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="56.500000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">1</text></g><g id="2"><g class="shape" ><rect x="173" y="0" width="159" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="252.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">2</text></g><g id="hello"><g class="shape" ><rect x="182" y="226" width="140" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="252.000000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">hello</text></g><g id="(1 -> 2)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M NaN NaN C 56.500000 226.000000 56.500000 226.000000 NaN NaN" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /></g><g id="(foo baz -> hello)[0]"><path d="M 252.000000 128.000000 C 252.000000 166.000000 252.000000 186.000000 252.000000 222.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /></g><style type="text/css"><![CDATA[
|
</style><g id="foo baz"><g class="shape" ><rect x="173" y="0" width="159" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="252.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">Foo Baz</text></g><g id="1"><g class="shape" ><rect x="1" y="0" width="112" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="57.000000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">1</text></g><g id="2"><g class="shape" ><rect x="0" y="226" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="56.500000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">2</text></g><g id="hello"><g class="shape" ><rect x="182" y="226" width="140" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /></g><text class="text-bold" x="252.000000" y="292.000000" style="text-anchor:middle;font-size:16px;fill:#0A0F25">hello</text></g><g id="(1 -> 2)[0]"><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 56.500000 128.000000 C 56.500000 166.000000 56.500000 186.000000 56.500000 222.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /></g><g id="(foo baz -> hello)[0]"><path d="M 252.000000 128.000000 C 252.000000 166.000000 252.000000 186.000000 252.000000 222.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /></g><style type="text/css"><![CDATA[
|
||||||
.text-bold {
|
.text-bold {
|
||||||
font-family: "font-bold";
|
font-family: "font-bold";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 325 KiB After Width: | Height: | Size: 325 KiB |
Loading…
Reference in a new issue