Skip to content

Commit 0685a15

Browse files
committed
fix TCO calculator ruler line position and attach tooltip to bars directly
1 parent 82b7963 commit 0685a15

1 file changed

Lines changed: 8 additions & 50 deletions

File tree

packages/app/src/components/calculator/ThroughputBarChart.tsx

Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)