boolean(from, to, factor) {
return factor > 0.5 ? to : from;
},
+ /**
+ * @param {string} from
+ * @param {string} to
+ * @param {number} factor
+ */
color(from, to, factor) {
const c0 = helpersColor(from || transparent);
const c1 = c0.valid && helpersColor(to || transparent);
this.chart._dataChanges.push([this.index, ...args]);
}
- /**
- * @private
- */
_onDataPush() {
const count = arguments.length;
this._sync(['_insertElements', this.getDataset().data.length - count, count]);
}
- /**
- * @private
- */
_onDataPop() {
this._sync(['_removeElements', this._cachedMeta.data.length - 1, 1]);
}
- /**
- * @private
- */
_onDataShift() {
this._sync(['_removeElements', 0, 1]);
}
- /**
- * @private
- */
_onDataSplice(start, count) {
if (count) {
this._sync(['_removeElements', start, count]);
}
}
- /**
- * @private
- */
_onDataUnshift() {
this._sync(['_insertElements', 0, arguments.length]);
}
import {_readValueToProps} from '../helpers/helpers.options';
/** @typedef {{ x: number, y: number, startAngle: number, endAngle: number, innerRadius: number, outerRadius: number, circumference: number }} ArcProps */
+/** @typedef {import('../../types/geometric').Point} Point */
function clipArc(ctx, element, endAngle) {
const {startAngle, pixelMargin, x, y, outerRadius, innerRadius} = element;
* @param {boolean} [useFinalPosition]
*/
inRange(chartX, chartY, useFinalPosition) {
- const point = this.getProps(['x', 'y'], useFinalPosition);
+ const point = /** @type {Point} */ (this.getProps(['x', 'y'], useFinalPosition));
const {angle, distance} = getAngleFromPoint(point, {x: chartX, y: chartY});
const {startAngle, endAngle, innerRadius, outerRadius, circumference} = /** @type {ArcProps} */ (this.getProps([
'startAngle',
/**
* Binary search
- * @param {array} table - the table search. must be sorted!
- * @param {number} value - value to find
- * @param {function} [cmp]
+ * @param table - the table search. must be sorted!
+ * @param value - value to find
+ * @param cmp
* @private
*/
-export function _lookup(table, value, cmp) {
+export function _lookup(
+ table: number[],
+ value: number,
+ cmp?: (value: number) => boolean
+): {lo: number, hi: number};
+export function _lookup<T>(
+ table: T[],
+ value: number,
+ cmp: (value: number) => boolean
+): {lo: number, hi: number};
+export function _lookup(
+ table: unknown[],
+ value: number,
+ cmp?: (value: number) => boolean
+) {
cmp = cmp || ((index) => table[index] < value);
let hi = table.length - 1;
let lo = 0;
- let mid;
+ let mid: number;
while (hi - lo > 1) {
mid = (lo + hi) >> 1;
/**
* Binary search
- * @param {array} table - the table search. must be sorted!
- * @param {string} key - property name for the value in each entry
- * @param {number} value - value to find
- * @param {boolean} [last] - lookup last index
+ * @param table - the table search. must be sorted!
+ * @param key - property name for the value in each entry
+ * @param value - value to find
+ * @param last - lookup last index
* @private
*/
-export const _lookupByKey = (table, key, value, last) =>
+export const _lookupByKey = (
+ table: Record<string, number>[],
+ key: string,
+ value: number,
+ last?: boolean
+) =>
_lookup(table, value, last
? index => {
const ti = table[index][key];
/**
* Reverse binary search
- * @param {array} table - the table search. must be sorted!
- * @param {string} key - property name for the value in each entry
- * @param {number} value - value to find
+ * @param table - the table search. must be sorted!
+ * @param key - property name for the value in each entry
+ * @param value - value to find
* @private
*/
-export const _rlookupByKey = (table, key, value) =>
+export const _rlookupByKey = (
+ table: Record<string, number>[],
+ key: string,
+ value: number
+) =>
_lookup(table, value, index => table[index][key] >= value);
/**
* Return subset of `values` between `min` and `max` inclusive.
* Values are assumed to be in sorted order.
- * @param {number[]} values - sorted array of values
- * @param {number} min - min value
- * @param {number} max - max value
+ * @param values - sorted array of values
+ * @param min - min value
+ * @param max - max value
*/
-export function _filterBetween(values, min, max) {
+export function _filterBetween(values: number[], min: number, max: number) {
let start = 0;
let end = values.length;
: values;
}
-const arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
+const arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'] as const;
+
+export interface ArrayListener<T> {
+ _onDataPush?(...item: T[]): void;
+ _onDataPop?(): void;
+ _onDataShift?(): void;
+ _onDataSplice?(index: number, deleteCount: number, ...items: T[]): void;
+ _onDataUnshift?(...item: T[]): void;
+}
/**
* Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',
* 'unshift') and notify the listener AFTER the array has been altered. Listeners are
* called on the '_onData*' callbacks (e.g. _onDataPush, etc.) with same arguments.
*/
+export function listenArrayEvents<T>(array: T[], listener: ArrayListener<T>): void;
export function listenArrayEvents(array, listener) {
if (array._chartjs) {
array._chartjs.listeners.push(listener);
* Removes the given array event listener and cleanup extra attached properties (such as
* the _chartjs stub and overridden methods) if array doesn't have any more listeners.
*/
+export function unlistenArrayEvents<T>(array: T[], listener: ArrayListener<T>): void;
export function unlistenArrayEvents(array, listener) {
const stub = array._chartjs;
if (!stub) {
}
/**
- * @param {Array} items
+ * @param items
*/
-export function _arrayUnique(items) {
- const set = new Set();
- let i, ilen;
+export function _arrayUnique<T>(items: T[]) {
+ const set = new Set<T>();
+ let i: number, ilen: number;
for (i = 0, ilen = items.length; i < ilen; ++i) {
set.add(items[i]);
+++ /dev/null
-import colorLib from '@kurkle/color';
-
-export function isPatternOrGradient(value) {
- if (value && typeof value === 'object') {
- const type = value.toString();
- return type === '[object CanvasPattern]' || type === '[object CanvasGradient]';
- }
-
- return false;
-}
-
-export function color(value) {
- return isPatternOrGradient(value) ? value : colorLib(value);
-}
-
-export function getHoverColor(value) {
- return isPatternOrGradient(value)
- ? value
- : colorLib(value).saturate(0.5).darken(0.1).hexString();
-}
--- /dev/null
+import colorLib, {Color} from '@kurkle/color';
+
+export function isPatternOrGradient(value: unknown): value is CanvasPattern | CanvasGradient {
+ if (value && typeof value === 'object') {
+ const type = value.toString();
+ return type === '[object CanvasPattern]' || type === '[object CanvasGradient]';
+ }
+
+ return false;
+}
+
+export function color(value: CanvasGradient): CanvasGradient;
+export function color(value: CanvasPattern): CanvasPattern;
+export function color(
+ value:
+ | string
+ | { r: number; g: number; b: number; a: number }
+ | [number, number, number]
+ | [number, number, number, number]
+): Color;
+export function color(value) {
+ return isPatternOrGradient(value) ? value : colorLib(value);
+}
+
+export function getHoverColor(value: CanvasGradient): CanvasGradient;
+export function getHoverColor(value: CanvasPattern): CanvasPattern;
+export function getHoverColor(value: string): string;
+export function getHoverColor(value) {
+ return isPatternOrGradient(value)
+ ? value
+ : colorLib(value).saturate(0.5).darken(0.1).hexString();
+}
+++ /dev/null
-/**
- * @private
- */
-export function _pointInLine(p1, p2, t, mode) { // eslint-disable-line no-unused-vars
- return {
- x: p1.x + t * (p2.x - p1.x),
- y: p1.y + t * (p2.y - p1.y)
- };
-}
-
-/**
- * @private
- */
-export function _steppedInterpolation(p1, p2, t, mode) {
- return {
- x: p1.x + t * (p2.x - p1.x),
- y: mode === 'middle' ? t < 0.5 ? p1.y : p2.y
- : mode === 'after' ? t < 1 ? p1.y : p2.y
- : t > 0 ? p2.y : p1.y
- };
-}
-
-/**
- * @private
- */
-export function _bezierInterpolation(p1, p2, t, mode) { // eslint-disable-line no-unused-vars
- const cp1 = {x: p1.cp2x, y: p1.cp2y};
- const cp2 = {x: p2.cp1x, y: p2.cp1y};
- const a = _pointInLine(p1, cp1, t);
- const b = _pointInLine(cp1, cp2, t);
- const c = _pointInLine(cp2, p2, t);
- const d = _pointInLine(a, b, t);
- const e = _pointInLine(b, c, t);
- return _pointInLine(d, e, t);
-}
--- /dev/null
+import type {Point} from '../../types/geometric';
+import type {MonotoneSplinePoint} from '../../types/helpers';
+
+/**
+ * @private
+ */
+export function _pointInLine(p1: Point, p2: Point, t: number, mode?) { // eslint-disable-line @typescript-eslint/no-unused-vars
+ return {
+ x: p1.x + t * (p2.x - p1.x),
+ y: p1.y + t * (p2.y - p1.y)
+ };
+}
+
+/**
+ * @private
+ */
+export function _steppedInterpolation(
+ p1: Point,
+ p2: Point,
+ t: number, mode: 'middle' | 'after' | unknown
+) {
+ return {
+ x: p1.x + t * (p2.x - p1.x),
+ y: mode === 'middle' ? t < 0.5 ? p1.y : p2.y
+ : mode === 'after' ? t < 1 ? p1.y : p2.y
+ : t > 0 ? p2.y : p1.y
+ };
+}
+
+/**
+ * @private
+ */
+export function _bezierInterpolation(p1: MonotoneSplinePoint, p2: MonotoneSplinePoint, t: number, mode?) { // eslint-disable-line @typescript-eslint/no-unused-vars
+ const cp1 = {x: p1.cp2x, y: p1.cp2y};
+ const cp2 = {x: p2.cp1x, y: p2.cp1y};
+ const a = _pointInLine(p1, cp1, t);
+ const b = _pointInLine(cp1, cp2, t);
+ const c = _pointInLine(cp2, p2, t);
+ const d = _pointInLine(a, b, t);
+ const e = _pointInLine(b, c, t);
+ return _pointInLine(d, e, t);
+}
-const intlCache = new Map();
+const intlCache = new Map<string, Intl.NumberFormat>();
-function getNumberFormat(locale, options) {
+function getNumberFormat(locale: string, options?: Intl.NumberFormatOptions) {
options = options || {};
const cacheKey = locale + JSON.stringify(options);
let formatter = intlCache.get(cacheKey);
return formatter;
}
-export function formatNumber(num, locale, options) {
+export function formatNumber(num: number, locale: string, options?: Intl.NumberFormatOptions) {
return getNumberFormat(locale, options).format(num);
}
+import type {Point} from '../../types/geometric';
import {isFinite as isFiniteNumber} from './helpers.core';
/**
export const log10 = Math.log10;
export const sign = Math.sign;
+export function almostEquals(x: number, y: number, epsilon: number) {
+ return Math.abs(x - y) < epsilon;
+}
+
/**
* Implementation of the nice number algorithm used in determining where axis labels will go
- * @return {number}
*/
-export function niceNum(range) {
+export function niceNum(range: number) {
const roundedRange = Math.round(range);
range = almostEquals(range, roundedRange, range / 1000) ? roundedRange : range;
const niceRange = Math.pow(10, Math.floor(log10(range)));
* Returns an array of factors sorted from 1 to sqrt(value)
* @private
*/
-export function _factorize(value) {
- const result = [];
+export function _factorize(value: number) {
+ const result: number[] = [];
const sqrt = Math.sqrt(value);
- let i;
+ let i: number;
for (i = 1; i < sqrt; i++) {
if (value % i === 0) {
return result;
}
-export function isNumber(n) {
- return !isNaN(parseFloat(n)) && isFinite(n);
-}
-
-export function almostEquals(x, y, epsilon) {
- return Math.abs(x - y) < epsilon;
+export function isNumber(n: unknown): n is number {
+ return !isNaN(parseFloat(n as string)) && isFinite(n as number);
}
-export function almostWhole(x, epsilon) {
+export function almostWhole(x: number, epsilon: number) {
const rounded = Math.round(x);
return ((rounded - epsilon) <= x) && ((rounded + epsilon) >= x);
}
/**
* @private
*/
-export function _setMinAndMaxByKey(array, target, property) {
- let i, ilen, value;
+export function _setMinAndMaxByKey(
+ array: Record<string, number>[],
+ target: { min: number, max: number },
+ property: string
+) {
+ let i: number, ilen: number, value: number;
for (i = 0, ilen = array.length; i < ilen; i++) {
value = array[i][property];
}
}
-export function toRadians(degrees) {
+export function toRadians(degrees: number) {
return degrees * (PI / 180);
}
-export function toDegrees(radians) {
+export function toDegrees(radians: number) {
return radians * (180 / PI);
}
/**
* Returns the number of decimal places
* i.e. the number of digits after the decimal point, of the value of this Number.
- * @param {number} x - A number.
- * @returns {number} The number of decimal places.
+ * @param x - A number.
+ * @returns The number of decimal places.
* @private
*/
-export function _decimalPlaces(x) {
+export function _decimalPlaces(x: number) {
if (!isFiniteNumber(x)) {
return;
}
}
// Gets the angle from vertical upright to the point about a centre.
-export function getAngleFromPoint(centrePoint, anglePoint) {
+export function getAngleFromPoint(
+ centrePoint: Point,
+ anglePoint: Point
+) {
const distanceFromXCenter = anglePoint.x - centrePoint.x;
const distanceFromYCenter = anglePoint.y - centrePoint.y;
const radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
};
}
-export function distanceBetweenPoints(pt1, pt2) {
+export function distanceBetweenPoints(pt1: Point, pt2: Point) {
return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
}
* Shortest distance between angles, in either direction.
* @private
*/
-export function _angleDiff(a, b) {
+export function _angleDiff(a: number, b: number) {
return (a - b + PITAU) % TAU - PI;
}
* Normalize angle to be between 0 and 2*PI
* @private
*/
-export function _normalizeAngle(a) {
+export function _normalizeAngle(a: number) {
return (a % TAU + TAU) % TAU;
}
/**
* @private
*/
-export function _angleBetween(angle, start, end, sameAngleIsFullCircle) {
+export function _angleBetween(angle: number, start: number, end: number, sameAngleIsFullCircle?: boolean) {
const a = _normalizeAngle(angle);
const s = _normalizeAngle(start);
const e = _normalizeAngle(end);
/**
* Limit `value` between `min` and `max`
- * @param {number} value
- * @param {number} min
- * @param {number} max
+ * @param value
+ * @param min
+ * @param max
* @private
*/
-export function _limitValue(value, min, max) {
+export function _limitValue(value: number, min: number, max: number) {
return Math.max(min, Math.min(max, value));
}
* @param {number} value
* @private
*/
-export function _int16Range(value) {
+export function _int16Range(value: number) {
return _limitValue(value, -32768, 32767);
}
/**
- * @param {number} value
- * @param {number} start
- * @param {number} end
- * @param {number} [epsilon]
+ * @param value
+ * @param start
+ * @param end
+ * @param [epsilon]
* @private
*/
-export function _isBetween(value, start, end, epsilon = 1e-6) {
+export function _isBetween(value: number, start: number, end: number, epsilon = 1e-6) {
return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon;
}
-const getRightToLeftAdapter = function(rectX, width) {
+export interface RTLAdapter {
+ x(x: number): number;
+ setWidth(w: number): void;
+ textAlign(align: 'center' | 'left' | 'right'): 'center' | 'left' | 'right';
+ xPlus(x: number, value: number): number;
+ leftForLtr(x: number, itemWidth: number): number;
+}
+
+const getRightToLeftAdapter = function(rectX: number, width: number): RTLAdapter {
return {
x(x) {
return rectX + rectX + width - x;
};
};
-const getLeftToRightAdapter = function() {
+const getLeftToRightAdapter = function(): RTLAdapter {
return {
x(x) {
return x;
xPlus(x, value) {
return x + value;
},
- leftForLtr(x, _itemWidth) { // eslint-disable-line no-unused-vars
+ leftForLtr(x, _itemWidth) { // eslint-disable-line @typescript-eslint/no-unused-vars
return x;
},
};
};
-export function getRtlAdapter(rtl, rectX, width) {
+export function getRtlAdapter(rtl: boolean, rectX: number, width: number) {
return rtl ? getRightToLeftAdapter(rectX, width) : getLeftToRightAdapter();
}
-export function overrideTextDirection(ctx, direction) {
- let style, original;
+export function overrideTextDirection(ctx: CanvasRenderingContext2D, direction: 'ltr' | 'rtl') {
+ let style: CSSStyleDeclaration, original: [string, string];
if (direction === 'ltr' || direction === 'rtl') {
style = ctx.canvas.style;
original = [
];
style.setProperty('direction', direction, 'important');
- ctx.prevTextDirection = original;
+ (ctx as { prevTextDirection?: [string, string] }).prevTextDirection = original;
}
}
-export function restoreTextDirection(ctx, original) {
+export function restoreTextDirection(ctx: CanvasRenderingContext2D, original?: [string, string]) {
if (original !== undefined) {
- delete ctx.prevTextDirection;
+ delete (ctx as { prevTextDirection?: [string, string] }).prevTextDirection;
ctx.canvas.style.setProperty('direction', original[0], original[1]);
}
}
*/
// export * from '.';
+export * from './helpers.color';
+export * from './helpers.collection';
export * from './helpers.core';
export * from './helpers.easing';
+export * from './helpers.interpolation';
+export * from './helpers.intl';
+export * from './helpers.math';
+export * from './helpers.rtl';
export * from '../../types/helpers';
+++ /dev/null
-export interface ArrayListener<T> {
- _onDataPush?(...item: T[]): void;
- _onDataPop?(): void;
- _onDataShift?(): void;
- _onDataSplice?(index: number, deleteCount: number, ...items: T[]): void;
- _onDataUnshift?(...item: T[]): void;
-}
-
-/**
- * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',
- * 'unshift') and notify the listener AFTER the array has been altered. Listeners are
- * called on the '_onData*' callbacks (e.g. _onDataPush, etc.) with same arguments.
- */
-export function listenArrayEvents<T>(array: T[], listener: ArrayListener<T>): void;
-
-/**
- * Removes the given array event listener and cleanup extra attached properties (such as
- * the _chartjs stub and overridden methods) if array doesn't have any more listeners.
- */
-export function unlistenArrayEvents<T>(array: T[], listener: ArrayListener<T>): void;
+++ /dev/null
-import { AnyObject } from '../basic';
-
-export function color(value: CanvasGradient): CanvasGradient;
-export function color(value: CanvasPattern): CanvasPattern;
-export function color(
- value:
- | string
- | { r: number; g: number; b: number; a: number }
- | [number, number, number]
- | [number, number, number, number]
-): ColorModel;
-
-export function isPatternOrGradient(value: unknown): value is CanvasPattern | CanvasGradient;
-
-export interface ColorModel {
- rgbString(): string;
- hexString(): string;
- hslString(): string;
- rgb: { r: number; g: number; b: number; a: number };
- valid: boolean;
- mix(color: ColorModel, weight: number): this;
- clone(): ColorModel;
- alpha(a: number): ColorModel;
- clearer(ration: number): ColorModel;
- greyscale(): ColorModel;
- opaquer(ratio: number): ColorModel;
- negate(): ColorModel;
- lighten(ratio: number): ColorModel;
- darken(ratio: number): ColorModel;
- saturate(ratio: number): ColorModel;
- desaturate(ratio: number): ColorModel;
- rotate(deg: number): this;
-}
-
-export function getHoverColor(value: CanvasGradient): CanvasGradient;
-export function getHoverColor(value: CanvasPattern): CanvasPattern;
-export function getHoverColor(value: string): string;
+++ /dev/null
-export {};
+++ /dev/null
-/**
- * Format a number using a localized number formatter.
- * @param num The number to format
- * @param locale The locale to pass to the Intl.NumberFormat constructor
- * @param options Number format options
- */
-export function formatNumber(num: number, locale: string, options: Intl.NumberFormatOptions): string;
+++ /dev/null
-export function log10(x: number): number;
-export function isNumber(v: unknown): v is Number;
-export function almostEquals(x: number, y: number, epsilon: number): boolean;
-export function almostWhole(x: number, epsilon: number): number;
-export function sign(x: number): number;
-export function niceNum(range: number): number;
-export function toRadians(degrees: number): number;
-export function toDegrees(radians: number): number;
-/**
- * Gets the angle from vertical upright to the point about a centre.
- */
-export function getAngleFromPoint(
- centrePoint: { x: number; y: number },
- anglePoint: { x: number; y: number }
-): { angle: number; distance: number };
-
-export function distanceBetweenPoints(pt1: { x: number; y: number }, pt2: { x: number; y: number }): number;
+++ /dev/null
-export interface RTLAdapter {
- x(x: number): number;
- setWidth(w: number): void;
- textAlign(align: 'center' | 'left' | 'right'): 'center' | 'left' | 'right';
- xPlus(x: number, value: number): number;
- leftForLtr(x: number, itemWidth: number): number;
-}
-export function getRtlAdapter(rtl: boolean, rectX: number, width: number): RTLAdapter;
-
-export function overrideTextDirection(ctx: CanvasRenderingContext2D, direction: 'ltr' | 'rtl'): void;
-
-export function restoreTextDirection(ctx: CanvasRenderingContext2D, original?: [string, string]): void;
export * from './helpers.canvas';
-export * from './helpers.collection';
-export * from './helpers.color';
export * from './helpers.curve';
export * from './helpers.dom';
export * from './helpers.extras';
-export * from './helpers.interpolation';
-export * from './helpers.intl';
-export * from './helpers.math';
export * from './helpers.options';
export * from './helpers.canvas';
-export * from './helpers.rtl';
export * from './helpers.segment';