You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 02:09:03