D3v6 拖动事件回调函数触发未定义参数

D3v6 drag event callback function fire with undefined parameters

根据 D3v6 文档,我无法在使用 d3.symbol 实用程序绘制的路径 SVG 元素上实现简单的拖动行为。打字稿 class 在这里显示为上下文。 事件在正确的元素上触发,但回调函数似乎没有收到 (event, datum) 参数。 任何帮助将不胜感激。

import * as d3 from "d3";

export default class Sliders {
    svg: SVGSVGElement;

    constructor(svg: SVGSVGElement){
        this.svg = svg;
    }

    draw(){
        const g = d3.select(this.svg).append('g').attr('class', 'symbol');   
        const circle = g.append('circle').attr('r', 200);

        const D = d3.drag() // `event` and `d` are always undefined in 3 lines below
            .on("start", (event, d) => circle.attr("stroke", "lime"))
            .on("drag", (event, d: any) => (d.x = event.x, d.y = event.y))
            .on("end", (event, d) => circle.attr("stroke", "black")) as any; // Could not fathom the proper type
        circle.call(D); 
    }
}

为一些细节回答我自己。 剥离任何 webpack/typescript 业务, 在单个html文件中,定义了拖动事件回调参数

<!DOCTYPE html>
<meta charset="utf-8">


<div id="data"> </div>

<script src="https://d3js.org/d3.v6.min.js"></script>
<script>
const svg = d3.select('#data').append('svg').attr('width', 500).attr('height', 500);
console.log(svg);
const circle = svg.append('circle').attr('r', 5).attr('cy', 25).attr('cx', 25);
// `event` parameter is defined
const D = d3.drag()
            .on("start", (event, d) => circle.attr("stroke", "lime"))
            .on("drag", (event, d) => { 
                  console.log(event);
            })  
            .on("end", (event, d) => circle.attr("stroke", "black")); 
circle.call(D); 
    
</script>

虽然没有解决我最初的问题。

问题的可能原因是第一个示例中使用的 d3 版本不是 v6.0。从 v5.x 到 v6.0 where the event is no longer a global variable but passed as a parameter in callbacks.

发生了重大变化

您的代码采用 v6.0 风格,因此它在第二个示例中有效,它从 https://d3js.org/

显式导入 v6.0

您可以确认您的原始代码是否是 运行 d3 v6.0,其中一个回调中带有 console.log(d3.event)

  .on("drag", () => { 
    console.log(d3.event);
  })  

如果上面的代码记录了事件,则表示您的 d3 版本为 v5.x。 如果它有效,但打字稿无论如何也会给出类型错误,这意味着您的打字(@types/d3)适用于 v6.0,因此它们与安装的 d3 版本不一致。

无论如何,如果 d3.event 有效,那么最简单的解决方案是将您的 d3 更新到 v6.0,因为您已经拥有与最新版本兼容的代码。

回调的第二个参数是元素绑定的数据。在你的例子中,它应该是 undefined 因为没有与圆相关联的数据(即 .append() 之前没有 .selectAll(...).data(...))。如果有兴趣,您可以查看a d3-drag example in v.6.0 that uses data binding以更好地理解它。

因此,在没有数据绑定的情况下,v5.0 中的最小拖动行为示例为:

 .on("drag", function() { 
    d3.select(this).attr("cx", d3.event.x).attr("cy", d3.event.y);
  })  

在 v6.0 中:

 .on("drag", function(event) { 
    d3.select(this).attr("cx", event.x).attr("cy", event.y);
  })  

节点:记得使用function关键字而不是箭头函数(() => ...)if you want acess to the correct this object inside it