@@ -224,17 +224,18 @@ 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+ d3 . select ( this ) . classed ( 'hovered' , true ) ;
235236 } )
236- . on ( 'mouseout' , ( event : MouseEvent , d : any ) => {
237- d3 . select ( event . currentTarget as Element ) . style ( 'cursor ', 'default' ) ;
237+ . on ( 'mouseout' , function ( _event : any , _d : any ) {
238+ d3 . select ( this ) . classed ( 'hovered ', false ) ;
238239 } ) ;
239240
240241 const rectHeight = 30 ;
@@ -255,29 +256,47 @@ export class DependencyGraphComponent implements OnInit, OnChanges {
255256 const self = this ;
256257 nodes . each ( function ( this : SVGGElement , d : any ) {
257258 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 ;
259+ let textWidth = 60 ;
260+ if ( textElem ) {
261+ try {
262+ textWidth = ( textElem . getBBox && textElem . getBBox ( ) . width ) || textWidth ;
263+ } catch {
264+ textWidth =
265+ ( textElem . getComputedTextLength && textElem . getComputedTextLength ( ) ) || textWidth ;
266+ }
261267 }
262- const rectWidth = textWidth + padding ;
263- d . rectWidth = rectWidth ; // Store for collision force
264- // Insert rect before text
268+
269+ const rectWidth = Math . ceil ( textWidth + padding ) ;
270+ d . rectWidth = rectWidth ; // store for collision force
271+
272+ // compute fill + hover color once
273+ const fillColor =
274+ d . relativeLevel == 0
275+ ? self . themeColors . mainNodeFill || 'green'
276+ : ( d . relativeLevel < 0
277+ ? self . themeColors . predecessorFill
278+ : self . themeColors . successorFill ) || 'white' ;
279+ const c = d3 . color ( fillColor ) ;
280+ const hoverColor = c ? c . darker ( 0.6 ) . toString ( ) : fillColor ;
281+
282+ // set CSS variables on the group so global stylesheet can use them
283+ d3 . select ( this )
284+ . style ( '--node-fill' , fillColor )
285+ . style ( '--node-hover-fill' , hoverColor )
286+ . style ( '--node-border' , self . themeColors . borderColor || 'black' ) ;
287+
288+ // Insert rect before text sized to measured text
265289 d3 . select ( this )
266290 . insert ( 'rect' , 'text' )
291+ . attr ( 'class' , 'node-rect' )
267292 . attr ( 'x' , - rectWidth / 2 )
268293 . attr ( 'y' , - rectHeight / 2 )
269294 . attr ( 'width' , rectWidth )
270295 . attr ( 'height' , rectHeight )
271296 . attr ( 'rx' , rectRx )
272297 . 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 ) ;
298+ . attr ( 'stroke-width' , 1.5 )
299+ . attr ( 'stroke' , 'currentColor' ) ; // stroke taken from --node-border via CSS
281300 } ) ;
282301
283302 this . simulation . nodes ( this . graphData [ 'nodes' ] ) . on ( 'tick' , ( ) => {
0 commit comments