import { Chart, BarController, ChartItem, ControllerDatasetOptions, ScriptableAndArrayOptions, CommonHoverOptions, ChartConfiguration, LinearScale, CategoryScale, AnimationOptions, ScriptableContext, CartesianScaleTypeRegistry, } from 'chart.js'; import { merge } from 'chart.js/helpers'; import { asViolinStats, IViolin, IViolinOptions } from '../data'; import { StatsBase, baseDefaults, defaultOverrides } from './StatsBase'; import { baseOptionKeys } from '../elements/base'; import { IViolinElementOptions, Violin } from '../elements'; import { interpolateKdeCoords } from '../animation'; import patchController from './patchController'; export class ViolinController extends StatsBase<IViolin, Required<IViolinOptions>> { /** * @hidden */ // eslint-disable-next-line class-methods-use-this,@typescript-eslint/explicit-module-boundary-types protected _parseStats(value: any, config: IViolinOptions): IViolin | undefined { return asViolinStats(value, config); } /** * @hidden */ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types protected _transformStats<T>(target: any, source: IViolin, mapper: (v: number) => T): void { super._transformStats(target, source, mapper); // eslint-disable-next-line no-param-reassign target.maxEstimate = source.maxEstimate; if (Array.isArray(source.coords)) { // eslint-disable-next-line no-param-reassign target.coords = source.coords.map((c) => ({ ...c, v: mapper(c.v) })); } } static readonly id = 'violin'; /** * @hidden */ static readonly defaults: any = /* #__PURE__ */ merge({}, [ BarController.defaults, baseDefaults(baseOptionKeys), { points: 100, animations: { numbers: { type: 'number', properties: (BarController.defaults as any).animations.numbers.properties.concat( ['q1', 'q3', 'min', 'max', 'median', 'maxEstimate'], baseOptionKeys.filter((c) => !c.endsWith('Color')) ), }, kdeCoords: { fn: interpolateKdeCoords, properties: ['coords'], }, }, dataElementType: Violin.id, }, ]); /** * @hidden */ static readonly overrides: any = /* #__PURE__ */ merge({}, [(BarController as any).overrides, defaultOverrides()]); } export type ViolinDataPoint = number[] | (Partial<IViolin> & Pick<IViolin, 'median' | 'coords'>); export interface ViolinControllerDatasetOptions extends ControllerDatasetOptions, IViolinOptions, ScriptableAndArrayOptions<IViolinElementOptions, ScriptableContext<'violin'>>, ScriptableAndArrayOptions<CommonHoverOptions, ScriptableContext<'violin'>>, AnimationOptions<'violin'> {} // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface IViolinChartOptions extends IViolinOptions {} declare module 'chart.js' { export interface ChartTypeRegistry { violin: { chartOptions: IViolinChartOptions; datasetOptions: ViolinControllerDatasetOptions; defaultDataPoint: ViolinDataPoint; scales: keyof CartesianScaleTypeRegistry; metaExtensions: {}; parsedDataType: IViolin & ChartTypeRegistry['bar']['parsedDataType']; }; } } export class ViolinChart<DATA extends unknown[] = ViolinDataPoint[], LABEL = string> extends Chart< 'violin', DATA, LABEL > { static id = ViolinController.id; constructor(item: ChartItem, config: Omit<ChartConfiguration<'violin', DATA, LABEL>, 'type'>) { super(item, patchController('violin', config, ViolinController, Violin, [LinearScale, CategoryScale])); } }