From 2be634a47862e6a8a0c80d77980788b72658b2d7 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Sat, 14 Dec 2019 10:09:50 -0800 Subject: [PATCH] Interactions cleanup (#6825) --- docs/configuration/tooltip.md | 8 +-- docs/developers/charts.md | 4 +- docs/getting-started/v3-migration.md | 3 +- src/core/core.interaction.js | 81 +++++++++++++--------------- src/core/core.tooltip.js | 6 +-- test/specs/core.tooltip.tests.js | 2 - 6 files changed, 45 insertions(+), 59 deletions(-) diff --git a/docs/configuration/tooltip.md b/docs/configuration/tooltip.md index 7ffefd93d..30d2e121d 100644 --- a/docs/configuration/tooltip.md +++ b/docs/configuration/tooltip.md @@ -187,13 +187,7 @@ The tooltip items passed to the tooltip callbacks implement the following interf datasetIndex: number, // Index of this data item in the dataset - index: number, - - // X position of matching point - x: number, - - // Y position of matching point - y: number + index: number } ``` diff --git a/docs/developers/charts.md b/docs/developers/charts.md index e3949b064..2e2e5c231 100644 --- a/docs/developers/charts.md +++ b/docs/developers/charts.md @@ -34,10 +34,10 @@ Dataset controllers must implement the following interface. draw: function(ease) {}, // Remove hover styling from the given element - removeHoverStyle: function(element) {}, + removeHoverStyle: function(element, datasetIndex, index) {}, // Add hover styling to the given element - setHoverStyle: function(element) {}, + setHoverStyle: function(element, datasetIndex, index) {}, // Update the elements in response to new data // @param reset : if true, put the elements into a reset state so they can animate to their final values diff --git a/docs/getting-started/v3-migration.md b/docs/getting-started/v3-migration.md index ffa87614f..dd8d3a222 100644 --- a/docs/getting-started/v3-migration.md +++ b/docs/getting-started/v3-migration.md @@ -83,6 +83,7 @@ Chart.js 3.0 introduces a number of breaking changes. Chart.js 2.0 was released * `Scale.ticksAsNumbers` * `Scale.handleDirectionalChanges` is now private * `Scale.tickValues` is now private +* The tooltip item's `x` and `y` attributes were removed. Use `datasetIndex` and `index` to get the element and any corresponding data from it #### Removal of private APIs @@ -142,7 +143,7 @@ Chart.js 3.0 introduces a number of breaking changes. Chart.js 2.0 was released ##### Dataset Controllers -* `setHoverStyle` now additionally takes the `datasetIndex` and `index` +* `setHoverStyle` and `removeHoverStyle` now additionally take the `datasetIndex` and `index` #### Interactions diff --git a/src/core/core.interaction.js b/src/core/core.interaction.js index 792ce2ecb..ad1ec4717 100644 --- a/src/core/core.interaction.js +++ b/src/core/core.interaction.js @@ -58,7 +58,7 @@ function getIntersectItems(chart, position) { } /** - * Helper function to get the items nearest to the event position considering all visible items in teh chart + * Helper function to get the items nearest to the event position considering all visible items in the chart * @param {Chart} chart - the chart to look at elements from * @param {object} position - the point to be nearest to * @param {boolean} intersect - if true, only consider items that intersect the position @@ -104,31 +104,6 @@ function getDistanceMetricForAxis(axis) { }; } -function indexMode(chart, e, options) { - var position = getRelativePosition(e, chart); - // Default axis for index mode is 'x' to match old behaviour - options.axis = options.axis || 'x'; - var distanceMetric = getDistanceMetricForAxis(options.axis); - var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); - var elements = []; - - if (!items.length) { - return []; - } - - chart._getSortedVisibleDatasetMetas().forEach(function(meta) { - var index = items[0].index; - var element = meta.data[index]; - - // don't count items that are skipped (null data) - if (element && !element._view.skip) { - elements.push({element, datasetIndex: meta.index, index}); - } - }); - - return elements; -} - /** * @interface IInteractionOptions */ @@ -155,7 +130,29 @@ module.exports = { * @param {IInteractionOptions} options - options to use during interaction * @return {Object[]} Array of elements that are under the point. If none are found, an empty array is returned */ - index: indexMode, + index: function(chart, e, options) { + const position = getRelativePosition(e, chart); + // Default axis for index mode is 'x' to match old behaviour + const distanceMetric = getDistanceMetricForAxis(options.axis || 'x'); + const items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); + const elements = []; + + if (!items.length) { + return []; + } + + chart._getSortedVisibleDatasetMetas().forEach(function(meta) { + const index = items[0].index; + const element = meta.data[index]; + + // don't count items that are skipped (null data) + if (element && !element._view.skip) { + elements.push({element, datasetIndex: meta.index, index}); + } + }); + + return elements; + }, /** * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something @@ -167,10 +164,9 @@ module.exports = { * @return {Object[]} Array of elements that are under the point. If none are found, an empty array is returned */ dataset: function(chart, e, options) { - var position = getRelativePosition(e, chart); - options.axis = options.axis || 'xy'; - var distanceMetric = getDistanceMetricForAxis(options.axis); - var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); + const position = getRelativePosition(e, chart); + const distanceMetric = getDistanceMetricForAxis(options.axis || 'xy'); + let items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); if (items.length > 0) { items = [{datasetIndex: items[0].datasetIndex}]; // when mode: 'dataset' we only need to return datasetIndex @@ -188,7 +184,7 @@ module.exports = { * @return {Object[]} Array of elements that are under the point. If none are found, an empty array is returned */ point: function(chart, e) { - var position = getRelativePosition(e, chart); + const position = getRelativePosition(e, chart); return getIntersectItems(chart, position); }, @@ -201,9 +197,8 @@ module.exports = { * @return {Object[]} Array of elements that are under the point. If none are found, an empty array is returned */ nearest: function(chart, e, options) { - var position = getRelativePosition(e, chart); - options.axis = options.axis || 'xy'; - var distanceMetric = getDistanceMetricForAxis(options.axis); + const position = getRelativePosition(e, chart); + const distanceMetric = getDistanceMetricForAxis(options.axis || 'xy'); return getNearestItems(chart, position, options.intersect, distanceMetric); }, @@ -216,9 +211,9 @@ module.exports = { * @return {Object[]} Array of elements that are under the point. If none are found, an empty array is returned */ x: function(chart, e, options) { - var position = getRelativePosition(e, chart); - var items = []; - var intersectsItem = false; + const position = getRelativePosition(e, chart); + const items = []; + let intersectsItem = false; parseVisibleItems(chart, function(element, datasetIndex, index) { if (element.inXRange(position.x)) { @@ -233,7 +228,7 @@ module.exports = { // If we want to trigger on an intersect and we don't have any items // that intersect the position, return nothing if (options.intersect && !intersectsItem) { - items = []; + return []; } return items; }, @@ -247,9 +242,9 @@ module.exports = { * @return {Object[]} Array of elements that are under the point. If none are found, an empty array is returned */ y: function(chart, e, options) { - var position = getRelativePosition(e, chart); - var items = []; - var intersectsItem = false; + const position = getRelativePosition(e, chart); + const items = []; + let intersectsItem = false; parseVisibleItems(chart, function(element, datasetIndex, index) { if (element.inYRange(position.y)) { @@ -264,7 +259,7 @@ module.exports = { // If we want to trigger on an intersect and we don't have any items // that intersect the position, return nothing if (options.intersect && !intersectsItem) { - items = []; + return []; } return items; } diff --git a/src/core/core.tooltip.js b/src/core/core.tooltip.js index c23a4073a..73122f8df 100644 --- a/src/core/core.tooltip.js +++ b/src/core/core.tooltip.js @@ -205,16 +205,14 @@ function splitNewlines(str) { * @return new tooltip item */ function createTooltipItem(chart, item) { - const {datasetIndex, element, index} = item; + const {datasetIndex, index} = item; const {label, value} = chart.getDatasetMeta(datasetIndex).controller._getLabelAndValue(index); return { label: label, value: value, index: index, - datasetIndex: datasetIndex, - x: element._model.x, - y: element._model.y + datasetIndex: datasetIndex }; } diff --git a/test/specs/core.tooltip.tests.js b/test/specs/core.tooltip.tests.js index 5b4a6142b..f0ad7441e 100755 --- a/test/specs/core.tooltip.tests.js +++ b/test/specs/core.tooltip.tests.js @@ -913,8 +913,6 @@ describe('Core.Tooltip', function() { expect(tooltipItem.label).toBe(chart.data.labels[pointIndex]); expect(typeof tooltipItem.value).toBe('string'); expect(tooltipItem.value).toBe('' + chart.data.datasets[datasetIndex].data[pointIndex]); - expect(tooltipItem.x).toBeCloseToPixel(point._model.x); - expect(tooltipItem.y).toBeCloseToPixel(point._model.y); }); }); -- 2.47.2