* }
*/
-import { DeepPartial, DistributiveArray } from './utils';
+import { DeepPartial, DistributiveArray, UnionToIntersection } from './utils';
import { TimeUnit } from './adapters';
import { AnimationEvent } from './animation';
export { ChartArea, Point } from './geometric';
export { LayoutItem, LayoutPosition } from './layout';
-export interface ScriptableContext<TParsedData extends unknown> {
+export interface ScriptableContext<TType extends ChartType> {
active: boolean;
- chart: Chart;
+ chart: UnionToIntersection<Chart<TType>>;
dataIndex: number;
- dataset: ChartDataset;
+ dataset: UnionToIntersection<ChartDataset<TType>>;
datasetIndex: number;
- parsed: TParsedData;
+ parsed: UnionToIntersection<ParsedDataType<TType>>;
raw: unknown;
}
-export type Scriptable<T, TType> = T | (TType extends ChartType ? { [TT in TType]: ((ctx: ScriptableContext<ParsedDataType<TT>>) => T) }[TType] : ((ctx: TType) => T));
-export type ScriptableOptions<T, TType extends ChartType> = { [P in keyof T]: Scriptable<T[P], TType> };
-export type ScriptableAndArray<T, TType extends ChartType> = readonly T[] | Scriptable<T, TType>;
-export type ScriptableAndArrayOptions<T, TType extends ChartType> = { [P in keyof T]: ScriptableAndArray<T[P], TType> };
+export type Scriptable<T, TContext> = T | ((ctx: TContext) => T);
+export type ScriptableOptions<T, TContext> = { [P in keyof T]: Scriptable<T[P], TContext> };
+export type ScriptableAndArray<T, TContext> = readonly T[] | Scriptable<T, TContext>;
+export type ScriptableAndArrayOptions<T, TContext> = { [P in keyof T]: ScriptableAndArray<T[P], TContext> };
export interface ParsingOptions {
/**
export interface BarControllerDatasetOptions
extends ControllerDatasetOptions,
- ScriptableAndArrayOptions<BarOptions, 'bar'>,
- ScriptableAndArrayOptions<CommonHoverOptions, 'bar'> {
+ ScriptableAndArrayOptions<BarOptions, ScriptableContext<'bar'>>,
+ ScriptableAndArrayOptions<CommonHoverOptions, ScriptableContext<'bar'>> {
/**
* The ID of the x axis to plot this dataset on.
*/
export interface BubbleControllerDatasetOptions
extends ControllerDatasetOptions,
- ScriptableAndArrayOptions<PointOptions, 'bubble'>,
- ScriptableAndArrayOptions<PointHoverOptions, 'bubble'> {}
+ ScriptableAndArrayOptions<PointOptions, ScriptableContext<'bubble'>>,
+ ScriptableAndArrayOptions<PointHoverOptions, ScriptableContext<'bubble'>> {}
export interface BubbleDataPoint {
/**
export interface LineControllerDatasetOptions
extends ControllerDatasetOptions,
- ScriptableAndArrayOptions<PointPrefixedOptions, 'line'>,
- ScriptableAndArrayOptions<PointPrefixedHoverOptions, 'line'>,
- ScriptableOptions<LineOptions, 'line'>,
- ScriptableOptions<LineHoverOptions, 'line'> {
+ ScriptableAndArrayOptions<PointPrefixedOptions, ScriptableContext<'line'>>,
+ ScriptableAndArrayOptions<PointPrefixedHoverOptions, ScriptableContext<'line'>>,
+ ScriptableOptions<LineOptions, ScriptableContext<'line'>>,
+ ScriptableOptions<LineHoverOptions, ScriptableContext<'line'>> {
/**
* The ID of the x axis to plot this dataset on.
*/
export interface DoughnutControllerDatasetOptions
extends ControllerDatasetOptions,
- ScriptableAndArrayOptions<ArcOptions, 'doughnut'>,
- ScriptableAndArrayOptions<ArcHoverOptions, 'doughnut'> {
+ ScriptableAndArrayOptions<ArcOptions, ScriptableContext<'doughnut'>>,
+ ScriptableAndArrayOptions<ArcHoverOptions, ScriptableContext<'doughnut'>> {
/**
* Sweep to allow arcs to cover.
* String ending with '%' means percentage, number means pixels.
* @default 50
*/
- cutout: Scriptable<number | string, 'doughnut'>;
+ cutout: Scriptable<number | string, ScriptableContext<'doughnut'>>;
/**
* The outer radius of the chart. String ending with '%' means percentage of maximum radius, number means pixels.
* @default '100%'
*/
- radius: Scriptable<number | string, 'doughnut'>;
+ radius: Scriptable<number | string, ScriptableContext<'doughnut'>>;
/**
* Starting angle to draw arcs from.
export interface RadarControllerDatasetOptions
extends ControllerDatasetOptions,
- ScriptableOptions<PointPrefixedOptions, 'radar'>,
- ScriptableOptions<PointPrefixedHoverOptions, 'radar'>,
- ScriptableOptions<LineOptions, 'radar'>,
- ScriptableOptions<LineHoverOptions, 'radar'> {
+ ScriptableOptions<PointPrefixedOptions, ScriptableContext<'radar'>>,
+ ScriptableOptions<PointPrefixedHoverOptions, ScriptableContext<'radar'>>,
+ ScriptableOptions<LineOptions, ScriptableContext<'radar'>>,
+ ScriptableOptions<LineHoverOptions, ScriptableContext<'radar'>> {
/**
* The ID of the x axis to plot this dataset on.
*/
onClick(event: ChartEvent, elements: ActiveElement[], chart: Chart): void;
layout: {
- padding: Scriptable<number | ChartArea, TType>;
+ padding: Scriptable<number | ChartArea, ScriptableContext<TType>>;
};
}
* The number of milliseconds an animation takes.
* @default 1000
*/
- duration: Scriptable<number, TType>;
+ duration: Scriptable<number, ScriptableContext<TType>>;
/**
* Easing function to use
* @default 'easeOutQuart'
*/
- easing: Scriptable<EasingFunction, TType>;
+ easing: Scriptable<EasingFunction, ScriptableContext<TType>>;
/**
* Running animation count + FPS display in upper left corner of the chart.
* @default false
*/
- debug: Scriptable<boolean, TType>;
+ debug: Scriptable<boolean, ScriptableContext<TType>>;
/**
* Delay before starting the animations.
* @default 0
*/
- delay: Scriptable<number, TType>;
+ delay: Scriptable<number, ScriptableContext<TType>>;
/**
* If set to true, the animations loop endlessly.
* @default false
*/
- loop: Scriptable<boolean, TType>;
+ loop: Scriptable<boolean, ScriptableContext<TType>>;
}
export type AnimationsSpec<TType extends ChartType> = {
/**
* Start value for the animation. Current value is used when undefined
*/
- from: Scriptable<Color | number | boolean, TType>;
+ from: Scriptable<Color | number | boolean, ScriptableContext<TType>>;
/**
*
*/
- to: Scriptable<Color | number | boolean, TType>;
+ to: Scriptable<Color | number | boolean, ScriptableContext<TType>>;
}
}
-import { Scriptable } from '../index.esm';
+import { ChartType, Scriptable, ScriptableContext } from '../index.esm';
interface test {
- pie?: Scriptable<number, 'pie'>,
- line?: Scriptable<number, 'line'>,
- testA?: Scriptable<number, 'pie' | 'line' | 'bar'>
- testB?: Scriptable<number, 'pie' | 'line' | 'bar'>
- testC?: Scriptable<number, 'pie' | 'line' | 'bar'>
+ pie?: Scriptable<number, ScriptableContext<'pie'>>,
+ line?: Scriptable<number, ScriptableContext<'line'>>,
+ testA?: Scriptable<number, ScriptableContext<'pie'>>
+ testB?: Scriptable<number, ScriptableContext<'line' | 'bar'>>
+ testC?: Scriptable<number, ScriptableContext<'pie' | 'line' | 'bar'>>
+ testD?: Scriptable<number, ScriptableContext<ChartType>>
}
-const pieScriptable: Scriptable<number, 'pie'> = (ctx) => ctx.parsed;
-const lineScriptable: Scriptable<number, 'line'> = (ctx) => ctx.parsed.x + ctx.parsed.y;
-
export const testImpl: test = {
pie: (ctx) => ctx.parsed,
line: (ctx) => ctx.parsed.x + ctx.parsed.y,
- testA: pieScriptable,
- testB: lineScriptable,
- // @FIXME ts-expect-error combined type should not be any
- testC: (ctx) => ctx.fail
+ testA: (ctx) => ctx.parsed,
+ testB: (ctx) => ctx.parsed.x + ctx.parsed.y,
+ // @ts-expect-error combined type should not be any
+ testC: (ctx) => ctx.fail,
+ // combined types are intersections and permit invalid usage
+ testD: (ctx) => ctx.parsed + ctx.parsed.x + ctx.parsed.r + ctx.parsed._custom.barEnd
};
+