d3合并缩放和拖动调用吗?

时间:2019-06-18 00:36:35

标签: d3.js

是否可以有条件地从拖动事件中忽略拖动功能?我有一个平移/缩放画布(如此处所示:www.proofapp.io/workspace),我正在尝试实现一个shift + Drag多选套索。 svg对象已经注册了缩放功能,因此当我在其上方放置拖动功能时,永远不会调用缩放。由于call在开始时只运行一次,所以我不确定如何使它工作。有什么建议吗?

const zoom = d3.zoom()
                    .scaleExtent([0.25 ,5])
                    .on("zoom", function() {
                        root.attr('transform', d3.event.transform);
                    });

// THIS DOESNT WORK BECAUSE IT ONLY RUNS ONCE AT THE BEGINNING
const lasso = function() {
    if (d3.event.sourceEvent) {
        if (d3.event.sourceEvent.shiftKey) {
            d3.drag()
                .dragDisable() // maybe the answer is with this?
                .on("start", function() { console.log('lasso-start') })
                .on("drag", function() { console.log('lasso-drag') })
                .on("end", function() { console.log('lasso-end') });
        }
    }
}

var svg = d3.select("div#nodegraph")
                    .append("svg")
                        .attr("width", "100%")
                        .attr("height", "100%")
                        .on('click', Graph.setNodeInactive)
                        .call(lasso)
                        .call(zoom);

更新

尝试仅使用mousedown.drag事件,以便我可以控制事件冒泡。尚未完全实现,但是行为是正确的(仅在按下shift键时才缩放块)。

const zoom = d3.zoom()
                    .scaleExtent([0.25 ,5])
                    .on("zoom", function() {
                        root.attr('transform', d3.event.transform);
                    });

function lasso() {
    if (d3.event.shiftKey) {
        // do stuff
        d3.event.stopImmediatePropagation();
    }
}

var svg = d3.select("div#nodegraph")
                    .append("svg")
                        .attr("width", "100%")
                        .attr("height", "100%")
                        .on('click', Graph.setNodeInactive)
                        .on('mousedown.drag', lasso)
                        .call(zoom);

1 个答案:

答案 0 :(得分:0)

如果有d3方式可以做到这一点,我仍然很想知道它如何发挥d3.drag的所有优点。在此之前,这里是一个相当完整的示例,其中考虑了缩放的画布。

Selection = {};
Selection.DragLasso = {};
Selection.DragLasso.__lasso = null;
Selection.DragLasso.handler = function() {
    if (d3.event.shiftKey) {
        d3.event.stopImmediatePropagation();

        if (Selection.DragLasso.__lasso) {
            Selection.DragLasso.__lasso.remove();
            Selection.DragLasso.__lasso = null;
        }

        var m = d3.mouse(this);

        svg
            .on('mousemove.drag', Selection.DragLasso.drag)
            .on('mouseup.drag', Selection.DragLasso.end);

        var z = d3.zoomTransform(svg.node());
        var x = (z.x / z.k * -1) + (m[0] / z.k);
        var y = (z.y / z.k * -1) + (m[1] / z.k);

        Selection.DragLasso.__lasso = noderoot.append('rect')
                                                    .attr("fill", 'red')
                                                    .attr('x', x)
                                                    .attr('y', y)
                                                    .attr('width', 0)
                                                    .attr('height', 0)
                                                    .classed('selection-lasso', true);
    }
}
Selection.DragLasso.drag = function(e) {
    var m = d3.mouse(this);

    var z = d3.zoomTransform(svg.node());
    var x = (z.x / z.k * -1) + (m[0] / z.k);
    var y = (z.y / z.k * -1) + (m[1] / z.k);

    Selection.DragLasso.__lasso
        .attr("width", Math.max(0,  x - +Selection.DragLasso.__lasso.attr("x")))
        .attr("height", Math.max(0, y - +Selection.DragLasso.__lasso.attr("y")));

}
Selection.DragLasso.end = function() {
    svg.on('mousemove.drag', null).on('mouseup.drag', null);
    Selection.DragLasso.__lasso.remove();
    Selection.DragLasso.__lasso = null;
}


var svg = d3.select("div#nodegraph")
                    .append("svg")
                        .attr("width", "100%")
                        .attr("height", "100%")
                        .on('mousedown.drag', Selection.DragLasso.handler)
                        .call(zoom);