@malinconico/nmcharts 2.4.0 → 2.5.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.d.ts +75 -2
- package/nmcharts.js +60 -53
- package/package.json +1 -1
package/nmcharts.d.ts
CHANGED
|
@@ -39,8 +39,8 @@ interface NMChartsOptions {
|
|
|
39
39
|
interface NMChartsInstance {
|
|
40
40
|
render(): void;
|
|
41
41
|
exportPNG(filename?: string): void;
|
|
42
|
-
/** Export chart as SVG file (
|
|
43
|
-
exportSVG(filename?: string): void;
|
|
42
|
+
/** Export chart as SVG file (requires nmcharts-extras.js) */
|
|
43
|
+
exportSVG?(filename?: string): void;
|
|
44
44
|
setDarkMode(enabled: boolean): void;
|
|
45
45
|
updateSeries(series: NMChartsSeries[]): void;
|
|
46
46
|
destroy(): void;
|
|
@@ -79,6 +79,8 @@ interface NMCategoryOptions {
|
|
|
79
79
|
gridColor?: string;
|
|
80
80
|
gridDashed?: boolean;
|
|
81
81
|
colors?: string[];
|
|
82
|
+
zoomPan?: boolean;
|
|
83
|
+
annotations?: NMAnnotation[];
|
|
82
84
|
barWidth?: number;
|
|
83
85
|
barGap?: number;
|
|
84
86
|
groupPadding?: number;
|
|
@@ -314,6 +316,69 @@ interface NMLinkInstance {
|
|
|
314
316
|
destroy(): void;
|
|
315
317
|
}
|
|
316
318
|
|
|
319
|
+
interface NMBookingTimelineOptions {
|
|
320
|
+
title?: string;
|
|
321
|
+
month?: number;
|
|
322
|
+
year?: number;
|
|
323
|
+
properties?: Array<{
|
|
324
|
+
name: string;
|
|
325
|
+
location?: string;
|
|
326
|
+
rating?: number;
|
|
327
|
+
avatar?: string;
|
|
328
|
+
color?: string;
|
|
329
|
+
}>;
|
|
330
|
+
bookings?: Array<{
|
|
331
|
+
property: number;
|
|
332
|
+
guest?: string;
|
|
333
|
+
checkIn: string;
|
|
334
|
+
checkOut: string;
|
|
335
|
+
status?: 'confirmed' | 'pending' | 'checked-in' | 'checked-out' | 'cancelled' | 'blocked';
|
|
336
|
+
price?: string;
|
|
337
|
+
platform?: 'airbnb' | 'booking' | 'direct' | string;
|
|
338
|
+
color?: string;
|
|
339
|
+
guestAvatar?: string;
|
|
340
|
+
nights?: number;
|
|
341
|
+
}>;
|
|
342
|
+
cellWidth?: number;
|
|
343
|
+
rowHeight?: number;
|
|
344
|
+
avatarSize?: number;
|
|
345
|
+
statusColors?: Record<string, string>;
|
|
346
|
+
onBookingClick?: (booking: any) => void;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
interface NMBookingTimelineInstance {
|
|
350
|
+
destroy(): void;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
interface NMAnnotation {
|
|
354
|
+
type: 'line' | 'band' | 'vline' | 'marker';
|
|
355
|
+
value?: number;
|
|
356
|
+
from?: number;
|
|
357
|
+
to?: number;
|
|
358
|
+
category?: string | number;
|
|
359
|
+
color?: string;
|
|
360
|
+
label?: string;
|
|
361
|
+
labelColor?: string;
|
|
362
|
+
labelAlign?: string;
|
|
363
|
+
lineWidth?: number;
|
|
364
|
+
dash?: number[];
|
|
365
|
+
radius?: number;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
interface NMDiagnosticResult {
|
|
369
|
+
nmchartsLoaded: boolean;
|
|
370
|
+
version: string;
|
|
371
|
+
debug: boolean;
|
|
372
|
+
cspFallback: boolean;
|
|
373
|
+
stylesInjected: boolean;
|
|
374
|
+
nmchartsStyleTag: boolean;
|
|
375
|
+
dpr: number;
|
|
376
|
+
roundRectNative: boolean;
|
|
377
|
+
container: any;
|
|
378
|
+
cssVars?: any;
|
|
379
|
+
chartMethods: string[];
|
|
380
|
+
}
|
|
381
|
+
|
|
317
382
|
// --- Theme definitions ---
|
|
318
383
|
|
|
319
384
|
interface NMChartsThemes {
|
|
@@ -348,7 +413,11 @@ interface NMChartsStatic {
|
|
|
348
413
|
boxplot(selector: string | HTMLElement, options: NMBoxplotOptions): NMCategoryInstance;
|
|
349
414
|
sparkline(selector: string | HTMLElement, data: number[], options?: NMSparklineOptions): NMSparklineInstance;
|
|
350
415
|
link(charts: NMCategoryInstance[], options?: NMLinkOptions): NMLinkInstance;
|
|
416
|
+
bookingTimeline(selector: string | HTMLElement, options: NMBookingTimelineOptions): NMBookingTimelineInstance;
|
|
351
417
|
lttb(data: any[], threshold: number): any[];
|
|
418
|
+
diagnose(selector?: string | HTMLElement): NMDiagnosticResult;
|
|
419
|
+
debug: boolean;
|
|
420
|
+
_cspNonce: string;
|
|
352
421
|
themes: NMChartsThemes;
|
|
353
422
|
}
|
|
354
423
|
|
|
@@ -364,6 +433,10 @@ export {
|
|
|
364
433
|
NMBulletOptions, NMTimelineOptions, NMWaterfallOptions,
|
|
365
434
|
NMTreemapOptions, NMFunnelOptions, NMPolarOptions,
|
|
366
435
|
NMScatterOptions, NMSankeyOptions, NMBoxplotOptions,
|
|
436
|
+
NMSparklineOptions, NMSparklineInstance,
|
|
437
|
+
NMLinkOptions, NMLinkInstance,
|
|
438
|
+
NMBookingTimelineOptions, NMBookingTimelineInstance,
|
|
439
|
+
NMAnnotation, NMDiagnosticResult,
|
|
367
440
|
NMChartsThemes
|
|
368
441
|
};
|
|
369
442
|
export default NMCharts;
|
package/nmcharts.js
CHANGED
|
@@ -177,7 +177,10 @@
|
|
|
177
177
|
e = !0;
|
|
178
178
|
_styleEl = document.createElement("style");
|
|
179
179
|
_styleEl.setAttribute("data-nmcharts", "");
|
|
180
|
-
(
|
|
180
|
+
var _nonce = (t.NMCharts && t.NMCharts._cspNonce) || "";
|
|
181
|
+
if (_nonce) _styleEl.setAttribute("nonce", _nonce);
|
|
182
|
+
_styleEl.textContent = i;
|
|
183
|
+
try { document.head.appendChild(_styleEl); } catch(ex) { console.warn("[NMCharts] CSP blocked style injection:", ex.message); }
|
|
181
184
|
}
|
|
182
185
|
_instanceCount++;
|
|
183
186
|
})(),
|
|
@@ -186,9 +189,12 @@
|
|
|
186
189
|
!this.el)
|
|
187
190
|
)
|
|
188
191
|
throw new Error("NMCharts: container not found");
|
|
192
|
+
if (t.NMCharts && t.NMCharts.debug) console.log("[NMCharts:create] Creating time-series chart", { container: this.el.id || this.el.tagName, width: this.el.getBoundingClientRect().width, series: (n.series||[]).length, title: n.title || '' });
|
|
189
193
|
((this.opts = n),
|
|
190
194
|
(this.bands = n.bands || []),
|
|
191
|
-
(this.forecastFrom = n.forecastFrom || null)
|
|
195
|
+
(this.forecastFrom = n.forecastFrom || null),
|
|
196
|
+
(this._externalListeners = []),
|
|
197
|
+
(this._destroyed = !1));
|
|
192
198
|
var a = n.toolbar || {};
|
|
193
199
|
((this.series = (n.series || []).map(function (t) {
|
|
194
200
|
return {
|
|
@@ -230,14 +236,15 @@
|
|
|
230
236
|
}
|
|
231
237
|
((v.prototype._buildDOM = function (t, e) {
|
|
232
238
|
var i = p("div", "mc-root", this.el);
|
|
239
|
+
i.style.maxWidth = "100%"; i.style.overflow = "hidden"; i.style.boxSizing = "border-box";
|
|
233
240
|
this._root = i;
|
|
234
241
|
var n = p("div", "mc-header", i);
|
|
235
242
|
p("div", "", n).style.width = "120px";
|
|
236
243
|
var a = p("div", "mc-titles", n);
|
|
237
244
|
((p("div", "mc-title", a).textContent = t.title || ""),
|
|
238
|
-
(p("div", "mc-subtitle", a).
|
|
245
|
+
(p("div", "mc-subtitle", a).textContent =
|
|
239
246
|
t.subtitle ||
|
|
240
|
-
"Drag to zoom
|
|
247
|
+
"Drag to zoom \u00B7 Shift+drag to pan \u00B7 Scroll to zoom \u00B7 Double-click to reset"));
|
|
241
248
|
var o = p("div", "mc-toolbar", n),
|
|
242
249
|
r = this;
|
|
243
250
|
if (!1 !== e.dark) {
|
|
@@ -317,6 +324,20 @@
|
|
|
317
324
|
var t = window.devicePixelRatio || 1,
|
|
318
325
|
e = this._wrap.getBoundingClientRect().width,
|
|
319
326
|
i = Math.round(0.42 * e);
|
|
327
|
+
if (e <= 0) {
|
|
328
|
+
var self = this;
|
|
329
|
+
if (!this._sizeRetry) this._sizeRetry = 0;
|
|
330
|
+
if (this._sizeRetry < 20) {
|
|
331
|
+
this._sizeRetry++;
|
|
332
|
+
if (window.NMCharts && window.NMCharts.debug) console.log("[NMCharts:create] Width=0, retrying (" + this._sizeRetry + "/20)");
|
|
333
|
+
this._sizeTimer = setTimeout(function () { self._initSize(); if (self.W > 0) { if (window.NMCharts && window.NMCharts.debug) console.log("[NMCharts:create] Container now visible, width=" + self.W); self._entryProgress = 0; self._startEntryAnim(); } }, 66);
|
|
334
|
+
} else {
|
|
335
|
+
if (window.NMCharts && window.NMCharts.debug) console.warn("[NMCharts:create] WARNING: Container still 0px after 20 retries", { el: this.el.id || this.el.tagName, display: getComputedStyle(this.el).display });
|
|
336
|
+
}
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
this._sizeRetry = 0;
|
|
340
|
+
if (window.NMCharts && window.NMCharts.debug && !this._sizeLogged) { this._sizeLogged = true; console.log("[NMCharts:create] Size OK", { width: e, height: i, dpr: t }); }
|
|
320
341
|
((this.canvas.width = e * t),
|
|
321
342
|
(this.canvas.height = i * t),
|
|
322
343
|
(this.canvas.style.height = i + "px"),
|
|
@@ -336,7 +357,7 @@
|
|
|
336
357
|
}),
|
|
337
358
|
(v.prototype._buildLegend = function () {
|
|
338
359
|
var t = this;
|
|
339
|
-
((this._legendEl.
|
|
360
|
+
((this._legendEl.textContent = ""),
|
|
340
361
|
this.series.forEach(function (e) {
|
|
341
362
|
var i = p(
|
|
342
363
|
"div",
|
|
@@ -355,12 +376,12 @@
|
|
|
355
376
|
e.color +
|
|
356
377
|
";height:0;margin-top:1px"
|
|
357
378
|
: "background:" + e.color;
|
|
358
|
-
(
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
379
|
+
(i.textContent = "",
|
|
380
|
+
(function() {
|
|
381
|
+
var sw = document.createElement("div"); sw.className = "mc-legend-swatch"; sw.style.cssText = n;
|
|
382
|
+
var sp = document.createElement("span"); sp.textContent = e.name;
|
|
383
|
+
i.appendChild(sw); i.appendChild(sp);
|
|
384
|
+
})(),
|
|
364
385
|
i.addEventListener("click", function () {
|
|
365
386
|
((e.visible = !e.visible),
|
|
366
387
|
i.classList.toggle("disabled", !e.visible),
|
|
@@ -1024,42 +1045,31 @@
|
|
|
1024
1045
|
(v.prototype._showTooltip = function (t, e) {
|
|
1025
1046
|
if (e < 0) this._hideTooltip();
|
|
1026
1047
|
else {
|
|
1027
|
-
var
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
(
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
n[e.getUTCMonth()] +
|
|
1053
|
-
" " +
|
|
1054
|
-
e.getUTCDate() +
|
|
1055
|
-
", " +
|
|
1056
|
-
e.getUTCFullYear()
|
|
1057
|
-
);
|
|
1058
|
-
})(o) +
|
|
1059
|
-
"</div>" +
|
|
1060
|
-
i),
|
|
1061
|
-
(this._tooltipEl.innerHTML = i),
|
|
1062
|
-
this._tooltipEl.classList.add("visible"));
|
|
1048
|
+
var o = null;
|
|
1049
|
+
var entries = [];
|
|
1050
|
+
this.series.forEach(function (t) {
|
|
1051
|
+
if (!t.visible || e >= t.data.length) return;
|
|
1052
|
+
if (!o) o = t.data[e][0];
|
|
1053
|
+
entries.push({ color: t.color, name: t.name, value: l(t.data[e][1]) });
|
|
1054
|
+
});
|
|
1055
|
+
if (o) {
|
|
1056
|
+
// Build tooltip with safe DOM methods (no innerHTML)
|
|
1057
|
+
this._tooltipEl.textContent = "";
|
|
1058
|
+
var dateDiv = document.createElement("div"); dateDiv.className = "mc-tooltip-date";
|
|
1059
|
+
dateDiv.textContent = (function (t) {
|
|
1060
|
+
var e = new Date(t);
|
|
1061
|
+
return a[e.getUTCDay()] + ", " + n[e.getUTCMonth()] + " " + e.getUTCDate() + ", " + e.getUTCFullYear();
|
|
1062
|
+
})(o);
|
|
1063
|
+
this._tooltipEl.appendChild(dateDiv);
|
|
1064
|
+
entries.forEach(function (entry) {
|
|
1065
|
+
var row = document.createElement("div"); row.className = "mc-tooltip-row";
|
|
1066
|
+
var dot = document.createElement("div"); dot.className = "mc-tooltip-dot"; dot.style.background = entry.color;
|
|
1067
|
+
var nm = document.createElement("span"); nm.textContent = entry.name;
|
|
1068
|
+
var val = document.createElement("span"); val.className = "mc-tooltip-val"; val.textContent = entry.value;
|
|
1069
|
+
row.appendChild(dot); row.appendChild(nm); row.appendChild(val);
|
|
1070
|
+
this._tooltipEl.appendChild(row);
|
|
1071
|
+
}.bind(this));
|
|
1072
|
+
this._tooltipEl.classList.add("visible");
|
|
1063
1073
|
var s = this._tooltipEl.offsetWidth,
|
|
1064
1074
|
c = this._tooltipEl.offsetHeight,
|
|
1065
1075
|
d = t.x + 16,
|
|
@@ -1116,6 +1126,7 @@
|
|
|
1116
1126
|
if (this._rafId) { cancelAnimationFrame(this._rafId); this._rafId = null; }
|
|
1117
1127
|
// Clear resize debounce timer
|
|
1118
1128
|
if (this._resizeTimer) { clearTimeout(this._resizeTimer); this._resizeTimer = null; }
|
|
1129
|
+
if (this._sizeTimer) { clearTimeout(this._sizeTimer); this._sizeTimer = null; }
|
|
1119
1130
|
// Remove all external listeners (window/document)
|
|
1120
1131
|
if (this._externalListeners) {
|
|
1121
1132
|
for (var i = 0; i < this._externalListeners.length; i++) {
|
|
@@ -1128,13 +1139,9 @@
|
|
|
1128
1139
|
if (this._root && this._root.parentNode) {
|
|
1129
1140
|
this._root.parentNode.removeChild(this._root);
|
|
1130
1141
|
}
|
|
1131
|
-
// Decrement instance count
|
|
1142
|
+
// Decrement instance count (keep styles — category charts may depend on them)
|
|
1132
1143
|
_instanceCount--;
|
|
1133
|
-
if (_instanceCount
|
|
1134
|
-
_styleEl.parentNode.removeChild(_styleEl);
|
|
1135
|
-
_styleEl = null;
|
|
1136
|
-
e = !1;
|
|
1137
|
-
_instanceCount = 0;
|
|
1144
|
+
if (_instanceCount < 0) _instanceCount = 0;
|
|
1138
1145
|
}
|
|
1139
1146
|
// Null out references to aid GC
|
|
1140
1147
|
this.canvas = null;
|