如何使用 d3.js 以编程方式触发拖动事件?

2024-03-22

我编写了一些对 svg 元素使用拖动事件的代码。该代码运行良好,我想为其编写一些测试。我不想手动移动鼠标,而是想以编程方式触发dragstart and drag事件与选择.调度 https://github.com/d3/d3-selection#selection_dispatch:

     svgSelection.dispatch('dragstart',{bubbles:true});
     svgSelection.dispatch('drag',{bubbles:true});

然而,这些事件似乎并没有被解雇。也许我使用了错误的事件键或需要包含一些附加选项?

我还尝试使用以下没有帮助的变体:

svgElement.dispatchEvent(new Event('drag', {bubbles:true}));

svgSelection.dispatch('mousedown.drag',{bubbles:true});

If I try

svgElement.on('mousedown.drag')()

我收到一个错误

Uncaught TypeError: Cannot read property 'ctrlKey' of null
    at defaultFilter (drag.js?009f:10)
    at mousedowned (drag.js?009f:51)

触发以下代码中使用的事件“开始”和“拖动”的正确方法是什么?

    let offset = [0,0];
    let drag = d3.drag()
        .on('start', () => this.__dragStarted(d3, svgSelection, offset))
        .on('drag', ()=> this.__dragged(d3, svgSelection, offset));
    svgSelection.call(drag);

我的测试示例:

it('enableDragAndDrop', ()=>{
     let element = document.createElement('svg');
     let svgSelection = d3.select(element);

     spyOn(sut, '__dragStarted');
     spyOn(sut, '__dragged');

     sut.enableDragAndDrop(svgSelection);
     svgSelection.dispatch('dragstart',{bubbles:true});
     svgSelection.dispatch('drag',{bubbles:true});

     expect(sut.__dragStarted).toHaveBeenCalled();
     expect(sut.__dragged).toHaveBeenCalled();

});

我的代码示例:

enableDragAndDrop(svgSelection){
    let offset = [0,0];
    let drag = d3.drag()
        .on('start', () => this.__dragStarted(d3, svgSelection, offset))
        .on('drag', ()=> this.__dragged(d3, svgSelection, offset));
    svgSelection.call(drag);
}

__dragStarted(d3, svgSelection, offset){
    if(!svgSelection.attr('transform')){
        svgSelection.attr('transform','translate(0,0)');
    }

    let transform = svgSelection.attr('transform');
    let translate = this.__extractTranslate(transform);
    offset[0] = translate[0] - d3.event.x;
    offset[1] = translate[1] - d3.event.y;
}

__dragged(d3, svgSelection, offset){

    let x = d3.event.x + offset[0];
    let y = d3.event.y + offset[1];
    svgSelection
        .attr('transform', 'translate(' + x + ', ' + y + ')');
}

__extractTranslate(transformString){
    let stripped = transformString;
    stripped = stripped.replace('translate(','');
    stripped = stripped.replace(')','');
    let numberStrings = stripped.split(',');
    return numberStrings.map(numberString=>parseFloat(numberString));
}

相关问题:

如何外部触发d3事件 https://stackoverflow.com/questions/40415144/how-to-externally-trigger-d3-events

JavaScript中如何触发事件? https://stackoverflow.com/questions/2490825/how-to-trigger-event-in-javascript

以编程方式创建拖动事件时 dataTransfer 为 null https://stackoverflow.com/questions/20867245/datatransfer-is-null-when-creating-drag-event-programmatically


这是一个用 jest 部分模拟 d3 的解决方法:

import * as d3 from 'd3';

jest.mock('d3', ()=>{

    let wrappedD3 = jest.requireActual('d3');

    var d3Mock = {
        drag: undefined,
        event: wrappedD3.event,
        select: wrappedD3.select,
        __passedEventHandlers: []
    };

    d3Mock.drag = ()=>{
        let dragMock = {
            apply: ()=>{}
        };
        dragMock.on = (event, eventHandler)=>{
                d3Mock.__passedEventHandlers.push(eventHandler);
                return dragMock;
        }
        return dragMock;
    };

    return d3Mock;

});

测试中的用法示例:

