@@ -326,6 +326,7 @@ export default function ThroughputBarChart({
326326 const chartRef = useRef < D3ChartHandle > ( null ) ;
327327
328328 // Stable refs to avoid re-running the D3 effect
329+ const hoveredBarXRef = useRef ( 0 ) ;
329330 const selectedBarsRef = useRef ( selectedBars ) ;
330331 selectedBarsRef . current = selectedBars ;
331332
@@ -387,32 +388,6 @@ export default function ThroughputBarChart({
387388 } ,
388389 } ;
389390
390- // Hit areas — transparent full-width rects for easier mouse interaction
391- const hitAreaLayer : CustomLayerConfig = {
392- type : 'custom' ,
393- key : 'hit-areas' ,
394- render : ( zoomGroup , ctx ) => {
395- const yScale = ctx . yScale as d3 . ScaleBand < string > ;
396-
397- return zoomGroup
398- . selectAll < SVGRectElement , InterpolatedResult > ( '.bar-hit' )
399- . data ( sortedResults , ( d ) => d . resultKey )
400- . join ( 'rect' )
401- . attr ( 'class' , 'bar-hit' )
402- . attr ( 'y' , ( d ) => yScale ( d . resultKey ) ?? 0 )
403- . attr ( 'x' , 0 )
404- . attr ( 'width' , ctx . width )
405- . attr ( 'height' , yScale . bandwidth ( ) )
406- . attr ( 'fill' , 'transparent' )
407- . style ( 'cursor' , 'pointer' ) ;
408- } ,
409- onZoom : ( zoomGroup , ctx ) => {
410- zoomGroup
411- . selectAll < SVGRectElement , InterpolatedResult > ( '.bar-hit' )
412- . attr ( 'width' , ctx . width ) ;
413- } ,
414- } ;
415-
416391 // Combined label layer — value + overlay labels flip inside/outside together
417392 const labelLayer : CustomLayerConfig = {
418393 type : 'custom' ,
@@ -468,7 +443,7 @@ export default function ThroughputBarChart({
468443 } ,
469444 } ;
470445
471- return [ barLayer , hitAreaLayer , labelLayer ] ;
446+ return [ barLayer , labelLayer ] ;
472447 } , [ sortedResults , barMetric , costType , hardwareConfig , mode ] ) ;
473448
474449 // ── Tooltip ──
@@ -478,43 +453,26 @@ export default function ThroughputBarChart({
478453 rulerType : 'vertical' as const ,
479454 content : ( d : InterpolatedResult , _isPinned : boolean ) =>
480455 generateTooltipHTML ( d , hardwareConfig , mode , barMetric , costType , runUrl ) ,
481- getRulerX : (
482- d : InterpolatedResult ,
483- xScale :
484- | d3 . ScaleBand < string >
485- | d3 . ScaleLinear < number , number >
486- | d3 . ScaleLogarithmic < number , number > ,
487- ) => ( xScale as d3 . ScaleLinear < number , number > ) ( getMetricValue ( d , barMetric , costType ) ) ,
488- onHoverStart : (
489- sel : d3 . Selection < any , InterpolatedResult , any , any > ,
490- d : InterpolatedResult ,
491- ) => {
492- // Highlight the corresponding visible bar, not the transparent hit area
493- const barGroup = sel . node ( ) ?. parentNode ;
494- if ( ! barGroup ) return ;
495- const bars = d3 . select ( barGroup ) . selectAll < SVGRectElement , InterpolatedResult > ( '.bar' ) ;
496- const bar = bars . filter ( ( b ) => b . resultKey === d . resultKey ) ;
456+ getRulerX : ( ) => hoveredBarXRef . current ,
457+ onHoverStart : ( sel : d3 . Selection < any , InterpolatedResult , any , any > ) => {
458+ hoveredBarXRef . current = parseFloat ( sel . attr ( 'width' ) || '0' ) ;
497459 const hasSelection = selectedBarsRef . current . size > 0 ;
498460 if ( ! hasSelection ) {
499- bar . attr ( 'opacity' , 1 ) . attr ( 'stroke' , 'var(--foreground)' ) . attr ( 'stroke-width' , 1.5 ) ;
461+ sel . attr ( 'opacity' , 1 ) . attr ( 'stroke' , 'var(--foreground)' ) . attr ( 'stroke-width' , 1.5 ) ;
500462 }
501463 } ,
502464 onHoverEnd : ( sel : d3 . Selection < any , InterpolatedResult , any , any > , d : InterpolatedResult ) => {
503- const barGroup = sel . node ( ) ?. parentNode ;
504- if ( ! barGroup ) return ;
505- const bars = d3 . select ( barGroup ) . selectAll < SVGRectElement , InterpolatedResult > ( '.bar' ) ;
506- const bar = bars . filter ( ( b ) => b . resultKey === d . resultKey ) ;
507465 const hasSelection = selectedBarsRef . current . size > 0 ;
508466 const isSelected = selectedBarsRef . current . has ( d . resultKey ) ;
509- bar
467+ sel
510468 . attr ( 'opacity' , hasSelection ? ( isSelected ? 0.95 : 0.15 ) : 0.85 )
511469 . attr ( 'stroke' , 'none' ) ;
512470 } ,
513471 onPointClick : ( d : InterpolatedResult ) => {
514472 onBarSelectRef . current ( d . resultKey ) ;
515473 track ( 'calculator_bar_selected' , { gpu : d . hwKey , precision : d . precision } ) ;
516474 } ,
517- attachToLayer : 1 ,
475+ attachToLayer : 0 ,
518476 } ) ,
519477 [ hardwareConfig , mode , barMetric , costType , runUrl ] ,
520478 ) ;
0 commit comments