Skip to content

Instantly share code, notes, and snippets.

@tmcw
Created November 13, 2012 18:58
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save tmcw/4067674 to your computer and use it in GitHub Desktop.
Save tmcw/4067674 to your computer and use it in GitHub Desktop.
double click and single click separation
<!DOCTYPE html>
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style>
body { margin:0; padding:0; }
#map { width:960px; height:500px; background:cyan; }
</style>
</head>
<body>
<div id='map'></div>
<script>
function clickcancel() {
var event = d3.dispatch('click', 'dblclick');
function cc(selection) {
var down,
tolerance = 5,
last,
wait = null;
// euclidean distance
function dist(a, b) {
return Math.sqrt(Math.pow(a[0] - b[0], 2), Math.pow(a[1] - b[1], 2));
}
selection.on('mousedown', function() {
down = d3.mouse(document.body);
last = +new Date();
});
selection.on('mouseup', function() {
if (dist(down, d3.mouse(document.body)) > tolerance) {
return;
} else {
if (wait) {
window.clearTimeout(wait);
wait = null;
event.dblclick(d3.event);
} else {
wait = window.setTimeout((function(e) {
return function() {
event.click(e);
wait = null;
};
})(d3.event), 300);
}
}
});
};
return d3.rebind(cc, event, 'on');
}
var cc = clickcancel();
d3.select('#map').call(cc);
cc.on('click', function() {
d3.select('#map').text(d3.select('#map').text() + 'click, ');
});
cc.on('dblclick', function() {
d3.select('#map').text(d3.select('#map').text() + 'dblclick, ');
});
</script>
</body>
</html>
@prakashkolandaivelu
Copy link

selection.on("click", function(d, i) {
dispatch.custom.apply(this, arguments);
});

This way the argument can also be passed

@turquoiseowl
Copy link

It looks like the last variable is redundant?

@pkraker
Copy link

pkraker commented May 26, 2016

@pkolanda: At what line did you insert the snippet you posted? Thanks!

@nharrisanalyst
Copy link

I updated this snippet for d3v4 and v5
you first have to put the rebind function back into d3 which can be found here https://github.com/d3/d3/blob/v3.5.17/src/core/rebind.js

function clickCancel() {
var event = d3.dispatch('click', 'dblclick');
function cc(selection) {
var down,
tolerance = 5,
last,
wait = null;
// euclidean distance
function dist(a, b) {
return Math.sqrt(Math.pow(a[0] - b[0], 2), Math.pow(a[1] - b[1], 2));
}
selection.on('mousedown', function() {
down = d3.mouse(document.body);
last = +new Date();
});
selection.on('mouseup', function() {
if (dist(down, d3.mouse(document.body)) > tolerance) {
return;
} else {
if (wait) {
window.clearTimeout(wait);
wait = null;
event.call('dblclick',d3.event)
//event.dblclick(d3.event);
} else {
wait = window.setTimeout((function(e) {
return function() {
event.call('click',e)
//event.click(e);
wait = null;
};
})(d3.event), 300);
}
}
});
};
return d3.rebind(cc, event, 'on');
}

@nharrisanalyst
Copy link

Also if you want the mouse event to go into both the double click and the single click you have to pass it down through the anonymous functions

@mnehrig
Copy link

mnehrig commented Sep 5, 2018

Hey!

I created a fork of your snippet to stretch your euclidean distance to another dimension, when I learned, that a comment might be a better way to fight against discrimination of the vertical movement.
Math.sqrt(Math.pow(...) + Math.pow(...))
Don't just drop her into the void, please.

Your snippet helped me so much. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment