import React , { ReactElement } from 'react' ; import { Item , ModelConfig , ShapeOptions } from '@antv/g6-core/lib' ; import { IGroup } from '@antv/g-base' ; import getShapeFromReact from '@/Register/getDataFromReactNode' ; import getPositionUsingYoga , { LayoutedNode , } from '@/Layout/getPositionsUsingYoga' ; import { animateShapeWithConfig } from '@/Animation/animate' ; export const registerNodeReact = ( el ) => { const result = getShapeFromReact ( el ) ; const target = getPositionUsingYoga ( result ) ; return target ; } ; const renderTarget = ( target , group ) => { let g = group ; let keyshape = group ; const { attrs = { } , boundaryBox , type , children , props } = target ; if ( target . type !== 'group' ) { const shape = group . addShape ( target . type , { attrs , origin : { boundaryBox , type , children , } , ... props , } ) ; keyshape = shape ; animateShapeWithConfig ( shape , props . animation ) ; } else { g = group . addGroup ( props ) ; keyshape = g ; } if ( target . children ) { const keyshapes = target . children . map ( ( n ) => renderTarget ( n , g ) ) . filter ( ( e ) => e ) ; if ( keyshapes . length ) { keyshape = keyshapes . pop ( ) ; } } return keyshape ; } ; const getRealStructure = ( target ) : LayoutedNode [ ] => { const { children } = target ; target . children = [ ] ; let realChildren = [ ] ; for ( let i = 0 ; i < children . length ; i += 1 ) { const result = getRealStructure ( children [ i ] ) ; realChildren = realChildren . concat ( result ) ; } if ( target . type !== 'group' ) { return [ target , ... realChildren ] ; } else { target . children = realChildren ; return [ target ] ; } } ; const diffTarget = ( container , shapeArr ) => { const childrenList = [ ... container . getChildren ( ) ] ; for ( let i = 0 ; i < childrenList . length ; i += 1 ) { const lastShape = childrenList [ i ] ; const nowShape = shapeArr [ i ] ; if ( ! nowShape ) { container . removeChild ( lastShape , true ) ; } else if ( ! lastShape ) { renderTarget ( nowShape , container ) ; } else if ( lastShape . cfg . type !== nowShape . type ) { container . removeChild ( lastShape , true ) ; renderTarget ( nowShape , container ) ; } else { if ( nowShape . props ) { lastShape . cfg = { ... lastShape . cfg , ... nowShape . props , } ; } if ( nowShape . attrs && lastShape . attr ) { lastShape . attr ( nowShape . attrs ) ; } if ( nowShape . type === 'group' ) { diffTarget ( lastShape as IGroup , nowShape . children ) ; } } } } ; export function createNodeFromReact ( Component ) { const compileXML = ( cfg ) => registerNodeReact ( < Component cfg = { cfg } / > ) ; return { draw ( cfg , fatherGroup ) { const resultTarget = compileXML ( cfg || { } ) ; let keyshape = fatherGroup ; keyshape = renderTarget ( resultTarget , fatherGroup ) ; return keyshape ; } , update ( cfg , node ) { const resultTarget = compileXML ( cfg || { } ) ; const nodeGroup = node . getContainer ( ) ; const realTarget = getRealStructure ( resultTarget ) ; diffTarget ( nodeGroup , realTarget ) ; } , getAnchorPoints ( ) { return [ [ 0 , 0.5 ] , [ 1 , 0.5 ] , [ 0.5 , 1 ] , [ 0.5 , 0 ] , ] ; } , } as ShapeOptions ; }