]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Add interaction options (#7922)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Mon, 19 Oct 2020 11:24:06 +0000 (14:24 +0300)
committerGitHub <noreply@github.com>
Mon, 19 Oct 2020 11:24:06 +0000 (07:24 -0400)
* Add interaction options
* Add migration note

13 files changed:
docs/docs/configuration/tooltip.md
docs/docs/general/interactions/index.md
docs/docs/general/interactions/modes.md
docs/docs/getting-started/v3-migration.md
samples/charts/line/multi-axis.html
samples/charts/scatter/multi-axis.html
src/controllers/controller.bar.js
src/controllers/controller.line.js
src/core/core.controller.js
src/core/core.defaults.js
src/plugins/plugin.tooltip.js
test/specs/core.controller.tests.js
types/core/index.d.ts

index d6287e659c3c602c0e3cd85866cdd38b8d2b839e..56f1bbe6771e79c0e327b0c42d6840047aed21a7 100644 (file)
@@ -10,8 +10,8 @@ The tooltip configuration is passed into the `options.tooltips` namespace. The g
 | ---- | ---- | ------- | -----------
 | `enabled` | `boolean` | `true` | Are on-canvas tooltips enabled?
 | `custom` | `function` | `null` | See [custom tooltip](#external-custom-tooltips) section.
-| `mode` | `string` | `'nearest'` | Sets which elements appear in the tooltip. [more...](../general/interactions/modes.md#interaction-modes).
-| `intersect` | `boolean` | `true` | If true, the tooltip mode applies only when the mouse position intersects with an element. If false, the mode will be applied at all times.
+| `mode` | `string` | | Sets which elements appear in the tooltip. [more...](../general/interactions/modes.md#interaction-modes).
+| `intersect` | `boolean` | | If true, the tooltip mode applies only when the mouse position intersects with an element. If false, the mode will be applied at all times.
 | `position` | `string` | `'average'` | The mode for positioning the tooltip. [more...](#position-modes)
 | `callbacks` | `object` | | See the [callbacks section](#tooltip-callbacks).
 | `itemSort` | `function` | | Sort tooltip items. [more...](#sort-callback)
index ebed6f2a4cf01c238cf998862d18a8a70b41e901..ee23346bb56b3182d1b93c825ee5b1c75fab5ad9 100644 (file)
@@ -2,7 +2,7 @@
 title: Interactions
 ---
 
-The hover configuration is passed into the `options.hover` namespace. The global hover configuration is at `Chart.defaults.hover`. To configure which events trigger chart interactions, see [events](./events.md#events).
+The interaction configuration is passed into the `options.interaction` namespace. The global interaction configuration is at `Chart.defaults.interaction`. To configure which events trigger chart interactions, see [events](./events.md#events).
 
 | Name | Type | Default | Description
 | ---- | ---- | ------- | -----------
index 636dc5001c865707f5ceb8d591a4b155891f4a77..751f5d502048e11de651f05ea17e197c7bf18b93 100644 (file)
@@ -4,6 +4,8 @@ title: Interaction Modes
 
 When configuring interaction with the graph via hover or tooltips, a number of different modes are available.
 
+`options.hover` and `options.tooltips` extend from `options.interaction`. So if `mode`, `intersect` or any other common settings are configured only in `options.interaction`, both hover and tooltips obey that.
+
 The modes are detailed below and how they behave in conjunction with the `intersect` setting.
 
 ## point
@@ -15,7 +17,7 @@ var chart = new Chart(ctx, {
     type: 'line',
     data: data,
     options: {
-        tooltips: {
+        interaction: {
             mode: 'point'
         }
     }
@@ -31,7 +33,7 @@ var chart = new Chart(ctx, {
     type: 'line',
     data: data,
     options: {
-        tooltips: {
+        interaction: {
             mode: 'nearest'
         }
     }
@@ -47,7 +49,7 @@ var chart = new Chart(ctx, {
     type: 'line',
     data: data,
     options: {
-        tooltips: {
+        interaction: {
             mode: 'index'
         }
     }
@@ -61,7 +63,7 @@ var chart = new Chart(ctx, {
     type: 'bar',
     data: data,
     options: {
-        tooltips: {
+        interaction: {
             mode: 'index',
             axis: 'y'
         }
@@ -77,7 +79,7 @@ var chart = new Chart(ctx, {
     type: 'line',
     data: data,
     options: {
-        tooltips: {
+        interaction: {
             mode: 'dataset'
         }
     }
@@ -92,7 +94,7 @@ var chart = new Chart(ctx, {
     type: 'line',
     data: data,
     options: {
-        tooltips: {
+        interaction: {
             mode: 'x'
         }
     }
@@ -107,7 +109,7 @@ var chart = new Chart(ctx, {
     type: 'line',
     data: data,
     options: {
-        tooltips: {
+        interaction: {
             mode: 'y'
         }
     }
index d2cfb6f1926653d9c925604bbcc7a29e19d12758..30105d699f6a274edfc4c93f173e2b0f0907c6df 100644 (file)
@@ -202,6 +202,7 @@ Animation system was completely rewritten in Chart.js v3. Each property can now
 
 #### Interactions
 
+* To allow DRY configuration, a root options scope for common interaction options was added. `options.hover` and `options.tooltips` now both extend from `options.interaction`. Defaults are defined at `defaults.interaction` level, so by default hover and tooltip interactions share the same mode etc.
 * `interactions` are now limited to the chart area
 * `{mode: 'label'}` was replaced with `{mode: 'index'}`
 * `{mode: 'single'}` was replaced with `{mode: 'nearest', intersect: true}`
index 4a457aac48f61ed84606d49f90642d483abbd0bb..be5ebf2fe41eb62946ce7c635e39db7b418dd789 100644 (file)
@@ -62,7 +62,9 @@
                                data: lineChartData,
                                options: {
                                        responsive: true,
-                                       hoverMode: 'index',
+                                       interaction: {
+                                               mode: 'index'
+                                       },
                                        stacked: false,
                                        title: {
                                                display: true,
index 853ab352953b10ac574fc79dbd841ed3a38aded2..feaafda0d53bade415fd6d316a6cf9f17cfbd373 100644 (file)
                        data: scatterChartData,
                        options: {
                                responsive: true,
-                               hoverMode: 'nearest',
-                               intersect: true,
+                               interaction: {
+                                       intersect: true,
+                                       mode: 'nearest'
+                               },
                                title: {
                                        display: true,
                                        text: 'Chart.js Scatter Chart - Multi Axis'
index 173c649cbde4bd79b9477b617dfdec55f95a32d4..cd02a2656b3b6afc805ad39569cf40ea9deba24e 100644 (file)
@@ -528,10 +528,12 @@ BarController.defaults = {
                'maxBarThickness',
                'minBarLength',
        ],
-       hover: {
+       interaction: {
                mode: 'index'
        },
 
+       hover: {},
+
        datasets: {
                categoryPercentage: 0.8,
                barPercentage: 0.9,
index 669b602319f4387d8cbb16895de06dee0bdc761b..f9ae019e703179627f81070ff167a6043ada75dc 100644 (file)
@@ -164,10 +164,12 @@ LineController.defaults = {
        showLines: true,
        spanGaps: false,
 
-       hover: {
+       interaction: {
                mode: 'index'
        },
 
+       hover: {},
+
        scales: {
                _index_: {
                        type: 'category',
index 0621bc8847ead1224d07b961e71fa8a029b07e3d..52c35c03b1c0661b1d6ddb9fb7587ca4cef48ed3 100644 (file)
@@ -116,10 +116,25 @@ function initConfig(config) {
                defaults[config.type],
                config.options || {});
 
+       options.hover = merge(Object.create(null), [
+               defaults.interaction,
+               defaults.hover,
+               options.interaction,
+               options.hover
+       ]);
+
        options.scales = scaleConfig;
 
-       options.title = (options.title !== false) && merge(Object.create(null), [defaults.plugins.title, options.title]);
-       options.tooltips = (options.tooltips !== false) && merge(Object.create(null), [defaults.plugins.tooltip, options.tooltips]);
+       options.title = (options.title !== false) && merge(Object.create(null), [
+               defaults.plugins.title,
+               options.title
+       ]);
+       options.tooltips = (options.tooltips !== false) && merge(Object.create(null), [
+               defaults.interaction,
+               defaults.plugins.tooltip,
+               options.interaction,
+               options.tooltips
+       ]);
 
        return config;
 }
index 6ee9e681e0c9d0fd21cb171256859b4e811ca2ac..be9449d621134e2ab0e37429005707af48f1923f 100644 (file)
@@ -42,12 +42,15 @@ export class Defaults {
                        lineWidth: 0,
                        strokeStyle: undefined
                };
-               this.hover = {
-                       onHover: null,
+               this.interaction = {
                        mode: 'nearest',
                        intersect: true
                };
+               this.hover = {
+                       onHover: null
+               };
                this.maintainAspectRatio = true;
+               this.onHover = null;
                this.onClick = null;
                this.responsive = true;
                this.showLines = true;
index 58e5fd932e43c361b79575b78a7617e2c70dbf02..d9da0d8098ec0ee4dc95a0c96585649cc3bfb288 100644 (file)
@@ -1066,9 +1066,7 @@ export default {
        defaults: {
                enabled: true,
                custom: null,
-               mode: 'nearest',
                position: 'average',
-               intersect: true,
                backgroundColor: 'rgba(0,0,0,0.8)',
                titleFont: {
                        style: 'bold',
index 7467c08306e739e335a3cb87204262f6267e9da0..fe0dd85583101f08fa09d99e8508c57390326086 100644 (file)
@@ -89,13 +89,38 @@ describe('Chart', function() {
                        expect(chart.data.datasets[0].data).toEqual([10, 11, 12]);
                });
 
-               it('should initialize config with default options', function() {
+               it('should initialize config with default interaction options', function() {
                        var callback = function() {};
                        var defaults = Chart.defaults;
+                       var defaultMode = defaults.line.interaction.mode;
 
                        defaults.hover.onHover = callback;
                        defaults.line.spanGaps = true;
-                       defaults.line.hover.mode = 'x-axis';
+                       defaults.line.interaction.mode = 'test';
+
+                       var chart = acquireChart({
+                               type: 'line'
+                       });
+
+                       var options = chart.options;
+                       expect(options.font.size).toBe(defaults.font.size);
+                       expect(options.showLines).toBe(defaults.line.showLines);
+                       expect(options.spanGaps).toBe(true);
+                       expect(options.hover.onHover).toBe(callback);
+                       expect(options.hover.mode).toBe('test');
+
+                       defaults.hover.onHover = null;
+                       defaults.line.spanGaps = false;
+                       defaults.line.interaction.mode = defaultMode;
+               });
+
+               it('should initialize config with default hover options', function() {
+                       var callback = function() {};
+                       var defaults = Chart.defaults;
+
+                       defaults.hover.onHover = callback;
+                       defaults.line.spanGaps = true;
+                       defaults.line.hover.mode = 'test';
 
                        var chart = acquireChart({
                                type: 'line'
@@ -106,11 +131,11 @@ describe('Chart', function() {
                        expect(options.showLines).toBe(defaults.line.showLines);
                        expect(options.spanGaps).toBe(true);
                        expect(options.hover.onHover).toBe(callback);
-                       expect(options.hover.mode).toBe('x-axis');
+                       expect(options.hover.mode).toBe('test');
 
                        defaults.hover.onHover = null;
                        defaults.line.spanGaps = false;
-                       defaults.line.hover.mode = 'index';
+                       delete defaults.line.hover.mode;
                });
 
                it('should override default options', function() {
@@ -141,7 +166,7 @@ describe('Chart', function() {
                        expect(options.title.position).toBe('bottom');
 
                        defaults.hover.onHover = null;
-                       defaults.line.hover.mode = 'index';
+                       delete defaults.line.hover.mode;
                        defaults.line.spanGaps = false;
                });
 
index 730ae8d4a52c841ab44cf737f84a79203ccf501b..05104d4785cd73cfe36e3a08810a7a609f593bbb 100644 (file)
@@ -417,13 +417,18 @@ export interface Defaults {
   readonly color: string;
   readonly events: ('mousemove' | 'mouseout' | 'click' | 'touchstart' | 'touchmove')[];
   readonly font: IFontSpec;
-  readonly hover: {
-    onHover?: () => void;
+  readonly interaction: {
     mode: InteractionMode | string;
     intersect: boolean;
   };
+  readonly hover: {
+    onHover?: () => void;
+    mode?: InteractionMode | string;
+    intersect?: boolean;
+  };
   readonly maintainAspectRatio: boolean;
   readonly onClick?: () => void;
+  readonly onHover?: () => void;
   readonly responsive: boolean;
 
   readonly plugins: { [key: string]: any };