| `position` | `string` | `'top'` | Position of the legend. [more...](#position)
| `align` | `string` | `'center'` | Alignment of the legend. [more...](#align)
| `fullWidth` | `boolean` | `true` | Marks that this box should take the full width of the canvas (pushing down other boxes). This is unlikely to need to be changed in day-to-day use.
-| `onClick` | `function` | | A callback that is called when a click event is registered on a label item.
-| `onHover` | `function` | | A callback that is called when a 'mousemove' event is registered on top of a label item.
-| `onLeave` | `function` | | A callback that is called when a 'mousemove' event is registered outside of a previously hovered label item.
+| `onClick` | `function` | | A callback that is called when a click event is registered on a label item. Arguments: `[event, legendItem, legend]`.
+| `onHover` | `function` | | A callback that is called when a 'mousemove' event is registered on top of a label item. Arguments: `[event, legendItem, legend]`.
+| `onLeave` | `function` | | A callback that is called when a 'mousemove' event is registered outside of a previously hovered label item. Arguments: `[event, legendItem, legend]`.
| `reverse` | `boolean` | `false` | Legend will show datasets in reverse order.
| `labels` | `object` | | See the [Legend Label Configuration](#legend-label-configuration) section below.
| `rtl` | `boolean` | | `true` for rendering the legends from right to left.
The default legend click handler is:
```javascript
-function(e, legendItem) {
- var index = legendItem.datasetIndex;
- var ci = this.chart;
- var meta = ci.getDatasetMeta(index);
-
- // See controller.isDatasetVisible comment
- meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
-
- // We hid a dataset ... rerender the chart
- ci.update();
+function(e, legendItem, legend) {
+ const index = legendItem.datasetIndex;
+ const ci = legend.chart;
+ if (ci.isDatasetVisible(index)) {
+ ci.hide(index);
+ legendItem.hidden = true;
+ } else {
+ ci.show(index);
+ legendItem.hidden = false;
+ }
}
```
```javascript
var defaultLegendClickHandler = Chart.defaults.legend.onClick;
-var newLegendClickHandler = function (e, legendItem) {
+var newLegendClickHandler = function (e, legendItem, legend) {
var index = legendItem.datasetIndex;
if (index > 1) {
// Do the original logic
defaultLegendClickHandler(e, legendItem);
} else {
- let ci = this.chart;
+ let ci = legend.chart;
[
ci.getDatasetMeta(0),
ci.getDatasetMeta(1)
| Name | Type | Default | Description
| ---- | ---- | ------- | -----------
| `events` | `string[]` | `['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove']` | The `events` option defines the browser events that the chart should listen to for tooltips and hovering. [more...](#event-option)
-| `onHover` | `function` | `null` | Called when any of the events fire. Called in the context of the chart and passed the event and an array of active elements (bars, points, etc).
-| `onClick` | `function` | `null` | Called if the event is of type `'mouseup'` or `'click'`. Called in the context of the chart and passed the event and an array of active elements.
+| `onHover` | `function` | `null` | Called when any of the events fire. Passed the event, an array of active elements (bars, points, etc), and the chart.
+| `onClick` | `function` | `null` | Called if the event is of type `'mouseup'` or `'click'`. Passed the event, an array of active elements, and the chart.
## Event Option
For example, to have the chart only respond to click events, you could do:
* `{mode: 'single'}` was replaced with `{mode: 'nearest', intersect: true}`
* `modes['X-axis']` was replaced with `{mode: 'index', intersect: false}`
* `options.onClick` is now limited to the chart area
+* `options.onClick` and `options.onHover` now receive the `chart` instance as a 3rd argument
#### Ticks
* `IPlugin.afterScaleUpdate`. Use `afterLayout` instead
* `Legend.margins` is now private
+* Legend `onClick`, `onHover`, and `onLeave` options now receive the legend as the 3rd argument in addition to implicitly via `this`
+* Legend `onClick`, `onHover`, and `onLeave` options now receive a wrapped `event` as the first parameter. The previous first parameter value is accessible via `event.native`.
* `Title.margins` 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
return labels;
}
},
- onClick: function(mouseEvent, legendItem) {
+ onClick: function(mouseEvent, legendItem, legend) {
// toggle the visibility of the dataset from what it currently is
- this.chart.getDatasetMeta(
+ legend.chart.getDatasetMeta(
legendItem.datasetIndex
- ).hidden = this.chart.isDatasetVisible(legendItem.datasetIndex);
- this.chart.update();
+ ).hidden = legend.chart.isDatasetVisible(legendItem.datasetIndex);
+ legend.chart.update();
}
},
tooltips: {
label: 'New dataset ' + config.data.datasets.length,
};
- for (var index = 0; index < config.data.labels.length; ++index) {
+ for (var index = 0; index < 10; ++index) {
newDataset.data.push(randomScalingFactor());
var colorName = colorNames[index % colorNames.length];
}
},
- onClick(e, legendItem) {
- this.chart.toggleDataVisibility(legendItem.index);
- this.chart.update();
+ onClick(e, legendItem, legend) {
+ legend.chart.toggleDataVisibility(legendItem.index);
+ legend.chart.update();
}
},
}
},
- onClick(e, legendItem) {
- this.chart.toggleDataVisibility(legendItem.index);
- this.chart.update();
+ onClick(e, legendItem, legend) {
+ legend.chart.toggleDataVisibility(legendItem.index);
+ legend.chart.update();
}
},
// Invoke onHover hook
// Need to call with native event here to not break backwards compatibility
- callCallback(options.onHover || options.hover.onHover, [e.native, me.active], me);
+ callCallback(options.onHover || options.hover.onHover, [e.native, me.active, me], me);
if (e.type === 'mouseup' || e.type === 'click') {
- if (options.onClick && _isPointInArea(e, me.chartArea)) {
+ if (_isPointInArea(e, me.chartArea)) {
// Use e.native here for backwards compatibility
- options.onClick.call(me, e.native, me.active);
+ callCallback(options.onClick, [e, me.active, me], me);
}
}
weight: 1000,
// a callback that will handle
- onClick(e, legendItem) {
+ onClick(e, legendItem, legend) {
const index = legendItem.datasetIndex;
- const ci = this.chart;
+ const ci = legend.chart;
if (ci.isDatasetVisible(index)) {
ci.hide(index);
legendItem.hidden = true;
const hoveredItem = me._getLegendItemAt(e.x, e.y);
if (type === 'click') {
- if (hoveredItem && opts.onClick) {
- // use e.native for backwards compatibility
- opts.onClick.call(me, e.native, hoveredItem);
+ if (hoveredItem) {
+ call(opts.onClick, [e, hoveredItem, me], me);
}
} else {
if (opts.onLeave && hoveredItem !== me._hoveredItem) {
if (me._hoveredItem) {
- opts.onLeave.call(me, e.native, me._hoveredItem);
+ call(opts.onLeave, [e, me._hoveredItem, me], me);
}
me._hoveredItem = hoveredItem;
}
- if (opts.onHover && hoveredItem) {
- // use e.native for backwards compatibility
- opts.onHover.call(me, e.native, hoveredItem);
+ if (hoveredItem) {
+ call(opts.onHover, [e, hoveredItem, me], me);
}
}
}
spyOn(chart, 'update').and.callThrough();
var legendItem = chart.legend.legendItems[0];
- config.legend.onClick.call(chart.legend, null, legendItem);
+ config.legend.onClick(null, legendItem, chart.legend);
expect(chart.getDataVisibility(0)).toBe(false);
expect(chart.update).toHaveBeenCalled();
- config.legend.onClick.call(chart.legend, null, legendItem);
+ config.legend.onClick(null, legendItem, chart.legend);
expect(chart.getDataVisibility(0)).toBe(true);
});
});
spyOn(chart, 'update').and.callThrough();
var legendItem = chart.legend.legendItems[0];
- config.legend.onClick.call(chart.legend, null, legendItem);
+ config.legend.onClick(null, legendItem, chart.legend);
expect(chart.getDataVisibility(0)).toBe(false);
expect(chart.update).toHaveBeenCalled();
- config.legend.onClick.call(chart.legend, null, legendItem);
+ config.legend.onClick(null, legendItem, chart.legend);
expect(chart.getDataVisibility(0)).toBe(true);
});
});