[for visualization purpose] an attempt to have better layout (arrange nodes) #1547
Closed
phineas-pta
started this conversation in
Show and tell
Replies: 2 comments 6 replies
-
This is a good approach! |
Beta Was this translation helpful? Give feedback.
5 replies
-
tysm @ltdrdata i succeed tinkering to create a working prototype as comfyui extension: biggest TODO is to add UI options to change density |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
update
i have a working extension here: https://github.com/phineas-pta/comfyui-auto-nodes-layout
short intro
there's already an 1-click auto-arrange graph but it relies on default
arrange()
ofLiteGraph.js
which positions the nodes according to level of dependencies, it's neat but imo the wires are very disorientated for visualization purposefrom my very limited understanding, most if not all ComfyUI workflows can be qualified as directed acyclic graph, so we can apply better graph drawing algorithm, so here is my proof-of-concept with Dagre layout
credit: inspiration from this comment
disclaimer: personal preference, not always guarantee a better layout
steps
edit file
ComfyUI/web/index.html
before the line
<script type="module">
add dagrejsafter the line
window.graph = app.graph;
add the following scriptreload the page to see the change
note: i find that it works visually better if remove all reroute nodes before change layout (can be re-added later)
example
using noisy latent composition example
original:
remove groups coz nodes placed very differently
using 1-click auto-arrange graph:
Dagre layout:
the flows are now very visible and can easily read left to right,
additional steps would be add some reroute nodes for any wires partially hidden by nodes
other layout
ELK.js
supports even more layoutsattempt with ELK.js "layered" layout (other layouts are visually bad)
<script src="https://cdn.jsdelivr.net/npm/elkjs/lib/elk.bundled.min.js"></script>
const myCytoNodes = app.graph._nodes.map((n) => ({ "id": n.id, "width": n.size[0], "height": n.size[1] })); const myCytoEdges = app.graph.links.filter(Boolean).map((e) => ({ "id": e.id, "sources": [ e.origin_id ], "targets": [ e.target_id ] })); const myCytoGraph = { "id": "root", "children": myCytoNodes, "edges": myCytoEdges, "layoutOptions": { "elk.algorithm": "layered" } } const elk = new ELK(); elk.layout(myCytoGraph) .then((val) => { for (let nodeLaidOut of val.children) { const n = app.graph.getNodeById(nodeLaidOut.id); n.pos[0] = nodeLaidOut.x * 2; // add more spacing n.pos[1] = nodeLaidOut.y * 2; } }) .catch(console.error);
Cytoscape.js
also has some layouts (see my original post unedited for cytoscape integration)edit 0: original post
edit 1+2: typo, add more notes about layout
edit 3+4: reduce dependencies to only dagre, remove cytoscape
edit 5: attempt with ELK.js
edit 6: extension implemented
Beta Was this translation helpful? Give feedback.
All reactions