it('enableDragAndDrop', ()=>{
     let element = document.createElement('svg');
     document.body.appendChild(element);

     let svgSelection = d3.select(element);   

     sut.enableDragAndDrop(svgSelection);

     spyOn(sut, '__dragStarted');
     let dragStartedHandler = d3.__passedEventHandlers[0];
     dragStartedHandler();
     expect(sut.__dragStarted).toHaveBeenCalled();

     spyOn(sut, '__dragged');
     let draggedHandler = d3.__passedEventHandlers[1];
     draggedHandler();
     expect(sut.__dragged).toHaveBeenCalled();

});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 d3.js 以编程方式触发拖动事件? 的相关文章

  • 使用 keyup 上的 Submit() 提交表单两次

    我有一个与此类似的 jQuery HTML 代码
  • 向 JS 计算器添加键盘支持时出现的问题

    我想为我的计算器添加键盘支持 当我用键盘按下操作 即 或 时 js将其视为数字 而不是操作 例如 当我通过点击计算 10 11 时 我将得到 21 作为结果 当我通过键盘输入时 我会得到 10 为什么会发生这种情况 是否可以改变它 div
  • 将组件注册到现有的 Vue.js 实例

    我是 Vue js 新手 我想注册一个本地组件 如下所述 https v2 vuejs org v2 guide components html Local Registration https v2 vuejs org v2 guide
  • 如何在下拉列表中选择一个选项

    我正在使用 AngularJS 指令 我需要在模板中设置下拉列表的选定选项
  • D3 v4 在同一元素上进行画笔和缩放(鼠标事件不冲突)

    我的目标是构建一个使用两者的 D3 v4 图表d3 zoom https github com d3 d3 zoom and d3 brush https github com d3 d3 brush一起 如下 当鼠标位于 x 轴上时 用户
  • 语法:const {} = 变量名,任何人都可以解释或指出我正确的方向[重复]

    这个问题在这里已经有答案了 这个语法在 JavaScript 中意味着什么 可能是 ES6 const 变量名 我目前正在尝试掌握 React 在很多例子中我都遇到过这种语法 例如 const girls guys women men st
  • SVG 中三角形的圆角

    我正在尝试制作一个具有圆角的三角形 三角形将如下所示 左下角是唯一看起来相当容易制作的角 主要是因为这是一个 90 度的 转弯 该转弯是使用QSVG 中的命令具有以下参数 Q x y height x y height RADIUS从我正在
  • JavaScript 原型 - 请澄清

    有人可以帮我理解原型属性吗 我不明白原型属性是函数的属性还是函数内部的属性 假设我们创建以下构造函数 Food 此时 函数 Food 具有 Food prototype 属性 由于 Food 是 Object 的实例 因此这意味着 Obec
  • AngularJS - 服务、工厂、过滤器等中的依赖注入

    因此 我想在我的 Angular 应用程序中使用一些插件和库 目前 我只是引用这些函数 方法 因为它们是在 99 的应用程序中以完全忽略依赖注入的方式使用的 我有 例如 javascript 库 MomentJS 它处理格式化和验证日期 并
  • 当表格在 IE 中获得焦点时,表格滚动条会向上跳跃

    问题 我有一个table有包装的div with overflow y auto 一旦table获得焦点 滚动条向上跳 我怎样才能防止这种情况发生 我经历过这种行为IE9 不在 Chrome 中 请注意 我已添加tabindex到桌子上 以
  • 全局未在 ../node_modules/socket.io-parser/is-buffer.js 中定义

    预先感谢您帮助我 我正在尝试在我的一个角度组件中连接套接字 但在浏览器的控制台中它会抛出一个错误 指出 Global 未在 Object node modules socket io parser is buffer js 中定义 这是我的
  • 更改特定字符串的颜色

    有谁知道如果将特定单词输入文本区域 我如何更改它的颜色 例如 如果用户输入 你好我的朋友 它会动态地将 你好 更改为绿色 在google上花了很多时间 找不到任何相关的东西 谢谢 textareas 的设计目的不是选择性着色
  • 我可以在不使用 Jquery UI 的情况下获得 Jquery Pulsate Effect 吗?

    我遇到了由于某种原因无法使用 Jquery UI 的情况 我正在尝试在不使用 Jquery UI 的情况下获得 Jquery UI 脉冲效果 与此链接类似 http docs jquery com UI Effects Pulsate ht
  • 清理 html 字符串中的所有脚本

    HTML5 剪贴板很棒 但我正在寻找一种使其安全的方法 用户正在将文本 html 粘贴到我的网页中 这允许他们粘贴图像 表格等 我正在寻找一种方法 在将粘贴的内容添加到页面之前删除所有脚本 我需要删除
  • 表单序列化javascript(无框架)

    想知道 javascript 中是否有一个没有 jquery 或任何框架的函数可以让我序列化表单并访问序列化版本 2023 年更新 Use FormData https developer mozilla org en US docs We
  • D3.js - 具有多个环的圆环图

    以下示例显示了 D3 js 中的圆环图 是否可以向图表添加多个圆环 var dataset apples 53245 28479 19697 24037 40245 var width 460 height 300 radius Math
  • d3力定向布局-链接距离优先

    在 d3 中使用力导向布局 如何使链接距离成为优先事项 同时仍然保持良好的图形布局 如果我指定动态链接距离 但保留默认费用 则我的图形距离会因费用函数而发生一些变形 并且不再是准确的距离 但是 如果我删除电荷 图表将如下所示 任何建议表示赞
  • 当选项卡重新加载(chrome 扩展)时,如何运行此脚本?

    所以我想在指定 URL 中重新加载选项卡时运行脚本 它几乎可以工作 但实际上 id 不能 这是我的清单文件 manifest version 2 name Sample Extension description Sample Chrome
  • ES6 Reflect API 的好处

    我一直在努力升级一些代码以使用 ES6 语法 我有以下代码行 delete this foo 我的 linter 提出了使用建议 Reflect deleteProperty this foo 您可以找到该方法的文档here https d
  • 使用 div 或表格来包含链接列更好吗?

    我的页面底部有 3 列链接 每列都放入一个 div 中 所有三个 div 都包装在页面中央的一个大 div 中 这是更适合桌子的东西还是桌子不适合这项工作 您还可以使用 ul http www w3schools com tags tag

随机推荐