From: etimberg Date: Fri, 4 Nov 2016 22:40:53 +0000 (-0400) Subject: X and Y interaction modes now use the intersect option X-Git-Tag: v2.4.0~1^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=74d4dbc608fc1c4e27b81d97a0f9cc8af82decab;p=thirdparty%2FChart.js.git X and Y interaction modes now use the intersect option --- diff --git a/samples/tooltips/interaction-modes.html b/samples/tooltips/interaction-modes.html index f3dec217f..17cacf42a 100644 --- a/samples/tooltips/interaction-modes.html +++ b/samples/tooltips/interaction-modes.html @@ -94,9 +94,15 @@ }, { mode: 'nearest', intersect: false, + }, { + mode: 'x', + intersect: true }, { mode: 'x', intersect: false + }, { + mode: 'y', + intersect: true }, { mode: 'y', intersect: false diff --git a/src/core/core.interaction.js b/src/core/core.interaction.js index 2d7b99597..aacdda19c 100644 --- a/src/core/core.interaction.js +++ b/src/core/core.interaction.js @@ -237,14 +237,26 @@ module.exports = function(Chart) { * @param options {IInteractionOptions} options to use * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned */ - x: function(chart, e) { + x: function(chart, e, options) { var position = helpers.getRelativePosition(e, chart.chart); var items = []; + var intersectsItem = false; + parseVisibleItems(chart, function(element) { if (element.inXRange(position.x)) { items.push(element); } + + if (element.inRange(position.x, position.y)) { + intersectsItem = true; + } }); + + // 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 items; }, @@ -256,14 +268,26 @@ module.exports = function(Chart) { * @param options {IInteractionOptions} options to use * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned */ - y: function(chart, e) { + y: function(chart, e, options) { var position = helpers.getRelativePosition(e, chart.chart); var items = []; + var intersectsItem = false; + parseVisibleItems(chart, function(element) { if (element.inYRange(position.y)) { items.push(element); } + + if (element.inRange(position.x, position.y)) { + intersectsItem = true; + } }); + + // 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 items; } } diff --git a/test/core.interaction.tests.js b/test/core.interaction.tests.js index 15189a477..7d8e339ca 100644 --- a/test/core.interaction.tests.js +++ b/test/core.interaction.tests.js @@ -558,4 +558,240 @@ describe('Core.Interaction', function() { expect(elements).toEqual([meta0.data[1]]); }); }); + + describe('x mode', function() { + it('should return items at the same x value when intersect is false', function() { + var chartInstance = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + label: 'Dataset 1', + data: [10, 40, 30], + pointRadius: [5, 10, 5], + pointHoverBorderColor: 'rgb(255, 0, 0)', + pointHoverBackgroundColor: 'rgb(0, 255, 0)' + }, { + label: 'Dataset 2', + data: [40, 40, 40], + pointRadius: [10, 10, 10], + pointHoverBorderColor: 'rgb(0, 0, 255)', + pointHoverBackgroundColor: 'rgb(0, 255, 255)' + }], + labels: ['Point 1', 'Point 2', 'Point 3'] + } + }); + + // Trigger an event over top of the + var meta0 = chartInstance.getDatasetMeta(0); + var meta1 = chartInstance.getDatasetMeta(1); + + // Halfway between 2 mid points + var pt = { + x: meta0.data[1]._view.x, + y: meta0.data[1]._view.y + }; + + var node = chartInstance.chart.canvas; + var rect = node.getBoundingClientRect(); + var evt = { + view: window, + bubbles: true, + cancelable: true, + clientX: rect.left + pt.x, + clientY: rect.top, + currentTarget: node + }; + + var elements = Chart.Interaction.modes.x(chartInstance, evt, {intersect: false}); + expect(elements).toEqual([meta0.data[1], meta1.data[1]]); + + evt = { + view: window, + bubbles: true, + cancelable: true, + clientX: rect.left + pt.x + 20, // out of range + clientY: rect.top, + currentTarget: node + }; + + elements = Chart.Interaction.modes.x(chartInstance, evt, {intersect: false}); + expect(elements).toEqual([]); + }); + + it('should return items at the same x value when intersect is true', function() { + var chartInstance = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + label: 'Dataset 1', + data: [10, 40, 30], + pointRadius: [5, 10, 5], + pointHoverBorderColor: 'rgb(255, 0, 0)', + pointHoverBackgroundColor: 'rgb(0, 255, 0)' + }, { + label: 'Dataset 2', + data: [40, 40, 40], + pointRadius: [10, 10, 10], + pointHoverBorderColor: 'rgb(0, 0, 255)', + pointHoverBackgroundColor: 'rgb(0, 255, 255)' + }], + labels: ['Point 1', 'Point 2', 'Point 3'] + } + }); + + // Trigger an event over top of the + var meta0 = chartInstance.getDatasetMeta(0); + var meta1 = chartInstance.getDatasetMeta(1); + + // Halfway between 2 mid points + var pt = { + x: meta0.data[1]._view.x, + y: meta0.data[1]._view.y + }; + + var node = chartInstance.chart.canvas; + var rect = node.getBoundingClientRect(); + var evt = { + view: window, + bubbles: true, + cancelable: true, + clientX: rect.left + pt.x, + clientY: rect.top, + currentTarget: node + }; + + var elements = Chart.Interaction.modes.x(chartInstance, evt, {intersect: true}); + expect(elements).toEqual([]); // we don't intersect anything + + evt = { + view: window, + bubbles: true, + cancelable: true, + clientX: rect.left + pt.x, + clientY: rect.top + pt.y, + currentTarget: node + }; + + elements = Chart.Interaction.modes.x(chartInstance, evt, {intersect: true}); + expect(elements).toEqual([meta0.data[1], meta1.data[1]]); + }); + }); + + describe('y mode', function() { + it('should return items at the same y value when intersect is false', function() { + var chartInstance = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + label: 'Dataset 1', + data: [10, 40, 30], + pointRadius: [5, 10, 5], + pointHoverBorderColor: 'rgb(255, 0, 0)', + pointHoverBackgroundColor: 'rgb(0, 255, 0)' + }, { + label: 'Dataset 2', + data: [40, 40, 40], + pointRadius: [10, 10, 10], + pointHoverBorderColor: 'rgb(0, 0, 255)', + pointHoverBackgroundColor: 'rgb(0, 255, 255)' + }], + labels: ['Point 1', 'Point 2', 'Point 3'] + } + }); + + // Trigger an event over top of the + var meta0 = chartInstance.getDatasetMeta(0); + var meta1 = chartInstance.getDatasetMeta(1); + + // Halfway between 2 mid points + var pt = { + x: meta0.data[1]._view.x, + y: meta0.data[1]._view.y + }; + + var node = chartInstance.chart.canvas; + var rect = node.getBoundingClientRect(); + var evt = { + view: window, + bubbles: true, + cancelable: true, + clientX: rect.left, + clientY: rect.top + pt.y, + currentTarget: node + }; + + var elements = Chart.Interaction.modes.y(chartInstance, evt, {intersect: false}); + expect(elements).toEqual([meta0.data[1], meta1.data[0], meta1.data[1], meta1.data[2]]); + + evt = { + view: window, + bubbles: true, + cancelable: true, + clientX: rect.left + pt.x, + clientY: rect.top + pt.y + 20, // out of range + currentTarget: node + }; + + elements = Chart.Interaction.modes.y(chartInstance, evt, {intersect: false}); + expect(elements).toEqual([]); + }); + + it('should return items at the same y value when intersect is true', function() { + var chartInstance = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + label: 'Dataset 1', + data: [10, 40, 30], + pointRadius: [5, 10, 5], + pointHoverBorderColor: 'rgb(255, 0, 0)', + pointHoverBackgroundColor: 'rgb(0, 255, 0)' + }, { + label: 'Dataset 2', + data: [40, 40, 40], + pointRadius: [10, 10, 10], + pointHoverBorderColor: 'rgb(0, 0, 255)', + pointHoverBackgroundColor: 'rgb(0, 255, 255)' + }], + labels: ['Point 1', 'Point 2', 'Point 3'] + } + }); + + // Trigger an event over top of the + var meta0 = chartInstance.getDatasetMeta(0); + var meta1 = chartInstance.getDatasetMeta(1); + + // Halfway between 2 mid points + var pt = { + x: meta0.data[1]._view.x, + y: meta0.data[1]._view.y + }; + + var node = chartInstance.chart.canvas; + var rect = node.getBoundingClientRect(); + var evt = { + view: window, + bubbles: true, + cancelable: true, + clientX: rect.left, + clientY: rect.top + pt.y, + currentTarget: node + }; + + var elements = Chart.Interaction.modes.y(chartInstance, evt, {intersect: true}); + expect(elements).toEqual([]); // we don't intersect anything + + evt = { + view: window, + bubbles: true, + cancelable: true, + clientX: rect.left + pt.x, + clientY: rect.top + pt.y, + currentTarget: node + }; + + elements = Chart.Interaction.modes.y(chartInstance, evt, {intersect: true}); + expect(elements).toEqual([meta0.data[1], meta1.data[0], meta1.data[1], meta1.data[2]]); + }); + }); });