【问题标题】:D3v6 drag event callback function fire with undefined parameters带有未定义参数的 D3v6 拖动事件回调函数触发
【发布时间】:2021-01-21 15:29:28
【问题描述】:

按照 D3v6 文档,我无法在使用 d3.symbol 工具绘制的路径 SVG 元素上实现简单的拖动行为。 typescript 类在此处显示为上下文。 事件在正确的元素上触发,但回调函数似乎没有接收到 (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); 
    }
}

【问题讨论】:

    标签: d3.js events parameters callback draggable


    【解决方案1】:

    问题的一个可能原因是第一个示例中使用的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

    您可以在其中一个回调中使用console.log(d3.event) 来确认您的原始代码是否正在运行 d3 v6.0:

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

    如果上面的代码记录了事件,这意味着你的 d3 是 v5.x 版本。 如果它有效,但 typescript 无论如何也会给出类型错误,这意味着您的类型 (@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

    【讨论】:

    • 感谢您的提示。原来我的设置是使用 d3v6 类型,但可能安装了 d3v5.X 模块。 npm install d3@\^6 直截了当,现在定义了 event 和 d 参数。
    【解决方案2】:

    回答我自己的一些细节。 剥离任何 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>
    
    

    但并不能解决我最初的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-17
      • 2020-01-14
      • 2019-03-11
      • 2022-07-16
      • 1970-01-01
      • 1970-01-01
      • 2023-02-21
      • 1970-01-01
      相关资源
      最近更新 更多