javascript - d3.js: Skilj mellan drag/start/slut och klickhändelse


Som titeln säger, jag har ett objekt, och jag behöver alla dess dra- och klickhändelser. Det har varit en del diskussion om detta problem, men det handlade mest om klick- och dra-händelser. (och ett svarsfiddle fungerade inte korrekt)

Jag har en fiddle här av var jag befinner mig. När jag drar förhindras klick, men när jag klickar utlöses dragstart- och slut-händelserna. Jag skulle vilja att de inte utlöses när jag klickar, och jag skulle vilja att klick inte utlöses när jag vill dra.

var drag = d3.behavior.drag()
  .origin(function(d){return d})
  .on('drag', function(d){
   d3.select(this).attr('cx', function(d){ return d.x += d3.event.dx });
   d3.select(this).attr('cy', function(d){ return d.y += d3.event.dy });   
   console.log('dragging');
})
.on('dragstart', function(d){
  d3.event.sourceEvent.stopPropagation()
  console.log('drag start');
})
.on('dragend', function(d){
  console.log('drag end');
})

// ..... 

 MySvgElementWith3DStuffOnIt.on('click', function(){
  if(d3.event.defaultPrevented) return;
  console.log('clicked');
});

Svar #1

En liten uppdatering av @thatOneGuy för att använda d3v4 drag-modul

https://jsfiddle.net/mhebrard/q5eL5qyv/

var drag = d3.drag()
    .on('drag', function(d){
    d3.select(this).attr('cx', function(d){ return d.x += d3.event.dx });
    d3.select(this).attr('cy', function(d){ return d.y += d3.event.dy });   
    console.log('dragging');
  })
  .on('start', function(d){
    console.log('drag start');
  })
  .on('end', function(d){
    console.log('drag end');
  })

Svar #2

Ditt exempel fungerar som förväntat. Se uppdaterad fiddle: https://jsfiddle.net/thatOneGuy/dd4nujxo/1/

Jag har lagt till några extra konsolloggar. När du drar den här raden :

if (d3.event.defaultPrevented) {console.log('return'); return};

Kommer att stoppa klickhändelsen från att utlösas. Och när du bara klickar, utlöses dragstart och dragend (som förväntat), men drag gör det inte. Vilket är anledningen till att du placerar koden för att flytta cirkeln inuti drag-funktionen. Hela grejen fungerar som förväntat :)