@@ -31,6 +31,10 @@ import { CollaborativeCursors } from "../CursorView";
3131
3232import { getHandlePosition } from "@/lib/getHandlePosition" ;
3333
34+ import ELK from "elkjs" ;
35+
36+ const elk = new ELK ( ) ;
37+
3438const proOptions = { hideAttribution : true } ;
3539
3640interface YNode extends Node {
@@ -192,6 +196,41 @@ function Flow({ className }: CanvasProps) {
192196 } ) ;
193197 } , [ pages , ydoc ] ) ;
194198
199+ const performLayout = async ( ) => {
200+ const graph = {
201+ id : "root" ,
202+ layoutOptions : {
203+ "elk.algorithm" : "force" ,
204+ } ,
205+ children : nodes . map ( ( node ) => ( {
206+ id : node . id ,
207+ width : 160 , // 실제 노드 너비로 변경하기 (node.width)
208+ height : 40 , // 실제 노드 높이로 변경하기 (node.height)
209+ } ) ) ,
210+ edges : edges . map ( ( edge ) => ( {
211+ id : edge . id ,
212+ sources : [ edge . source ] ,
213+ targets : [ edge . target ] ,
214+ } ) ) ,
215+ } ;
216+
217+ const layout = await elk . layout ( graph ) ;
218+
219+ const updatedNodes = nodes . map ( ( node ) => {
220+ const layoutNode = layout ! . children ! . find ( ( n ) => n . id === node . id ) ;
221+
222+ return {
223+ ...node ,
224+ position : {
225+ x : layoutNode ! . x as number ,
226+ y : layoutNode ! . y as number ,
227+ } ,
228+ } ;
229+ } ) ;
230+
231+ setNodes ( updatedNodes ) ;
232+ } ;
233+
195234 const handleNodesChange = useCallback (
196235 ( changes : NodeChange [ ] ) => {
197236 if ( ! ydoc ) return ;
@@ -387,6 +426,18 @@ function Flow({ className }: CanvasProps) {
387426 selectNodesOnDrag = { false }
388427 >
389428 < Controls />
429+ < div
430+ id = "layout-button"
431+ style = { {
432+ display : "flex" ,
433+ justifyContent : "center" ,
434+ marginBottom : "10px" ,
435+ zIndex : 999 ,
436+ position : "relative" ,
437+ } }
438+ >
439+ < button onClick = { performLayout } > Layout</ button >
440+ </ div >
390441 < MiniMap />
391442 < Background variant = { BackgroundVariant . Dots } gap = { 12 } size = { 1 } />
392443 < CollaborativeCursors cursors = { cursors } />
0 commit comments