import { isString , isNumber , isNil , isArray } from '@antv/util' ; import { G6GraphEvent } from '../interface/behavior' ; import { IG6GraphEvent , Padding , Matrix , Item } from '../types' ; export const uniqueId = ( type ) : string => { return `${ type }-${ Math . random ( ) }${ Date . now ( ) }` ; } ; param { Number | Array } padding return { array } export const formatPadding = ( padding ) : number [ ] => { if ( isArray ( padding ) ) { switch ( padding . length ) { case 4 : return padding ; case 3 : padding . push ( padding [ 1 ] ) ; return padding ; case 2 : return padding . concat ( padding ) ; case 1 : return [ padding [ 0 ] , padding [ 0 ] , padding [ 0 ] , padding [ 0 ] ] ; default : return [ 0 , 0 , 0 , 0 ] ; } } if ( isNumber ( padding ) ) { return [ padding , padding , padding , padding ] ; } else if ( isString ( padding ) ) { const intPadding = parseInt ( padding , 10 ) ; return [ intPadding , intPadding , intPadding , intPadding ] ; } return [ 0 , 0 , 0 , 0 ] ; } ; param e export const cloneEvent = ( e ) : IG6GraphEvent => { const event = new G6GraphEvent ( e . type , e ) ; event . clientX = e . clientX ; event . clientY = e . clientY ; event . x = e . x ; event . y = e . y ; event . target = e . target ; event . currentTarget = e . currentTarget ; event . bubbles = true ; ( event . item as Item | null ) = e . item ; return event ; } ; param matrix export const isViewportChanged = ( matrix ) => { if ( ! matrix ) { return false ; } const MATRIX_LEN = 9 ; const ORIGIN_MATRIX = [ 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 ] ; for ( let i = 0 ; i < MATRIX_LEN ; i ++ ) { if ( matrix [ i ] !== ORIGIN_MATRIX [ i ] ) { return true ; } } return false ; } ; export const isNaN = ( input ) => Number . isNaN ( Number ( input ) ) ; param items export const calculationItemsBBox = ( items ) => { let minx = Infinity ; let maxx = - Infinity ; let miny = Infinity ; let maxy = - Infinity ; for ( let i = 0 ; i < items . length ; i ++ ) { const element = items [ i ] ; const bbox = element . getBBox ( ) ; const { minX , minY , maxX , maxY } = bbox ; if ( minX < minx ) { minx = minX ; } if ( minY < miny ) { miny = minY ; } if ( maxX > maxx ) { maxx = maxX ; } if ( maxY > maxy ) { maxy = maxY ; } } const x = Math . floor ( minx ) ; const y = Math . floor ( miny ) ; const width = Math . ceil ( maxx ) - Math . floor ( minx ) ; const height = Math . ceil ( maxy ) - Math . floor ( miny ) ; return { x , y , width , height , minX : minx , minY : miny , maxX : maxx , maxY : maxy , } ; } ; param edges param offsetDiff param multiEdgeType param singleEdgeType param loopEdgeType export const processParallelEdges = ( edges , offsetDiff = 15 , multiEdgeType = 'quadratic' , singleEdgeType = undefined , loopEdgeType = undefined ) => { const len = edges . length ; const cod = offsetDiff * 2 ; const loopPosition = [ 'top' , 'top-right' , 'right' , 'bottom-right' , 'bottom' , 'bottom-left' , 'left' , 'top-left' , ] ; const edgeMap = { } ; const tags = [ ] ; const reverses = { } ; for ( let i = 0 ; i < len ; i ++ ) { const edge = edges [ i ] ; const { source , target } = edge ; const sourceTarget = `${ source }-${ target }` ; if ( tags [ i ] ) continue ; if ( ! edgeMap [ sourceTarget ] ) { edgeMap [ sourceTarget ] = [ ] ; } tags [ i ] = true ; edgeMap [ sourceTarget ] . push ( edge ) ; for ( let j = 0 ; j < len ; j ++ ) { if ( i === j ) continue ; const sedge = edges [ j ] ; const src = sedge . source ; const dst = sedge . target ; if ( ! tags [ j ] ) { if ( source === dst && target === src ) { edgeMap [ sourceTarget ] . push ( sedge ) ; tags [ j ] = true ; reverses [ `${ src }|${ dst }|${ edgeMap [ sourceTarget ] . length - 1 }` ] = true ; } else if ( source === src && target === dst ) { edgeMap [ sourceTarget ] . push ( sedge ) ; tags [ j ] = true ; } } } } for ( const key in edgeMap ) { const arcEdges = edgeMap [ key ] ; const { length } = arcEdges ; for ( let k = 0 ; k < length ; k ++ ) { const current = arcEdges [ k ] ; if ( current . source === current . target ) { if ( loopEdgeType ) current . type = loopEdgeType ; current . loopCfg = { position : loopPosition [ k % 8 ] , dist : Math . floor ( k / 8 ) * 20 + 50 , } ; continue ; } if ( length === 1 && singleEdgeType && current . source !== current . target ) { current . type = singleEdgeType ; continue ; } current . type = multiEdgeType ; const sign = ( k % 2 === 0 ? 1 : - 1 ) * ( reverses [ `${ current . source }|${ current . target }|${ k }` ] ? - 1 : 1 ) ; if ( length % 2 === 1 ) { current . curveOffset = sign * Math . ceil ( k / 2 ) * cod ; } else { current . curveOffset = sign * ( Math . floor ( k / 2 ) * cod + offsetDiff ) ; } } } return edges ; } ;