Событие масштабирования переопределяет поведение перетаскивания в d3js

Я пытаюсь реализовать обработчики событий перетаскивания и масштабирования для элемента круга, используя d3js. Я добавил поведение для обоих событий, как указано ниже.

var circle = svg.append("circle")
    .attr("fill", "green")
    .attr("opacity", 0.6)
    .attr("cx", 100)
    .attr("cy", 100)
    .attr("r", 13)
    .call(d3.behavior.drag().on("drag", drag))
    .call(d3.behavior.zoom().on("zoom", zoom));

без масштабирования объекта перетаскивание работает нормально. после увеличения/уменьшения масштаба объекта перетаскивание не работает, но все события, содержащие наведение мыши, перехватываются как событие «масштабирования».

Полный исходный код см. на странице http://jsfiddle.net/xTaDC/.

Кажется, я не понял "d3.behavior". https://github.com/mbostock/d3/blob/master/examples/mercator/mercator-zoom-constrained.html предоставляет только обработчик масштабирования и обрабатывает как перетаскивание, так и масштабирование.

Что я здесь делаю неправильно?


person altunyurt    schedule 23.11.2012    source источник
comment
Привет, у меня та же проблема. Не могли бы вы указать мне рабочий пример, в котором работает перетаскивание узлов, панорамирование и масштабирование?   -  person user602599    schedule 03.10.2013
comment
d3js zoom обеспечивает как перетаскивание, так и масштабирование. При масштабировании вы можете либо перевести(), либо масштабировать() свои фигуры. Смотрите ответ Леви.   -  person altunyurt    schedule 03.10.2013
comment
В частности, я не могу реализовать перетаскивание узла в этом примере: bl.ocks.org/mbostock/3680999   -  person user602599    schedule 04.10.2013


Ответы (4)


Насколько я знаю, поведение масштабирования d3 уже обрабатывает перетаскивание, поэтому перетаскивание является излишним. Попробуйте использовать масштаб d3.event.translate (который представляет собой массив из 2 элементов, поэтому, если вы хотите получить только значение x, вы можете использовать d3.event.translate[0]), чтобы воспроизвести функциональность в вашем перетаскивании. ваш зум.

Дополнительный совет: чтобы облегчить себе задачу, убедитесь, что вы применяете свой вызов (масштабирование) к родителю того, что вы пытаетесь перетащить. Это предотвратит нервное и шаткое поведение.

Источник, конечно же, вики d3. «Это поведение автоматически создает прослушиватели событий для обработки жестов масштабирования и панорамирования на элементе-контейнере. Поддерживаются как события мыши, так и события касания». https://github.com/mbostock/d3/wiki/Zoom-Behavior

person Levi    schedule 04.12.2012

Я столкнулся с аналогичной проблемой и решил ее, переопределив другие вспомогательные события масштабирования.

Добавьте приведенный ниже код после масштабирования и перетаскивания прослушивателей событий.

.on("mousedown.zoom", null)
.on("touchstart.zoom", null)
.on("touchmove.zoom", null)
.on("touchend.zoom", null);

Таким образом, полный код будет выглядеть так

var circle = svg.append("circle")
    .attr("fill", "green")
    .attr("opacity", 0.6)
    .attr("cx", 100)
    .attr("cy", 100)
    .attr("r", 13)
    .call(d3.behavior.drag().on("drag", drag))
    .call(d3.behavior.zoom().on("zoom", zoom))
    .on("mousedown.zoom", null)
    .on("touchstart.zoom", null)
    .on("touchmove.zoom", null)
    .on("touchend.zoom", null);
person kushdilip    schedule 14.05.2014

Добавьте к вашему графику чувствительную область событий (должно быть последним добавлением):

var rect = svg.append("svg:rect")
    .attr("class", "pane")
    .attr("width", w)
    .attr("height", h);

ПОСЛЕ (не включать) добавить управление событиями в этой области

rect.call(d3.behavior.zoom().x(x).scaleExtent([0.5, 4]).on("zoom", draw));

и функция рисования

function draw() {
    svg.select("g.x.axis").call(xAxis);
    svg.select("g.y.axis").call(yAxis);
    svg.select("path.area").attr("d", area);
    svg.select("path.line").attr("d", line);
}

см. этот пример: https://groups.google.com/forum/?fromgroups=#!topic/d3-js/6p7Lbnz-jRQ%5B1-25-false%5D

person Alban    schedule 17.02.2013

В 2020 году используйте d3.zoom, чтобы включить масштабирование и панорамирование: https://observablehq.com/@d3/zoom

Если вы хотите включить панорамирование фона, позволяя перетаскивать круг, см. официальный пример, где d3.drag и d3.zoom используются для разных элементов: https://observablehq.com/@d3/drag-zoom

person Sylvain Lesage    schedule 04.02.2020