I have an svg element I'd like to be able to click and drag separately. As far as I can tell in D3, clicking fires the "drag end" event (and possibly also drag start?). In the code below, simply clicking the circle gives it a red outline:
var svg = d3.select('body').append('svg');
var g = svg.append('g');
var c = g.append('circle').attr('r', 20).attr('cx', 25).attr('cy', 25)
.call(d3.drag().on('drag', dragged).on('end', end))
.on('click', clicked);
function dragged() {
d3.select(this).attr('fill', 'green').attr('cx', d3.event.x).attr('cy', d3.event.y);
}
function end() {
d3.select(this).attr('fill', 'red').attr('stroke', 'red').attr('stroke-width', 5);
}
function clicked() {
if (d3.event.defaultPrevented) return;
d3.select(this).attr('fill', 'blue');
}
It seems like most of the questions and blocks about clicking and dragging seem to want to suppress the click action on dragging, so are not relevant.
Since mouseup indicates a click's completion and the end of a drag you could skip the click event and simply add some logic to determine if a drag occured:
// track action:
var wasMoved = false;
// Drag event:
function dragged() {
d3.select(this).attr('fill', 'green').attr('cx', d3.event.x).attr('cy', d3.event.y);
wasMoved = true; // or alternatively, measure the change in distance.
}
// Mouse up event: drag end & click:
function end() {
if(wasMoved) {
// It was a drag:
d3.select(this).attr('fill', 'red').attr('stroke', 'red').attr('stroke-width', 5);
}
// Otherwise it was a click:
else {
d3.select(this).attr('fill', 'blue');
}
wasMoved = false; // reset for next drag.
}
Now we can only trigger one action on mouseup: drag end or what we wanted on click:
var svg = d3.select('body').append('svg');
var g = svg.append('g');
var drag = d3.drag().on("drag", dragged).on("end",end);
var c = g.append('circle')
.attr('r', 20).attr('cx', 25).attr('cy', 25)
.call(drag)
var wasMoved = false;
function dragged() {
d3.select(this).attr('fill', 'green').attr('cx', d3.event.x).attr('cy', d3.event.y);
wasMoved = true;
}
function end() {
if(wasMoved) {
// It was a drag:
d3.select(this).attr('fill', 'red').attr('stroke', 'orange').attr('stroke-width', 5);
}
// It was a click:
else {
d3.select(this).attr('fill', 'blue');
}
wasMoved = false;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.0.0/d3.min.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With