Skip to content

Commit 8ed8fd6

Browse files
committed
fix: sync hover by exact step
1 parent 9c16549 commit 8ed8fd6

2 files changed

Lines changed: 24 additions & 12 deletions

File tree

src/components/ChartContainer.jsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,22 +76,25 @@ const ChartWrapper = ({ data, options, chartId, onRegisterChart, onSyncHover })
7676

7777
const enhancedOptions = {
7878
...options,
79-
onHover: (event, activeElements) => {
80-
if (activeElements.length > 0 && chartRef.current) {
81-
const { datasetIndex, index } = activeElements[0];
82-
const point = chartRef.current.data?.datasets?.[datasetIndex]?.data?.[index];
83-
const step = typeof point?.x === 'number' ? point.x : index;
84-
onSyncHover(step, chartId);
79+
onHover: (event) => {
80+
if (!chartRef.current) return;
81+
const chart = chartRef.current;
82+
const x = event.x;
83+
const withinChart =
84+
x >= chart.chartArea.left && x <= chart.chartArea.right;
85+
if (withinChart) {
86+
const step = Math.round(chart.scales.x.getValueForPixel(x));
87+
onSyncHover(step);
8588
} else {
86-
onSyncHover(null, chartId);
89+
onSyncHover(null);
8790
}
8891
},
8992
events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
9093
};
9194

9295
const handleContainerMouseLeave = useCallback(() => {
93-
onSyncHover(null, chartId);
94-
}, [onSyncHover, chartId]);
96+
onSyncHover(null);
97+
}, [onSyncHover]);
9598

9699
return (
97100
<div onMouseLeave={handleContainerMouseLeave} style={{ width: '100%', height: '100%' }}>
@@ -117,14 +120,14 @@ export default function ChartContainer({
117120
chartRefs.current.set(id, inst);
118121
}, []);
119122

120-
const syncHoverToAllCharts = useCallback((step, sourceId) => {
121-
chartRefs.current.forEach((chart, id) => {
123+
const syncHoverToAllCharts = useCallback((step) => {
124+
chartRefs.current.forEach((chart) => {
122125
if (!chart) return;
123126
if (step === null) {
124127
chart.setActiveElements([]);
125128
chart.tooltip.setActiveElements([]);
126129
chart.update('none');
127-
} else if (id !== sourceId) {
130+
} else {
128131
const activeElements = getActiveElementsAtStep(chart.data.datasets, step);
129132
chart.setActiveElements(activeElements);
130133
chart.tooltip.setActiveElements(activeElements, { x: 0, y: 0 });

src/components/__tests__/ChartContainer.test.jsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,13 @@ describe('ChartContainer', () => {
117117
const result = getActiveElementsAtStep(datasets, 2);
118118
expect(result).toEqual([{ datasetIndex: 0, index: 0 }, { datasetIndex: 1, index: 1 }]);
119119
});
120+
121+
it('returns empty array when no dataset contains the step', () => {
122+
const datasets = [
123+
{ data: [{ x: 210, y: 1 }, { x: 220, y: 2 }] },
124+
{ data: [{ x: 5, y: 3 }, { x: 6, y: 4 }] }
125+
];
126+
const result = getActiveElementsAtStep(datasets, 0);
127+
expect(result).toEqual([]);
128+
});
120129
});

0 commit comments

Comments
 (0)