From f68501e80ebfee9d2f3baa5421d2cef440ae3bcb Mon Sep 17 00:00:00 2001 From: Dan Manastireanu <498419+danmana@users.noreply.github.com> Date: Mon, 27 Apr 2020 15:15:44 +0300 Subject: [PATCH] [@types/chartjs-plugin-annotation] Create new type definitions for chartjs-plugin-annotation (#44114) * chore: generate new typings for chartjs-plugin-annotation * [@types/chartjs-plugin-annotation] Create new type definisions for chartjs-plugin-annotation * fix: Make scaleID fields mandatory (annotations do not work without them) * fix: remove redundant package.json --- .../chartjs-plugin-annotation-tests.ts | 280 ++++++++++++++++++ types/chartjs-plugin-annotation/index.d.ts | 159 ++++++++++ types/chartjs-plugin-annotation/tsconfig.json | 24 ++ types/chartjs-plugin-annotation/tslint.json | 1 + 4 files changed, 464 insertions(+) create mode 100644 types/chartjs-plugin-annotation/chartjs-plugin-annotation-tests.ts create mode 100644 types/chartjs-plugin-annotation/index.d.ts create mode 100644 types/chartjs-plugin-annotation/tsconfig.json create mode 100644 types/chartjs-plugin-annotation/tslint.json diff --git a/types/chartjs-plugin-annotation/chartjs-plugin-annotation-tests.ts b/types/chartjs-plugin-annotation/chartjs-plugin-annotation-tests.ts new file mode 100644 index 0000000000..bc577d4090 --- /dev/null +++ b/types/chartjs-plugin-annotation/chartjs-plugin-annotation-tests.ts @@ -0,0 +1,280 @@ +import * as Chart from 'chart.js'; +import * as ChartJsAnnotation from 'chartjs-plugin-annotation'; + +Chart.pluginService.register(ChartJsAnnotation); +Chart.pluginService.unregister(ChartJsAnnotation); + +const ctx = new CanvasRenderingContext2D(); +const chartData = {}; + +// example from the demo codepen https://codepen.io/compwright/pen/mmQMrZ +const codepenChart = new Chart(ctx, { + type: 'bar', + data: chartData, + options: { + responsive: true, + title: { + display: true, + text: 'Chart.js Combo Bar Line Chart' + }, + tooltips: { + mode: 'index', + intersect: true + }, + annotation: { + events: ['click'], + annotations: [ + { + drawTime: 'afterDatasetsDraw', + id: 'hline', + type: 'line', + mode: 'horizontal', + scaleID: 'y-axis-0', + value: 30, + borderColor: 'black', + borderWidth: 5, + label: { + backgroundColor: 'red', + content: 'Test Label', + enabled: true + }, + // tslint:disable-next-line:object-literal-shorthand + onClick: function(e) { + // The annotation is is bound to the `this` variable + console.log('Annotation', e.type, this); + } + }, + { + drawTime: 'beforeDatasetsDraw', + type: 'box', + xScaleID: 'x-axis-0', + yScaleID: 'y-axis-0', + xMin: 'February', + xMax: 'April', + yMin: -30, + yMax: 30, + backgroundColor: 'rgba(101, 33, 171, 0.5)', + borderColor: 'rgb(101, 33, 171)', + borderWidth: 1, + onClick(e) { + console.log('Box', e.type, this); + } + } + ] + } + } +}); + +// examples from github readme +// https://github.com/chartjs/chartjs-plugin-annotation/tree/v0.5.7 + +const exampleChart = new Chart(ctx, { + type: 'bar', + data: chartData, + options: { + annotation: { + // Defines when the annotations are drawn. + // This allows positioning of the annotation relative to the other + // elements of the graph. + // + // Should be one of: afterDraw, afterDatasetsDraw, beforeDatasetsDraw + // See http://www.chartjs.org/docs/#advanced-usage-creating-plugins + drawTime: 'afterDatasetsDraw', // (default) + + // Mouse events to enable on each annotation. + // Should be an array of one or more browser-supported mouse events + // See https://developer.mozilla.org/en-US/docs/Web/Events + events: ['click'], + + // Double-click speed in ms used to distinguish single-clicks from + // double-clicks whenever you need to capture both. When listening for + // both click and dblclick, click events will be delayed by this + // amount. + dblClickSpeed: 350, // ms (default) + + // Array of annotation configuration objects + // See below for detailed descriptions of the annotation options + annotations: [{ + drawTime: 'afterDraw', // overrides annotation.drawTime if set + id: 'a-line-1', // optional + type: 'line', + mode: 'horizontal', + scaleID: 'y-axis-0', + value: '25', + borderColor: 'red', + borderWidth: 2, + + // Fires when the user clicks this annotation on the chart + // (be sure to enable the event in the events array below). + onClick(e) { + // `this` is bound to the annotation element + } + }] + } + } +}); + +// https://github.com/chartjs/chartjs-plugin-annotation/tree/v0.5.7#line-annotations +const lineAnnotation: ChartJsAnnotation.LineAnnotationOptions = { + type: 'line', + + // optional drawTime to control layering, overrides global drawTime setting + drawTime: 'afterDatasetsDraw', + + // optional annotation ID (must be unique) + id: 'a-line-1', + + // set to 'vertical' to draw a vertical line + mode: 'horizontal', + + // ID of the scale to bind onto + scaleID: 'y-axis-0', + + // Data value to draw the line at + value: 25, + + // Optional value at which the line draw should end + endValue: 26, + + // Line color + borderColor: 'red', + + // Line width + borderWidth: 2, + + // Line dash + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash + borderDash: [2, 2], + + // Line Dash Offset + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset + borderDashOffset: 5, + + label: { + // Background color of label, default below + backgroundColor: 'rgba(0,0,0,0.8)', + + // Font family of text, inherits from global + fontFamily: "sans-serif", + + // Font size of text, inherits from global + fontSize: 12, + + // Font style of text, default below + fontStyle: "bold", + + // Font color of text, default below + fontColor: "#fff", + + // Padding of label to add left/right, default below + xPadding: 6, + + // Padding of label to add top/bottom, default below + yPadding: 6, + + // Radius of label rectangle, default below + cornerRadius: 6, + + // Anchor position of label on line, can be one of: top, bottom, left, right, center. Default below. + position: "center", + + // Adjustment along x-axis (left-right) of label relative to above number (can be negative) + // For horizontal lines positioned left or right, negative values move + // the label toward the edge, and positive values toward the center. + xAdjust: 0, + + // Adjustment along y-axis (top-bottom) of label relative to above number (can be negative) + // For vertical lines positioned top or bottom, negative values move + // the label toward the edge, and positive values toward the center. + yAdjust: 0, + + // Whether the label is enabled and should be displayed + enabled: false, + + // Text to display in label - default is null + content: "Test label" + }, + + // Mouse event handlers - be sure to enable the corresponding events in the + // annotation events array or the event handler will not be called. + // See https://developer.mozilla.org/en-US/docs/Web/Events for a list of + // supported mouse events. + onMouseenter(e) { }, + onMouseover(e) { }, + onMouseleave(e) { }, + onMouseout(e) { }, + onMousemove(e) { }, + onMousedown(e) { }, + onMouseup(e) { }, + onClick(e) { }, + onDblclick(e) { }, + onContextmenu(e) { }, + onWheel(e) { } +}; + +// https://github.com/chartjs/chartjs-plugin-annotation/tree/v0.5.7#box-annotations +const boxAnnotation: ChartJsAnnotation.BoxAnnotationOptions = { + type: 'box', + + // optional drawTime to control layering, overrides global drawTime setting + drawTime: 'beforeDatasetsDraw', + + // optional annotation ID (must be unique) + id: 'a-box-1', + + // ID of the X scale to bind onto + xScaleID: 'x-axis-0', + + // ID of the Y scale to bind onto + yScaleID: 'y-axis-0', + + // Left edge of the box. in units along the x axis + xMin: 25, + + // Right edge of the box + xMax: 40, + + // Top edge of the box in units along the y axis + yMax: 20, + + // Bottom edge of the box + yMin: 15, + + // Stroke color + borderColor: 'red', + + // Stroke width + borderWidth: 2, + + // Fill color + backgroundColor: 'green', + + // Mouse event handlers - be sure to enable the corresponding events in the + // annotation events array or the event handler will not be called. + // See https://developer.mozilla.org/en-US/docs/Web/Events for a list of + // supported mouse events. + onMouseenter(e) { }, + onMouseover(e) { }, + onMouseleave(e) { }, + onMouseout(e) { }, + onMousemove(e) { }, + onMousedown(e) { }, + onMouseup(e) { }, + onClick(e) { }, + onDblclick(e) { }, + onContextmenu(e) { }, + onWheel(e) { } +}; + +const annotatedChart = new Chart(ctx, { + type: 'bar', + data: chartData, + options: { + annotation: { + annotations: [ + lineAnnotation, + boxAnnotation + ] + } + } +}); diff --git a/types/chartjs-plugin-annotation/index.d.ts b/types/chartjs-plugin-annotation/index.d.ts new file mode 100644 index 0000000000..42c7135254 --- /dev/null +++ b/types/chartjs-plugin-annotation/index.d.ts @@ -0,0 +1,159 @@ +// Type definitions for chartjs-plugin-annotation 0.5 +// Project: https://github.com/chartjs/chartjs-plugin-annotation#readme +// Definitions by: Dan Manastireanu +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.4 + +import * as Chart from 'chart.js'; + +// Extend the types from chart.js +declare module 'chart.js' { + interface ChartOptions { + // This is deprecated on master (not released yet) + annotation?: ChartJsAnnotation.AnnotationConfig; + } + + // This is the correct version on master (not released yet) + // interface ChartPluginsOptions { + // annotation?: ChartJsAnnotation.AnnotationConfig; + // } + + const Annotation: ChartJsAnnotation.AnnotationStatic; +} + +// This is the actual export of the library, +// but because we use the same name for it as the namespace below we can export the interfaces as well. +// This is called declaration merging: https://www.typescriptlang.org/docs/handbook/declaration-merging.html +// It allows us import the plugin as: import * as ChartJsAnnotation from 'chartjs-plugin-annotation'; +// and use the interfaces and types as: ChartJsAnnotation.LineAnnotationOptions +declare const ChartJsAnnotation: Chart.PluginServiceGlobalRegistration & Chart.PluginServiceRegistrationOptions; + +// Note: the namespace should contain only interfaces +// We do not want to expose in typings a class that is not actually accessible in the lib. +// The lib exposes the enum and classes under different names/props in Chart.Annotation +declare namespace ChartJsAnnotation { + interface AnnotationConfig { + drawTime?: keyof typeof DrawTimeOptions; + events?: string[]; + dblClickSpeed?: number; + annotations: AnnotationOptions[]; + } + + interface AnnotationStatic { + drawTimeOptions: typeof DrawTimeOptions; + defaults: AnnotationConfig; + labelDefaults: LineAnnotationLabel; + Element: typeof AnnotationElement; + types: { + line: typeof LineAnnotation; + box: typeof BoxAnnotation; + }; + } + + interface CommonAnnotationOptions { + type: 'line' | 'box'; + drawTime?: keyof typeof DrawTimeOptions; + id?: string; + + onMouseenter?: (event: MouseEvent) => void; + onMouseover?: (event: MouseEvent) => void; + onMouseleave?: (event: MouseEvent) => void; + onMouseout?: (event: MouseEvent) => void; + onMousemove?: (event: MouseEvent) => void; + onMousedown?: (event: MouseEvent) => void; + onMouseup?: (event: MouseEvent) => void; + onClick?: (event: MouseEvent) => void; + onDblclick?: (event: MouseEvent) => void; + onContextmenu?: (event: MouseEvent) => void; + onWheel?: (event: MouseEvent) => void; + } + + interface LineAnnotationOptions extends CommonAnnotationOptions { + type: 'line'; + mode: 'horizontal' | 'vertical'; + scaleID: string; + value: number | string; // value or label + endValue?: number | string; // value or label + + borderColor?: Chart.ChartColor; + borderWidth?: number; + borderDash?: number[]; + borderDashOffset?: number; + + label?: LineAnnotationLabel; + } + + interface BoxAnnotationOptions extends CommonAnnotationOptions { + type: 'box'; + xScaleID?: string; + yScaleID?: string; + xMin: number | string; // value or label + xMax: number | string; + yMin: number | string; + yMax: number | string; + + borderColor?: Chart.ChartColor; + borderWidth?: number; + backgroundColor?: Chart.ChartColor; + } + + type AnnotationOptions = LineAnnotationOptions | BoxAnnotationOptions; + + interface LineAnnotationLabel { + backgroundColor?: Chart.ChartColor; + fontFamily?: string; + fontSize?: number; + fontStyle?: string; + fontColor?: Chart.ChartColor; + xPadding?: number; + yPadding?: number; + cornerRadius?: number; + position?: 'top' | 'bottom' | 'left' | 'right' | 'center'; + xAdjust?: number; + yAdjust?: number; + enabled?: boolean; + content?: string; // | string[]; // only on master (not released yet) + // rotation?: number; // only on master (not released yet) + } + + interface AnnotationElementOptions { + id: string; + options: T; + chartInstance: Chart; + } +} + +// Note: classes and enums need to be outside the namespace, +// otherwise the merge with the constant ChartJsAnnotation fails +declare class AnnotationElement { // TODO: this should extend Chart.Element, but that typing is not defined in chart.js + hidden: boolean; + hovering: boolean; + _model: any; + + initialize: () => void; + destroy: () => void; + setDataLimits: () => void; + configure: () => void; + inRange: () => void; + getCenterPoint: () => void; + getWidth: () => void; + getHeight: () => void; + getArea: () => void; + draw: () => void; +} + +declare class LineAnnotation extends AnnotationElement { + constructor(options: ChartJsAnnotation.AnnotationElementOptions); +} + +declare class BoxAnnotation extends AnnotationElement { + constructor(options: ChartJsAnnotation.AnnotationElementOptions); +} + +declare enum DrawTimeOptions { + afterDraw = 'afterDraw', + afterDatasetsDraw = 'afterDatasetsDraw', + beforeDatasetsDraw = 'beforeDatasetsDraw' +} + +export = ChartJsAnnotation; diff --git a/types/chartjs-plugin-annotation/tsconfig.json b/types/chartjs-plugin-annotation/tsconfig.json new file mode 100644 index 0000000000..5c67853ae9 --- /dev/null +++ b/types/chartjs-plugin-annotation/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "chartjs-plugin-annotation-tests.ts" + ] +} diff --git a/types/chartjs-plugin-annotation/tslint.json b/types/chartjs-plugin-annotation/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/chartjs-plugin-annotation/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }