React D3折线图鼠标悬停tooltip报错:reading 'label' of undefined
错误根因分析
你遇到的d0 is undefined问题由两个核心错误共同导致:
- 第一:d3.pointer传参错误
D3 v6及更高版本中,事件回调的第一个参数为原生事件对象,d3.pointer()需要接收event作为入参来计算正确的坐标,你代码中传入this导致拿到的xPos坐标异常,xScale.invert(xPos)得到的x轴数值超出你的数据范围。 - 第二:bisect返回值未做边界限制
d3.bisector.left当传入的查询值大于数组中所有元素时,会直接返回数组的总长度。比如你的测试数据共20条,数组下标范围是0~19,bisect返回20时data[20]自然为undefined。
修复方案
修改mousemove函数的代码即可解决问题,修正后的代码如下:
function mousemove(event) { const bisect = d3.bisector(d => d.label).left; // 修正:d3.pointer传入event而不是this const xPos = d3.pointer(event)[0]; const x0 = bisect(data, xScale.invert(xPos)); // 新增:边界钳制,确保x0不会超出数组下标范围 const clampedX0 = Math.max(0, Math.min(x0, data.length - 1)); const d0 = data[clampedX0]; // 可选:加上兜底判断,避免极端场景报错 if (!d0) return; console.log(d0); focus.attr( 'transform', `translate(${xScale(d0.label)},${yScale(d0.value)})`, ); tooltip .transition() .duration(300) .style('opacity', 0.9); tooltip .html(d0.tooltipContent || d0.label) .style( 'transform', `translate(${xScale(d0.label) + 30}px,${yScale(d0.value) - 30}px)`, ); }
额外优化建议
你现在每次data变化都会完整删除SVG重绘,性能较低,可以后续优化为用D3的enter/update/exit模式做增量更新,不需要每次全量销毁重建。
内容的提问来源于stack exchange,提问作者Jericho
相关产品推荐
相关产品推荐

