Skip to content

Instantly share code, notes, and snippets.

@ropeladder
Forked from kashesandr/index.html
Last active June 25, 2017 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ropeladder/83915942ac42f17c087a82001418f2ee to your computer and use it in GitHub Desktop.
Save ropeladder/83915942ac42f17c087a82001418f2ee to your computer and use it in GitHub Desktop.
Distinguishing click and double-click in D3.
license: mit
<!DOCTYPE html>
<html>
<head>
<script src="http://d3js.org/d3.v4.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() {
// we want to a distinguish single/double click
// details http://bl.ocks.org/couchand/6394506
var dispatcher = d3.dispatch('click', 'dblclick');
function cc(selection) {
var down, tolerance = 5, last, wait = null, args;
// 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();
args = arguments;
});
selection.on('mouseup', function() {
if (dist(down, d3.mouse(document.body)) > tolerance) {
return;
} else {
if (wait) {
window.clearTimeout(wait);
wait = null;
dispatcher.apply("dblclick", this, args);
} else {
wait = window.setTimeout((function() {
return function() {
dispatcher.apply("click", this, args);
wait = null;
};
})(), 300);
}
}
});
};
// Copies a variable number of methods from source to target.
var d3rebind = function(target, source) {
var i = 1, n = arguments.length, method;
while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);
return target;
};
// Method is assumed to be a standard D3 getter-setter:
// If passed with no arguments, gets the value.
// If passed with arguments, sets the value and returns the target.
function d3_rebind(target, source, method) {
return function() {
var value = method.apply(source, arguments);
return value === source ? target : value;
};
}
return d3rebind(cc, dispatcher, 'on');
}
var cc = clickcancel();
d3.select('#map').call(cc);
cc.on('click', function(d, index) {
d3.select('#map').text(d3.select('#map').text() + 'click, ');
});
cc.on('dblclick', function(d, index) {
d3.select('#map').text(d3.select('#map').text() + 'dblclick, ');
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment