1
- import React , { useEffect , useRef , useState } from "react" ;
1
+ import React , { useCallback , useEffect , useRef , useState } from "react" ;
2
2
import * as d3 from "d3" ;
3
3
import type { Monolith , SystemState } from "ott-vis/types" ;
4
4
import { dedupeMonoliths } from "aggregate" ;
@@ -245,6 +245,16 @@ const TreeDisplay: React.FC<TreeDisplayProps> = ({
245
245
246
246
const [ chartTransform , setChartTransform ] = useState ( "translate(0, 0)" ) ;
247
247
248
+ const getRadius = useCallback ( ( group : string ) : number => {
249
+ if ( group === "client" ) {
250
+ return clientNodeRadius ;
251
+ } else if ( group === "balancer" ) {
252
+ return balancerNodeRadius ;
253
+ } else {
254
+ return baseNodeRadius ;
255
+ }
256
+ } , [ baseNodeRadius , balancerNodeRadius , clientNodeRadius ] ) ;
257
+
248
258
useEffect ( ( ) => {
249
259
if ( svgRef . current ) {
250
260
// because d3-hierarchy doesn't support trees with multiple parents, we need to do manual layouts for balancers and monoliths, but we can use the built-in tree layout for monolith down to clients
@@ -536,13 +546,7 @@ const TreeDisplay: React.FC<TreeDisplayProps> = ({
536
546
. transition ( tr )
537
547
. attr ( "cx" , ( d : any ) => d . x )
538
548
. attr ( "cy" , ( d : any ) => d . y )
539
- . attr ( "r" , d => {
540
- if ( d . data . group === "client" ) {
541
- return clientNodeRadius ;
542
- } else {
543
- return baseNodeRadius ;
544
- }
545
- } ) ;
549
+ . attr ( "r" , d => getRadius ( d . data . group ) ) ;
546
550
547
551
const monolithTexts = monolith
548
552
. selectAll ( ".monolith-text" )
@@ -635,6 +639,7 @@ const TreeDisplay: React.FC<TreeDisplayProps> = ({
635
639
balancerNodeRadius ,
636
640
clientNodeRadius ,
637
641
balancerGroupStyle ,
642
+ getRadius ,
638
643
] ) ;
639
644
640
645
// run this only once after the first render
@@ -650,17 +655,26 @@ const TreeDisplay: React.FC<TreeDisplayProps> = ({
650
655
const eventBus = useEventBus ( ) ;
651
656
useEffect ( ( ) => {
652
657
const sub = eventBus . subscribe ( event => {
653
- d3 . select ( `[data-nodeid="${ event . node_id } "]` )
654
- . transition ( "highlight" )
655
- . duration ( 100 )
656
- . attrTween ( "stroke" , ( ) => d3 . interpolateRgb ( "#f00" , "#fff" ) )
657
- . attrTween ( "stroke-width" , ( ) => t => d3 . interpolateNumber ( 4 , 1.5 ) ( t ) . toString ( ) ) ;
658
+ const node = d3 . select ( `[data-nodeid="${ event . node_id } "]` ) ;
659
+ if ( node . empty ( ) ) {
660
+ return ;
661
+ }
662
+ const data = node . data ( ) [ 0 ] as d3 . HierarchyNode < TreeNode > ;
663
+ const endRadius = data ? getRadius ( data . data . group ) : 20 ;
664
+ const radiusCurrent = parseFloat ( node . attr ( "r" ) ) ;
665
+ const newRadius = Math . max ( Math . min ( radiusCurrent + 5 , 40 ) , endRadius ) ;
666
+ node . transition ( "highlight" )
667
+ . duration ( 333 )
668
+ . ease ( d3 . easeCubicOut )
669
+ . attrTween ( "stroke" , ( ) => d3 . interpolateRgb ( "#0f0" , "#fff" ) )
670
+ . attrTween ( "stroke-width" , ( ) => t => d3 . interpolateNumber ( 4 , 1.5 ) ( t ) . toString ( ) )
671
+ . attrTween ( "r" , ( ) => t => d3 . interpolateNumber ( newRadius , endRadius ) ( t ) . toString ( ) ) ;
658
672
} ) ;
659
673
660
674
return ( ) => {
661
675
sub . unsubscribe ( ) ;
662
676
} ;
663
- } , [ eventBus ] ) ;
677
+ } , [ eventBus , getRadius ] ) ;
664
678
665
679
return (
666
680
< svg
0 commit comments