import { Node , Point , Position , Size } from "./types" ; import { Config , NodeConfig } from "./configs" ; import isEqual from "lodash-es/isEqual" ; export function keyOf < T > ( obj ) { return Object . keys ( obj ) as ( keyof T ) [ ] ; } export function entriesOf < T , K extends keyof T > ( obj ) { return Object . entries ( obj ) as [ K , T [ K ] ] [ ] ; } export function updateObjectDiff < T extends Record < string , any > > ( target , from ) { const keys = new Set < keyof T > ( Object . keys ( target ) ) ; entriesOf ( from ) . forEach ( ( [ key , value ] ) => { if ( ! isEqual ( target [ key ] , value ) ) { target [ key ] = value ; } keys . delete ( key ) ; } ) ; keys . forEach ( k => delete target [ k ] ) ; } export function getNodeSize ( node , style , scale ) { const shape = Config . values ( style . normal , node ) ; if ( shape . type == "circle" ) { return { width : shape . radius * 2 * scale , height : shape . radius * 2 * scale , } ; } else { return { width : shape . width * scale , height : shape . height * scale , } ; } } export function areNodesCollision ( nodePos , nodeSize , targetNodePos , targetNodeSize ) { const distanceX = Math . abs ( nodePos . x - targetNodePos . x ) ; const collisionX = distanceX < nodeSize . width / 2 + targetNodeSize . width / 2 ; const distanceY = Math . abs ( nodePos . y - targetNodePos . y ) ; const collisionY = distanceY < nodeSize . height / 2 + targetNodeSize . height / 2 ; return collisionX && collisionY ; } export function applyScaleToDasharray ( dasharray , scale ) { let result = 0 ; if ( scale === 1 || dasharray === undefined || dasharray === "none" ) { result = dasharray ?? 0 ; } else if ( typeof dasharray === "string" ) { result = dasharray . split ( /\s+/ ) . map ( v => parseInt ( v ) * scale ) . filter ( v => ! isNaN ( v ) ) . join ( " " ) ; } else { result = dasharray * scale ; } return result && result !== "0" ? result : undefined ; } export function getDasharrayUnit ( dasharray ) { let result = 0 ; if ( dasharray === undefined || dasharray === "none" ) { result = 0 ; } else if ( typeof dasharray === "string" ) { const array = dasharray . split ( /\s+/ ) . map ( v => parseInt ( v ) ) . filter ( v => ! isNaN ( v ) ) ; if ( array . length % 2 === 0 ) { result = array . reduce ( ( s , n ) => s + n , 0 ) ; } else { result = array . reduce ( ( s , n ) => s + n , 0 ) * 2 ; } } else { result = dasharray * 2 ; } return result ; } export class MapUtil { static valueOf < K , V > ( map ) { return Array . from ( map . values ( ) ) ; } } type Args < T > = [ ... ( T | null ) [ ] , T ] ; export function findFirstNonNull < T > ( ... values ) { return values . find ( v => ! ! v ) as T ; } export function convertToAscii ( source ) { if ( typeof btoa === undefined ) { return Buffer . from ( source ) . toString ( "base64" ) . replaceAll ( "=" , "" ) ; } else { return btoa ( source ) . replaceAll ( "=" , "" ) ; } } export function translateFromDomToSvgCoordinates ( svg , viewport , coordinates ) { const point = svg . createSVGPoint ( ) ; point . x = coordinates . x ; point . y = coordinates . y ; const svgPoint = point . matrixTransform ( viewport . getCTM ( ) ?. inverse ( ) ) ; return { x : svgPoint . x , y : svgPoint . y } ; } export function translateFromSvgToDomCoordinates ( svg , viewport , coordinates ) { const point = svg . createSVGPoint ( ) ; point . x = coordinates . x ; point . y = coordinates . y ; const domPoint = point . matrixTransform ( viewport . getCTM ( ) as DOMMatrixInit ) ; return { x : domPoint . x , y : domPoint . y } ; }