Open dponch opened 10 years ago
Hi Dponch,
You could create a timeout function in your onclick function with a timeout you decide. If you have not received a doubleclick by then, interpret it as a click.
var doubleClick = false;
function onclick() {
setTimeout(function () {
if (doubleClick == false) {
doOnClick();
}
else {doubleClick = false;}
},400);
}
function doOnClick() {
...
do stuff
}
function onDoubleClick() {
doubleClick = true;
...
do stuff
}
Regards,
Alex
Hi,
That's a good idea, thanks for your help. But it didn't work out. I'm seeing that when I doubleclick it makes: 1) Call to click event. This can be avoid with your solution 2) Call to doubleclick event 3) Call to click event again. So finally, it does the click stuff.
I'm using Firefox30. Could it be a problem?
Hi Dponch,
You're right! I forgot about the second click hehe :). This should work:
network.on('click', onClick);
network.on('doubleClick', onDoubleClick);
var doubleClickTime = 0;
var threshold = 200;
function onClick() {
var t0 = new Date();
if (t0 - doubleClickTime > threshold) {
setTimeout(function () {
if (t0 - doubleClickTime > threshold) {
doOnClick();
}
},threshold);
}
}
function doOnClick() {
console.log("execute onClick function");
}
function onDoubleClick() {
doubleClickTime = new Date();
console.log("execute onDoubleClick function");
}
Let me know if this works!
It works perfectly! Many thanks!!!
You're welcome. We have not put this in vis because it would delay the click event. If a user doesnt use the double click that would be annoying :).
Alex,
Sorry to reopen an old ticket, but I came here looking for a solution to the multiple event issue. I completely understand why you wouldn't want the code above which delays the click()
event, but would it be possible for vis to suppress the second spurious click()
event? At the moment, if you double-click on the network, the user code gets:
click()
doubleClick()
click()
Is there a case for ever getting the second click()
event? Just the first two would seem to be 'normal' behaviour in, e.g. vb.net, etc. At the moment, I've had to put a variation of your code in to prevent that happening:
network.on('click', onClick);
network.on('doubleClick', onDoubleClick);
var doubleClickTime = 0;
var threshold = 200;
function onClick() {
var t0 = new Date();
if (t0 - doubleClickTime > threshold) {
doOnClick();
}
}
function doOnClick() {
console.log("execute onClick function");
}
function onDoubleClick() {
doubleClickTime = new Date();
console.log("execute onDoubleClick function");
}
This reduces a double-click on the network to these events:
click()
doubleClick()
which is actually exactly what I want. People who don't want the first click()
event when the user double-clicks can the use very similar user-side code to wait and see if there's a double-click event following within their own timeout.
The only side-effect of this would be that a double-click can't be followed by a single-click within the threshold time - but again, that's pretty normal I think.
Hi Dave,
That's perfectly fine. This code was just a suggestion or idea. To answer your question, no I don't think it's up to us to determine if people want a click after a double click. Since the solution is very easy, I'd prefer to leave that up to the devs using vis.
Regards,
Alex
It makes sense to me to just have the click-doubleclick
events, instead of click-doubleclick-click
. The second click is "eaten" or replaced by a doubleclick when within the threshold.
I can't come up with a use case where you would want click-doubleclick-click
. I think this behavior is unwanted in practice.
Double click can color a node and then click again somewhere else to deselect?
Nevermind, misread the issue.
I think there are three use cases:
click
. Click should react immediately.click
and doubleclick
, and it is fine to have both fired on the same user event. Click can then react immediately.click
and doubleclick
, and these two involve actions which should not happen on the same user event, I want either click
or doubleclick
fired but not both. For example on singleclick I create something, on doubleclick I delete something. This means a single click needs to wait for the threshold before it knows it was not the first click of a doubleclick. I think 1. and 2. are important. We could realize the third option as well, that requires the developer to set an option to specify this behavior.
The first item, only using click, makes it unacceptable for vis to eat a click for the doubleClick event. Since the events are always fired, regardless of listeners, what do you suggest? Options to pass to network on init?
If the default settings are anything other then it is now it could give unexpected behaviour. Also the doubleClick threshold (time to wait) could be customised. I'm not sure if I'd want to have people use the code as stated above or add more options.
What do you think?
The first item, only using click, makes it unacceptable for vis to eat a click for the doubleClick event.
Why? Seen from a user perspective, the user either does a single click (resulting in a click
event) or a double click (which should result in one click
and one doubleclick
event). In case of a double click, the second click is fired as a doubleclick
event instead of a second click
event.
So I think we can keep current behavior, except for the second click
event not being fired anymore when doubleclicking. Then we have situations 1. and 2. right?
Option 3 is an extra, that would require configuration via the options.
If you're only using clicks, and you are clicking twice fast I find it strange that you'd have to listen to the doubleClick event instead of just the click event because you might lose a click. Now vis gives you exactly what happens. There ARE two clicks and they were fast enough that it could be called a double click. I would argue this gives the most reliable result. We could add event options to streamline this if needed.
yeah, that's true. We could introduce an option for this with three different modes.
I'm torn between Alex's last comment (what you get is exactly what is happening), and the vast experience of developing on, e.g. Win32 where that isn't what you get. I'm not saying Win32 is right here, just that I was confused by the event stream being 'different'.
I think a 'doubleClickMode' option would be ideal - I'll leave it to someone else to argue what the default should be :). Then I can code on the user side exactly as I do in other apps, and get the same events I would normally expect. Here's my suggestion:
When the user just 'clicks', you should always get a click()
event. When the user 'double-clicks', you should get 1 of 4 things:
doubleClickMode: false
- you just get the 2 click()
events, very close together. Maybe this isn't strictly necessary - you just wouldn't subscribe to the doubleClick()
event...doubleClickMode: {mode: 'only', threshold: 200}
- you just get 1 doubleClick()
event, with the side-effect that all click()
events will be delayed by threshold
milliseconds, to allow for the detection of a double-clickdoubleClickMode: {mode: 'normal', threshold: 200}
- you get a click()
event immediately, and then a doubleClick()
event if the user clicks again within threshold
milliseconds (2 events in total)doubleClickMode: {mode: 'all', threshold: 200}
- you get a click()
event immediately, and then a second click()
event and a doubleClick()
event if the user clicks again within threshold
milliseconds (3 events in total)Hi Dave,
I would argue that 1 and 4 are the same. That leaves:
eventOptions : {
doubleClickThreshold : 200, // default 200?
doubleClick: true, // true will hide the second click, false: will not fire a doubleClick event at all.
... maybe future event options?
}
Hows that? If the user chooses to use the double click he'll have to work with the initial click anyway. I'm opposed to delaying ALL clicks, seems nasty.
Regards
Agree 1 isn't necessary as 1 == 4 if you don't subscribe to the doubleclick event.
Not sure what doubleClick: false
above would give - isn't that the same again as just not subscribing to the double-click event?
I'd strongly argue for including case 2. though, with a warning in the docs that it will delay clicks. If that's the behaviour you want, your user-side click handler will end up being delayed anyway, and this way it makes the user-side code much cleaner and easier to understand. IMO, we shouldn't be putting that level of click handling stuff in the application - it would be much nicer if the library did it for us. Understand this makes vis messier inside though. How about this version?
eventOptions : {
doubleClickThreshold : 200, // default 200? Read from OS (yuck)?
hideSingleClicks: 2 // default 1 (convention) or 0 (backwards compatibility for vis)
// Hide 0, 1 or 2 of the associated single clicks when a double click is detected
// 0 - user sees 'click', 'doubleClick', 'click' - no delay to click events
// 1 - user sees 'click', 'doubleClick' - no delay to click events
// 2 - user sees 'doubleClick' - all click events delayed
// ... maybe future event options?
}
I would argue that doubleClick: false in my example completely removes the double click functionality from the network. If true, we can delay all clicks and hide the second one. The user would essentially be "toggling" the double click functionality on or off.
I'm still a little unclear what the difference is between turning doubleClick off, and simply not subscribing to the doubleClick event. But anyway, would doubleClick: false
then send click()
or click(), click()
to the user? And if you set doubleClick(): true
, you then have no option to get all the events, which is the current behaviour. Doesn't that risk breaking old code?
if false, the user would get click - click, if true, the user would get
I think that's basically cases 0 and 1 in my list. Case 2 is the 'new' one, where click = click()
and double-click = doubleClick()
, which might be good for new apps, and would save the user having to put the wait code in.
In your last scenario, supposing I wanted a user's 'click' to do something, but a user's 'double-click' to do nothing. I'd have to subscribe to the doubleClick()
event, just to surpress the previous click()
event that I got first on the first press of the mouse! Seems like it makes the library quite awkward from a developers point of view...
Hi,
Over the last year a lot of feature requests have been made. We have just introduced our new website which has a list of the requested features. We have placed this request on that list.
The list can be found here: http://visjs.org/featureRequests.html
An explaination of the new system can be found here: http://visjs.org/blog.html#New\ website\ for\ vis.js!
I would like to stress that this does not mean we abandon this request. Discussion here will continue if needed on this feature but we will close it to keep our Github issue page more of a bug-todo list.
Future feature requests will still be made here and then added to the website by us.
Regards,
Alex
Reopening as Feature-Request issue (see #2114). Everybody: Please feel free to implement this!
Onclick of buttons how to show the particular segments of node.In vis js. If any knows please help me out.
@supriyasureshg You commented here so I'll remove the label Inactive
.
However, I don't really understand your comment, would you mind making it more clear?
It is certainly very nice and ergonomic to be able to distinguish different actions using the same left mouse button. Since the double click is a problem, an alternative could be to detect the time between the button down and the release.
I'd recommend to use Rx.js
I have following work to do :
I have written a function and map it to the clickCallBack of Dygraph. Things are working fine but soon you double click on graph will again call the function and I lost default feature of reset zoom. I know there should be something to differentiate the single click vs double click. The solution above told will not work for me since I need to fetch x axis value and click on container which holds graph will not fetch me point on which click was made.
I have even tried interactionModel but facing same problem. Please let me know your suggestion. @dponch @AlexDM0
Thanks, Rohit Jaiswal
const source = Rx.Observable.fromEvent(container, 'click')
.map(({ offsetX }) => offsetX)
.throttleTime(300)
.subscribe(offsetX => {
console.log(offsetX);
// make ajax call here
});
@MishaMykhalyukCogniance will it work for container which holds dygraph based graph. I have not used Rx before.
@rohit2503 It should work. I've checked it on official site:
Sorry I tried but it's not working. I have used this RX js https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.2.0/rxjs.umd.js in my code. When I am typing in browser console Rx it is giving error Rx not found.
Hi,
I want to use the events click and doubleclick on a network graph, but I realized that the event doubleclick triggers the event click, so when I doubleclick 2 functions are called. Is there a way to avoid this?
Thanks