| ---- | ---- | ------- | -----------
| `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)
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
| ---- | ---- | ------- | -----------
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
type: 'line',
data: data,
options: {
- tooltips: {
+ interaction: {
mode: 'point'
}
}
type: 'line',
data: data,
options: {
- tooltips: {
+ interaction: {
mode: 'nearest'
}
}
type: 'line',
data: data,
options: {
- tooltips: {
+ interaction: {
mode: 'index'
}
}
type: 'bar',
data: data,
options: {
- tooltips: {
+ interaction: {
mode: 'index',
axis: 'y'
}
type: 'line',
data: data,
options: {
- tooltips: {
+ interaction: {
mode: 'dataset'
}
}
type: 'line',
data: data,
options: {
- tooltips: {
+ interaction: {
mode: 'x'
}
}
type: 'line',
data: data,
options: {
- tooltips: {
+ interaction: {
mode: 'y'
}
}
#### 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}`
data: lineChartData,
options: {
responsive: true,
- hoverMode: 'index',
+ interaction: {
+ mode: 'index'
+ },
stacked: false,
title: {
display: true,
data: scatterChartData,
options: {
responsive: true,
- hoverMode: 'nearest',
- intersect: true,
+ interaction: {
+ intersect: true,
+ mode: 'nearest'
+ },
title: {
display: true,
text: 'Chart.js Scatter Chart - Multi Axis'
'maxBarThickness',
'minBarLength',
],
- hover: {
+ interaction: {
mode: 'index'
},
+ hover: {},
+
datasets: {
categoryPercentage: 0.8,
barPercentage: 0.9,
showLines: true,
spanGaps: false,
- hover: {
+ interaction: {
mode: 'index'
},
+ hover: {},
+
scales: {
_index_: {
type: 'category',
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;
}
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;
defaults: {
enabled: true,
custom: null,
- mode: 'nearest',
position: 'average',
- intersect: true,
backgroundColor: 'rgba(0,0,0,0.8)',
titleFont: {
style: 'bold',
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'
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() {
expect(options.title.position).toBe('bottom');
defaults.hover.onHover = null;
- defaults.line.hover.mode = 'index';
+ delete defaults.line.hover.mode;
defaults.line.spanGaps = false;
});
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 };