Skip to content

Remove dblclick hook to prepare chart redrawing from an event hook #716

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions docs/guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ The following options are available at the top level. They apply to all annotati
| ---- | ---- | :----: | ---- | ----
| [`animations`](#animations) | `object` | No | [see here](#default-animations) | To configure which element properties are animated and how.
| `clip` | `boolean` | No | `true` | Are the annotations clipped to the chartArea.
| `dblClickSpeed` | `number` | Yes | `350` | Time to detect a double click in ms.
| `drawTime` | `string` | Yes | `'afterDatasetsDraw'` | See [drawTime](options#draw-time).
| [`interaction`](options#interaction) | `Object` | No | `options.interaction` | To configure which events trigger plugin interactions

Expand Down Expand Up @@ -65,6 +64,5 @@ The following options are available for all annotation types. These options can
| Name | Type | [Scriptable](options#scriptable-options) | Notes
| ---- | ---- | :----: | ----
| `click` | `(context, event) => void` | No | Called when a single click occurs on the annotation.
| `dblClick` | `(context, event) => void` | No | Called when a double click occurs on the annotation.
| `enter` | `(context, event) => void` | No | Called when the mouse enters the annotation.
| `leave` | `(context, event) => void` | No | Called when the mouse leaves the annotation.
3 changes: 3 additions & 0 deletions docs/guide/migrationV2.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ A number of changes were made to the configuration options passed to the plugin
* `cornerRadius` option was replaced by `borderRadius` in the box annotation configuration and in the label configuration of line annotation to align with Chart.js options.
* `xPadding` and `yPadding` options were merged into a single `padding` object in the label configuration of line annotation to align with Chart.js options.
* `enabled` option was replaced by `display` in the callout configuration of label annotation, in the label configuration of line and box annotations and in the arrow heads configuration of line annotation to have the same option on all elements.
* `dblClickSpeed` option was removed from the plugin options because `dblclick` event hook is not available anymore.

## Events

`chartjs-plugin-annotation` plugin version 2 introduces the [`interaction`](options#interaction) options, to configure which events trigger annotation interactions. By default, the plugin uses the [chart interaction configuration](https://www.chartjs.org/docs/latest/configuration/interactions.html#interactions).

* When [scatter charts](https://www.chartjs.org/docs/latest/charts/scatter.html) are used, the interaction default `mode` in Chart.js is `point`, while, in the previous plugin version, the default was `nearest`.

The `dblclick` event hook was removed from annotations options because, being executed asynchronously, it can not enable the chart re-rendering, automatically after processing the event completely. This is important when the user requires re-draws. It gets slow and messy if every event hook does the draw (or update!).
1 change: 0 additions & 1 deletion src/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ export default {
},
},
clip: true,
dblClickSpeed: 350, // ms
drawTime: 'afterDatasetsDraw',
interaction: {
mode: undefined,
Expand Down
30 changes: 4 additions & 26 deletions src/events.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import {defined, callback} from 'chart.js/helpers';
import {getElements} from './interaction';

const clickHooks = ['click', 'dblclick'];
const moveHooks = ['enter', 'leave'];
export const hooks = clickHooks.concat(moveHooks);
export const hooks = moveHooks.concat('click');

export function updateListeners(chart, state, options) {
state.listened = false;
Expand All @@ -26,12 +25,8 @@ export function updateListeners(chart, state, options) {

if (!state.listened || !state.moveListened) {
state.annotations.forEach(scope => {
if (!state.listened) {
clickHooks.forEach(hook => {
if (typeof scope[hook] === 'function') {
state.listened = true;
}
});
if (!state.listened && typeof scope.click === 'function') {
state.listened = true;
}
if (!state.moveListened) {
moveHooks.forEach(hook => {
Expand Down Expand Up @@ -93,24 +88,7 @@ function handleClickEvents(state, event, options) {
const listeners = state.listeners;
const elements = getElements(state, event, options.interaction);
for (const element of elements) {
const elOpts = element.options;
const dblclick = elOpts.dblclick || listeners.dblclick;
const click = elOpts.click || listeners.click;
if (element.clickTimeout) {
// 2nd click before timeout, so its a double click
clearTimeout(element.clickTimeout);
delete element.clickTimeout;
dispatchEvent(dblclick, element, event);
} else if (dblclick) {
// if there is a dblclick handler, wait for dblClickSpeed ms before deciding its a click
element.clickTimeout = setTimeout(() => {
delete element.clickTimeout;
dispatchEvent(click, element, event);
}, options.dblClickSpeed);
} else {
// no double click handler, just call the click handler directly
dispatchEvent(click, element, event);
}
dispatchEvent(element.options.click || listeners.click, element, event);
}
}

Expand Down
25 changes: 0 additions & 25 deletions test/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,31 +99,6 @@ export function testEvents(options) {
});
window.triggerMouseEvent(chart, 'click', getCenterPoint(chart));
});

it('should detect dbl click event', function(done) {
const dblClickSpy = jasmine.createSpy('dblclick');

targetOptions.dblclick = dblClickSpy;
pluginOpts.dblClickSpeed = 1000;
pluginOpts.annotations = [options];

const chart = window.acquireChart(chartConfig);
const eventPoint = getCenterPoint(chart);

let dblClick = false;
window.afterEvent(chart, 'click', function() {
if (!dblClick) {
dblClick = true;
window.triggerMouseEvent(chart, 'click', eventPoint);
} else {
expect(dblClickSpy.calls.count()).toBe(1);
delete targetOptions.dblclick;
delete pluginOpts.dblClickSpeed;
done();
}
});
window.triggerMouseEvent(chart, 'click', eventPoint);
});
});
});
}
23 changes: 0 additions & 23 deletions test/specs/events.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,28 +93,5 @@ describe('Common', function() {
});
});
});

it('should detect a click event even if 2 clicks are fired', function(done) {
const dblClickSpy = jasmine.createSpy('dblclick');
annotation.dblclick = dblClickSpy;

const chart = window.scatterChart(10, 10, {annotation});
const eventPoint = window.getCenterPoint(chart);

let dblClick = false;
window.afterEvent(chart, 'click', function() {
if (!dblClick) {
dblClick = true;
setTimeout(() => {
window.triggerMouseEvent(chart, 'click', eventPoint);
}, 500);
} else {
expect(dblClickSpy.calls.count()).toBe(0);
delete annotation.dblclick;
done();
}
});
window.triggerMouseEvent(chart, 'click', eventPoint);
});
});
});
1 change: 0 additions & 1 deletion types/events.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@ export interface AnnotationEvents {
enter?(context: EventContext, event: ChartEvent): void,
leave?(context: EventContext, event: ChartEvent): void,
click?(context: EventContext, event: ChartEvent): void,
dblclick?(context: EventContext, event: ChartEvent): void,
}
1 change: 0 additions & 1 deletion types/options.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ export interface AnnotationPluginOptions extends AnnotationEvents {
animations?: Record<string, unknown>,
annotations: AnnotationOptions[] | Record<string, AnnotationOptions>,
clip?: boolean,
dblClickSpeed?: Scriptable<number, PartialEventContext>,
drawTime?: Scriptable<DrawTime, PartialEventContext>,
interaction?: CoreInteractionOptions
}