import { injectable } from 'inversify' ; import { SModelIndex , SModelElementSchema } from 'sprotty' ; import { DependencyGraphNodeSchema , DependencyGraphEdgeSchema , isNode } from './graph-model' ; import { IGraphGenerator } from './graph-generator' ; @ injectable ( ) export class DependencyGraphFilter { protected nameFilter : ( name : string ) => boolean = node => true ; setFilter ( text ) { const textTrim = text . trim ( ) ; if ( textTrim . length === 0 ) this . nameFilter = name => true ; else if ( text . startsWith ( ' ' ) && text . endsWith ( ' ' ) ) this . nameFilter = name => name === textTrim ; else if ( text . startsWith ( ' ' ) ) this . nameFilter = name => name . startsWith ( textTrim ) ; else if ( text . endsWith ( ' ' ) ) this . nameFilter = name => name . endsWith ( textTrim ) ; else this . nameFilter = name => name . indexOf ( textTrim ) >= 0 ; } refresh ( generator ) { let nodeCount = 0 ; let visibleCount = 0 ; for ( const node of generator . nodes ) { const visible = this . nameFilter ( node . name ) ; node . hidden = ! visible ; nodeCount ++ ; if ( visible ) visibleCount ++ ; } if ( visibleCount === nodeCount ) return ; const incoming = this . createIncomingMap ( generator . edges , generator . index ) ; const dfsMark = { } ; for ( const node of generator . nodes ) { if ( ! node . hidden ) { this . dfs ( node , incoming , dfsMark , generator . index ) ; } } } protected createIncomingMap ( edges , index ) { const incoming = new Map < DependencyGraphNodeSchema , DependencyGraphEdgeSchema [ ] > ( ) ; for ( const edge of edges ) { const target = index . getById ( edge . targetId ) ; if ( isNode ( target ) ) { let arr = incoming . get ( target ) ; if ( arr ) { arr . push ( edge ) ; } else { arr = [ edge ] ; incoming . set ( target , arr ) ; } } } return incoming ; } protected dfs ( node , incoming , mark , index ) { if ( mark [ node . id ] ) return ; mark [ node . id ] = true ; for ( const edge of incoming . get ( node ) || [ ] ) { const source = index . getById ( edge . sourceId ) ; if ( isNode ( source ) ) { source . hidden = false ; this . dfs ( source , incoming , mark , index ) ; } } } }