ml-time-graph 1.0.0

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,481 @@
1
+ import { e as LegendOrientation, f as Renderer, M as Marker, d as LegendItem, b as LayoutResult, R as RenderOutput, t as theme } from './layout-Sc5UkC0r.js';
2
+ import { V as LineVariant, h as AnySeries, ab as Threshold, Q as Highlight, J as Gap, O as GapsConfig, e as Annotation, f as AnnotationBandConfig, p as DrawCommand, ae as TimeScale, W as LinearScale, P as HatchVariant, H as FillSpec, a as AggregatedSeries, l as DataPoint, ag as TimeSeries } from './scale-Cbr0KpPz.js';
3
+ export { A as AggregatedPoint, b as AggregationConfig, c as AggregationMode, g as AnnotationBandItem, m as DataPointRef, E as EnumMap, F as FillBound, y as FillDirectionType, z as FillRegion, G as FillSide, I as FillStyle, K as GapConfig, L as GapLabel, M as GapRegion, N as GapStyle, S as LineDashStyle, U as LineStyle, Y as MarkerStyle, $ as PointStyleType, a3 as SensorType, a4 as SeriesOverlay, a5 as SeriesOverlayKind, a6 as SeriesStyle, a7 as SeriesType, a8 as ShadowStyle, ac as ThresholdLabelConfig, ad as ThresholdLabelPosition } from './scale-Cbr0KpPz.js';
4
+ export { L as LimitStatsPoint, M as MktPoint, S as StatsAggregatedPoint, a as StdDevPoint } from './aggregated_subtypes-DZNZyFTX.js';
5
+
6
+ /*!
7
+ * MLTimeGraph — Copyright (c) 2026 Michael Lechner
8
+ * MIT with Attribution: free use incl. commercial requires visible credit to
9
+ * "Michael Lechner". Commercial license (no attribution) on request. See LICENSE.
10
+ */
11
+
12
+ /** Tick density / sizing for one axis. */
13
+ interface TickConfig {
14
+ /** Target number of major (labelled) ticks. */
15
+ major?: number;
16
+ /** How many minor ticks to place between two major ticks. Default 0 = off. */
17
+ minor?: number;
18
+ /** Tick mark length in px. */
19
+ size?: number;
20
+ }
21
+ /** Grid line styling for one tick level. `false` disables that grid level. */
22
+ interface GridLineStyle {
23
+ color?: string;
24
+ width?: number;
25
+ style?: LineVariant;
26
+ opacity?: number;
27
+ }
28
+ /**
29
+ * Per-axis grid configuration. Each tick level (major / minor) can be styled
30
+ * independently or disabled. Defaults: major grid shown with theme colours,
31
+ * minor grid off.
32
+ */
33
+ interface GridStyle {
34
+ major?: GridLineStyle | false;
35
+ minor?: GridLineStyle | false;
36
+ }
37
+ /** Axis baseline + tick marks styling. */
38
+ interface AxisStyle {
39
+ color?: string;
40
+ width?: number;
41
+ }
42
+ /** Tick / axis-label text styling. */
43
+ interface AxisLabelsStyle {
44
+ color?: string;
45
+ fontSize?: number;
46
+ }
47
+ /** Configuration for one Y-axis (left or right). */
48
+ interface YAxisConfig {
49
+ /** Rotated label drawn next to the axis. */
50
+ label?: string;
51
+ /** Override the value domain. `'auto'` lets the chart compute it from data. */
52
+ domain?: [number, number] | "auto";
53
+ /** Format a tick value into its label text. */
54
+ format?: (value: number) => string;
55
+ /** Tick density / sizing. */
56
+ ticks?: TickConfig;
57
+ /** Per-tick-level grid styling. */
58
+ grid?: GridStyle;
59
+ /** Axis baseline + tick marks styling. */
60
+ axis?: AxisStyle;
61
+ /** Tick label text styling. */
62
+ labels?: AxisLabelsStyle;
63
+ }
64
+ /** Configuration for the X (time) axis. */
65
+ interface XAxisConfig {
66
+ /** Label drawn below the axis. */
67
+ label?: string;
68
+ /** Override the time domain. `'auto'` lets the chart compute it from data. */
69
+ domain?: [number, number] | "auto";
70
+ /** Custom formatter for tick labels (called with a `Date`). */
71
+ format?: (d: Date) => string;
72
+ /** Tick density / sizing. */
73
+ ticks?: TickConfig;
74
+ /** Per-tick-level grid styling. */
75
+ grid?: GridStyle;
76
+ /** Axis baseline + tick marks styling. */
77
+ axis?: AxisStyle;
78
+ /** Tick label text styling. */
79
+ labels?: AxisLabelsStyle;
80
+ }
81
+ /**
82
+ * Top-level axes container on {@link MLTimeGraphOptions}.
83
+ * `left` and `right` correspond to `yAxisIndex: 0` and `yAxisIndex: 1` series.
84
+ */
85
+ interface AxesConfig {
86
+ x?: XAxisConfig;
87
+ left?: YAxisConfig;
88
+ right?: YAxisConfig;
89
+ }
90
+
91
+ /*!
92
+ * MLTimeGraph — Copyright (c) 2026 Michael Lechner
93
+ * MIT with Attribution: free use incl. commercial requires visible credit to
94
+ * "Michael Lechner". Commercial license (no attribution) on request. See LICENSE.
95
+ */
96
+
97
+ /** Chart margins in pixels. */
98
+ interface Margin {
99
+ top: number;
100
+ right: number;
101
+ bottom: number;
102
+ left: number;
103
+ }
104
+ /** Legend placement position — inside or outside the chart area. */
105
+ type LegendPosition = 'inside-right' | 'inside-left' | 'outside-right' | 'outside-left' | 'separate';
106
+ interface LegendOptions {
107
+ /** Show the legend (default false). */
108
+ show?: boolean;
109
+ /** Placement (default 'inside-right'). 'separate' draws nothing — read chart.legendItems() and render your own. */
110
+ position?: LegendPosition;
111
+ /** Item layout direction (default 'vertical'). */
112
+ orientation?: LegendOrientation;
113
+ }
114
+ interface MLTimeGraphOptions {
115
+ /** Chart dimensions */
116
+ width?: number;
117
+ height?: number;
118
+ /** Margins */
119
+ margin?: Margin;
120
+ /** Renderer (injected) */
121
+ renderer?: Renderer;
122
+ /** Time series data (raw or aggregated min/max/avg) */
123
+ series?: AnySeries[];
124
+ /** Locale for i18n (e.g. 'de-DE') */
125
+ locale?: string;
126
+ /** Integrated legend configuration */
127
+ legend?: LegendOptions;
128
+ /** Markers */
129
+ markers?: Marker[];
130
+ /** Threshold bands / lines / fills drawn behind the series */
131
+ thresholds?: Threshold[];
132
+ /** Highlighted time regions drawn behind the series */
133
+ highlights?: Highlight[];
134
+ /**
135
+ * Data-gap configuration. Two equivalent forms:
136
+ * - `Gap[]` — legacy: array of region objects with flat
137
+ * fill/hatch/labelBaseline/rotate fields.
138
+ * - {@link GapsConfig} — new (preferred): `{ regions?, autoDetect?,
139
+ * minGapMs?, style? }`, where `style` provides
140
+ * per-region fallbacks and `autoDetect` (TODO)
141
+ * will derive gaps from time spacing in
142
+ * Phase 3+. For now: typed but not yet acted on.
143
+ */
144
+ gaps?: Gap[] | GapsConfig;
145
+ /** Free-form overlays (arrow, line, rect, point, label) in data coordinates */
146
+ annotations?: Annotation[];
147
+ /** Horizontal annotation bands below the chart (colored time ranges + labels) */
148
+ annotationBands?: AnnotationBandConfig[];
149
+ /**
150
+ * First-class axes configuration: per-axis `label`, `format`, `ticks`, `grid`,
151
+ * `axis`, `labels` (see API_DESIGN.md §7).
152
+ */
153
+ axes?: AxesConfig;
154
+ }
155
+
156
+ /*!
157
+ * MLTimeGraph — Copyright (c) 2026 Michael Lechner
158
+ * MIT with Attribution: free use incl. commercial requires visible credit to
159
+ * "Michael Lechner". Commercial license (no attribution) on request. See LICENSE.
160
+ */
161
+
162
+ /**
163
+ * Time-series chart. Configure it with {@link MLTimeGraphOptions} (series,
164
+ * thresholds, legend, axis labels, …), then call {@link MLTimeGraph.renderCommands}
165
+ * to get renderer-agnostic draw commands — a {@link Renderer} (e.g. SVGRenderer)
166
+ * turns those into output. The chart never touches the DOM itself.
167
+ */
168
+ declare class MLTimeGraph {
169
+ private readonly _layout;
170
+ private readonly _renderer?;
171
+ private readonly _locale?;
172
+ private readonly _legend?;
173
+ private readonly _markers;
174
+ private readonly _thresholds;
175
+ private readonly _highlights;
176
+ private readonly _gaps;
177
+ private readonly _gapsAutoDetect;
178
+ private readonly _gapsMinGapMs;
179
+ private _annotations;
180
+ private readonly _annotationBands;
181
+ private readonly _disabledAnnotations;
182
+ private _annotationSeq;
183
+ private readonly _axes?;
184
+ private _series;
185
+ private _annotationBandHeight;
186
+ private _timeScale?;
187
+ private _valueScales;
188
+ /** @param options Chart configuration; every field is optional and has a sensible default. */
189
+ constructor(options?: MLTimeGraphOptions);
190
+ getWidth(): number;
191
+ getHeight(): number;
192
+ /** Read-only view of the parsed series array (post-`setData`). */
193
+ get series(): readonly AnySeries[];
194
+ _annotationBandTotalHeight(): number;
195
+ /** Set chart data (raw or aggregated series with a non-empty `data` array). */
196
+ setData(series: AnySeries[]): void;
197
+ /** Add a free-form annotation. Returns its id. */
198
+ addAnnotation(annotation: Annotation): string;
199
+ /** Remove an annotation by id. */
200
+ removeAnnotation(id: string): boolean;
201
+ /** Replace all annotations. */
202
+ setAnnotations(annotations: Annotation[]): void;
203
+ /** Remove all annotations. */
204
+ clearAnnotations(): void;
205
+ /** Current annotations (read-only snapshot). */
206
+ getAnnotations(): readonly Annotation[];
207
+ /** Hide an annotation by id. */
208
+ disableAnnotation(id: string): void;
209
+ /** Re-show a previously disabled annotation. */
210
+ enableAnnotation(id: string): void;
211
+ private _axisIndexOf;
212
+ private _timesOf;
213
+ private _valuesOf;
214
+ /**
215
+ * Compute the chart's renderer-agnostic draw commands.
216
+ */
217
+ renderCommands(): DrawCommand[];
218
+ /** Build the draw commands for a single series based on its type. */
219
+ private _renderSeries;
220
+ private _interpolateValue;
221
+ legendItems(): LegendItem[];
222
+ private _legendItems;
223
+ get renderer(): Renderer | undefined;
224
+ get layout(): LayoutResult;
225
+ get timeScale(): TimeScale | undefined;
226
+ get valueScales(): Map<number, LinearScale>;
227
+ invertTime(x: number): number;
228
+ invertValue(y: number, axisIndex?: number): number;
229
+ project(time: number, value: number, axisIndex?: number): {
230
+ x: number;
231
+ y: number;
232
+ };
233
+ }
234
+
235
+ /*!
236
+ * MLTimeGraph — Copyright (c) 2026 Michael Lechner
237
+ * MIT with Attribution: free use incl. commercial requires visible credit to
238
+ * "Michael Lechner". Commercial license (no attribution) on request. See LICENSE.
239
+ */
240
+
241
+ /** A single sample at the cursor's X position — one per series. */
242
+ interface TooltipSample {
243
+ /** Index of the series in the chart's `series[]`. */
244
+ seriesIndex: number;
245
+ /** The series itself (for `.name`, `.style.line.color`, etc.). */
246
+ series: AnySeries;
247
+ /** Timestamp of the closest sample to the cursor (ms). */
248
+ time: number;
249
+ /** Numeric value of the sample. For aggregated series this is the `avg`. */
250
+ value: number;
251
+ /** Pixel X of the sample in the rendered SVG. */
252
+ x: number;
253
+ /** Pixel Y of the sample in the rendered SVG. */
254
+ y: number;
255
+ }
256
+ /** Configuration for the DOM-attached tooltip helper. */
257
+ interface TooltipOptions {
258
+ /** Master switch — set to true to enable. Default: false. */
259
+ show?: boolean;
260
+ /**
261
+ * Custom HTML formatter. The argument is one entry per series at the
262
+ * cursor's X position. Return raw HTML — it goes into the tooltip's
263
+ * `innerHTML`. If not given, a sensible default is used (time header
264
+ * + one row per series with `name: value`).
265
+ */
266
+ format?: (samples: TooltipSample[]) => string;
267
+ /**
268
+ * Maximum cursor-to-sample distance in pixels for a sample to count.
269
+ * Default: `Infinity` (always snap to the nearest sample of each
270
+ * series, regardless of distance).
271
+ */
272
+ snapRadius?: number;
273
+ /** CSS class for the tooltip `<div>`. Default: `'mlc-tooltip'`. */
274
+ className?: string;
275
+ /**
276
+ * Highlight each picked sample with a hollow-ring marker in the SVG
277
+ * (white fill, stroke = series colour). Default: `true`.
278
+ */
279
+ showPicks?: boolean;
280
+ /** Radius (px) for the pick marker. Default: 5. */
281
+ pickRadius?: number;
282
+ /** CSS class for the picks-group `<g>`. Default: `'mlc-tooltip-picks'`. */
283
+ picksClassName?: string;
284
+ }
285
+ /**
286
+ * Attach an interactive tooltip to a rendered chart. Listens to mousemove
287
+ * on the chart's `<svg>` element, snaps each series to its nearest sample
288
+ * at the cursor's X position, and renders the result via the `format`
289
+ * callback into a positioned `<div>`.
290
+ *
291
+ * Returns a cleanup function that removes the listeners and the tooltip
292
+ * element. Idempotent — calling cleanup twice is a no-op.
293
+ *
294
+ * Style the tooltip via CSS:
295
+ *
296
+ * ```css
297
+ * .mlc-tooltip {
298
+ * position: absolute;
299
+ * pointer-events: none;
300
+ * padding: 6px 10px;
301
+ * background: rgba(15, 23, 42, 0.92);
302
+ * color: #fff;
303
+ * border-radius: 4px;
304
+ * font-size: 12px;
305
+ * transform: translate(8px, 8px);
306
+ * }
307
+ * .mlc-tooltip__time { opacity: 0.7; margin-bottom: 4px; }
308
+ * .mlc-tooltip__name { opacity: 0.8; }
309
+ * ```
310
+ */
311
+ declare function attachTooltip(target: HTMLElement, chart: MLTimeGraph, options?: TooltipOptions): () => void;
312
+
313
+ /*!
314
+ * MLTimeGraph — Copyright (c) 2026 Michael Lechner
315
+ * MIT with Attribution: free use incl. commercial requires visible credit to
316
+ * "Michael Lechner". Commercial license (no attribution) on request. See LICENSE.
317
+ */
318
+
319
+ /** Options accepted by {@link mount} on top of `MLTimeGraphOptions`. */
320
+ interface MountOptions extends MLTimeGraphOptions {
321
+ /**
322
+ * Attach a DOM tooltip. The library finds the nearest sample per
323
+ * series at the cursor's X position, renders the result via the
324
+ * `format` callback into an absolutely-positioned `<div>`.
325
+ *
326
+ * Pass `{ show: true }` to use the default formatter (time header +
327
+ * `name: value` per series), or supply your own `format(samples)`
328
+ * for full control over the markup.
329
+ */
330
+ tooltip?: TooltipOptions;
331
+ }
332
+ /**
333
+ * Create a chart and inject its SVG into `target` in one call.
334
+ *
335
+ * Replaces the manual three-step boilerplate:
336
+ * const chart = new MLTimeGraph({...});
337
+ * const { content } = new SVGRenderer().render(chart.renderCommands());
338
+ * el.innerHTML = content;
339
+ *
340
+ * Width defaults to the target's measured width (falls back to 800),
341
+ * height to the explicit option or 350. The `<svg>` is left responsive
342
+ * (`width="100%"`, viewBox set to the rendered dimensions) so the chart
343
+ * scales with its container.
344
+ *
345
+ * Optionally attaches an interactive tooltip via `options.tooltip` —
346
+ * see {@link attachTooltip} for the full options surface.
347
+ *
348
+ * Returns the chart instance — useful for later `invertTime` /
349
+ * `invertValue` / `setData` calls.
350
+ *
351
+ * @param target DOM element to render into, or a CSS selector string
352
+ * resolved against `document` (throws if not found).
353
+ */
354
+ declare function mount(target: HTMLElement | string, options?: MountOptions): MLTimeGraph;
355
+
356
+ /*!
357
+ * MLTimeGraph — Copyright (c) 2026 Michael Lechner
358
+ * MIT with Attribution: free use incl. commercial requires visible credit to
359
+ * "Michael Lechner". Commercial license (no attribution) on request. See LICENSE.
360
+ */
361
+
362
+ declare class SVGRenderer extends Renderer {
363
+ #private;
364
+ constructor(options?: {
365
+ width?: number | string;
366
+ height?: number | string;
367
+ });
368
+ render(commands: DrawCommand[]): RenderOutput;
369
+ _toSVG(cmd: DrawCommand): string;
370
+ /** Register or retrieve a hatch pattern by variant. Returns the pattern id for use as fill="url(#id)". */
371
+ _hatchPattern(variant: string, fillColor: string | undefined): string;
372
+ /** Monotonic counter for unique hatch pattern ids. */
373
+ _hatchIndex: number;
374
+ _path(c: Extract<DrawCommand, {
375
+ type: "path";
376
+ }>): string;
377
+ _line(c: Extract<DrawCommand, {
378
+ type: "line";
379
+ }>): string;
380
+ _rect(c: Extract<DrawCommand, {
381
+ type: "rect";
382
+ }>): string;
383
+ _circle(c: Extract<DrawCommand, {
384
+ type: "circle";
385
+ }>): string;
386
+ _gradient(c: Extract<DrawCommand, {
387
+ type: "gradient";
388
+ }>): string;
389
+ _gap(c: Extract<DrawCommand, {
390
+ type: "gap";
391
+ }>): string;
392
+ _group(c: Extract<DrawCommand, {
393
+ type: "group";
394
+ }>): string;
395
+ _esc(s: string): string;
396
+ }
397
+
398
+ /*!
399
+ * MLTimeGraph — Copyright (c) 2026 Michael Lechner
400
+ * MIT with Attribution: free use incl. commercial requires visible credit to
401
+ * "Michael Lechner". Commercial license (no attribution) on request. See LICENSE.
402
+ */
403
+
404
+ /** Input shape for {@link fillBetweenThresholds}. */
405
+ interface FillBetweenThresholdsInput {
406
+ /** Threshold names in ascending value order (low → high). */
407
+ thresholds: string[];
408
+ /** One colour per zone — must be exactly `thresholds.length + 1` entries. */
409
+ colors: string[];
410
+ /** Optional hatch pattern per zone (`undefined` slots are plain colour). */
411
+ hatches?: (HatchVariant | undefined)[];
412
+ }
413
+ /**
414
+ * Build a {@link FillSpec} that paints the area beneath the series in
415
+ * stacked zones, partitioned by N named thresholds. Returns N+1 regions:
416
+ *
417
+ * region 0 chartBottom .. threshold[0]
418
+ * region 1..N-1 threshold[i-1] .. threshold[i]
419
+ * region N threshold[N-1] .. series (i.e. up to the line)
420
+ *
421
+ * Mirrors the legacy `fillByThresholds` + `fillByThresholdsHatches`
422
+ * combination but as a single, composable, type-safe call.
423
+ *
424
+ * @example
425
+ * style: {
426
+ * fill: fillBetweenThresholds({
427
+ * thresholds: ['cold', 'norm', 'hot'],
428
+ * colors: ['#60a5fa33', '#22c55e33', '#fbbf2433', '#ef444433'],
429
+ * hatches: ['classic-diagonal', 'crosshatch', 'dots', 'waves'],
430
+ * }),
431
+ * }
432
+ */
433
+ declare function fillBetweenThresholds(input: FillBetweenThresholdsInput): FillSpec;
434
+
435
+ /*!
436
+ * MLTimeGraph — Copyright (c) 2026 Michael Lechner
437
+ * MIT with Attribution: free use incl. commercial requires visible credit to
438
+ * "Michael Lechner". Commercial license (no attribution) on request. See LICENSE.
439
+ */
440
+
441
+ /**
442
+ * Parse raw JSON to internal DataPoint format.
443
+ * Validiert: time (ms-Timestamp, number), value (number).
444
+ */
445
+ declare function parseDataPoint(obj: unknown): DataPoint;
446
+ /** Parse raw JSON array to TimeSeries[] or raw DataPoint[] */
447
+ declare function parseSeries(obj: unknown): TimeSeries | DataPoint[];
448
+ /** Parse aggregated series (AggregatedPoint[] — min/max/avg per slot) */
449
+ declare function parseAggregated(obj: unknown): AggregatedSeries;
450
+
451
+ /*!
452
+ * MLTimeGraph — Copyright (c) 2026 Michael Lechner
453
+ * MIT with Attribution: free use incl. commercial requires visible credit to
454
+ * "Michael Lechner". Commercial license (no attribution) on request. See LICENSE.
455
+ */
456
+
457
+ /** The Theme type — same shape as the immutable BUILTIN_DEFAULTS object. */
458
+ type Theme = typeof theme;
459
+ /**
460
+ * Apply a partial override on top of the current global default theme.
461
+ * Merged shallowly — nested objects (e.g. {@link Theme.palette}) are replaced
462
+ * wholesale, not deep-merged.
463
+ *
464
+ * @example
465
+ * setDefaultTheme({ stroke: '#0f172a', gridStroke: '#f1f5f9' });
466
+ * new MLTimeGraph({ ... }); // picks up the new defaults
467
+ */
468
+ declare function setDefaultTheme(partial: Partial<Theme>): void;
469
+ /**
470
+ * Read the current global default theme (a snapshot — mutating the result
471
+ * does NOT affect future reads).
472
+ */
473
+ declare function getDefaultTheme(): Readonly<Theme>;
474
+ /**
475
+ * Restore the global default theme to the library's built-in values
476
+ * (`BUILTIN_DEFAULTS` from {@link ./defaults.ts}). Useful in test
477
+ * `afterEach` hooks and when you want to undo a previous `setDefaultTheme`.
478
+ */
479
+ declare function resetDefaultTheme(): void;
480
+
481
+ export { AggregatedSeries, Annotation, AnnotationBandConfig, AnySeries, type AxesConfig, type AxisLabelsStyle, type AxisStyle, DataPoint, type FillBetweenThresholdsInput, FillSpec, Gap, GapsConfig, type GridLineStyle, type GridStyle, HatchVariant, Highlight, type LegendOptions, type LegendPosition, MLTimeGraph, type MLTimeGraphOptions, type Margin, Marker, SVGRenderer, type Theme, Threshold, type TickConfig, TimeSeries, type TooltipOptions, type TooltipSample, type XAxisConfig, type YAxisConfig, attachTooltip, fillBetweenThresholds, getDefaultTheme, mount, parseAggregated, parseDataPoint, parseSeries, resetDefaultTheme, setDefaultTheme };