如何使用d3.js以编程方式触发拖动事件? [英] How to programmatically trigger drag events with d3.js?

查看:265
本文介绍了如何使用d3.js以编程方式触发拖动事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一些对SVG元素使用拖动事件的代码.该代码工作正常,我想为此编写一些测试.与其手动手动移动鼠标,不如通过编程方式使用

I wrote some code that uses a drag event for svg elements. The code works fine and I would like to write some tests for it. Instead of manually moving my mouse by hand I would like to programmatically trigger the dragstart and drag events with selection.dispatch:

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

但是,事件似乎没有被触发.也许我使用了错误的事件键,或者需要包含一些其他选项?

However, the events do not seem to be fired. Maybe I use the wrong event keys or need to include some additional option?

我还尝试使用以下无济于事的变体:

I also tried to use following variants that did not help:

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

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

如果我尝试

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

我得到一个错误

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

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

What is the right way to trigger the events 'start' and 'drag' used in following code?

    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事件

如何在JavaScript中触发事件?

以编程方式创建拖动事件时,dataTransfer为空

推荐答案

下面是一项工作,该工作部分用笑话模拟了d3:

Here is a work around that partially mocks d3 with jest:

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();

});

这篇关于如何使用d3.js以编程方式触发拖动事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