Skip to content

Instantly share code, notes, and snippets.

@tmcw
Created November 13, 2012 18:58
Show Gist options
  • Select an option

  • Save tmcw/4067674 to your computer and use it in GitHub Desktop.

Select an option

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>
@bel1k0v

bel1k0v commented Jan 16, 2014

Copy link
Copy Markdown

Thanks a lot!

@lazybios

Copy link
Copy Markdown

Nice !

@wmayner

wmayner commented Jan 14, 2015

Copy link
Copy Markdown

Thanks, this is awesome. You might want to change +new Date() to new Date().getTime(), though; see http://jsperf.com/new-date-timing.

@prakashkolandaivelu

Copy link
Copy Markdown

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

This way the argument can also be passed

@turquoiseowl

Copy link
Copy Markdown

It looks like the last variable is redundant?

@pkraker

pkraker commented May 26, 2016

Copy link
Copy Markdown

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

@nharrisanalyst

Copy link
Copy Markdown

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
Copy Markdown

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

mnehrig commented Sep 5, 2018

Copy link
Copy Markdown

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