Skip to content

Commit

Permalink
nearest: return all
Browse files Browse the repository at this point in the history
Return all items that are at the nearest distance to the point.
  • Loading branch information
kurkle committed Nov 26, 2018
1 parent b68341d commit 07abfd8
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 82 deletions.
2 changes: 1 addition & 1 deletion docs/general/interactions/modes.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var chart = new Chart(ctx, {
```

## nearest
Gets the item that is nearest to the point. The nearest item is determined based on the distance to the center of the chart item (point, bar). If 2 or more items are at the same distance, the one with the smallest area is used. If `intersect` is true, this is only triggered when the mouse position intersects an item in the graph. This is very useful for combo charts where points are hidden behind bars.
Gets the items that are at the nearest distance to the point. The nearest item is determined based on the distance to the center of the chart item (point, bar). You can use the `axis` setting to define which directions are used in distance calculation. If `intersect` is true, this is only triggered when the mouse position intersects an item in the graph. This is very useful for combo charts where points are hidden behind bars.

```javascript
var chart = new Chart(ctx, {
Expand Down
21 changes: 1 addition & 20 deletions src/core/core.interaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,26 +243,7 @@ module.exports = {
var position = getRelativePosition(e, chart);
options.axis = options.axis || 'xy';
var distanceMetric = getDistanceMetricForAxis(options.axis);
var nearestItems = getNearestItems(chart, position, options.intersect, distanceMetric);

// We have multiple items at the same distance from the event. Now sort by smallest
if (nearestItems.length > 1) {
nearestItems.sort(function(a, b) {
var sizeA = a.getArea();
var sizeB = b.getArea();
var ret = sizeA - sizeB;

if (ret === 0) {
// if equal sort by dataset index
ret = a._datasetIndex - b._datasetIndex;
}

return ret;
});
}

// Return only 1 item
return nearestItems.slice(0, 1);
return getNearestItems(chart, position, options.intersect, distanceMetric);
},

/**
Expand Down
64 changes: 3 additions & 61 deletions test/specs/core.interaction.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,37 +363,8 @@ describe('Core.Interaction', function() {
expect(elements).toEqual([meta.data[0]]);
});

it ('should return the smallest item if more than 1 are at the same distance', function() {
var chart = this.chart;
var meta0 = chart.getDatasetMeta(0);
var meta1 = chart.getDatasetMeta(1);

// Halfway between 2 mid points
var pt = {
x: meta0.data[1]._view.x,
y: (meta0.data[1]._view.y + meta1.data[1]._view.y) / 2
};

var evt = {
type: 'click',
chart: chart,
native: true, // needed otherwise things its a DOM event
x: pt.x,
y: pt.y
};

// Nearest to 0,0 (top left) will be first point of dataset 2
var elements = Chart.Interaction.modes.nearest(chart, evt, {intersect: false});
expect(elements).toEqual([meta0.data[1]]);
});

it ('should return the lowest dataset index if size and area are the same', function() {
it ('should return all items at the same nearest distance', function() {
var chart = this.chart;
// Make equal sized points at index: 1
chart.data.datasets[0].pointRadius[1] = 10;
chart.update();

// Trigger an event over top of the
var meta0 = chart.getDatasetMeta(0);
var meta1 = chart.getDatasetMeta(1);

Expand All @@ -411,9 +382,9 @@ describe('Core.Interaction', function() {
y: pt.y
};

// Nearest to 0,0 (top left) will be first point of dataset 2
// Both points are nearest
var elements = Chart.Interaction.modes.nearest(chart, evt, {intersect: false});
expect(elements).toEqual([meta0.data[1]]);
expect(elements).toEqual([meta0.data[1], meta1.data[1]]);
});
});

Expand Down Expand Up @@ -521,35 +492,6 @@ describe('Core.Interaction', function() {
var elements = Chart.Interaction.modes.nearest(chart, evt, {intersect: true});
expect(elements).toEqual([meta0.data[1]]);
});

it ('should return the item at the lowest dataset index if distance and area are the same', function() {
var chart = this.chart;
chart.data.datasets[0].pointRadius = [5, 10, 5];
chart.data.datasets[0].data[1] = 40;

chart.data.datasets[1].pointRadius = [10, 10, 10];

// Trigger an event over top of the
var meta0 = chart.getDatasetMeta(0);

// Halfway between 2 mid points
var pt = {
x: meta0.data[1]._view.x,
y: meta0.data[1]._view.y
};

var evt = {
type: 'click',
chart: chart,
native: true, // needed otherwise things its a DOM event
x: pt.x,
y: pt.y
};

// Nearest to 0,0 (top left) will be first point of dataset 2
var elements = Chart.Interaction.modes.nearest(chart, evt, {intersect: true});
expect(elements).toEqual([meta0.data[1]]);
});
});
});

Expand Down

0 comments on commit 07abfd8

Please sign in to comment.