@malinconico/nmcharts 2.3.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.
- package/nmcharts-categories.js +5597 -0
- package/nmcharts-categories.min.js +1 -0
- package/nmcharts-extras.js +320 -0
- package/nmcharts-extras.min.js +1 -0
- package/nmcharts.d.ts +369 -0
- package/nmcharts.esm.js +14 -0
- package/nmcharts.js +1 -0
- package/package.json +69 -0
package/nmcharts.d.ts
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
// --- Shared interfaces ---
|
|
2
|
+
|
|
3
|
+
interface NMChartsSeries {
|
|
4
|
+
name: string;
|
|
5
|
+
data: [number, number][];
|
|
6
|
+
color?: string;
|
|
7
|
+
type?: 'area' | 'line';
|
|
8
|
+
dashStyle?: 'dashed' | 'dotted' | null;
|
|
9
|
+
lineWidth?: number;
|
|
10
|
+
/** Spline tension: 0 = straight, 1 = default smooth, >1 = extra smooth */
|
|
11
|
+
tension?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface NMChartsBand {
|
|
15
|
+
from: number;
|
|
16
|
+
to: number;
|
|
17
|
+
color: string;
|
|
18
|
+
label?: string;
|
|
19
|
+
labelColor?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface NMChartsToolbar {
|
|
23
|
+
dark?: boolean;
|
|
24
|
+
export?: boolean;
|
|
25
|
+
fullscreen?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface NMChartsOptions {
|
|
29
|
+
title?: string;
|
|
30
|
+
subtitle?: string;
|
|
31
|
+
series: NMChartsSeries[];
|
|
32
|
+
bands?: NMChartsBand[];
|
|
33
|
+
forecastFrom?: number;
|
|
34
|
+
toolbar?: NMChartsToolbar;
|
|
35
|
+
/** Apply a predefined theme palette: 'corporate' | 'pastel' | 'vibrant' | 'monochrome' | 'colorblind' */
|
|
36
|
+
theme?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface NMChartsInstance {
|
|
40
|
+
render(): void;
|
|
41
|
+
exportPNG(filename?: string): void;
|
|
42
|
+
/** Export chart as SVG file (raster image embedded in SVG wrapper) */
|
|
43
|
+
exportSVG(filename?: string): void;
|
|
44
|
+
setDarkMode(enabled: boolean): void;
|
|
45
|
+
updateSeries(series: NMChartsSeries[]): void;
|
|
46
|
+
destroy(): void;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// --- Category chart interfaces ---
|
|
50
|
+
|
|
51
|
+
interface NMCategorySeries {
|
|
52
|
+
name: string;
|
|
53
|
+
data: number[];
|
|
54
|
+
color?: string;
|
|
55
|
+
type?: string;
|
|
56
|
+
value?: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface NMCategoryOptions {
|
|
60
|
+
title?: string;
|
|
61
|
+
subtitle?: string;
|
|
62
|
+
categories?: string[];
|
|
63
|
+
series?: NMCategorySeries[];
|
|
64
|
+
height?: number;
|
|
65
|
+
toolbar?: NMChartsToolbar;
|
|
66
|
+
tooltip?: boolean;
|
|
67
|
+
responsive?: boolean;
|
|
68
|
+
gradient?: boolean;
|
|
69
|
+
gradientOpacity?: [number, number];
|
|
70
|
+
showValues?: boolean;
|
|
71
|
+
animDuration?: number;
|
|
72
|
+
legendPosition?: 'top' | 'bottom';
|
|
73
|
+
legendHidden?: boolean;
|
|
74
|
+
padding?: { top?: number; right?: number; bottom?: number; left?: number };
|
|
75
|
+
opacity?: number;
|
|
76
|
+
hoverOpacity?: number;
|
|
77
|
+
borderRadius?: number;
|
|
78
|
+
gridLines?: boolean;
|
|
79
|
+
gridColor?: string;
|
|
80
|
+
gridDashed?: boolean;
|
|
81
|
+
colors?: string[];
|
|
82
|
+
barWidth?: number;
|
|
83
|
+
barGap?: number;
|
|
84
|
+
groupPadding?: number;
|
|
85
|
+
borderWidth?: number;
|
|
86
|
+
borderColor?: string;
|
|
87
|
+
/** Apply a predefined theme palette */
|
|
88
|
+
theme?: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
interface NMDonutOptions {
|
|
92
|
+
title?: string;
|
|
93
|
+
segments: Array<{ label: string; value: number; color?: string }>;
|
|
94
|
+
innerRadius?: number;
|
|
95
|
+
padAngle?: number;
|
|
96
|
+
cornerRadius?: number;
|
|
97
|
+
centerLabel?: string;
|
|
98
|
+
centerSubLabel?: string;
|
|
99
|
+
hoverScale?: number;
|
|
100
|
+
strokeWidth?: number;
|
|
101
|
+
strokeColor?: string;
|
|
102
|
+
height?: number;
|
|
103
|
+
toolbar?: NMChartsToolbar;
|
|
104
|
+
theme?: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface NMGaugeOptions {
|
|
108
|
+
title?: string;
|
|
109
|
+
value: number;
|
|
110
|
+
min?: number;
|
|
111
|
+
max?: number;
|
|
112
|
+
unit?: string;
|
|
113
|
+
zones?: Array<{ from: number; to: number; color: string }>;
|
|
114
|
+
needleColor?: string;
|
|
115
|
+
needleWidth?: number;
|
|
116
|
+
arcWidth?: number;
|
|
117
|
+
showTicks?: boolean;
|
|
118
|
+
height?: number;
|
|
119
|
+
toolbar?: NMChartsToolbar;
|
|
120
|
+
theme?: string;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
interface NMRadarOptions {
|
|
124
|
+
title?: string;
|
|
125
|
+
categories: string[];
|
|
126
|
+
series: NMCategorySeries[];
|
|
127
|
+
max?: number;
|
|
128
|
+
levels?: number;
|
|
129
|
+
fillOpacity?: number;
|
|
130
|
+
lineWidth?: number;
|
|
131
|
+
dotRadius?: number;
|
|
132
|
+
showValues?: boolean;
|
|
133
|
+
gridStyle?: 'polygon' | 'circle';
|
|
134
|
+
axisLabels?: boolean;
|
|
135
|
+
height?: number;
|
|
136
|
+
toolbar?: NMChartsToolbar;
|
|
137
|
+
theme?: string;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
interface NMHeatmapOptions {
|
|
141
|
+
title?: string;
|
|
142
|
+
xLabels: string[];
|
|
143
|
+
yLabels: string[];
|
|
144
|
+
data: [number, number, number][];
|
|
145
|
+
colorRange?: [string, string];
|
|
146
|
+
showCellValues?: boolean;
|
|
147
|
+
cellRadius?: number;
|
|
148
|
+
cellGap?: number;
|
|
149
|
+
cellFontSize?: number;
|
|
150
|
+
height?: number;
|
|
151
|
+
toolbar?: NMChartsToolbar;
|
|
152
|
+
theme?: string;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
interface NMBulletOptions {
|
|
156
|
+
title?: string;
|
|
157
|
+
items: Array<{ label: string; actual: number; target: number; ranges: number[] }>;
|
|
158
|
+
rangeColors?: string[];
|
|
159
|
+
markerColor?: string;
|
|
160
|
+
barColor?: string;
|
|
161
|
+
barHeight?: number;
|
|
162
|
+
height?: number;
|
|
163
|
+
toolbar?: NMChartsToolbar;
|
|
164
|
+
theme?: string;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
interface NMTimelineOptions {
|
|
168
|
+
title?: string;
|
|
169
|
+
segments: Array<{ label: string; value: number; color?: string }>;
|
|
170
|
+
height?: number;
|
|
171
|
+
showPercent?: boolean;
|
|
172
|
+
showValues?: boolean;
|
|
173
|
+
rounded?: boolean;
|
|
174
|
+
gap?: number;
|
|
175
|
+
toolbar?: NMChartsToolbar;
|
|
176
|
+
theme?: string;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
interface NMWaterfallOptions {
|
|
180
|
+
title?: string;
|
|
181
|
+
categories: string[];
|
|
182
|
+
series: Array<{ data: number[] }>;
|
|
183
|
+
showTotal?: boolean;
|
|
184
|
+
showConnectors?: boolean;
|
|
185
|
+
positiveColor?: string;
|
|
186
|
+
negativeColor?: string;
|
|
187
|
+
totalColor?: string;
|
|
188
|
+
height?: number;
|
|
189
|
+
toolbar?: NMChartsToolbar;
|
|
190
|
+
theme?: string;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
interface NMTreemapOptions {
|
|
194
|
+
title?: string;
|
|
195
|
+
items: Array<{ label: string; value: number; color?: string; children?: any[] }>;
|
|
196
|
+
cellRadius?: number;
|
|
197
|
+
cellGap?: number;
|
|
198
|
+
showLabels?: boolean;
|
|
199
|
+
showValues?: boolean;
|
|
200
|
+
gradient?: boolean;
|
|
201
|
+
height?: number;
|
|
202
|
+
toolbar?: NMChartsToolbar;
|
|
203
|
+
theme?: string;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
interface NMFunnelOptions {
|
|
207
|
+
title?: string;
|
|
208
|
+
stages: Array<{ label: string; value: number; color?: string }>;
|
|
209
|
+
neckWidth?: number;
|
|
210
|
+
gap?: number;
|
|
211
|
+
showLabels?: boolean;
|
|
212
|
+
showValues?: boolean;
|
|
213
|
+
gradient?: boolean;
|
|
214
|
+
direction?: 'vertical' | 'horizontal';
|
|
215
|
+
height?: number;
|
|
216
|
+
toolbar?: NMChartsToolbar;
|
|
217
|
+
theme?: string;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
interface NMPolarOptions {
|
|
221
|
+
title?: string;
|
|
222
|
+
segments: Array<{ label: string; value: number; color?: string }>;
|
|
223
|
+
innerRadius?: number;
|
|
224
|
+
padAngle?: number;
|
|
225
|
+
showLabels?: boolean;
|
|
226
|
+
showValues?: boolean;
|
|
227
|
+
gradient?: boolean;
|
|
228
|
+
height?: number;
|
|
229
|
+
toolbar?: NMChartsToolbar;
|
|
230
|
+
theme?: string;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
interface NMScatterOptions {
|
|
234
|
+
title?: string;
|
|
235
|
+
series: Array<{ name: string; data: number[][]; color?: string }>;
|
|
236
|
+
bubbleMode?: boolean;
|
|
237
|
+
minRadius?: number;
|
|
238
|
+
maxRadius?: number;
|
|
239
|
+
xLabel?: string;
|
|
240
|
+
yLabel?: string;
|
|
241
|
+
gridLines?: boolean;
|
|
242
|
+
gridDashed?: boolean;
|
|
243
|
+
showValues?: boolean;
|
|
244
|
+
gradient?: boolean;
|
|
245
|
+
height?: number;
|
|
246
|
+
toolbar?: NMChartsToolbar;
|
|
247
|
+
legendHidden?: boolean;
|
|
248
|
+
legendPosition?: 'top' | 'bottom';
|
|
249
|
+
theme?: string;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
interface NMSankeyOptions {
|
|
253
|
+
title?: string;
|
|
254
|
+
nodes: Array<{ name: string; color?: string } | string>;
|
|
255
|
+
links: Array<{ source: number; target: number; value: number }>;
|
|
256
|
+
nodeWidth?: number;
|
|
257
|
+
nodePadding?: number;
|
|
258
|
+
showLabels?: boolean;
|
|
259
|
+
gradient?: boolean;
|
|
260
|
+
height?: number;
|
|
261
|
+
toolbar?: NMChartsToolbar;
|
|
262
|
+
theme?: string;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
interface NMBoxplotOptions {
|
|
266
|
+
title?: string;
|
|
267
|
+
categories: string[];
|
|
268
|
+
series: Array<{ data: Array<{ min: number; q1: number; median: number; q3: number; max: number; outliers?: number[] }> }>;
|
|
269
|
+
boxWidth?: number;
|
|
270
|
+
whiskerWidth?: number;
|
|
271
|
+
outlierRadius?: number;
|
|
272
|
+
showOutliers?: boolean;
|
|
273
|
+
gradient?: boolean;
|
|
274
|
+
gridLines?: boolean;
|
|
275
|
+
gridDashed?: boolean;
|
|
276
|
+
height?: number;
|
|
277
|
+
toolbar?: NMChartsToolbar;
|
|
278
|
+
theme?: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
interface NMCategoryInstance {
|
|
282
|
+
render(): void;
|
|
283
|
+
exportPNG(filename?: string): void;
|
|
284
|
+
exportSVG(filename?: string): void;
|
|
285
|
+
appendData(seriesIndex: number, dataPoint: any, opts?: { maxPoints?: number; category?: string }): NMCategoryInstance;
|
|
286
|
+
updateData(newSeries: Array<{ data?: any[]; color?: string; name?: string }>, newCategories?: string[]): NMCategoryInstance;
|
|
287
|
+
destroy(): void;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
interface NMSparklineOptions {
|
|
291
|
+
type?: 'line' | 'area' | 'bar';
|
|
292
|
+
color?: string;
|
|
293
|
+
fillColor?: string;
|
|
294
|
+
width?: number;
|
|
295
|
+
height?: number;
|
|
296
|
+
h?: number;
|
|
297
|
+
lineWidth?: number;
|
|
298
|
+
showLast?: boolean;
|
|
299
|
+
showMinMax?: boolean;
|
|
300
|
+
barGap?: number;
|
|
301
|
+
borderRadius?: number;
|
|
302
|
+
interactive?: boolean;
|
|
303
|
+
gradient?: boolean;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
interface NMSparklineInstance {
|
|
307
|
+
update(data: number[]): void;
|
|
308
|
+
destroy(): void;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
interface NMLinkOptions {}
|
|
312
|
+
|
|
313
|
+
interface NMLinkInstance {
|
|
314
|
+
destroy(): void;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// --- Theme definitions ---
|
|
318
|
+
|
|
319
|
+
interface NMChartsThemes {
|
|
320
|
+
corporate: string[];
|
|
321
|
+
pastel: string[];
|
|
322
|
+
vibrant: string[];
|
|
323
|
+
monochrome: string[];
|
|
324
|
+
colorblind: string[];
|
|
325
|
+
[key: string]: string[];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
interface NMChartsStatic {
|
|
329
|
+
create(selector: string | HTMLElement, options: NMChartsOptions): NMChartsInstance;
|
|
330
|
+
bar(selector: string | HTMLElement, options: NMCategoryOptions): NMCategoryInstance;
|
|
331
|
+
column(selector: string | HTMLElement, options: NMCategoryOptions): NMCategoryInstance;
|
|
332
|
+
barStacked(selector: string | HTMLElement, options: NMCategoryOptions): NMCategoryInstance;
|
|
333
|
+
lollipop(selector: string | HTMLElement, options: NMCategoryOptions): NMCategoryInstance;
|
|
334
|
+
combo(selector: string | HTMLElement, options: NMCategoryOptions): NMCategoryInstance;
|
|
335
|
+
donut(selector: string | HTMLElement, options: NMDonutOptions): NMCategoryInstance;
|
|
336
|
+
gauge(selector: string | HTMLElement, options: NMGaugeOptions): NMCategoryInstance;
|
|
337
|
+
heatmap(selector: string | HTMLElement, options: NMHeatmapOptions): NMCategoryInstance;
|
|
338
|
+
radar(selector: string | HTMLElement, options: NMRadarOptions): NMCategoryInstance;
|
|
339
|
+
lineBar(selector: string | HTMLElement, options: NMCategoryOptions): NMCategoryInstance;
|
|
340
|
+
waterfall(selector: string | HTMLElement, options: NMWaterfallOptions): NMCategoryInstance;
|
|
341
|
+
bullet(selector: string | HTMLElement, options: NMBulletOptions): NMCategoryInstance;
|
|
342
|
+
timeline(selector: string | HTMLElement, options: NMTimelineOptions): NMCategoryInstance;
|
|
343
|
+
treemap(selector: string | HTMLElement, options: NMTreemapOptions): NMCategoryInstance;
|
|
344
|
+
funnel(selector: string | HTMLElement, options: NMFunnelOptions): NMCategoryInstance;
|
|
345
|
+
polar(selector: string | HTMLElement, options: NMPolarOptions): NMCategoryInstance;
|
|
346
|
+
scatter(selector: string | HTMLElement, options: NMScatterOptions): NMCategoryInstance;
|
|
347
|
+
sankey(selector: string | HTMLElement, options: NMSankeyOptions): NMCategoryInstance;
|
|
348
|
+
boxplot(selector: string | HTMLElement, options: NMBoxplotOptions): NMCategoryInstance;
|
|
349
|
+
sparkline(selector: string | HTMLElement, data: number[], options?: NMSparklineOptions): NMSparklineInstance;
|
|
350
|
+
link(charts: NMCategoryInstance[], options?: NMLinkOptions): NMLinkInstance;
|
|
351
|
+
lttb(data: any[], threshold: number): any[];
|
|
352
|
+
themes: NMChartsThemes;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// --- Global declaration (for angular.json "scripts" usage) ---
|
|
356
|
+
declare var NMCharts: NMChartsStatic;
|
|
357
|
+
|
|
358
|
+
// --- ES Module export ---
|
|
359
|
+
export {
|
|
360
|
+
NMChartsSeries, NMChartsBand, NMChartsToolbar, NMChartsOptions,
|
|
361
|
+
NMChartsInstance, NMChartsStatic, NMCharts,
|
|
362
|
+
NMCategorySeries, NMCategoryOptions, NMCategoryInstance,
|
|
363
|
+
NMDonutOptions, NMGaugeOptions, NMRadarOptions, NMHeatmapOptions,
|
|
364
|
+
NMBulletOptions, NMTimelineOptions, NMWaterfallOptions,
|
|
365
|
+
NMTreemapOptions, NMFunnelOptions, NMPolarOptions,
|
|
366
|
+
NMScatterOptions, NMSankeyOptions, NMBoxplotOptions,
|
|
367
|
+
NMChartsThemes
|
|
368
|
+
};
|
|
369
|
+
export default NMCharts;
|
package/nmcharts.esm.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NM Charts — ES Module
|
|
3
|
+
* Zero-dependency Canvas charting library
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* import { NMCharts } from './nmcharts.esm';
|
|
7
|
+
* const chart = NMCharts.create('#container', { ... });
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var NMCharts;!function(){"use strict";var e=!1,i=[":root{","--mc-bg:#f5f7fa;--mc-card:#fff;--mc-text:#1e293b;--mc-text2:#475569;--mc-muted:#94a3b8;","--mc-grid:#e2e8f0;--mc-border:#e2e8f0;--mc-hover:rgba(0,0,0,.04);","--mc-tt-bg:#1e293b;--mc-tt-fg:#fff;","--mc-sel:rgba(79,70,229,.1);--mc-sel-b:rgba(79,70,229,.3);","--mc-btn:#4f46e5;--mc-btn-h:#4338ca;--mc-mask:rgba(148,163,184,.18);","}",".mc-dark{","--mc-bg:#0f172a;--mc-card:#1e293b;--mc-text:#f1f5f9;--mc-text2:#cbd5e1;--mc-muted:#64748b;","--mc-grid:#334155;--mc-border:#334155;--mc-hover:rgba(255,255,255,.05);","--mc-tt-bg:#0f172a;--mc-tt-fg:#f1f5f9;","--mc-sel:rgba(129,120,255,.15);--mc-sel-b:rgba(129,120,255,.35);","--mc-btn:#6366f1;--mc-btn-h:#818cf8;--mc-mask:rgba(100,116,139,.3);","}",'.mc-root{position:relative;background:var(--mc-card);border-radius:12px;box-shadow:0 2px 16px rgba(0,0,0,.08);padding:20px 20px 14px;user-select:none;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;color:var(--mc-text);transition:background .3s,box-shadow .3s}',".mc-dark .mc-root{box-shadow:0 2px 24px rgba(0,0,0,.3)}",".mc-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}",".mc-titles{text-align:center;flex:1}",".mc-title{font-size:18px;font-weight:600}",".mc-subtitle{font-size:12px;color:var(--mc-muted);margin-top:2px}",".mc-toolbar{display:flex;gap:4px;flex-shrink:0}",".mc-toolbar button{width:32px;height:32px;border:1px solid var(--mc-border);border-radius:6px;background:transparent;color:var(--mc-text2);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s,border-color .15s}",".mc-toolbar button:hover{background:var(--mc-hover)}",".mc-toolbar button.active{background:var(--mc-btn);color:#fff;border-color:var(--mc-btn)}",".mc-toolbar button svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}",".mc-wrap{position:relative;width:100%}",".mc-wrap canvas{display:block;width:100%}",".mc-legend{display:flex;justify-content:center;gap:20px;margin-top:8px;flex-wrap:wrap}",".mc-legend-item{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--mc-text2);cursor:pointer;padding:2px 6px;border-radius:4px;transition:background .15s}",".mc-legend-item:hover{background:var(--mc-hover)}",".mc-legend-swatch{width:14px;height:3px;border-radius:2px}",".mc-legend-item.disabled .mc-legend-swatch{opacity:.25}",".mc-legend-item.disabled span:last-child{text-decoration:line-through;opacity:.4}",".mc-tooltip{position:absolute;pointer-events:none;opacity:0;background:var(--mc-tt-bg);color:var(--mc-tt-fg);border-radius:8px;padding:10px 14px;font-size:12px;line-height:1.6;white-space:nowrap;box-shadow:0 4px 12px rgba(0,0,0,.2);transition:opacity .1s;z-index:10}",".mc-tooltip.visible{opacity:1}",".mc-tooltip-date{font-weight:600;margin-bottom:2px}",".mc-tooltip-row{display:flex;align-items:center;gap:6px}",".mc-tooltip-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}",".mc-tooltip-val{margin-left:auto;padding-left:12px;font-weight:600}",".mc-selection{position:absolute;top:0;height:100%;background:var(--mc-sel);border-left:1px solid var(--mc-sel-b);border-right:1px solid var(--mc-sel-b);pointer-events:none;display:none}",".mc-reset{position:absolute;top:8px;right:8px;background:var(--mc-btn);color:#fff;border:none;border-radius:6px;padding:4px 10px;font-size:11px;font-weight:500;cursor:pointer;opacity:0;pointer-events:none;transition:opacity .2s}",".mc-reset.visible{opacity:1;pointer-events:auto}",".mc-reset:hover{background:var(--mc-btn-h)}",".mc-nav{position:relative;width:100%;height:48px;margin-top:6px;border-top:1px solid var(--mc-border)}",".mc-nav canvas{display:block;width:100%;height:48px}",".mc-nav-mask{position:absolute;top:0;height:100%;background:var(--mc-mask);pointer-events:none}",".mc-nav-mask.left{left:0}",".mc-nav-mask.right{right:0}",".mc-nav-win{position:absolute;top:0;height:100%;border-left:2px solid var(--mc-btn);border-right:2px solid var(--mc-btn);cursor:grab;z-index:2}",".mc-nav-h{position:absolute;top:50%;transform:translateY(-50%);width:6px;height:20px;background:var(--mc-btn);border-radius:3px;cursor:ew-resize;z-index:3}",".mc-nav-h.l{left:-4px}",".mc-nav-h.r{right:-4px}",".mc-root:fullscreen,.mc-root:-webkit-full-screen{display:flex;flex-direction:column;justify-content:center;max-width:100%;width:100%;border-radius:0}"].join("\n"),n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],a=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];function o(t,e,i){return t+(e-t)*i}function r(t,e,i){return Math.max(e,Math.min(i,t))}function s(t,e){var i=Math.floor(Math.log10(t)),n=t/Math.pow(10,i);return(e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10)*Math.pow(10,i)}function l(t){return Math.abs(t)>=1e3?t.toLocaleString("en-US",{maximumFractionDigits:1}):t===Math.floor(t)?t.toString():t.toFixed(1)}function c(t,e,i,_t){var T=typeof _t==="number"?_t:1;var n=e.length;if(!(n<2))if(i||t.moveTo(e[0][0],e[0][1]),2!==n){if(T<=0){for(var j=1;j<n;j++)t.lineTo(e[j][0],e[j][1]);return}for(var a=[],o=[],r=[],s=0;s<n-1;s++)a[s]=e[s+1][0]-e[s][0],o[s]=e[s+1][1]-e[s][1],r[s]=0===a[s]?0:o[s]/a[s];var l=[r[0]];for(s=1;s<n-1;s++)l[s]=r[s-1]*r[s]<=0?0:(r[s-1]+r[s])/2;for(l[n-1]=r[n-2],s=0;s<n-1;s++)if(Math.abs(r[s])<1e-10)l[s]=0,l[s+1]=0;else{var c=l[s]/r[s],d=l[s+1]/r[s],h=c*c+d*d;if(h>9){var p=3/Math.sqrt(h);l[s]=p*c*r[s],l[s+1]=p*d*r[s]}}for(s=0;s<n-1;s++){var v=a[s]*T/3;t.bezierCurveTo(e[s][0]+v,e[s][1]+l[s]*v,e[s+1][0]-v,e[s+1][1]-l[s+1]*v,e[s+1][0],e[s+1][1])}}else t.lineTo(e[1][0],e[1][1])}function d(t,e){return"rgba("+parseInt(t.slice(1,3),16)+","+parseInt(t.slice(3,5),16)+","+parseInt(t.slice(5,7),16)+","+e+")"}function h(t){return getComputedStyle(document.documentElement).getPropertyValue("--mc-"+t).trim()}function p(t,e,i){var n=document.createElement(t);return e&&(n.className=e),i&&i.appendChild(n),n}function v(t,n){if(function(){if(!e){e=!0;var t=document.createElement("style");t.textContent=i,document.head.appendChild(t)}}(),n=n||{},this.el="string"==typeof t?document.querySelector(t):t,!this.el)throw new Error("NMCharts: container not found");this.opts=n,this.bands=n.bands||[],this.forecastFrom=n.forecastFrom||null;var a=n.toolbar||{};this.series=(n.series||[]).map(function(t){return{name:t.name,data:t.data.slice().sort(function(t,e){return t[0]-e[0]}),color:t.color,type:t.type||"area",dashStyle:t.dashStyle||null,lineWidth:t.lineWidth||2.5,tension:typeof t.tension==="number"?t.tension:1,visible:!0}}),this._buildDOM(n,a),this._computeFullBounds(),this.viewXMin=this.fullXMin,this.viewXMax=this.fullXMax,this._dragStart=null,this._dragging=!1,this._panning=!1,this._panAnchorX=0,this._panViewStart=0,this._panViewEnd=0,this._hoverIdx=-1,this._zoomed=!1,this._entryProgress=0,this._entryStart=performance.now(),this._initSize(),this._buildLegend(),this._bindEvents(),this._bindNavigator(),this._startEntryAnim()}v.prototype._buildDOM=function(t,e){var i=p("div","mc-root",this.el);this._root=i;var n=p("div","mc-header",i);p("div","",n).style.width="120px";var a=p("div","mc-titles",n);p("div","mc-title",a).textContent=t.title||"",p("div","mc-subtitle",a).innerHTML=t.subtitle||"Drag to zoom · Shift+drag to pan · Scroll to zoom · Double-click to reset";var o=p("div","mc-toolbar",n),r=this;if(!1!==e.dark){var s=p("button","",o);s.title="Dark mode",s.innerHTML='<svg viewBox="0 0 24 24"><path d="M21 12.79A9 9 0 0 1 11.21 3a7 7 0 1 0 9.79 9.79z"/></svg>',s.addEventListener("click",function(){r.el.classList.toggle("mc-dark"),s.classList.toggle("active"),r.render(),r._renderNav()})}if(!1!==e.export){var l=p("button","",o);l.title="Export PNG",l.innerHTML='<svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>',l.addEventListener("click",function(){r.exportPNG()})}if(!1!==e.fullscreen){var c=p("button","",o);c.title="Fullscreen",c.innerHTML='<svg viewBox="0 0 24 24"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>',c.addEventListener("click",function(){document.fullscreenElement?(document.exitFullscreen||document.webkitExitFullscreen).call(document):(i.requestFullscreen||i.webkitRequestFullscreen).call(i)}),["fullscreenchange","webkitfullscreenchange"].forEach(function(t){document.addEventListener(t,function(){setTimeout(function(){r._initSize(),r.render(),r._renderNav()},100)})})}var d=p("div","mc-wrap",i);this._wrap=d,this.canvas=p("canvas","",d),this.ctx=this.canvas.getContext("2d"),this._tooltipEl=p("div","mc-tooltip",d),this._selEl=p("div","mc-selection",d),this._resetBtn=p("button","mc-reset",d),this._resetBtn.textContent="Reset zoom";var h=p("div","mc-nav",i);this._navWrap=h,this._navCanvas=p("canvas","",h),this._navCtx=this._navCanvas.getContext("2d"),this._navMaskL=p("div","mc-nav-mask left",h),this._navMaskR=p("div","mc-nav-mask right",h);var v=p("div","mc-nav-win",h);this._navWin=v,this._navHL=p("div","mc-nav-h l",v),this._navHR=p("div","mc-nav-h r",v),this._legendEl=p("div","mc-legend",i)},v.prototype._computeFullBounds=function(){for(var t=1/0,e=-1/0,i=0;i<this.series.length;i++){var n=this.series[i].data;n.length&&(t=Math.min(t,n[0][0]),e=Math.max(e,n[n.length-1][0]))}this.fullXMin=t,this.fullXMax=e},v.prototype._initSize=function(){var t=window.devicePixelRatio||1,e=this._wrap.getBoundingClientRect().width,i=Math.round(.42*e);this.canvas.width=e*t,this.canvas.height=i*t,this.canvas.style.height=i+"px",this.ctx.setTransform(t,0,0,t,0,0),this.W=e,this.H=i,this.pX=58,this.pY=24,this.pW=e-58-24,this.pH=i-24-44;var n=this._navWrap.getBoundingClientRect().width;this._navCanvas.width=n*t,this._navCanvas.height=48*t,this._navCtx.setTransform(t,0,0,t,0,0),this._nW=n,this._nH=48},v.prototype._buildLegend=function(){var t=this;this._legendEl.innerHTML="",this.series.forEach(function(e){var i=p("div","mc-legend-item"+(e.visible?"":" disabled"),t._legendEl),n="line"===e.type?"background:transparent;border-top:2.5px "+("dashed"===e.dashStyle?"dashed":"dotted"===e.dashStyle?"dotted":"solid")+" "+e.color+";height:0;margin-top:1px":"background:"+e.color;i.innerHTML='<div class="mc-legend-swatch" style="'+n+'"></div><span>'+e.name+"</span>",i.addEventListener("click",function(){e.visible=!e.visible,i.classList.toggle("disabled",!e.visible),t.render(),t._renderNav()})})},v.prototype._x2px=function(t){return this.pX+(t-this.viewXMin)/(this.viewXMax-this.viewXMin)*this.pW},v.prototype._y2px=function(t,e){return this.pY+this.pH-(t-e.min)/(e.max-e.min)*this.pH},v.prototype._px2x=function(t){return this.viewXMin+(t-this.pX)/this.pW*(this.viewXMax-this.viewXMin)},v.prototype._yScale=function(){for(var t=1/0,e=-1/0,i=0;i<this.series.length;i++)if(this.series[i].visible)for(var n=this.series[i].data,a=0;a<n.length;a++)n[a][0]>=this.viewXMin&&n[a][0]<=this.viewXMax&&(t=Math.min(t,n[a][1]),e=Math.max(e,n[a][1]));return t===1/0&&(t=0,e=100),function(t,e){t===e&&(t-=1,e+=1);for(var i=s(e-t,!1),n=s(i/5,!0),a=Math.floor(t/n)*n,o=Math.ceil(e/n)*n,r=[],l=a;l<=o+.5*n;l+=n)r.push(Math.round(1e10*l)/1e10);return{min:a,max:o,step:n,ticks:r}}(t=Math.min(0,t),e)},v.prototype._startEntryAnim=function(){var t=this,e=performance.now();!function i(n){var a=r((n-e)/800,0,1);t._entryProgress=1-Math.pow(1-a,3),t.render(),t._renderNav(),a<1&&requestAnimationFrame(i)}(e)},v.prototype.render=function(){var t=this.ctx,e=this._yScale(),i=this,a=h("grid"),o=h("muted"),s='11px -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif';t.clearRect(0,0,this.W,this.H),this.bands.forEach(function(n){var a=i._y2px(Math.min(n.to,e.max),e),o=i._y2px(Math.max(n.from,e.min),e);o<=i.pY||a>=i.pY+i.pH||(a=r(a,i.pY,i.pY+i.pH),o=r(o,i.pY,i.pY+i.pH),t.fillStyle=n.color,t.fillRect(i.pX,a,i.pW,o-a),n.label&&(t.save(),t.font="9px "+s,t.fillStyle=n.labelColor||n.color,t.textAlign="right",t.textBaseline="top",t.globalAlpha=.7,t.fillText(n.label,i.pX+i.pW-4,a+2),t.restore()))}),t.save(),t.font=s,t.textAlign="right",t.textBaseline="middle",e.ticks.forEach(function(n){var r=i._y2px(n,e);t.strokeStyle=a,t.lineWidth=1,t.beginPath(),t.moveTo(i.pX,Math.round(r)+.5),t.lineTo(i.pX+i.pW,Math.round(r)+.5),t.stroke(),t.fillStyle=o,t.fillText(l(n),i.pX-8,r)}),t.restore();var p=function(t,e,i){for(var n=e-t,a=864e5,o=[a,2*a,5*a,7*a,14*a,30*a,60*a,90*a,180*a,365*a],r=a,s=0;s<o.length;s++)if(n/o[s]<=i){r=o[s];break}for(var l=[],c=Math.ceil(t/r)*r;c<=e;c+=r)l.push(c);return l}(this.viewXMin,this.viewXMax,Math.floor(this.pW/80));t.save(),t.font=s,t.textAlign="center",t.textBaseline="top",t.fillStyle=o,p.forEach(function(e){var o=i._x2px(e);o>=i.pX&&o<=i.pX+i.pW&&(t.strokeStyle=a,t.beginPath(),t.moveTo(Math.round(o)+.5,i.pY+i.pH),t.lineTo(Math.round(o)+.5,i.pY+i.pH+5),t.stroke(),t.fillText(function(t){var e=new Date(t);return e.getUTCDate()+" "+n[e.getUTCMonth()]}(e),o,i.pY+i.pH+8))}),t.restore(),t.strokeStyle=a,t.lineWidth=1,t.beginPath(),t.moveTo(this.pX,this.pY),t.lineTo(this.pX,this.pY+this.pH),t.lineTo(this.pX+this.pW,this.pY+this.pH),t.stroke(),t.save(),t.beginPath(),t.rect(this.pX,this.pY,this.pW,this.pH),t.clip();var v=this.pW*this._entryProgress;if(this.series.forEach(function(n){if(n.visible){for(var a=[],o=.05*(i.viewXMax-i.viewXMin),r=0;r<n.data.length;r++){var s=n.data[r][0],l=n.data[r][1];s<i.viewXMin-o||s>i.viewXMax+o||a.push([i._x2px(s),i._y2px(l,e),s])}if(!(a.length<2)){var h=i._y2px(e.min,e);t.save(),t.beginPath(),t.rect(i.pX,i.pY,v,i.pH),t.clip();var p=a,u=null;if(i.forecastFrom){p=[],u=[];for(var f=0;f<a.length;f++)a[f][2]<i.forecastFrom?p.push(a[f]):u.push(a[f]);p.length&&u.length&&u.unshift(p[p.length-1])}var m="line"===n.type,g="dashed"===n.dashStyle?[6,4]:"dotted"===n.dashStyle?[2,3]:null;x(p,!1),u&&u.length>=2&&x(u,!0),t.restore()}}function x(e,a){if(!(e.length<2)){if(!m){var o=t.createLinearGradient(0,i.pY,0,h);o.addColorStop(0,d(n.color,.22)),o.addColorStop(1,d(n.color,.02)),t.beginPath(),t.moveTo(e[0][0],h),t.lineTo(e[0][0],e[0][1]),c(t,e,!0,n.tension),t.lineTo(e[e.length-1][0],h),t.closePath(),t.fillStyle=o,t.fill()}var r=a?[6,4]:g;r&&t.setLineDash(r),t.beginPath(),c(t,e,!1,n.tension),t.strokeStyle=n.color,t.lineWidth=n.lineWidth,t.lineJoin="round",t.lineCap="round",t.stroke(),r&&t.setLineDash([])}}}),this._hoverIdx>=0&&this._entryProgress>=1){var u=null;this.series.forEach(function(n){if(n.visible&&!(i._hoverIdx>=n.data.length)){var a=n.data[i._hoverIdx],o=i._x2px(a[0]),r=i._y2px(a[1],e);u=o,t.beginPath(),t.arc(o,r,5,0,2*Math.PI),t.fillStyle=h("card"),t.fill(),t.strokeStyle=n.color,t.lineWidth=2.5,t.stroke()}}),null!==u&&(t.strokeStyle=d(o,.4),t.lineWidth=1,t.setLineDash([4,3]),t.beginPath(),t.moveTo(Math.round(u)+.5,i.pY),t.lineTo(Math.round(u)+.5,i.pY+i.pH),t.stroke(),t.setLineDash([]))}t.restore()},v.prototype._renderNav=function(){var t=this._navCtx,e=this._nW,i=this._nH,n=this,a=e-2-2,o=i-4-4;t.clearRect(0,0,e,i);var r=1/0,s=-1/0;this.series.forEach(function(t){t.visible&&t.data.forEach(function(t){r=Math.min(r,t[1]),s=Math.max(s,t[1])})}),r===1/0&&(r=0,s=100),r=Math.min(0,r);var l=4+o;this.series.forEach(function(e){if(e.visible){var i=e.data.map(function(t){return[2+(t[0]-n.fullXMin)/(n.fullXMax-n.fullXMin)*a,4+o-(t[1]-r)/(s-r)*o]});if(!(i.length<2)){if("line"!==e.type){var h=t.createLinearGradient(0,4,0,l);h.addColorStop(0,d(e.color,.18)),h.addColorStop(1,d(e.color,.02)),t.beginPath(),t.moveTo(i[0][0],l),t.lineTo(i[0][0],i[0][1]),c(t,i,!0,e.tension),t.lineTo(i[i.length-1][0],l),t.closePath(),t.fillStyle=h,t.fill()}var p="dashed"===e.dashStyle?[4,3]:"dotted"===e.dashStyle?[2,2]:null;p&&t.setLineDash(p),t.beginPath(),c(t,i,!1,e.tension),t.strokeStyle=d(e.color,.6),t.lineWidth=1.2,t.stroke(),p&&t.setLineDash([])}}});var h=(this.viewXMin-this.fullXMin)/(this.fullXMax-this.fullXMin)*100,p=(this.fullXMax-this.viewXMax)/(this.fullXMax-this.fullXMin)*100;this._navWin.style.left=h+"%",this._navWin.style.right=p+"%",this._navMaskL.style.width=h+"%",this._navMaskR.style.width=p+"%"},v.prototype._bindNavigator=function(){var t,e,i,n=this,a=null;function o(o,r){o.preventDefault(),o.stopPropagation(),a=r,t=o.clientX,e=n.viewXMin,i=n.viewXMax,document.addEventListener("mousemove",s),document.addEventListener("mouseup",l)}function s(o){var s=n._navWrap.getBoundingClientRect(),l=(o.clientX-t)/s.width*(n.fullXMax-n.fullXMin),c=1728e5;if("move"===a){var d=e+l,h=i+l;d<n.fullXMin&&(h+=n.fullXMin-d,d=n.fullXMin),h>n.fullXMax&&(d-=h-n.fullXMax,h=n.fullXMax),n.viewXMin=d,n.viewXMax=h}else"left"===a?n.viewXMin=r(e+l,n.fullXMin,n.viewXMax-c):n.viewXMax=r(i+l,n.viewXMin+c,n.fullXMax);n._zoomed=n.viewXMin>n.fullXMin||n.viewXMax<n.fullXMax,n._resetBtn.classList.toggle("visible",n._zoomed),n.render(),n._renderNav()}function l(){a=null,document.removeEventListener("mousemove",s),document.removeEventListener("mouseup",l)}this._navWin.addEventListener("mousedown",function(t){o(t,"move")}),this._navHL.addEventListener("mousedown",function(t){o(t,"left")}),this._navHR.addEventListener("mousedown",function(t){o(t,"right")}),this._navWrap.addEventListener("mousedown",function(t){if(t.target===n._navCanvas){var e=n._navWrap.getBoundingClientRect(),i=n.fullXMin+(t.clientX-e.left)/e.width*(n.fullXMax-n.fullXMin),a=n.viewXMax-n.viewXMin,o=i-a/2,r=i+a/2;o<n.fullXMin&&(r+=n.fullXMin-o,o=n.fullXMin),r>n.fullXMax&&(o-=r-n.fullXMax,r=n.fullXMax),n._zoomed=!0,n._resetBtn.classList.add("visible"),n._animateTo(o,r)}})},v.prototype._animateTo=function(t,e){var i={a:this.viewXMin,b:this.viewXMax},n=this,a=performance.now();!function s(l){var c=r((l-a)/400,0,1),d=1-Math.pow(1-c,3);n.viewXMin=o(i.a,t,d),n.viewXMax=o(i.b,e,d),n.render(),n._renderNav(),c<1&&requestAnimationFrame(s)}(a)},v.prototype._bindEvents=function(){var t,e=this,i=this.canvas;function n(t){var e=i.getBoundingClientRect();return{x:t.clientX-e.left,y:t.clientY-e.top}}function a(t){return t.x>=e.pX&&t.x<=e.pX+e.pW&&t.y>=e.pY&&t.y<=e.pY+e.pH}window.addEventListener("resize",function(){clearTimeout(t),t=setTimeout(function(){e._initSize(),e.render(),e._renderNav()},80)}),i.addEventListener("mousedown",function(t){var o=n(t);a(o)&&(t.shiftKey&&e._zoomed?(e._panning=!0,e._panAnchorX=o.x,e._panViewStart=e.viewXMin,e._panViewEnd=e.viewXMax,i.style.cursor="grabbing"):(e._dragStart=o.x,e._dragging=!0,e._selEl.style.display="block",e._selEl.style.left=o.x+"px",e._selEl.style.width="0px"))}),i.addEventListener("mousemove",function(t){var o=n(t);if(e._panning){var s=o.x-e._panAnchorX,l=e._panViewEnd-e._panViewStart,c=-s/e.pW*l,d=e._panViewStart+c,h=e._panViewEnd+c;return d<e.fullXMin&&(h+=e.fullXMin-d,d=e.fullXMin),h>e.fullXMax&&(d-=h-e.fullXMax,h=e.fullXMax),e.viewXMin=d,e.viewXMax=h,e.render(),void e._renderNav()}if(e._dragging){var p=Math.min(e._dragStart,o.x),v=Math.abs(o.x-e._dragStart);p=r(p,e.pX,e.pX+e.pW);var u=r(p+v,e.pX,e.pX+e.pW);return e._selEl.style.left=p+"px",void(e._selEl.style.width=u-p+"px")}if(a(o)){i.style.cursor=t.shiftKey&&e._zoomed?"grab":"crosshair";var f=function(t){for(var i=e._px2x(t),n=null,a=0;a<e.series.length;a++)if(e.series[a].visible){n=e.series[a].data;break}if(!n||!n.length)return-1;for(var o=0,r=1/0,s=0;s<n.length;s++){var l=Math.abs(n[s][0]-i);l<r&&(r=l,o=s)}return o}(o.x);f!==e._hoverIdx&&(e._hoverIdx=f,e.render()),e._showTooltip(o,f)}else e._hideTooltip()}),window.addEventListener("mouseup",function(){if(e._panning)return e._panning=!1,void(i.style.cursor="crosshair");if(e._dragging){e._dragging=!1,e._selEl.style.display="none";var t=parseFloat(e._selEl.style.width);if(t<10)e._dragStart=null;else{var n=parseFloat(e._selEl.style.left);e._zoomed=!0,e._resetBtn.classList.add("visible"),e._animateTo(e._px2x(n),e._px2x(n+t)),e._dragStart=null}}}),i.addEventListener("mouseleave",function(){e._hideTooltip()}),i.addEventListener("dblclick",function(t){t.preventDefault(),e._zoomed&&(e._zoomed=!1,e._resetBtn.classList.remove("visible"),e._animateTo(e.fullXMin,e.fullXMax))}),i.addEventListener("wheel",function(t){var i=n(t);if(a(i)){t.preventDefault();var o=t.deltaY>0?1.15:1/1.15,r=e._px2x(i.x),s=e.viewXMax-e.viewXMin,l=s*o;if(!(l<1728e5)){var c=(r-e.viewXMin)/s,d=Math.max(r-c*l,e.fullXMin),h=Math.min(r+(1-c)*l,e.fullXMax);e.viewXMin=d,e.viewXMax=h,e._zoomed=d>e.fullXMin||h<e.fullXMax,e._resetBtn.classList.toggle("visible",e._zoomed),e.render(),e._renderNav()}}},{passive:!1}),this._resetBtn.addEventListener("click",function(){e._zoomed=!1,e._resetBtn.classList.remove("visible"),e._animateTo(e.fullXMin,e.fullXMax)}),document.addEventListener("keydown",function(t){if("INPUT"!==t.target.tagName&&"TEXTAREA"!==t.target.tagName){var i=e.viewXMax-e.viewXMin,n=.15*i;if("ArrowLeft"===t.key){var a=Math.max(e.viewXMin-n,e.fullXMin);e._animateTo(a,a+i)}else if("ArrowRight"===t.key){var o=Math.min(e.viewXMax+n,e.fullXMax);e._animateTo(o-i,o)}else if("+"===t.key||"="===t.key){var r=.7*i,s=(e.viewXMin+e.viewXMax)/2;e._zoomed=!0,e._resetBtn.classList.add("visible"),e._animateTo(s-r/2,s+r/2)}else if("-"===t.key){var l=Math.min(1.4*i,e.fullXMax-e.fullXMin),c=(e.viewXMin+e.viewXMax)/2,d=Math.max(c-l/2,e.fullXMin),h=Math.min(c+l/2,e.fullXMax);e._zoomed=d>e.fullXMin||h<e.fullXMax,e._resetBtn.classList.toggle("visible",e._zoomed),e._animateTo(d,h)}else"Escape"===t.key&&e._zoomed&&(e._zoomed=!1,e._resetBtn.classList.remove("visible"),e._animateTo(e.fullXMin,e.fullXMax))}});var o=null;i.addEventListener("touchstart",function(t){1===t.touches.length?(e._panning=!0,e._panAnchorX=t.touches[0].clientX-i.getBoundingClientRect().left,e._panViewStart=e.viewXMin,e._panViewEnd=e.viewXMax):2===t.touches.length&&(e._panning=!1,o=Math.abs(t.touches[1].clientX-t.touches[0].clientX)),t.preventDefault()},{passive:!1}),i.addEventListener("touchmove",function(t){if(1===t.touches.length&&e._panning){var n=t.touches[0].clientX-i.getBoundingClientRect().left-e._panAnchorX,a=e._panViewEnd-e._panViewStart,r=-n/e.pW*a,s=e._panViewStart+r,l=e._panViewEnd+r;s<e.fullXMin&&(l+=e.fullXMin-s,s=e.fullXMin),l>e.fullXMax&&(s-=l-e.fullXMax,l=e.fullXMax),e.viewXMin=s,e.viewXMax=l,e.render(),e._renderNav()}else if(2===t.touches.length&&o){var c=Math.abs(t.touches[1].clientX-t.touches[0].clientX),d=o/c,h=(t.touches[0].clientX+t.touches[1].clientX)/2-i.getBoundingClientRect().left,p=e._px2x(h),v=e.viewXMax-e.viewXMin,u=v*d;if(u<1728e5)return void t.preventDefault();var f=(p-e.viewXMin)/v;e.viewXMin=Math.max(p-f*u,e.fullXMin),e.viewXMax=Math.min(p+(1-f)*u,e.fullXMax),e._zoomed=!0,e._resetBtn.classList.add("visible"),o=c,e.render(),e._renderNav()}t.preventDefault()},{passive:!1}),i.addEventListener("touchend",function(){e._panning=!1,o=null})},v.prototype._showTooltip=function(t,e){if(e<0)this._hideTooltip();else{var i="",o=null;if(this.series.forEach(function(t){!t.visible||e>=t.data.length||(o||(o=t.data[e][0]),i+='<div class="mc-tooltip-row"><div class="mc-tooltip-dot" style="background:'+t.color+'"></div><span>'+t.name+'</span><span class="mc-tooltip-val">'+l(t.data[e][1])+"</span></div>")}),o){i='<div class="mc-tooltip-date">'+function(t){var e=new Date(t);return a[e.getUTCDay()]+", "+n[e.getUTCMonth()]+" "+e.getUTCDate()+", "+e.getUTCFullYear()}(o)+"</div>"+i,this._tooltipEl.innerHTML=i,this._tooltipEl.classList.add("visible");var s=this._tooltipEl.offsetWidth,c=this._tooltipEl.offsetHeight,d=t.x+16,h=t.y-c/2;d+s>this.W-8&&(d=t.x-s-16),h=r(h,4,this.H-c-4),this._tooltipEl.style.left=d+"px",this._tooltipEl.style.top=h+"px"}else this._hideTooltip()}},v.prototype._hideTooltip=function(){this._tooltipEl.classList.remove("visible"),this._hoverIdx>=0&&(this._hoverIdx=-1,this.render())},v.prototype.exportPNG=function(t){var e=document.createElement("a");e.download=t||"chart.png",e.href=this.canvas.toDataURL("image/png"),e.click()},v.prototype.setDarkMode=function(t){this.el.classList.toggle("mc-dark",t),this.render(),this._renderNav()},v.prototype.updateSeries=function(t){this.series=t.map(function(t){return{name:t.name,data:t.data.slice().sort(function(t,e){return t[0]-e[0]}),color:t.color,type:t.type||"area",dashStyle:t.dashStyle||null,lineWidth:t.lineWidth||2.5,tension:typeof t.tension==="number"?t.tension:1,visible:!0}}),this._computeFullBounds(),this.viewXMin=this.fullXMin,this.viewXMax=this.fullXMax,this._zoomed=!1,this._resetBtn.classList.remove("visible"),this._buildLegend(),this.render(),this._renderNav()},v.prototype.destroy=function(){this._root.remove()},v.create=function(t,e){return new v(t,e)}
|
|
11
|
+
;NMCharts=v}();
|
|
12
|
+
|
|
13
|
+
export { NMCharts };
|
|
14
|
+
export default NMCharts;
|
package/nmcharts.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(t){"use strict";var e=!1,i=[":root{","--mc-bg:#f5f7fa;--mc-card:#fff;--mc-text:#1e293b;--mc-text2:#475569;--mc-muted:#94a3b8;","--mc-grid:#e2e8f0;--mc-border:#e2e8f0;--mc-hover:rgba(0,0,0,.04);","--mc-tt-bg:#1e293b;--mc-tt-fg:#fff;","--mc-sel:rgba(79,70,229,.1);--mc-sel-b:rgba(79,70,229,.3);","--mc-btn:#4f46e5;--mc-btn-h:#4338ca;--mc-mask:rgba(148,163,184,.18);","}",".mc-dark{","--mc-bg:#0f172a;--mc-card:#1e293b;--mc-text:#f1f5f9;--mc-text2:#cbd5e1;--mc-muted:#64748b;","--mc-grid:#334155;--mc-border:#334155;--mc-hover:rgba(255,255,255,.05);","--mc-tt-bg:#0f172a;--mc-tt-fg:#f1f5f9;","--mc-sel:rgba(129,120,255,.15);--mc-sel-b:rgba(129,120,255,.35);","--mc-btn:#6366f1;--mc-btn-h:#818cf8;--mc-mask:rgba(100,116,139,.3);","}",'.mc-root{position:relative;background:var(--mc-card);border-radius:12px;box-shadow:0 2px 16px rgba(0,0,0,.08);padding:20px 20px 14px;user-select:none;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;color:var(--mc-text);transition:background .3s,box-shadow .3s}',".mc-dark .mc-root{box-shadow:0 2px 24px rgba(0,0,0,.3)}",".mc-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}",".mc-titles{text-align:center;flex:1}",".mc-title{font-size:18px;font-weight:600}",".mc-subtitle{font-size:12px;color:var(--mc-muted);margin-top:2px}",".mc-toolbar{display:flex;gap:4px;flex-shrink:0}",".mc-toolbar button{width:32px;height:32px;border:1px solid var(--mc-border);border-radius:6px;background:transparent;color:var(--mc-text2);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s,border-color .15s}",".mc-toolbar button:hover{background:var(--mc-hover)}",".mc-toolbar button.active{background:var(--mc-btn);color:#fff;border-color:var(--mc-btn)}",".mc-toolbar button svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}",".mc-wrap{position:relative;width:100%}",".mc-wrap canvas{display:block;width:100%}",".mc-legend{display:flex;justify-content:center;gap:20px;margin-top:8px;flex-wrap:wrap}",".mc-legend-item{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--mc-text2);cursor:pointer;padding:2px 6px;border-radius:4px;transition:background .15s}",".mc-legend-item:hover{background:var(--mc-hover)}",".mc-legend-swatch{width:14px;height:3px;border-radius:2px}",".mc-legend-item.disabled .mc-legend-swatch{opacity:.25}",".mc-legend-item.disabled span:last-child{text-decoration:line-through;opacity:.4}",".mc-tooltip{position:absolute;pointer-events:none;opacity:0;background:var(--mc-tt-bg);color:var(--mc-tt-fg);border-radius:8px;padding:10px 14px;font-size:12px;line-height:1.6;white-space:nowrap;box-shadow:0 4px 12px rgba(0,0,0,.2);transition:opacity .1s;z-index:10}",".mc-tooltip.visible{opacity:1}",".mc-tooltip-date{font-weight:600;margin-bottom:2px}",".mc-tooltip-row{display:flex;align-items:center;gap:6px}",".mc-tooltip-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}",".mc-tooltip-val{margin-left:auto;padding-left:12px;font-weight:600}",".mc-selection{position:absolute;top:0;height:100%;background:var(--mc-sel);border-left:1px solid var(--mc-sel-b);border-right:1px solid var(--mc-sel-b);pointer-events:none;display:none}",".mc-reset{position:absolute;top:8px;right:8px;background:var(--mc-btn);color:#fff;border:none;border-radius:6px;padding:4px 10px;font-size:11px;font-weight:500;cursor:pointer;opacity:0;pointer-events:none;transition:opacity .2s}",".mc-reset.visible{opacity:1;pointer-events:auto}",".mc-reset:hover{background:var(--mc-btn-h)}",".mc-nav{position:relative;width:100%;height:48px;margin-top:6px;border-top:1px solid var(--mc-border)}",".mc-nav canvas{display:block;width:100%;height:48px}",".mc-nav-mask{position:absolute;top:0;height:100%;background:var(--mc-mask);pointer-events:none}",".mc-nav-mask.left{left:0}",".mc-nav-mask.right{right:0}",".mc-nav-win{position:absolute;top:0;height:100%;border-left:2px solid var(--mc-btn);border-right:2px solid var(--mc-btn);cursor:grab;z-index:2}",".mc-nav-h{position:absolute;top:50%;transform:translateY(-50%);width:6px;height:20px;background:var(--mc-btn);border-radius:3px;cursor:ew-resize;z-index:3}",".mc-nav-h.l{left:-4px}",".mc-nav-h.r{right:-4px}",".mc-root:fullscreen,.mc-root:-webkit-full-screen{display:flex;flex-direction:column;justify-content:center;max-width:100%;width:100%;border-radius:0}"].join("\n"),n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],a=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];function o(t,e,i){return t+(e-t)*i}function r(t,e,i){return Math.max(e,Math.min(i,t))}function s(t,e){var i=Math.floor(Math.log10(t)),n=t/Math.pow(10,i);return(e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10)*Math.pow(10,i)}function l(t){return Math.abs(t)>=1e3?t.toLocaleString("en-US",{maximumFractionDigits:1}):t===Math.floor(t)?t.toString():t.toFixed(1)}function c(t,e,i,_t){var T=typeof _t==="number"?_t:1;var n=e.length;if(!(n<2))if(i||t.moveTo(e[0][0],e[0][1]),2!==n){if(T<=0){for(var j=1;j<n;j++)t.lineTo(e[j][0],e[j][1]);return}for(var a=[],o=[],r=[],s=0;s<n-1;s++)a[s]=e[s+1][0]-e[s][0],o[s]=e[s+1][1]-e[s][1],r[s]=0===a[s]?0:o[s]/a[s];var l=[r[0]];for(s=1;s<n-1;s++)l[s]=r[s-1]*r[s]<=0?0:(r[s-1]+r[s])/2;for(l[n-1]=r[n-2],s=0;s<n-1;s++)if(Math.abs(r[s])<1e-10)l[s]=0,l[s+1]=0;else{var c=l[s]/r[s],d=l[s+1]/r[s],h=c*c+d*d;if(h>9){var p=3/Math.sqrt(h);l[s]=p*c*r[s],l[s+1]=p*d*r[s]}}for(s=0;s<n-1;s++){var v=a[s]*T/3;t.bezierCurveTo(e[s][0]+v,e[s][1]+l[s]*v,e[s+1][0]-v,e[s+1][1]-l[s+1]*v,e[s+1][0],e[s+1][1])}}else t.lineTo(e[1][0],e[1][1])}function d(t,e){return"rgba("+parseInt(t.slice(1,3),16)+","+parseInt(t.slice(3,5),16)+","+parseInt(t.slice(5,7),16)+","+e+")"}function h(t){return getComputedStyle(document.documentElement).getPropertyValue("--mc-"+t).trim()}function p(t,e,i){var n=document.createElement(t);return e&&(n.className=e),i&&i.appendChild(n),n}function v(t,n){if(function(){if(!e){e=!0;var t=document.createElement("style");t.textContent=i,document.head.appendChild(t)}}(),n=n||{},this.el="string"==typeof t?document.querySelector(t):t,!this.el)throw new Error("NMCharts: container not found");this.opts=n,this.bands=n.bands||[],this.forecastFrom=n.forecastFrom||null;var a=n.toolbar||{};this.series=(n.series||[]).map(function(t){return{name:t.name,data:t.data.slice().sort(function(t,e){return t[0]-e[0]}),color:t.color,type:t.type||"area",dashStyle:t.dashStyle||null,lineWidth:t.lineWidth||2.5,tension:typeof t.tension==="number"?t.tension:1,visible:!0}}),this._buildDOM(n,a),this._computeFullBounds(),this.viewXMin=this.fullXMin,this.viewXMax=this.fullXMax,this._dragStart=null,this._dragging=!1,this._panning=!1,this._panAnchorX=0,this._panViewStart=0,this._panViewEnd=0,this._hoverIdx=-1,this._zoomed=!1,this._entryProgress=0,this._entryStart=performance.now(),this._initSize(),this._buildLegend(),this._bindEvents(),this._bindNavigator(),this._startEntryAnim()}v.prototype._buildDOM=function(t,e){var i=p("div","mc-root",this.el);this._root=i;var n=p("div","mc-header",i);p("div","",n).style.width="120px";var a=p("div","mc-titles",n);p("div","mc-title",a).textContent=t.title||"",p("div","mc-subtitle",a).innerHTML=t.subtitle||"Drag to zoom · Shift+drag to pan · Scroll to zoom · Double-click to reset";var o=p("div","mc-toolbar",n),r=this;if(!1!==e.dark){var s=p("button","",o);s.title="Dark mode",s.innerHTML='<svg viewBox="0 0 24 24"><path d="M21 12.79A9 9 0 0 1 11.21 3a7 7 0 1 0 9.79 9.79z"/></svg>',s.addEventListener("click",function(){r.el.classList.toggle("mc-dark"),s.classList.toggle("active"),r.render(),r._renderNav()})}if(!1!==e.export){var l=p("button","",o);l.title="Export PNG",l.innerHTML='<svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>',l.addEventListener("click",function(){r.exportPNG()})}if(!1!==e.fullscreen){var c=p("button","",o);c.title="Fullscreen",c.innerHTML='<svg viewBox="0 0 24 24"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>',c.addEventListener("click",function(){document.fullscreenElement?(document.exitFullscreen||document.webkitExitFullscreen).call(document):(i.requestFullscreen||i.webkitRequestFullscreen).call(i)}),["fullscreenchange","webkitfullscreenchange"].forEach(function(t){document.addEventListener(t,function(){setTimeout(function(){r._initSize(),r.render(),r._renderNav()},100)})})}var d=p("div","mc-wrap",i);this._wrap=d,this.canvas=p("canvas","",d),this.ctx=this.canvas.getContext("2d"),this._tooltipEl=p("div","mc-tooltip",d),this._selEl=p("div","mc-selection",d),this._resetBtn=p("button","mc-reset",d),this._resetBtn.textContent="Reset zoom";var h=p("div","mc-nav",i);this._navWrap=h,this._navCanvas=p("canvas","",h),this._navCtx=this._navCanvas.getContext("2d"),this._navMaskL=p("div","mc-nav-mask left",h),this._navMaskR=p("div","mc-nav-mask right",h);var v=p("div","mc-nav-win",h);this._navWin=v,this._navHL=p("div","mc-nav-h l",v),this._navHR=p("div","mc-nav-h r",v),this._legendEl=p("div","mc-legend",i)},v.prototype._computeFullBounds=function(){for(var t=1/0,e=-1/0,i=0;i<this.series.length;i++){var n=this.series[i].data;n.length&&(t=Math.min(t,n[0][0]),e=Math.max(e,n[n.length-1][0]))}this.fullXMin=t,this.fullXMax=e},v.prototype._initSize=function(){var t=window.devicePixelRatio||1,e=this._wrap.getBoundingClientRect().width,i=Math.round(.42*e);this.canvas.width=e*t,this.canvas.height=i*t,this.canvas.style.height=i+"px",this.ctx.setTransform(t,0,0,t,0,0),this.W=e,this.H=i,this.pX=58,this.pY=24,this.pW=e-58-24,this.pH=i-24-44;var n=this._navWrap.getBoundingClientRect().width;this._navCanvas.width=n*t,this._navCanvas.height=48*t,this._navCtx.setTransform(t,0,0,t,0,0),this._nW=n,this._nH=48},v.prototype._buildLegend=function(){var t=this;this._legendEl.innerHTML="",this.series.forEach(function(e){var i=p("div","mc-legend-item"+(e.visible?"":" disabled"),t._legendEl),n="line"===e.type?"background:transparent;border-top:2.5px "+("dashed"===e.dashStyle?"dashed":"dotted"===e.dashStyle?"dotted":"solid")+" "+e.color+";height:0;margin-top:1px":"background:"+e.color;i.innerHTML='<div class="mc-legend-swatch" style="'+n+'"></div><span>'+e.name+"</span>",i.addEventListener("click",function(){e.visible=!e.visible,i.classList.toggle("disabled",!e.visible),t.render(),t._renderNav()})})},v.prototype._x2px=function(t){return this.pX+(t-this.viewXMin)/(this.viewXMax-this.viewXMin)*this.pW},v.prototype._y2px=function(t,e){return this.pY+this.pH-(t-e.min)/(e.max-e.min)*this.pH},v.prototype._px2x=function(t){return this.viewXMin+(t-this.pX)/this.pW*(this.viewXMax-this.viewXMin)},v.prototype._yScale=function(){for(var t=1/0,e=-1/0,i=0;i<this.series.length;i++)if(this.series[i].visible)for(var n=this.series[i].data,a=0;a<n.length;a++)n[a][0]>=this.viewXMin&&n[a][0]<=this.viewXMax&&(t=Math.min(t,n[a][1]),e=Math.max(e,n[a][1]));return t===1/0&&(t=0,e=100),function(t,e){t===e&&(t-=1,e+=1);for(var i=s(e-t,!1),n=s(i/5,!0),a=Math.floor(t/n)*n,o=Math.ceil(e/n)*n,r=[],l=a;l<=o+.5*n;l+=n)r.push(Math.round(1e10*l)/1e10);return{min:a,max:o,step:n,ticks:r}}(t=Math.min(0,t),e)},v.prototype._startEntryAnim=function(){var t=this,e=performance.now();!function i(n){var a=r((n-e)/800,0,1);t._entryProgress=1-Math.pow(1-a,3),t.render(),t._renderNav(),a<1&&requestAnimationFrame(i)}(e)},v.prototype.render=function(){var t=this.ctx,e=this._yScale(),i=this,a=h("grid"),o=h("muted"),s='11px -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif';t.clearRect(0,0,this.W,this.H),this.bands.forEach(function(n){var a=i._y2px(Math.min(n.to,e.max),e),o=i._y2px(Math.max(n.from,e.min),e);o<=i.pY||a>=i.pY+i.pH||(a=r(a,i.pY,i.pY+i.pH),o=r(o,i.pY,i.pY+i.pH),t.fillStyle=n.color,t.fillRect(i.pX,a,i.pW,o-a),n.label&&(t.save(),t.font="9px "+s,t.fillStyle=n.labelColor||n.color,t.textAlign="right",t.textBaseline="top",t.globalAlpha=.7,t.fillText(n.label,i.pX+i.pW-4,a+2),t.restore()))}),t.save(),t.font=s,t.textAlign="right",t.textBaseline="middle",e.ticks.forEach(function(n){var r=i._y2px(n,e);t.strokeStyle=a,t.lineWidth=1,t.beginPath(),t.moveTo(i.pX,Math.round(r)+.5),t.lineTo(i.pX+i.pW,Math.round(r)+.5),t.stroke(),t.fillStyle=o,t.fillText(l(n),i.pX-8,r)}),t.restore();var p=function(t,e,i){for(var n=e-t,a=864e5,o=[a,2*a,5*a,7*a,14*a,30*a,60*a,90*a,180*a,365*a],r=a,s=0;s<o.length;s++)if(n/o[s]<=i){r=o[s];break}for(var l=[],c=Math.ceil(t/r)*r;c<=e;c+=r)l.push(c);return l}(this.viewXMin,this.viewXMax,Math.floor(this.pW/80));t.save(),t.font=s,t.textAlign="center",t.textBaseline="top",t.fillStyle=o,p.forEach(function(e){var o=i._x2px(e);o>=i.pX&&o<=i.pX+i.pW&&(t.strokeStyle=a,t.beginPath(),t.moveTo(Math.round(o)+.5,i.pY+i.pH),t.lineTo(Math.round(o)+.5,i.pY+i.pH+5),t.stroke(),t.fillText(function(t){var e=new Date(t);return e.getUTCDate()+" "+n[e.getUTCMonth()]}(e),o,i.pY+i.pH+8))}),t.restore(),t.strokeStyle=a,t.lineWidth=1,t.beginPath(),t.moveTo(this.pX,this.pY),t.lineTo(this.pX,this.pY+this.pH),t.lineTo(this.pX+this.pW,this.pY+this.pH),t.stroke(),t.save(),t.beginPath(),t.rect(this.pX,this.pY,this.pW,this.pH),t.clip();var v=this.pW*this._entryProgress;if(this.series.forEach(function(n){if(n.visible){for(var a=[],o=.05*(i.viewXMax-i.viewXMin),r=0;r<n.data.length;r++){var s=n.data[r][0],l=n.data[r][1];s<i.viewXMin-o||s>i.viewXMax+o||a.push([i._x2px(s),i._y2px(l,e),s])}if(!(a.length<2)){var h=i._y2px(e.min,e);t.save(),t.beginPath(),t.rect(i.pX,i.pY,v,i.pH),t.clip();var p=a,u=null;if(i.forecastFrom){p=[],u=[];for(var f=0;f<a.length;f++)a[f][2]<i.forecastFrom?p.push(a[f]):u.push(a[f]);p.length&&u.length&&u.unshift(p[p.length-1])}var m="line"===n.type,g="dashed"===n.dashStyle?[6,4]:"dotted"===n.dashStyle?[2,3]:null;x(p,!1),u&&u.length>=2&&x(u,!0),t.restore()}}function x(e,a){if(!(e.length<2)){if(!m){var o=t.createLinearGradient(0,i.pY,0,h);o.addColorStop(0,d(n.color,.22)),o.addColorStop(1,d(n.color,.02)),t.beginPath(),t.moveTo(e[0][0],h),t.lineTo(e[0][0],e[0][1]),c(t,e,!0,n.tension),t.lineTo(e[e.length-1][0],h),t.closePath(),t.fillStyle=o,t.fill()}var r=a?[6,4]:g;r&&t.setLineDash(r),t.beginPath(),c(t,e,!1,n.tension),t.strokeStyle=n.color,t.lineWidth=n.lineWidth,t.lineJoin="round",t.lineCap="round",t.stroke(),r&&t.setLineDash([])}}}),this._hoverIdx>=0&&this._entryProgress>=1){var u=null;this.series.forEach(function(n){if(n.visible&&!(i._hoverIdx>=n.data.length)){var a=n.data[i._hoverIdx],o=i._x2px(a[0]),r=i._y2px(a[1],e);u=o,t.beginPath(),t.arc(o,r,5,0,2*Math.PI),t.fillStyle=h("card"),t.fill(),t.strokeStyle=n.color,t.lineWidth=2.5,t.stroke()}}),null!==u&&(t.strokeStyle=d(o,.4),t.lineWidth=1,t.setLineDash([4,3]),t.beginPath(),t.moveTo(Math.round(u)+.5,i.pY),t.lineTo(Math.round(u)+.5,i.pY+i.pH),t.stroke(),t.setLineDash([]))}t.restore()},v.prototype._renderNav=function(){var t=this._navCtx,e=this._nW,i=this._nH,n=this,a=e-2-2,o=i-4-4;t.clearRect(0,0,e,i);var r=1/0,s=-1/0;this.series.forEach(function(t){t.visible&&t.data.forEach(function(t){r=Math.min(r,t[1]),s=Math.max(s,t[1])})}),r===1/0&&(r=0,s=100),r=Math.min(0,r);var l=4+o;this.series.forEach(function(e){if(e.visible){var i=e.data.map(function(t){return[2+(t[0]-n.fullXMin)/(n.fullXMax-n.fullXMin)*a,4+o-(t[1]-r)/(s-r)*o]});if(!(i.length<2)){if("line"!==e.type){var h=t.createLinearGradient(0,4,0,l);h.addColorStop(0,d(e.color,.18)),h.addColorStop(1,d(e.color,.02)),t.beginPath(),t.moveTo(i[0][0],l),t.lineTo(i[0][0],i[0][1]),c(t,i,!0,e.tension),t.lineTo(i[i.length-1][0],l),t.closePath(),t.fillStyle=h,t.fill()}var p="dashed"===e.dashStyle?[4,3]:"dotted"===e.dashStyle?[2,2]:null;p&&t.setLineDash(p),t.beginPath(),c(t,i,!1,e.tension),t.strokeStyle=d(e.color,.6),t.lineWidth=1.2,t.stroke(),p&&t.setLineDash([])}}});var h=(this.viewXMin-this.fullXMin)/(this.fullXMax-this.fullXMin)*100,p=(this.fullXMax-this.viewXMax)/(this.fullXMax-this.fullXMin)*100;this._navWin.style.left=h+"%",this._navWin.style.right=p+"%",this._navMaskL.style.width=h+"%",this._navMaskR.style.width=p+"%"},v.prototype._bindNavigator=function(){var t,e,i,n=this,a=null;function o(o,r){o.preventDefault(),o.stopPropagation(),a=r,t=o.clientX,e=n.viewXMin,i=n.viewXMax,document.addEventListener("mousemove",s),document.addEventListener("mouseup",l)}function s(o){var s=n._navWrap.getBoundingClientRect(),l=(o.clientX-t)/s.width*(n.fullXMax-n.fullXMin),c=1728e5;if("move"===a){var d=e+l,h=i+l;d<n.fullXMin&&(h+=n.fullXMin-d,d=n.fullXMin),h>n.fullXMax&&(d-=h-n.fullXMax,h=n.fullXMax),n.viewXMin=d,n.viewXMax=h}else"left"===a?n.viewXMin=r(e+l,n.fullXMin,n.viewXMax-c):n.viewXMax=r(i+l,n.viewXMin+c,n.fullXMax);n._zoomed=n.viewXMin>n.fullXMin||n.viewXMax<n.fullXMax,n._resetBtn.classList.toggle("visible",n._zoomed),n.render(),n._renderNav()}function l(){a=null,document.removeEventListener("mousemove",s),document.removeEventListener("mouseup",l)}this._navWin.addEventListener("mousedown",function(t){o(t,"move")}),this._navHL.addEventListener("mousedown",function(t){o(t,"left")}),this._navHR.addEventListener("mousedown",function(t){o(t,"right")}),this._navWrap.addEventListener("mousedown",function(t){if(t.target===n._navCanvas){var e=n._navWrap.getBoundingClientRect(),i=n.fullXMin+(t.clientX-e.left)/e.width*(n.fullXMax-n.fullXMin),a=n.viewXMax-n.viewXMin,o=i-a/2,r=i+a/2;o<n.fullXMin&&(r+=n.fullXMin-o,o=n.fullXMin),r>n.fullXMax&&(o-=r-n.fullXMax,r=n.fullXMax),n._zoomed=!0,n._resetBtn.classList.add("visible"),n._animateTo(o,r)}})},v.prototype._animateTo=function(t,e){var i={a:this.viewXMin,b:this.viewXMax},n=this,a=performance.now();!function s(l){var c=r((l-a)/400,0,1),d=1-Math.pow(1-c,3);n.viewXMin=o(i.a,t,d),n.viewXMax=o(i.b,e,d),n.render(),n._renderNav(),c<1&&requestAnimationFrame(s)}(a)},v.prototype._bindEvents=function(){var t,e=this,i=this.canvas;function n(t){var e=i.getBoundingClientRect();return{x:t.clientX-e.left,y:t.clientY-e.top}}function a(t){return t.x>=e.pX&&t.x<=e.pX+e.pW&&t.y>=e.pY&&t.y<=e.pY+e.pH}window.addEventListener("resize",function(){clearTimeout(t),t=setTimeout(function(){e._initSize(),e.render(),e._renderNav()},80)}),i.addEventListener("mousedown",function(t){var o=n(t);a(o)&&(t.shiftKey&&e._zoomed?(e._panning=!0,e._panAnchorX=o.x,e._panViewStart=e.viewXMin,e._panViewEnd=e.viewXMax,i.style.cursor="grabbing"):(e._dragStart=o.x,e._dragging=!0,e._selEl.style.display="block",e._selEl.style.left=o.x+"px",e._selEl.style.width="0px"))}),i.addEventListener("mousemove",function(t){var o=n(t);if(e._panning){var s=o.x-e._panAnchorX,l=e._panViewEnd-e._panViewStart,c=-s/e.pW*l,d=e._panViewStart+c,h=e._panViewEnd+c;return d<e.fullXMin&&(h+=e.fullXMin-d,d=e.fullXMin),h>e.fullXMax&&(d-=h-e.fullXMax,h=e.fullXMax),e.viewXMin=d,e.viewXMax=h,e.render(),void e._renderNav()}if(e._dragging){var p=Math.min(e._dragStart,o.x),v=Math.abs(o.x-e._dragStart);p=r(p,e.pX,e.pX+e.pW);var u=r(p+v,e.pX,e.pX+e.pW);return e._selEl.style.left=p+"px",void(e._selEl.style.width=u-p+"px")}if(a(o)){i.style.cursor=t.shiftKey&&e._zoomed?"grab":"crosshair";var f=function(t){for(var i=e._px2x(t),n=null,a=0;a<e.series.length;a++)if(e.series[a].visible){n=e.series[a].data;break}if(!n||!n.length)return-1;for(var o=0,r=1/0,s=0;s<n.length;s++){var l=Math.abs(n[s][0]-i);l<r&&(r=l,o=s)}return o}(o.x);f!==e._hoverIdx&&(e._hoverIdx=f,e.render()),e._showTooltip(o,f)}else e._hideTooltip()}),window.addEventListener("mouseup",function(){if(e._panning)return e._panning=!1,void(i.style.cursor="crosshair");if(e._dragging){e._dragging=!1,e._selEl.style.display="none";var t=parseFloat(e._selEl.style.width);if(t<10)e._dragStart=null;else{var n=parseFloat(e._selEl.style.left);e._zoomed=!0,e._resetBtn.classList.add("visible"),e._animateTo(e._px2x(n),e._px2x(n+t)),e._dragStart=null}}}),i.addEventListener("mouseleave",function(){e._hideTooltip()}),i.addEventListener("dblclick",function(t){t.preventDefault(),e._zoomed&&(e._zoomed=!1,e._resetBtn.classList.remove("visible"),e._animateTo(e.fullXMin,e.fullXMax))}),i.addEventListener("wheel",function(t){var i=n(t);if(a(i)){t.preventDefault();var o=t.deltaY>0?1.15:1/1.15,r=e._px2x(i.x),s=e.viewXMax-e.viewXMin,l=s*o;if(!(l<1728e5)){var c=(r-e.viewXMin)/s,d=Math.max(r-c*l,e.fullXMin),h=Math.min(r+(1-c)*l,e.fullXMax);e.viewXMin=d,e.viewXMax=h,e._zoomed=d>e.fullXMin||h<e.fullXMax,e._resetBtn.classList.toggle("visible",e._zoomed),e.render(),e._renderNav()}}},{passive:!1}),this._resetBtn.addEventListener("click",function(){e._zoomed=!1,e._resetBtn.classList.remove("visible"),e._animateTo(e.fullXMin,e.fullXMax)}),document.addEventListener("keydown",function(t){if("INPUT"!==t.target.tagName&&"TEXTAREA"!==t.target.tagName){var i=e.viewXMax-e.viewXMin,n=.15*i;if("ArrowLeft"===t.key){var a=Math.max(e.viewXMin-n,e.fullXMin);e._animateTo(a,a+i)}else if("ArrowRight"===t.key){var o=Math.min(e.viewXMax+n,e.fullXMax);e._animateTo(o-i,o)}else if("+"===t.key||"="===t.key){var r=.7*i,s=(e.viewXMin+e.viewXMax)/2;e._zoomed=!0,e._resetBtn.classList.add("visible"),e._animateTo(s-r/2,s+r/2)}else if("-"===t.key){var l=Math.min(1.4*i,e.fullXMax-e.fullXMin),c=(e.viewXMin+e.viewXMax)/2,d=Math.max(c-l/2,e.fullXMin),h=Math.min(c+l/2,e.fullXMax);e._zoomed=d>e.fullXMin||h<e.fullXMax,e._resetBtn.classList.toggle("visible",e._zoomed),e._animateTo(d,h)}else"Escape"===t.key&&e._zoomed&&(e._zoomed=!1,e._resetBtn.classList.remove("visible"),e._animateTo(e.fullXMin,e.fullXMax))}});var o=null;i.addEventListener("touchstart",function(t){1===t.touches.length?(e._panning=!0,e._panAnchorX=t.touches[0].clientX-i.getBoundingClientRect().left,e._panViewStart=e.viewXMin,e._panViewEnd=e.viewXMax):2===t.touches.length&&(e._panning=!1,o=Math.abs(t.touches[1].clientX-t.touches[0].clientX)),t.preventDefault()},{passive:!1}),i.addEventListener("touchmove",function(t){if(1===t.touches.length&&e._panning){var n=t.touches[0].clientX-i.getBoundingClientRect().left-e._panAnchorX,a=e._panViewEnd-e._panViewStart,r=-n/e.pW*a,s=e._panViewStart+r,l=e._panViewEnd+r;s<e.fullXMin&&(l+=e.fullXMin-s,s=e.fullXMin),l>e.fullXMax&&(s-=l-e.fullXMax,l=e.fullXMax),e.viewXMin=s,e.viewXMax=l,e.render(),e._renderNav()}else if(2===t.touches.length&&o){var c=Math.abs(t.touches[1].clientX-t.touches[0].clientX),d=o/c,h=(t.touches[0].clientX+t.touches[1].clientX)/2-i.getBoundingClientRect().left,p=e._px2x(h),v=e.viewXMax-e.viewXMin,u=v*d;if(u<1728e5)return void t.preventDefault();var f=(p-e.viewXMin)/v;e.viewXMin=Math.max(p-f*u,e.fullXMin),e.viewXMax=Math.min(p+(1-f)*u,e.fullXMax),e._zoomed=!0,e._resetBtn.classList.add("visible"),o=c,e.render(),e._renderNav()}t.preventDefault()},{passive:!1}),i.addEventListener("touchend",function(){e._panning=!1,o=null})},v.prototype._showTooltip=function(t,e){if(e<0)this._hideTooltip();else{var i="",o=null;if(this.series.forEach(function(t){!t.visible||e>=t.data.length||(o||(o=t.data[e][0]),i+='<div class="mc-tooltip-row"><div class="mc-tooltip-dot" style="background:'+t.color+'"></div><span>'+t.name+'</span><span class="mc-tooltip-val">'+l(t.data[e][1])+"</span></div>")}),o){i='<div class="mc-tooltip-date">'+function(t){var e=new Date(t);return a[e.getUTCDay()]+", "+n[e.getUTCMonth()]+" "+e.getUTCDate()+", "+e.getUTCFullYear()}(o)+"</div>"+i,this._tooltipEl.innerHTML=i,this._tooltipEl.classList.add("visible");var s=this._tooltipEl.offsetWidth,c=this._tooltipEl.offsetHeight,d=t.x+16,h=t.y-c/2;d+s>this.W-8&&(d=t.x-s-16),h=r(h,4,this.H-c-4),this._tooltipEl.style.left=d+"px",this._tooltipEl.style.top=h+"px"}else this._hideTooltip()}},v.prototype._hideTooltip=function(){this._tooltipEl.classList.remove("visible"),this._hoverIdx>=0&&(this._hoverIdx=-1,this.render())},v.prototype.exportPNG=function(t){var e=document.createElement("a");e.download=t||"chart.png",e.href=this.canvas.toDataURL("image/png"),e.click()},v.prototype.setDarkMode=function(t){this.el.classList.toggle("mc-dark",t),this.render(),this._renderNav()},v.prototype.updateSeries=function(t){this.series=t.map(function(t){return{name:t.name,data:t.data.slice().sort(function(t,e){return t[0]-e[0]}),color:t.color,type:t.type||"area",dashStyle:t.dashStyle||null,lineWidth:t.lineWidth||2.5,tension:typeof t.tension==="number"?t.tension:1,visible:!0}}),this._computeFullBounds(),this.viewXMin=this.fullXMin,this.viewXMax=this.fullXMax,this._zoomed=!1,this._resetBtn.classList.remove("visible"),this._buildLegend(),this.render(),this._renderNav()},v.prototype.destroy=function(){this._root.remove()},v.create=function(t,e){return new v(t,e)};"object"==typeof module&&module.exports?module.exports=v:"function"==typeof define&&define.amd?define(function(){return v}):t.NMCharts=v}("undefined"!=typeof window?window:"undefined"!=typeof globalThis?globalThis:this);
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@malinconico/nmcharts",
|
|
3
|
+
"version": "2.3.0",
|
|
4
|
+
"description": "NM Charts — Zero-dependency Canvas charting library with 23 chart types",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "nmcharts.js",
|
|
7
|
+
"module": "nmcharts.esm.js",
|
|
8
|
+
"types": "nmcharts.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./nmcharts.esm.js",
|
|
12
|
+
"require": "./nmcharts.js",
|
|
13
|
+
"types": "./nmcharts.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./categories": "./nmcharts-categories.js",
|
|
16
|
+
"./extras": "./nmcharts-extras.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"nmcharts.js",
|
|
20
|
+
"nmcharts.esm.js",
|
|
21
|
+
"nmcharts.d.ts",
|
|
22
|
+
"nmcharts-categories.js",
|
|
23
|
+
"nmcharts-categories.min.js",
|
|
24
|
+
"nmcharts-extras.js",
|
|
25
|
+
"nmcharts-extras.min.js"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "npx terser nmcharts-categories.js -o nmcharts-categories.min.js -c -m && npx terser nmcharts-extras.js -o nmcharts-extras.min.js -c -m",
|
|
29
|
+
"test": "node --test tests/"
|
|
30
|
+
},
|
|
31
|
+
"sideEffects": true,
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"author": "Malinconico Nicolas",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/malinconico/maquette"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://nmcharts.malinconico.lu",
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/malinconico/maquette/issues"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"chart",
|
|
44
|
+
"charts",
|
|
45
|
+
"canvas",
|
|
46
|
+
"graph",
|
|
47
|
+
"visualization",
|
|
48
|
+
"time-series",
|
|
49
|
+
"bar-chart",
|
|
50
|
+
"donut",
|
|
51
|
+
"gauge",
|
|
52
|
+
"radar",
|
|
53
|
+
"heatmap",
|
|
54
|
+
"waterfall",
|
|
55
|
+
"bullet",
|
|
56
|
+
"treemap",
|
|
57
|
+
"funnel",
|
|
58
|
+
"polar",
|
|
59
|
+
"scatter",
|
|
60
|
+
"bubble",
|
|
61
|
+
"sankey",
|
|
62
|
+
"boxplot",
|
|
63
|
+
"sparkline",
|
|
64
|
+
"crossfilter",
|
|
65
|
+
"zero-dependency",
|
|
66
|
+
"lightweight",
|
|
67
|
+
"responsive"
|
|
68
|
+
]
|
|
69
|
+
}
|