Skip to content
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

Fixes Too Many Datapoints being hovered #5332

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 13 additions & 3 deletions src/core/core.interaction.js
Expand Up @@ -37,6 +37,7 @@ function parseVisibleItems(chart, handler) {
for (j = 0, jlen = meta.data.length; j < jlen; ++j) {
var element = meta.data[j];
if (!element._view.skip) {
element.datasetlength = meta.data.length;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line seems unused

handler(element);
}
}
Expand Down Expand Up @@ -279,10 +280,19 @@ module.exports = {
var intersectsItem = false;

parseVisibleItems(chart, function(element) {
if (element.inXRange(position.x)) {
items.push(element);
if (element.datasetlength < 40) {
if (element.inXRange(position.x)) {
items.push(element);
}
} else if (element.datasetlength >= 40) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could turn this else if into simply an else

however, i'm not sure why the check for whether there are more or less than 40 elements is being added. Why not always to do the cleanup of extra elements?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right the else if check is kind of redundant. After some extensive testing, I found the issue occurs after there are 40 datapoints on the chart. From my understanding, the reason for inXRange is to allow the user to not have to be precisely on the 'x' coordinate to have the datapoint highlighted by the tooltip and rather have the user be in a certain range of the tooltip making it easier to highlight. However, the main problem here is when we have say 300+ datapoints there begins to be too many data points that fall within that same range. Overall the having a separate function inXRangeSmall narrows the range in which a datapoint will be returned if we have an extensive amount of datapoints (40+). Also I can add the cleanup to both just in case. Thanks for the review!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I convert the else if to else I get the "no-lonely-if" lint error.

chartjsif

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wants you to combine the else with the next if: } else iif (element.inXRangeSmall(position.x)) {

I still am not understanding though why we do not always call inXRangeSmall and remove the check for whether there are 40 datapoints

if (element.inXRangeSmall(position.x)) {
items.push(element);
// Cleanup extra elements
if (items.length > 1) {
items.splice(1, items.length);
}
}
}

if (element.inRange(position.x, position.y)) {
intersectsItem = true;
}
Expand Down
6 changes: 6 additions & 0 deletions src/elements/element.point.js
Expand Up @@ -27,6 +27,11 @@ function xRange(mouseX) {
return vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false;
}

function xRangeSmall(mouseX) {
var vm = this._view;
return vm ? (Math.abs(mouseX - vm.x) < 2) : false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why 2?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After testing I found 2 to be a reasonable number to have a decent X range without returning too many tooltip items. I found the lower the number the more precise the user has to be to the X coordinate of the datapoint for it to be highlighted which can get tedious if you have say 10 data points and are trying to have one highlighted.

}

function yRange(mouseY) {
var vm = this._view;
return vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false;
Expand All @@ -40,6 +45,7 @@ module.exports = Element.extend({

inLabelRange: xRange,
inXRange: xRange,
inXRangeSmall: xRangeSmall,
inYRange: yRange,

getCenterPoint: function() {
Expand Down