-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added "onHover" functionality for legend #3271
Conversation
d4popov
commented
Sep 7, 2016
- core.legend.js
- Created an "onHover" property in the legend object that will hold a user defined function (default is null)
- Modified the "handleEvent" function of the legend to check if the event passed to it is a "click/mouseup" or a "mousemove" to determine whether to call the "onClick" or the "onHover" event (this is for the sake of reusing the legend hitbox calculations)
- The "onHover" event will receive the same parameters as the "onClick" (the "event" itself and the "legendItem" the user is hovering over)
- core.controller.js
- Added a "mousemove" event to the "eventHandler" of the controller and put the new legend "onHover" logic in it
- Also moved the original chart "onHover" functionality under the "mousemove" clause too in order to put the hover events in one place for consistency.
* core.legend.js - Created an "onHover" property in the legend object that will hold a user defined function (default is null) - Modified the "handleEvent" function of the legend to check if the event passed to it is a "click/mouseup" or a "mousemove" to determine whether to call the "onClick" or the "onHover" event (this is for the sake of reusing the legend hitbox calculations) - The "onHover" event will receive the same parameters as the "onClick" (the "event" itself and the "legendItem" the user is hovering over) * core.controller.js - Added a "mousemove" event to the "eventHandler" of the controller and put the new legend "onHover" logic in it - Also moved the original chart "onHover" functionality under the "mousemove" clause too in order to put the hover events in one place for consistency.
if (hoverOptions.onHover) { | ||
hoverOptions.onHover.call(me, me.active); | ||
} | ||
if (me.legend && me.legend.handleEvent && me.legend.options.onHover) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we testing me.legend.options.onHover
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because if the user hasn't initialized the function onHover in their chart cofig, we won't need to go through the whole process of calculating the mouse position and if it is within the boundaries of the legend hitboxes. For the onClick event, it doesnt matter so much because it's activated once, but on the onHover it will be executed continuously so with that check I am not allowing the code to propagate to calling the legend handleEvent function. If I allow the code to propagate to the handleEvent function it will do all those mouse coordinate calculations, go through the forloop checking each and every legend hitbox and if the mouse is in it to eventually find that onHover is null and not do anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm even thinking that this eventHandler
should simply forward the event to the legend handleEvent
and so delegate all the event logic to the legend. Meaning, no e.type
check here, simply:
if (me.legend && me.legend.handleEvent) {
me.legend.handleEvent(e);
}
Which also mean that the legend handleEvent
should discard useless events asap:
handleEvent: function(e) {
var me = this;
var type = e.type;
type = type === 'mouseup'? 'click : type;
if (type === 'mousemove') {
if (!options.onHover) {
return;
}
} else if (type === 'click') {
if (!options.onClick) {
return;
}
} else {
return;
}
var position = ...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, the extra calculations should not be done if useless, but this is the responsibility of the legend, not the controller (since this logic is defined by the legend). I updated my previous comment accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Thanks for pointing that out Simon. I'll update my code and submit again.
* core.legend.js - Introduced logic that determines if the type of event passed to the "handleEvent" function is one we can handle. Currently allowing "click" and "mousemove" events. If the event is not one of those we stop the function execution. - Removed no longer needed checks later on in the function * core.controller.js - Since I moved the event type-check logic in the "handleEvent" legend function we no longer need to do the check in the "eventHandler" function in the controller.
LGTM, Travis is failing because there are some space indents. After fixing it, can you squash your commits? I like your commit messages, so feel free to describe the same way your squashed commit :) |
* core.legend.js - Fixed instances where I have used a mixture of spaces and tabs for indentation. Now the indentation comprises only of tabs.
I did fix the spacing. By the way, what do you mean by squash my commits? I haven't done it before. I am using Source Tree by the way. EDIT: I think I did something... Not sure if I did the correct thing :/ |
I mean, combine all your commits into a single one. After squashing commits, don't forget to force push to your branch ( Your last commit is not correct because you compute position before testing if it needs to (it should come after checking event type and callback presence). However you right, opts must be initialized before the checks. |
And you will need to update some tests because there is a new options: |
I am good to merge this once passing |
* core.legend.js - Removed some unnecessary tabs left behind after moving around blocks of code - Moved the position variables after the event checks in the "handleEvent" function to avoid unnecessary complexity * core.legend.tests.js - Added the "onHover" function to be expected as a standard field of the legend object (expecting a value of undefined) (+4 squashed commit) Squashed commit: [2acec2b] Fixed an error where I was trying to access a non initialized variable [d8a8a2a] Fix for inconsistent spacing * core.legend.js - Fixed instances where I have used a mixture of spaces and tabs for indentation. Now the indentation comprises only of tabs. [8bcb561] Improvements for "onHover" legend functionality * core.legend.js - Introduced logic that determines if the type of event passed to the "handleEvent" function is one we can handle. Currently allowing "click" and "mousemove" events. If the event is not one of those we stop the function execution. - Removed no longer needed checks later on in the function * core.controller.js - Since I moved the event type-check logic in the "handleEvent" legend function we no longer need to do the check in the "eventHandler" function in the controller. [6c4ff59] Added "onHover" functionality for legend * core.legend.js - Created an "onHover" property in the legend object that will hold a user defined function (default is null) - Modified the "handleEvent" function of the legend to check if the event passed to it is a "click/mouseup" or a "mousemove" to determine whether to call the "onClick" or the "onHover" event (this is for the sake of reusing the legend hitbox calculations) - The "onHover" event will receive the same parameters as the "onClick" (the "event" itself and the "legendItem" the user is hovering over) * core.controller.js - Added a "mousemove" event to the "eventHandler" of the controller and put the new legend "onHover" logic in it - Also moved the original chart "onHover" functionality under the "mousemove" clause too in order to put the hover events in one place for consistency.
…t.js into feature/Issue_#3267 # Conflicts: # src/core/core.legend.js
…nHover" field in legend property and expecting "onHover" to be (undefined) in the test case
I hope that fixed it. Sorry for the commits have turned out to be such a jungle... I have never before done commit squashing. If there is anything else to fix, please do tell me and i'll try my best. |
I think you squashed them correctly but forgot to force push to your branch. Also, I'm not sure why there are these merge commits. But no worries, I will squash them for you when merging :) Anyway, I realize that I made a small typo in the code example in my previous comment, can you please change:
by
|
I was actually thinking about it, but then left it alone because I thought you wanted it like that. I'll fix it right away and push again. |
Yeah, that was just example code, I don't mind if it's not exactly the same if it can be better :) I think I edited my comment to merge the |
Happy to hear that :) This is my first contribution to anything, so I wasn't very sure what was going on. I guess I need to read up some tutorials on indepth repository management and stuff. |
Forgot one important thing: can you update the document to add the new |
…d Configuration documentation file
I added the description of the new function to the doc file like you suggestes, and took the liberty of doing a small change to the "onClick" description as well. I copied the "onClick" description for the "onHover" function and wasn't sure if I should use the words "mouse hover" or "mousemove". So I ended up using the original event naming "...'mousemove' event is registered...", and then did the same for "onClick". Previously it was "...click is registered..." and changed it to "...'click' event is registered...". I hope thats all right. |
I think it's fine, if it's not, we will fix it later when cleaning the doc. |
Add "onHover" to the legend options that will hold a user defined function (default is null) and called when a "mousemove" event is registered on top of a label item, with same parameters as the "onClick" option. Also introduced logic that determines if the type of event passed to the legend "handleEvent" function is one we can handle. Currently allowing "click" and "mousemove" events. If the event is not one of those we stop the function execution (this is for the sake of reusing the legend hitbox calculations).
Add "onHover" to the legend options that will hold a user defined function (default is null) and called when a "mousemove" event is registered on top of a label item, with same parameters as the "onClick" option. Also introduced logic that determines if the type of event passed to the legend "handleEvent" function is one we can handle. Currently allowing "click" and "mousemove" events. If the event is not one of those we stop the function execution (this is for the sake of reusing the legend hitbox calculations).