import ForceLayout , { ForceProps } from '../force/ForceLayout' ; import { optimizeDrawing , optimizeDrawingByNode , } from '../../perf/optimizeDrawing' ; import { LayoutOptionBase , Data , Node as NodeType , ForceSimulation , } from '../../types' ; import forceWithWorker from './forceWithWorker' ; export interface ForceLayoutOptions extends ForceProps , LayoutOptionBase { isOptimization ? : boolean ; } interface Return { data : Data ; simulation : ForceSimulation ; } const forceLayout = ( data , options ) : Return => { const { width , height , graph , enableWorker = false , animation , done = ( _graph ) => { } , isOptimization , ... others } = options ; /** Webworker solution. Otherwise, browser UI rendering is blocked */ if ( enableWorker && data . nodes . length > 100 ) { return forceWithWorker ( data , options ) ; } /** 1. Create a force simulator */ const simulation = new ForceLayout ( { width , height , animation : animation !== undefined ? animation : true , done : ( ) => { if ( isOptimization ) { optimizeDrawing ( graph , false ) ; } done ( graph ) ; } , ... others , } ) ; simulation . setData ( data ) ; simulation . register ( 'render' , ( forceData ) => { try { forceData . nodes . forEach ( ( item ) => { const node = graph . findById ( item . id ) ; if ( node ) { const model = node . get ( 'model' ) ; model . x = item . x ; model . y = item . y ; if ( isOptimization ) { optimizeDrawingByNode ( true , node ) ; } } } ) ; graph . refreshPositions ( ) ; } catch ( error ) { console . error ( error ) ; } } ) ; /**  4. Start force  simulator */ simulation . start ( ) ; return { data , simulation , } ; } ; export default forceLayout ;