cancelableClick = {
const rebindMethod = (target, source, method) => {
return (...args) => {
const value = method.apply(source, args);
return value === source ? target : value;
};
}
const rebind = (target, source, ...methods) => {
for (let method of methods) {
target[method] = rebindMethod(target, source, source[method]);
}
return target;
};
return ({ tolerance = 5, timeout = 200, d3lib = d3 } = {}) => {
const dispatcher = d3lib.dispatch('click', 'dblclick');
const cc = (selection) => {
let downPt;
let lastTs;
let waitId;
let eventArgs;
selection.on('mousedown', (...args) => {
downPt = d3lib.mouse(document.body);
lastTs = Date.now();
eventArgs = args;
});
selection.on('mouseup', () => {
if (dist(downPt, d3lib.mouse(document.body)) >= tolerance) {
return;
}
if (waitId) {
window.clearTimeout(waitId);
waitId = null;
dispatcher.apply("dblclick", selection, eventArgs);
} else {
waitId = window.setTimeout(
() => {
dispatcher.apply("click", selection, eventArgs);
waitId = null;
},
timeout
);
}
});
};
return rebind(cc, dispatcher, 'on');
}
}