@@ -112,10 +112,10 @@ export class DependencyGraphComponent implements OnInit, OnChanges {
112112 populateGraphWithActivitiesCurrentActivityDependsOn ( activity : Activity ) : void {
113113 if ( activity . dependsOn ) {
114114 let i : number = 1 ;
115- for ( const prececcor of activity . dependsOn ) {
116- this . addNode ( prececcor , - 1 , i ++ ) ;
115+ for ( const predecessor of activity . dependsOn ) {
116+ this . addNode ( predecessor , - 1 , i ++ ) ;
117117 this . graphData [ 'links' ] . push ( {
118- source : prececcor ,
118+ source : predecessor ,
119119 target : activity . name ,
120120 } ) ;
121121 }
@@ -224,17 +224,20 @@ export class DependencyGraphComponent implements OnInit, OnChanges {
224224 this . activityClicked . emit ( d . id ) ;
225225 }
226226 } )
227- . on ( 'mouseover' , ( event : MouseEvent , d : any ) => {
228- if ( this . activityClicked . observed ) {
229- if ( d . relativeLevel != 0 ) {
230- d3 . select ( event . currentTarget as Element ) . style ( 'cursor' , 'pointer' ) ;
231- } else {
232- d3 . select ( event . currentTarget as Element ) . style ( 'cursor' , 'default' ) ;
233- }
234- }
227+ . classed ( 'clickable' , ( d : any ) => this . activityClicked . observed && d . relativeLevel != 0 )
228+ . classed ( 'predecessor' , ( d : any ) => d . relativeLevel < 0 )
229+ . classed ( 'successor' , ( d : any ) => d . relativeLevel > 0 )
230+ . classed ( 'main' , ( d : any ) => d . relativeLevel == 0 )
231+ . style ( 'cursor' , ( d : any ) =>
232+ this . activityClicked . observed && d . relativeLevel != 0 ? 'pointer' : 'default'
233+ )
234+ . on ( 'mouseover' , function ( _event : any , _d : any ) {
235+ if ( d3 . select ( this ) . classed ( 'clickable' ) ) {
236+ d3 . select ( this ) . classed ( 'hovered' , true ) ;
237+ }
235238 } )
236- . on ( 'mouseout' , ( event : MouseEvent , d : any ) => {
237- d3 . select ( event . currentTarget as Element ) . style ( 'cursor ', 'default' ) ;
239+ . on ( 'mouseout' , function ( _event : any , _d : any ) {
240+ d3 . select ( this ) . classed ( 'hovered ', false ) ;
238241 } ) ;
239242
240243 const rectHeight = 30 ;
@@ -255,29 +258,47 @@ export class DependencyGraphComponent implements OnInit, OnChanges {
255258 const self = this ;
256259 nodes . each ( function ( this : SVGGElement , d : any ) {
257260 const textElem = d3 . select ( this ) . select ( 'text' ) . node ( ) as SVGTextElement ;
258- let textWidth = 60 ; // fallback default
259- if ( textElem && textElem . getBBox ) {
260- textWidth = textElem . getBBox ( ) . width ;
261+ let textWidth = 60 ;
262+ if ( textElem ) {
263+ try {
264+ textWidth = ( textElem . getBBox && textElem . getBBox ( ) . width ) || textWidth ;
265+ } catch {
266+ textWidth =
267+ ( textElem . getComputedTextLength && textElem . getComputedTextLength ( ) ) || textWidth ;
268+ }
261269 }
262- const rectWidth = textWidth + padding ;
263- d . rectWidth = rectWidth ; // Store for collision force
264- // Insert rect before text
270+
271+ const rectWidth = Math . ceil ( textWidth + padding ) ;
272+ d . rectWidth = rectWidth ; // store for collision force
273+
274+ // compute fill + hover color once
275+ const fillColor =
276+ d . relativeLevel == 0
277+ ? self . themeColors . mainNodeFill || 'green'
278+ : ( d . relativeLevel < 0
279+ ? self . themeColors . predecessorFill
280+ : self . themeColors . successorFill ) || 'white' ;
281+ const c = d3 . color ( fillColor ) ;
282+ const hoverColor = c ? c . darker ( 0.6 ) . toString ( ) : fillColor ;
283+
284+ // set CSS variables on the group so global stylesheet can use them
285+ d3 . select ( this )
286+ . style ( '--node-fill' , fillColor )
287+ . style ( '--node-hover-fill' , hoverColor )
288+ . style ( '--node-border' , self . themeColors . borderColor || 'black' ) ;
289+
290+ // Insert rect before text sized to measured text
265291 d3 . select ( this )
266292 . insert ( 'rect' , 'text' )
293+ . attr ( 'class' , 'node-rect' )
267294 . attr ( 'x' , - rectWidth / 2 )
268295 . attr ( 'y' , - rectHeight / 2 )
269296 . attr ( 'width' , rectWidth )
270297 . attr ( 'height' , rectHeight )
271298 . attr ( 'rx' , rectRx )
272299 . attr ( 'ry' , rectRy )
273- . attr ( 'fill' , ( d : any ) => {
274- if ( d . relativeLevel == 0 ) return self . themeColors . mainNodeFill || 'green' ;
275- let col : string | undefined =
276- d . relativeLevel < 0 ? self . themeColors . predecessorFill : self . themeColors . successorFill ;
277- return col || 'white' ;
278- } )
279- . attr ( 'stroke' , self . themeColors . borderColor || 'black' )
280- . attr ( 'stroke-width' , 1.5 ) ;
300+ . attr ( 'stroke-width' , 1.5 )
301+ . attr ( 'stroke' , 'currentColor' ) ; // stroke taken from --node-border via CSS
281302 } ) ;
282303
283304 this . simulation . nodes ( this . graphData [ 'nodes' ] ) . on ( 'tick' , ( ) => {
0 commit comments