]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
X and Y interaction modes now use the intersect option
authoretimberg <evert.timberg@gmail.com>
Fri, 4 Nov 2016 22:40:53 +0000 (18:40 -0400)
committerEvert Timberg <evert.timberg+github@gmail.com>
Sat, 5 Nov 2016 12:19:07 +0000 (08:19 -0400)
samples/tooltips/interaction-modes.html
src/core/core.interaction.js
test/core.interaction.tests.js

index f3dec217ff750ae9ebc9b92b89fa733f1ee9e6e9..17cacf42a0055f542a8efef2851ea84297bc4e3f 100644 (file)
                        }, {
                                mode: 'nearest',
                                intersect: false,
+                       }, {
+                               mode: 'x',
+                               intersect: true
                        }, {
                                mode: 'x',
                                intersect: false
+                       }, {
+                               mode: 'y',
+                               intersect: true
                        }, {
                                mode: 'y',
                                intersect: false
index 2d7b99597f20408a1dd69141281beeca59b778c7..aacdda19c3845fc8fe36f3f1a52ccb26e48ab08f 100644 (file)
@@ -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;
                        }
                }
index 15189a4771d827a75f431cafcc8f8c7e094fb189..7d8e339caf97d5dc8051fe47ce49e8ed232b78f2 100644 (file)
@@ -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]]);
+               });
+       });
 });