@kevinburke/flot 5.0.0 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,580 @@
1
+ // Type definitions for @kevinburke/flot
2
+ //
3
+ // These are hand-written declarations covering the public API. The flot
4
+ // options type is large and permissive — many sub-options accept any value
5
+ // a plugin understands. When in doubt, unknown option keys are allowed.
6
+
7
+ // ============================================================================
8
+ // Data input
9
+ // ============================================================================
10
+
11
+ /**
12
+ * A single data point. Most commonly `[x, y]`, but error bars and similar
13
+ * plugins accept longer tuples.
14
+ */
15
+ export type DataPoint = number[] | null;
16
+
17
+ /**
18
+ * A series of data points, or a series descriptor containing data and
19
+ * per-series options.
20
+ */
21
+ export type DataSeries =
22
+ | DataPoint[]
23
+ | {
24
+ data: DataPoint[];
25
+ label?: string;
26
+ color?: number | string;
27
+ lines?: LinesOptions;
28
+ points?: PointsOptions;
29
+ bars?: BarsOptions;
30
+ xaxis?: number;
31
+ yaxis?: number;
32
+ hoverable?: boolean;
33
+ clickable?: boolean;
34
+ shadowSize?: number;
35
+ highlightColor?: string;
36
+ [key: string]: unknown;
37
+ };
38
+
39
+ // ============================================================================
40
+ // Options
41
+ // ============================================================================
42
+
43
+ export interface LinesOptions {
44
+ show?: boolean;
45
+ lineWidth?: number;
46
+ fill?: boolean | number;
47
+ fillColor?: string | null | { colors: Array<string | number | { opacity: number }> };
48
+ steps?: boolean;
49
+ zero?: boolean;
50
+ [key: string]: unknown;
51
+ }
52
+
53
+ export interface PointsOptions {
54
+ show?: boolean;
55
+ radius?: number;
56
+ lineWidth?: number;
57
+ fill?: boolean | number;
58
+ fillColor?: string | null;
59
+ symbol?:
60
+ | string
61
+ | ((
62
+ ctx: CanvasRenderingContext2D,
63
+ x: number,
64
+ y: number,
65
+ radius: number,
66
+ shadow: boolean,
67
+ ) => void);
68
+ [key: string]: unknown;
69
+ }
70
+
71
+ export interface BarsOptions {
72
+ show?: boolean;
73
+ lineWidth?: number;
74
+ barWidth?: number;
75
+ fill?: boolean | number;
76
+ fillColor?: string | null;
77
+ align?: "left" | "right" | "center";
78
+ horizontal?: boolean;
79
+ zero?: boolean;
80
+ [key: string]: unknown;
81
+ }
82
+
83
+ export interface SeriesOptions {
84
+ lines?: LinesOptions;
85
+ points?: PointsOptions;
86
+ bars?: BarsOptions;
87
+ shadowSize?: number;
88
+ highlightColor?: string;
89
+ hoverable?: boolean;
90
+ clickable?: boolean;
91
+ [key: string]: unknown;
92
+ }
93
+
94
+ export interface AxisOptions {
95
+ show?: boolean | null;
96
+ mode?: "time" | "categories" | null;
97
+ position?: "bottom" | "top" | "left" | "right";
98
+ color?: string | number | null;
99
+ tickColor?: string | number | null;
100
+ transform?: ((v: number) => number) | null;
101
+ inverseTransform?: ((v: number) => number) | null;
102
+ min?: number | null;
103
+ max?: number | null;
104
+ autoScale?: "loose" | "exact" | "none" | "sliding-window";
105
+ autoScaleMargin?: number;
106
+ ticks?:
107
+ | number
108
+ | number[]
109
+ | Array<[number, string]>
110
+ | ((axis: Axis) => Array<number | [number, string]>)
111
+ | null;
112
+ tickSize?: number | [number, string] | null;
113
+ minTickSize?: number | [number, string] | null;
114
+ tickFormatter?: ((value: number, axis: Axis) => string) | null;
115
+ tickDecimals?: number | null;
116
+ tickLength?: number | "full" | null;
117
+ alignTicksWithAxis?: number | null;
118
+ font?: FontOptions | null;
119
+ timezone?: string | null;
120
+ timeformat?: string | null;
121
+ twelveHourClock?: boolean;
122
+ monthNames?: string[] | null;
123
+ dayNames?: string[] | null;
124
+ reserveSpace?: boolean;
125
+ [key: string]: unknown;
126
+ }
127
+
128
+ export interface FontOptions {
129
+ size?: number;
130
+ lineHeight?: number;
131
+ style?: string;
132
+ weight?: string;
133
+ variant?: string;
134
+ family?: string;
135
+ color?: string;
136
+ }
137
+
138
+ export interface GridOptions {
139
+ show?: boolean;
140
+ aboveData?: boolean;
141
+ color?: string;
142
+ backgroundColor?: string | null | { colors: string[] };
143
+ margin?: number | { top?: number; bottom?: number; left?: number; right?: number };
144
+ labelMargin?: number;
145
+ axisMargin?: number;
146
+ borderWidth?: number | { top?: number; right?: number; bottom?: number; left?: number };
147
+ borderColor?: string | null | { top?: string; right?: string; bottom?: string; left?: string };
148
+ minBorderMargin?: number | null;
149
+ markings?: Marking[] | ((axes: Record<string, Axis>) => Marking[]) | null;
150
+ markingsColor?: string;
151
+ markingsLineWidth?: number;
152
+ clickable?: boolean;
153
+ hoverable?: boolean;
154
+ autoHighlight?: boolean;
155
+ mouseActiveRadius?: number;
156
+ [key: string]: unknown;
157
+ }
158
+
159
+ export interface Marking {
160
+ xaxis?: { from?: number; to?: number };
161
+ yaxis?: { from?: number; to?: number };
162
+ color?: string;
163
+ lineWidth?: number;
164
+ }
165
+
166
+ export interface LegendOptions {
167
+ show?: boolean;
168
+ labelFormatter?: ((label: string, series: unknown) => string) | null;
169
+ labelBoxBorderColor?: string;
170
+ noColumns?: number;
171
+ position?: "ne" | "nw" | "se" | "sw";
172
+ margin?: number | [number, number];
173
+ backgroundColor?: string | null;
174
+ backgroundOpacity?: number;
175
+ container?: HTMLElement | null;
176
+ sorted?:
177
+ | boolean
178
+ | "ascending"
179
+ | "descending"
180
+ | "reverse"
181
+ | ((a: unknown, b: unknown) => number)
182
+ | null;
183
+ [key: string]: unknown;
184
+ }
185
+
186
+ export interface ZoomOptions {
187
+ interactive?: boolean;
188
+ active?: boolean;
189
+ amount?: number;
190
+ [key: string]: unknown;
191
+ }
192
+
193
+ export interface PanOptions {
194
+ interactive?: boolean;
195
+ active?: boolean;
196
+ cursor?: string;
197
+ frameRate?: number;
198
+ mode?: "manual" | "smart";
199
+ [key: string]: unknown;
200
+ }
201
+
202
+ export interface SelectionOptions {
203
+ mode?: "x" | "y" | "xy" | null;
204
+ color?: string;
205
+ shape?: "round" | "miter" | "bevel";
206
+ minSize?: number;
207
+ [key: string]: unknown;
208
+ }
209
+
210
+ export interface PlotOptions {
211
+ series?: SeriesOptions;
212
+ xaxis?: AxisOptions;
213
+ yaxis?: AxisOptions;
214
+ xaxes?: AxisOptions[];
215
+ yaxes?: AxisOptions[];
216
+ grid?: GridOptions;
217
+ legend?: LegendOptions;
218
+ zoom?: ZoomOptions;
219
+ pan?: PanOptions;
220
+ selection?: SelectionOptions;
221
+ colors?: string[];
222
+ hooks?: Record<string, Array<(...args: unknown[]) => unknown>>;
223
+ interaction?: { redrawOverlayInterval?: number };
224
+ [key: string]: unknown;
225
+ }
226
+
227
+ // ============================================================================
228
+ // Plot runtime types
229
+ // ============================================================================
230
+
231
+ export interface Axis {
232
+ n: number;
233
+ direction: "x" | "y";
234
+ min: number;
235
+ max: number;
236
+ datamin: number;
237
+ datamax: number;
238
+ scale: number;
239
+ p2c(p: number): number;
240
+ c2p(c: number): number;
241
+ options: AxisOptions;
242
+ ticks: Array<{ v: number; label: string }>;
243
+ box?: { left: number; top: number; width: number; height: number };
244
+ }
245
+
246
+ export interface PlotOffset {
247
+ left: number;
248
+ right: number;
249
+ top: number;
250
+ bottom: number;
251
+ }
252
+
253
+ export interface Position {
254
+ pageX: number;
255
+ pageY: number;
256
+ [axisKey: string]: number;
257
+ }
258
+
259
+ export interface DataItem {
260
+ datapoint: number[];
261
+ dataIndex: number;
262
+ series: DataSeries;
263
+ seriesIndex: number;
264
+ pageX: number;
265
+ pageY: number;
266
+ }
267
+
268
+ /**
269
+ * A plot instance. Returned by `plot()` and used to inspect or mutate the
270
+ * chart after creation.
271
+ */
272
+ export interface Plot {
273
+ // Data and options
274
+ getData(): DataSeries[];
275
+ setData(data: DataSeries | DataSeries[]): void;
276
+ getOptions(): PlotOptions;
277
+
278
+ // Elements
279
+ getPlaceholder(): HTMLElement;
280
+ getCanvas(): HTMLCanvasElement;
281
+ getSurface(): unknown;
282
+ getEventHolder(): HTMLElement;
283
+ getPlotOffset(): PlotOffset;
284
+ width(): number;
285
+ height(): number;
286
+ offset(): { left: number; top: number };
287
+
288
+ // Axes
289
+ getAxes(): Record<string, Axis>;
290
+ getXAxes(): Axis[];
291
+ getYAxes(): Axis[];
292
+
293
+ // Coordinate conversion
294
+ c2p(pos: { left: number; top: number }): Position;
295
+ p2c(pos: Position): { left: number; top: number };
296
+ pointOffset(point: Record<string, number>): { left: number; top: number };
297
+
298
+ // Lifecycle
299
+ draw(): void;
300
+ setupGrid(autoScale?: boolean): void;
301
+ triggerRedrawOverlay(): void;
302
+ resize(): void;
303
+ shutdown(): void;
304
+ destroy(): void;
305
+ clearTextCache(): void;
306
+
307
+ // Hit testing
308
+ findNearbyItem(
309
+ mouseX: number,
310
+ mouseY: number,
311
+ seriesFilter?: (s: DataSeries) => boolean,
312
+ radius?: number,
313
+ ): DataItem | null;
314
+ findNearbyItems(
315
+ mouseX: number,
316
+ mouseY: number,
317
+ seriesFilter?: (s: DataSeries) => boolean,
318
+ radius?: number,
319
+ ): DataItem[];
320
+ findNearbyInterpolationPoint(
321
+ mouseX: number,
322
+ mouseY: number,
323
+ seriesFilter?: (s: DataSeries) => boolean,
324
+ ): DataItem | null;
325
+
326
+ // Axis helpers
327
+ autoScaleAxis(axis: Axis): void;
328
+ computeRangeForDataSeries(series: DataSeries): {
329
+ xmin: number;
330
+ xmax: number;
331
+ ymin: number;
332
+ ymax: number;
333
+ };
334
+ adjustSeriesDataRange(series: DataSeries, range: unknown): unknown;
335
+ computeValuePrecision(min: number, max: number, direction: "x" | "y", noTicks: number): number;
336
+ computeTickSize(min: number, max: number, noTicks?: number, tickDecimals?: number): number;
337
+
338
+ // Event handler priority
339
+ addEventHandler(
340
+ event: string,
341
+ handler: (e: Event) => void,
342
+ eventHolder: HTMLElement,
343
+ priority: number,
344
+ ): void;
345
+ hooks: Record<string, Array<(...args: unknown[]) => unknown>>;
346
+
347
+ // Plugin-provided methods (present when the relevant plugin is loaded)
348
+ // Hover plugin:
349
+ highlight?(series: number | DataSeries, point: number | DataPoint, auto?: boolean): void;
350
+ unhighlight?(series?: number | DataSeries, point?: number | DataPoint): void;
351
+
352
+ // Navigate plugin:
353
+ pan?(args: { left?: number; top?: number; axes?: Axis[]; preventEvent?: boolean }): void;
354
+ zoom?(args?: {
355
+ amount?: number;
356
+ center?: { left: number; top: number };
357
+ axes?: Axis[];
358
+ preventEvent?: boolean;
359
+ }): void;
360
+ zoomOut?(args?: { amount?: number }): void;
361
+ recenter?(args?: { axes?: Axis[] }): void;
362
+ smartPan?(
363
+ delta: { x: number; y: number },
364
+ initialState: unknown,
365
+ panAxes?: Axis[],
366
+ preventEvent?: boolean,
367
+ smartLock?: boolean,
368
+ ): void;
369
+ navigationState?(startPageX?: number, startPageY?: number): unknown;
370
+ getTouchedAxis?(touchPointX: number, touchPointY: number): Axis[];
371
+ activate?(): void;
372
+
373
+ // Selection plugin:
374
+ setSelection?(
375
+ ranges: { xaxis?: { from: number; to: number }; yaxis?: { from: number; to: number } },
376
+ preventEvent?: boolean,
377
+ ): void;
378
+ getSelection?(): {
379
+ xaxis?: { from: number; to: number };
380
+ yaxis?: { from: number; to: number };
381
+ } | null;
382
+ clearSelection?(preventEvent?: boolean): void;
383
+
384
+ // Compose images plugin:
385
+ composeImages?(
386
+ canvasOrSvgSources: Array<HTMLCanvasElement | SVGElement>,
387
+ destinationCanvas: HTMLCanvasElement,
388
+ ): Promise<number>;
389
+ }
390
+
391
+ // ============================================================================
392
+ // Main entry points
393
+ // ============================================================================
394
+
395
+ /**
396
+ * Create a plot in the given element.
397
+ *
398
+ * @param placeholder The container element. Must have explicit width and
399
+ * height set via CSS.
400
+ * @param data An array of data series.
401
+ * @param options Plot options.
402
+ */
403
+ export function plot(
404
+ placeholder: HTMLElement | string,
405
+ data: DataSeries[],
406
+ options?: PlotOptions,
407
+ ): Plot;
408
+
409
+ export const version: string;
410
+
411
+ export const plugins: Array<{
412
+ init: (plot: Plot, classes?: unknown) => void;
413
+ options?: PlotOptions;
414
+ name?: string;
415
+ version?: string;
416
+ }>;
417
+
418
+ // ============================================================================
419
+ // Helper exports
420
+ // ============================================================================
421
+
422
+ export interface Color {
423
+ r: number;
424
+ g: number;
425
+ b: number;
426
+ a: number;
427
+ add(channels: string, delta: number): Color;
428
+ scale(channels: string, factor: number): Color;
429
+ toString(): string;
430
+ normalize(): Color;
431
+ clone(): Color;
432
+ }
433
+
434
+ export const color: {
435
+ make(r: number, g: number, b: number, a?: number): Color;
436
+ parse(str: string): Color;
437
+ extract(elem: HTMLElement, cssProp: string): Color;
438
+ };
439
+
440
+ export const saturated: {
441
+ saturate(a: number): number;
442
+ delta(min: number, max: number, noTicks: number): number;
443
+ multiply(a: number, b: number): number;
444
+ multiplyAdd(a: number, bInt: number, c: number): number;
445
+ floorInBase(n: number, base: number): number;
446
+ };
447
+
448
+ export const browser: {
449
+ getPageXY(e: MouseEvent | TouchEvent): { X: number; Y: number };
450
+ getPixelRatio(context: CanvasRenderingContext2D): number;
451
+ isSafari(): boolean;
452
+ isMobileSafari(): boolean | null;
453
+ isOpera(): boolean;
454
+ isFirefox(): boolean;
455
+ isIE(): boolean;
456
+ isEdge(): boolean;
457
+ isChrome(): boolean;
458
+ isBlink(): boolean;
459
+ };
460
+
461
+ export const uiConstants: {
462
+ SNAPPING_CONSTANT: number;
463
+ PANHINT_LENGTH_CONSTANT: number;
464
+ MINOR_TICKS_COUNT_CONSTANT: number;
465
+ TICK_LENGTH_CONSTANT: number;
466
+ ZOOM_DISTANCE_MARGIN: number;
467
+ };
468
+
469
+ export const drawSeries: {
470
+ drawSeriesLines(
471
+ series: DataSeries,
472
+ ctx: CanvasRenderingContext2D,
473
+ plotOffset: PlotOffset,
474
+ plotWidth: number,
475
+ plotHeight: number,
476
+ drawSymbol: unknown,
477
+ getColorOrGradient: unknown,
478
+ ): void;
479
+ drawSeriesPoints(
480
+ series: DataSeries,
481
+ ctx: CanvasRenderingContext2D,
482
+ plotOffset: PlotOffset,
483
+ plotWidth: number,
484
+ plotHeight: number,
485
+ drawSymbol: unknown,
486
+ getColorOrGradient: unknown,
487
+ ): void;
488
+ drawSeriesBars(
489
+ series: DataSeries,
490
+ ctx: CanvasRenderingContext2D,
491
+ plotOffset: PlotOffset,
492
+ plotWidth: number,
493
+ plotHeight: number,
494
+ drawSymbol: unknown,
495
+ getColorOrGradient: unknown,
496
+ ): void;
497
+ drawBar(
498
+ x: number,
499
+ y: number,
500
+ b: number,
501
+ barLeft: number,
502
+ barRight: number,
503
+ fillStyleCallback: unknown,
504
+ axisx: Axis,
505
+ axisy: Axis,
506
+ c: CanvasRenderingContext2D,
507
+ horizontal: boolean,
508
+ lineWidth: number,
509
+ ): void;
510
+ };
511
+
512
+ export class Canvas {
513
+ constructor(cls: string, container: HTMLElement);
514
+ element: HTMLCanvasElement;
515
+ context: CanvasRenderingContext2D;
516
+ pixelRatio: number;
517
+ width: number;
518
+ height: number;
519
+ resize(width: number, height: number): void;
520
+ clear(): void;
521
+ render(): void;
522
+ clearCache(): void;
523
+ getTextInfo(
524
+ layer: string,
525
+ text: string,
526
+ font: FontOptions,
527
+ angle?: number,
528
+ width?: number,
529
+ ): unknown;
530
+ addText(
531
+ layer: string,
532
+ x: number,
533
+ y: number,
534
+ text: string,
535
+ font: FontOptions,
536
+ angle?: number,
537
+ width?: number,
538
+ halign?: string,
539
+ valign?: string,
540
+ ): void;
541
+ removeText(
542
+ layer: string,
543
+ x?: number,
544
+ y?: number,
545
+ text?: string,
546
+ font?: FontOptions,
547
+ angle?: number,
548
+ ): void;
549
+ }
550
+
551
+ // Tick generators and formatters
552
+ export function linearTickGenerator(axis: Axis): Array<number | [number, string]>;
553
+ export function defaultTickFormatter(value: number, axis: Axis, precision?: number): string;
554
+ export function expRepTickFormatter(value: number, axis: Axis, precision?: number): string;
555
+ export function logTicksGenerator(
556
+ plot: Plot,
557
+ axis: Axis,
558
+ noTicks?: number,
559
+ ): Array<number | [number, string]>;
560
+ export function logTickFormatter(value: number, axis: Axis, precision?: number): string;
561
+
562
+ // Time plugin exports
563
+ export function formatDate(
564
+ d: Date,
565
+ fmt: string,
566
+ monthNames?: string[],
567
+ dayNames?: string[],
568
+ ): string;
569
+ export function makeUtcWrapper(d: Date): unknown;
570
+ export function dateGenerator(
571
+ ts: number,
572
+ opts: { timezone?: string; timeBase?: "seconds" | "milliseconds" | "microseconds" },
573
+ ): unknown;
574
+ export function dateTickGenerator(axis: Axis): Array<number>;
575
+
576
+ // Compose images export
577
+ export function composeImages(
578
+ canvasOrSvgSources: Array<HTMLCanvasElement | SVGElement>,
579
+ destinationCanvas: HTMLCanvasElement,
580
+ ): Promise<number>;
@@ -0,0 +1,37 @@
1
+ // jQuery adapter types. Importing this module augments the jQuery
2
+ // static namespace with `$.plot()` and related properties.
3
+
4
+ import type { DataSeries, Plot, PlotOptions } from "./index.js";
5
+
6
+ declare global {
7
+ interface JQueryStatic {
8
+ plot: {
9
+ (placeholder: string | HTMLElement | JQuery, data: DataSeries[], options?: PlotOptions): Plot;
10
+ version: string;
11
+ plugins: unknown[];
12
+ saturated: unknown;
13
+ browser: unknown;
14
+ uiConstants: unknown;
15
+ drawSeries: unknown;
16
+ linearTickGenerator: unknown;
17
+ defaultTickFormatter: unknown;
18
+ expRepTickFormatter: unknown;
19
+ logTicksGenerator: unknown;
20
+ logTickFormatter: unknown;
21
+ formatDate: unknown;
22
+ makeUtcWrapper: unknown;
23
+ dateGenerator: unknown;
24
+ dateTickGenerator: unknown;
25
+ composeImages: unknown;
26
+ };
27
+ color: {
28
+ make(r: number, g: number, b: number, a?: number): unknown;
29
+ parse(str: string): unknown;
30
+ extract(elem: JQuery, cssProp: string): unknown;
31
+ };
32
+ }
33
+
34
+ interface JQuery {
35
+ plot(data: DataSeries[], options?: PlotOptions): JQuery;
36
+ }
37
+ }
package/types/test.ts ADDED
@@ -0,0 +1,72 @@
1
+ // Type test. Verifies the .d.ts files compile and the public API has
2
+ // sensible types. Run `npx tsc --noEmit types/test.ts` to check.
3
+
4
+ import {
5
+ color,
6
+ type DataSeries,
7
+ type Plot,
8
+ type PlotOptions,
9
+ plot,
10
+ saturated,
11
+ version,
12
+ } from "./index.js";
13
+
14
+ // Basic plot call
15
+ const el = document.getElementById("placeholder") as HTMLElement;
16
+ const data: DataSeries[] = [
17
+ [
18
+ [0, 0],
19
+ [1, 1],
20
+ [2, 4],
21
+ ],
22
+ {
23
+ data: [
24
+ [0, 3],
25
+ [4, 8],
26
+ ],
27
+ label: "series 2",
28
+ color: "#ff0000",
29
+ },
30
+ ];
31
+ const options: PlotOptions = {
32
+ xaxis: { mode: "time", min: 0 },
33
+ yaxis: { max: 10 },
34
+ series: {
35
+ lines: { show: true, fill: 0.5 },
36
+ points: { show: true, radius: 3 },
37
+ },
38
+ grid: { hoverable: true, clickable: true },
39
+ legend: { position: "ne", noColumns: 2 },
40
+ };
41
+
42
+ const p: Plot = plot(el, data, options);
43
+
44
+ // Plot methods
45
+ p.getData();
46
+ p.setData(data);
47
+ const _offset = p.getPlotOffset();
48
+ const _width: number = p.width();
49
+ const _height: number = p.height();
50
+ const _axes = p.getAxes();
51
+ const _xAxes = p.getXAxes();
52
+
53
+ // Plugin methods (optional)
54
+ p.highlight?.(0, 0);
55
+ p.pan?.({ left: 10, top: 0 });
56
+ p.setSelection?.({ xaxis: { from: 0, to: 5 } });
57
+
58
+ // Color helpers
59
+ const c = color.make(255, 0, 0);
60
+ c.scale("rgb", 0.5).toString();
61
+ const parsed = color.parse("#ff0000");
62
+ parsed.r; // number
63
+
64
+ // Math helpers
65
+ saturated.floorInBase(17, 5);
66
+ saturated.multiplyAdd(1e300, 10, 5);
67
+
68
+ // Version string
69
+ const _v: string = version;
70
+
71
+ // String placeholder also works
72
+ plot("#placeholder", data);
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2019",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ES2019", "DOM"],
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "skipLibCheck": true,
10
+ "types": ["jquery"],
11
+ "esModuleInterop": true,
12
+ "allowSyntheticDefaultImports": true
13
+ },
14
+ "include": ["*.d.ts", "test.ts"]
15
+ }