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

使用D3.js+TypeScript实现矩形悬停显示数值遇类型错误

解决TypeScript + D3.js鼠标悬停文本的类型错误

我用TypeScript结合D3.js开发数据可视化图表,黑色矩形的高度由generateData生成的正数决定。希望鼠标悬停在矩形上时显示对应的数值,但出现了TypeScript类型错误。

错误信息

没有匹配的重载调用。
重载1(共2个):'(selector: string): Selection<BaseType, unknown, HTMLElement, any>',给出以下错误:
参数类型“ParentNode | null”无法赋值给参数类型“string”。类型“null”无法赋值给参数类型“string”。
重载2(共2个):'(node: BaseType): Selection<BaseType, unknown, null, undefined>',给出以下错误:
参数类型“ParentNode | null”无法赋值给参数类型“BaseType”。类型“ParentNode”无法赋值给类型“BaseType”。类型“ParentNode”缺少类型“Document”的以下属性:URL、alinkColor、all、anchors等191个属性。ts(2769)

当前代码

const data = generateData(50);

const margin = { top: 10, right: 30, bottom: 30, left: 40 },
width = 800 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;

const svg = d3
   .select(".visualization")
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

const rects = svg.selectAll("rect").data(data).enter().append("rect");

rects
  .attr("x", (_, i) => i * (width / data.length))
  .attr("y", (d) => height - d)
  .attr("width", () => width / data.length - 1)
  .attr("height", (d) => d)
  .on("mouseover", function (d, i) {
    d3.select(this.parentNode).append("text").text(d);
   });

export {};

修复方案

错误根源

this.parentNode的类型是ParentNode | null,而D3的select()方法仅接受字符串选择器或符合BaseType的节点,TypeScript严格类型检查下两者不兼容。

具体修复步骤

  1. 类型断言兼容节点类型
    给this.parentNode添加类型断言,明确告诉TypeScript它是有效的SVG元素:

    d3.select(this.parentNode as SVGElement)
    
  2. 修正D3事件参数顺序(D3 v6+)
    D3 v6及之后的事件处理函数参数顺序为(event, d),而非旧版的(d, i),参数顺序错误会导致数据获取异常,修正后:

    .on("mouseover", function (event, d) {
      // 后续逻辑
    })
    
  3. 完善提示文本定位与避免重复创建
    新增文本时添加定位逻辑,同时在鼠标移出时移除提示,避免重复元素堆积:

    rects
      .attr("x", (_, i) => i * (width / data.length))
      .attr("y", (d) => height - d)
      .attr("width", () => width / data.length - 1)
      .attr("height", (d) => d)
      .on("mouseover", function (event, d) {
        const parent = d3.select(this.parentNode as SVGElement);
        // 移除已存在的提示文本
        parent.selectAll(".tooltip-text").remove();
        // 添加新的提示文本并定位
        parent.append("text")
          .attr("class", "tooltip-text")
          .attr("x", +d3.select(this).attr("x")!)
          .attr("y", +d3.select(this).attr("y")! - 5) // 文本置于矩形上方
          .attr("font-size", "12px")
          .text(d.toString());
      })
      .on("mouseout", function () {
        // 鼠标移出时删除提示
        d3.select(this.parentNode as SVGElement).selectAll(".tooltip-text").remove();
      });
    

内容的提问来源于stack exchange,提问作者kluzix

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 03:05:31