Skip to content

Commit

Permalink
Define default init animation logic to each annotation element (#863)
Browse files Browse the repository at this point in the history
* Move default init animation logic to each annotation element

* move defaults in an inner object of helpers

* remove element passed argument

* fixes JS doc

* CC duplications

* Returned value could be AnnotationElement to animate options
  • Loading branch information
stockiNail committed May 9, 2023
1 parent f447a34 commit 84545be
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 21 deletions.
2 changes: 1 addition & 1 deletion docs/guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ The `init` option is scriptable but it doesn't get the [options context](./optio
This is the signature of the scriptable option:

```javascript
({chart, properties, options}) => void | boolean | AnnotationBoxModel
({chart, properties, options}) => void | boolean | AnnotationElement
```

where the properties is the element model
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/helpers.chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,9 @@ export function resolveLineProperties(chart, options) {
* @param {boolean} [centerBased=false]
* @returns {AnnotationBoxModel}
*/
export function resolveBoxAndLabelProperties(chart, options, centerBased) {
export function resolveBoxAndLabelProperties(chart, options) {
const properties = resolveBoxProperties(chart, options);
properties.initProperties = initAnimationProperties(chart, properties, options, centerBased);
properties.initProperties = initAnimationProperties(chart, properties, options);
properties.elements = [{
type: 'label',
optionScope: 'label',
Expand Down
35 changes: 22 additions & 13 deletions src/helpers/helpers.options.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import {isObject, isFunction, valueOrDefault, defined, callback} from 'chart.js/helpers';
import {isObject, isFunction, valueOrDefault, defined, callback as invoke} from 'chart.js/helpers';
import {clamp} from './helpers.core';

const isPercentString = (s) => typeof s === 'string' && s.endsWith('%');
const toPercent = (s) => parseFloat(s) / 100;
const toPositivePercent = (s) => clamp(toPercent(s), 0, 1);

const boxAppering = (x, y) => ({x, y, x2: x, y2: y, width: 0, height: 0});
const defaultInitAnimation = {
box: (properties) => boxAppering(properties.centerX, properties.centerY),
ellipse: (properties) => ({centerX: properties.centerX, centerY: properties.centerX, radius: 0, width: 0, height: 0}),
label: (properties) => boxAppering(properties.centerX, properties.centerY),
line: (properties) => boxAppering(properties.x, properties.y),
point: (properties) => ({centerX: properties.centerX, centerY: properties.centerY, radius: 0, width: 0, height: 0}),
polygon: (properties) => boxAppering(properties.centerX, properties.centerY)
};

/**
* @typedef { import("chart.js").Chart } Chart
* @typedef { import('../../types/element').AnnotationBoxModel } AnnotationBoxModel
* @typedef { import('../../types/element').AnnotationElement } AnnotationElement
* @typedef { import('../../types/options').AnnotationPointCoordinates } AnnotationPointCoordinates
* @typedef { import('../../types/label').CoreLabelOptions } CoreLabelOptions
* @typedef { import('../../types/label').LabelPositionObject } LabelPositionObject
Expand Down Expand Up @@ -93,17 +104,16 @@ export function isBoundToPoint(options) {
* @param {Chart} chart
* @param {AnnotationBoxModel} properties
* @param {CoreAnnotationOptions} options
* @param {boolean} [centerBased=false]
* @returns {AnnotationBoxModel}
* @returns {AnnotationElement}
*/
export function initAnimationProperties(chart, properties, options, centerBased = false) {
export function initAnimationProperties(chart, properties, options) {
const initAnim = options.init;
if (!initAnim) {
return;
} else if (initAnim === true) {
return applyDefault(properties, centerBased);
return applyDefault(properties, options);
}
return checkCallbackResult(properties, centerBased, callback(initAnim, [{chart, properties, options}]));
return execCallback(chart, properties, options);
}

/**
Expand All @@ -125,16 +135,15 @@ export function loadHooks(options, hooks, hooksContainer) {
return activated;
}

function applyDefault({centerX, centerY}, centerBased) {
if (centerBased) {
return {centerX, centerY, radius: 0, width: 0, height: 0};
}
return {x: centerX, y: centerY, x2: centerX, y2: centerY, width: 0, height: 0};
function applyDefault(properties, options) {
const type = options.type || 'line';
return defaultInitAnimation[type](properties);
}

function checkCallbackResult(properties, centerBased, result) {
function execCallback(chart, properties, options) {
const result = invoke(options.init, [{chart, properties, options}]);
if (result === true) {
return applyDefault(properties, centerBased);
return applyDefault(properties, options);
} else if (isObject(result)) {
return result;
}
Expand Down
2 changes: 1 addition & 1 deletion src/types/ellipse.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default class EllipseAnnotation extends Element {
}

resolveElementProperties(chart, options) {
return resolveBoxAndLabelProperties(chart, options, true);
return resolveBoxAndLabelProperties(chart, options);
}

}
Expand Down
2 changes: 1 addition & 1 deletion src/types/point.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default class PointAnnotation extends Element {

resolveElementProperties(chart, options) {
const properties = resolvePointProperties(chart, options);
properties.initProperties = initAnimationProperties(chart, properties, options, true);
properties.initProperties = initAnimationProperties(chart, properties, options);
return properties;
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/specs/animation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ describe('Initial animation', function() {
box: 'x',
ellipse: 'width',
label: 'x',
line: 'x',
line: 'x2',
point: 'radius',
polygon: 'y'
};
Expand Down
4 changes: 2 additions & 2 deletions types/options.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Chart, Color, PointStyle, BorderRadius, CoreInteractionOptions } from 'chart.js';
import { AnnotationEvents, PartialEventContext, EventContext } from './events';
import { LabelOptions, BoxLabelOptions, LabelTypeOptions } from './label';
import { AnnotationBoxModel } from './element';
import { AnnotationBoxModel, AnnotationElement } from './element';

export type DrawTime = 'afterDraw' | 'afterDatasetsDraw' | 'beforeDraw' | 'beforeDatasetsDraw';

Expand Down Expand Up @@ -42,7 +42,7 @@ export interface CoreAnnotationOptions extends AnnotationEvents, ShadowOptions,
borderWidth?: Scriptable<number, PartialEventContext>,
display?: Scriptable<boolean, PartialEventContext>,
drawTime?: Scriptable<DrawTime, PartialEventContext>,
init?: boolean | ((chart: Chart, properties: AnnotationBoxModel, options: AnnotationOptions) => void | boolean | AnnotationBoxModel),
init?: boolean | ((chart: Chart, properties: AnnotationBoxModel, options: AnnotationOptions) => void | boolean | AnnotationElement),
id?: string,
xMax?: Scriptable<ScaleValue, PartialEventContext>,
xMin?: Scriptable<ScaleValue, PartialEventContext>,
Expand Down

0 comments on commit 84545be

Please sign in to comment.