@rm-graph/core 0.1.2 → 0.1.4
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/dist/{index-DWzDIVQ9.d.mts → index-QzUVGlSo.d.mts} +68 -66
- package/dist/{index-DWzDIVQ9.d.ts → index-QzUVGlSo.d.ts} +68 -66
- package/dist/index.d.mts +110 -186
- package/dist/index.d.ts +110 -186
- package/dist/index.js +668 -906
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +668 -900
- package/dist/index.mjs.map +1 -1
- package/dist/themes/index.d.mts +1 -1
- package/dist/themes/index.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { __require, ThemeManager } from './chunk-Q2ZHY445.mjs';
|
|
2
2
|
export { ThemeManager, darkTheme, getThemeManager, lightTheme, midnightTheme, modernTheme } from './chunk-Q2ZHY445.mjs';
|
|
3
|
-
import {
|
|
3
|
+
import { SciChart3DSurface, NumericAxis3D, MouseWheelZoomModifier3D, OrbitModifier3D, CameraController, Vector3, UniformGridDataSeries3D, GradientColorPalette, SurfaceMeshRenderableSeries3D, EDrawMeshAs, NumberRange, XyzDataSeries3D, ColumnRenderableSeries3D, PointLineRenderableSeries3D, TooltipModifier3D, SciChartSurface, NumericAxis, EAxisAlignment, ENumericFormat, EAutoRange, CursorModifier, RubberBandXyZoomModifier, ZoomExtentsModifier, HeatmapColorMap, UniformHeatmapDataSeries, UniformHeatmapRenderableSeries, XyDataSeries, FastLineRenderableSeries, HeatmapLegend } from 'scichart';
|
|
4
4
|
export { SciChartSurface } from 'scichart';
|
|
5
|
+
import { SciChartJSLightTheme } from 'scichart/Charting/Themes/SciChartJSLightTheme';
|
|
5
6
|
|
|
6
7
|
// src/utils/helpers.ts
|
|
7
8
|
function generateId(prefix = "chart") {
|
|
@@ -128,7 +129,7 @@ function hexToRgba(hex, alpha = 1) {
|
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
// src/charts/BaseChart.ts
|
|
131
|
-
var SCICHART_VERSION = "
|
|
132
|
+
var SCICHART_VERSION = "4.0.933";
|
|
132
133
|
var sciChartConfigured = false;
|
|
133
134
|
function ensureSciChartConfigured() {
|
|
134
135
|
if (sciChartConfigured) return;
|
|
@@ -138,8 +139,7 @@ function ensureSciChartConfigured() {
|
|
|
138
139
|
} catch {
|
|
139
140
|
try {
|
|
140
141
|
SciChartSurface.configure({
|
|
141
|
-
wasmUrl: `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION}/_wasm/scichart2d.wasm
|
|
142
|
-
dataUrl: `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION}/_wasm/scichart2d.data`
|
|
142
|
+
wasmUrl: `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION}/_wasm/scichart2d.wasm`
|
|
143
143
|
});
|
|
144
144
|
sciChartConfigured = true;
|
|
145
145
|
} catch {
|
|
@@ -224,6 +224,42 @@ var BaseChart = class {
|
|
|
224
224
|
applyTheme() {
|
|
225
225
|
if (!this.surface) return;
|
|
226
226
|
this.surface.background = this.theme.backgroundColor ?? "#ffffff";
|
|
227
|
+
try {
|
|
228
|
+
const themeName = this.config.theme;
|
|
229
|
+
const { SciChartJSDarkTheme, SciChartJSLightTheme: SciChartJSLightTheme2 } = __require("scichart");
|
|
230
|
+
const nextThemeProvider = themeName === "light" ? new SciChartJSLightTheme2() : new SciChartJSDarkTheme();
|
|
231
|
+
this.surface.applyTheme?.(nextThemeProvider);
|
|
232
|
+
} catch {
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
const applyAxisTheme = (axis) => {
|
|
236
|
+
if (!axis) return;
|
|
237
|
+
axis.axisTitleStyle = {
|
|
238
|
+
...axis.axisTitleStyle ?? {},
|
|
239
|
+
color: this.theme.axis?.titleColor,
|
|
240
|
+
fontFamily: this.theme.fontFamily
|
|
241
|
+
};
|
|
242
|
+
axis.labelStyle = {
|
|
243
|
+
...axis.labelStyle ?? {},
|
|
244
|
+
color: this.theme.axis?.labelColor,
|
|
245
|
+
fontFamily: this.theme.fontFamily
|
|
246
|
+
};
|
|
247
|
+
axis.majorGridLineStyle = {
|
|
248
|
+
...axis.majorGridLineStyle ?? {},
|
|
249
|
+
color: this.theme.axis?.gridLineColor
|
|
250
|
+
};
|
|
251
|
+
axis.axisBorder = {
|
|
252
|
+
...axis.axisBorder ?? {},
|
|
253
|
+
color: this.theme.axis?.lineColor
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
const xAxes = this.surface.xAxes;
|
|
257
|
+
const yAxes = this.surface.yAxes;
|
|
258
|
+
const toArray = (axes) => axes?.asArray?.() ?? axes?.itemsArray ?? axes?.items ?? [];
|
|
259
|
+
for (const axis of toArray(xAxes)) applyAxisTheme(axis);
|
|
260
|
+
for (const axis of toArray(yAxes)) applyAxisTheme(axis);
|
|
261
|
+
} catch {
|
|
262
|
+
}
|
|
227
263
|
}
|
|
228
264
|
/**
|
|
229
265
|
* Set up resize observer for responsive charts
|
|
@@ -256,915 +292,97 @@ var BaseChart = class {
|
|
|
256
292
|
this.handleResize();
|
|
257
293
|
}
|
|
258
294
|
/**
|
|
259
|
-
*
|
|
260
|
-
|
|
261
|
-
async exportImage(format = "png") {
|
|
262
|
-
if (!this.surface) {
|
|
263
|
-
throw new Error("Chart not initialized");
|
|
264
|
-
}
|
|
265
|
-
const canvas = this.container?.querySelector("canvas");
|
|
266
|
-
if (!canvas) {
|
|
267
|
-
throw new Error("Canvas not found");
|
|
268
|
-
}
|
|
269
|
-
const mimeType = format === "jpeg" ? "image/jpeg" : "image/png";
|
|
270
|
-
return canvas.toDataURL(mimeType);
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Add event listener
|
|
274
|
-
*/
|
|
275
|
-
on(event, handler) {
|
|
276
|
-
if (!this.eventHandlers.has(event)) {
|
|
277
|
-
this.eventHandlers.set(event, /* @__PURE__ */ new Set());
|
|
278
|
-
}
|
|
279
|
-
this.eventHandlers.get(event).add(handler);
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Remove event listener
|
|
283
|
-
*/
|
|
284
|
-
off(event, handler) {
|
|
285
|
-
const handlers = this.eventHandlers.get(event);
|
|
286
|
-
if (handlers) {
|
|
287
|
-
handlers.delete(handler);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Emit an event
|
|
292
|
-
*/
|
|
293
|
-
emit(event, data) {
|
|
294
|
-
const handlers = this.eventHandlers.get(event);
|
|
295
|
-
if (handlers) {
|
|
296
|
-
handlers.forEach((handler) => handler(data));
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Destroy the chart and clean up resources
|
|
301
|
-
*/
|
|
302
|
-
destroy() {
|
|
303
|
-
if (this.isDestroyed) return;
|
|
304
|
-
if (this.resizeObserver) {
|
|
305
|
-
this.resizeObserver.disconnect();
|
|
306
|
-
this.resizeObserver = null;
|
|
307
|
-
}
|
|
308
|
-
this.eventHandlers.clear();
|
|
309
|
-
if (this.surface) {
|
|
310
|
-
this.surface.delete();
|
|
311
|
-
this.surface = null;
|
|
312
|
-
}
|
|
313
|
-
if (this.container) {
|
|
314
|
-
this.container.innerHTML = "";
|
|
315
|
-
}
|
|
316
|
-
this.isDestroyed = true;
|
|
317
|
-
this.isInitialized = false;
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Get current configuration
|
|
321
|
-
*/
|
|
322
|
-
getConfig() {
|
|
323
|
-
return { ...this.config };
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Get current theme
|
|
327
|
-
*/
|
|
328
|
-
getTheme() {
|
|
329
|
-
return { ...this.theme };
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Check if chart is initialized
|
|
333
|
-
*/
|
|
334
|
-
isReady() {
|
|
335
|
-
return this.isInitialized && !this.isDestroyed;
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
function getSciChartTheme(themeName) {
|
|
339
|
-
switch (themeName) {
|
|
340
|
-
case "light":
|
|
341
|
-
return new SciChartJSLightTheme();
|
|
342
|
-
case "dark":
|
|
343
|
-
case "modern":
|
|
344
|
-
case "midnight":
|
|
345
|
-
default:
|
|
346
|
-
return new SciChartJSDarkTheme();
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
var LineChart = class extends BaseChart {
|
|
350
|
-
constructor(config) {
|
|
351
|
-
super(config);
|
|
352
|
-
this.dataSeries = /* @__PURE__ */ new Map();
|
|
353
|
-
this.renderableSeries = [];
|
|
354
|
-
this.wasmContext = null;
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* Create the SciChart surface for line chart
|
|
358
|
-
*/
|
|
359
|
-
async createSurface() {
|
|
360
|
-
if (!this.container) {
|
|
361
|
-
throw new Error("Container not set");
|
|
362
|
-
}
|
|
363
|
-
const sciChartTheme = getSciChartTheme(this.config.theme);
|
|
364
|
-
if (!this.container.id) {
|
|
365
|
-
this.container.id = this.id;
|
|
366
|
-
}
|
|
367
|
-
const { sciChartSurface, wasmContext } = await SciChartSurface.create(
|
|
368
|
-
this.container,
|
|
369
|
-
{
|
|
370
|
-
theme: sciChartTheme
|
|
371
|
-
}
|
|
372
|
-
);
|
|
373
|
-
this.surface = sciChartSurface;
|
|
374
|
-
this.wasmContext = wasmContext;
|
|
375
|
-
const xAxis = new NumericAxis(wasmContext, {
|
|
376
|
-
axisTitle: this.config.xAxis?.title,
|
|
377
|
-
drawMajorGridLines: this.config.xAxis?.gridLines?.show ?? true,
|
|
378
|
-
drawMinorGridLines: false,
|
|
379
|
-
axisTitleStyle: {
|
|
380
|
-
fontSize: 14,
|
|
381
|
-
fontFamily: this.theme.fontFamily,
|
|
382
|
-
color: this.theme.axis?.titleColor
|
|
383
|
-
},
|
|
384
|
-
labelStyle: {
|
|
385
|
-
fontSize: 12,
|
|
386
|
-
fontFamily: this.theme.fontFamily,
|
|
387
|
-
color: this.theme.axis?.labelColor
|
|
388
|
-
},
|
|
389
|
-
majorGridLineStyle: {
|
|
390
|
-
color: this.theme.axis?.gridLineColor ?? "#e9ecef",
|
|
391
|
-
strokeThickness: 1
|
|
392
|
-
},
|
|
393
|
-
axisBorder: {
|
|
394
|
-
color: this.theme.axis?.lineColor ?? "#dee2e6"
|
|
395
|
-
},
|
|
396
|
-
autoRange: EAutoRange.Always
|
|
397
|
-
});
|
|
398
|
-
const yAxis = new NumericAxis(wasmContext, {
|
|
399
|
-
axisTitle: this.config.yAxis?.title,
|
|
400
|
-
drawMajorGridLines: this.config.yAxis?.gridLines?.show ?? true,
|
|
401
|
-
drawMinorGridLines: false,
|
|
402
|
-
axisTitleStyle: {
|
|
403
|
-
fontSize: 14,
|
|
404
|
-
fontFamily: this.theme.fontFamily,
|
|
405
|
-
color: this.theme.axis?.titleColor
|
|
406
|
-
},
|
|
407
|
-
labelStyle: {
|
|
408
|
-
fontSize: 12,
|
|
409
|
-
fontFamily: this.theme.fontFamily,
|
|
410
|
-
color: this.theme.axis?.labelColor
|
|
411
|
-
},
|
|
412
|
-
majorGridLineStyle: {
|
|
413
|
-
color: this.theme.axis?.gridLineColor ?? "#e9ecef",
|
|
414
|
-
strokeThickness: 1
|
|
415
|
-
},
|
|
416
|
-
axisBorder: {
|
|
417
|
-
color: this.theme.axis?.lineColor ?? "#dee2e6"
|
|
418
|
-
},
|
|
419
|
-
autoRange: EAutoRange.Always
|
|
420
|
-
});
|
|
421
|
-
if (this.config.xAxis?.min !== void 0 && this.config.xAxis?.max !== void 0) {
|
|
422
|
-
xAxis.visibleRange = new NumberRange(this.config.xAxis.min, this.config.xAxis.max);
|
|
423
|
-
xAxis.autoRange = EAutoRange.Never;
|
|
424
|
-
}
|
|
425
|
-
if (this.config.yAxis?.min !== void 0 && this.config.yAxis?.max !== void 0) {
|
|
426
|
-
yAxis.visibleRange = new NumberRange(this.config.yAxis.min, this.config.yAxis.max);
|
|
427
|
-
yAxis.autoRange = EAutoRange.Never;
|
|
428
|
-
}
|
|
429
|
-
sciChartSurface.xAxes.add(xAxis);
|
|
430
|
-
sciChartSurface.yAxes.add(yAxis);
|
|
431
|
-
if (this.config.tooltip?.enabled !== false) {
|
|
432
|
-
sciChartSurface.chartModifiers.add(
|
|
433
|
-
new RolloverModifier({
|
|
434
|
-
showTooltip: true,
|
|
435
|
-
showAxisLabel: true
|
|
436
|
-
})
|
|
437
|
-
);
|
|
438
|
-
}
|
|
439
|
-
sciChartSurface.chartModifiers.add(new ZoomPanModifier());
|
|
440
|
-
sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
|
|
441
|
-
this.addSeries(this.config.series);
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
* Add series to the chart
|
|
445
|
-
*/
|
|
446
|
-
addSeries(seriesConfigs) {
|
|
447
|
-
if (!this.surface || !this.wasmContext) return;
|
|
448
|
-
const wasmContext = this.wasmContext;
|
|
449
|
-
const colorPalette = this.theme.colorPalette ?? [];
|
|
450
|
-
seriesConfigs.forEach((seriesConfig, index) => {
|
|
451
|
-
const data = normalizeDataPoints(seriesConfig.data);
|
|
452
|
-
const xValues = extractXValues(data);
|
|
453
|
-
const yValues = extractYValues(data);
|
|
454
|
-
const dataSeries = new XyDataSeries(wasmContext, {
|
|
455
|
-
xValues,
|
|
456
|
-
yValues,
|
|
457
|
-
dataSeriesName: seriesConfig.name
|
|
458
|
-
});
|
|
459
|
-
this.dataSeries.set(seriesConfig.name, dataSeries);
|
|
460
|
-
const color = seriesConfig.color ?? colorPalette[index % colorPalette.length] ?? "#6366f1";
|
|
461
|
-
const lineSeries = new FastLineRenderableSeries(wasmContext);
|
|
462
|
-
lineSeries.dataSeries = dataSeries;
|
|
463
|
-
lineSeries.stroke = color;
|
|
464
|
-
lineSeries.strokeThickness = this.config.lineWidth ?? 2;
|
|
465
|
-
if (this.config.showPoints) {
|
|
466
|
-
lineSeries.pointMarker = new EllipsePointMarker(wasmContext, {
|
|
467
|
-
width: this.config.pointSize ?? 8,
|
|
468
|
-
height: this.config.pointSize ?? 8,
|
|
469
|
-
fill: color,
|
|
470
|
-
stroke: color,
|
|
471
|
-
strokeThickness: 0
|
|
472
|
-
});
|
|
473
|
-
}
|
|
474
|
-
if (this.config.animation !== false) {
|
|
475
|
-
lineSeries.animation = new SweepAnimation({
|
|
476
|
-
duration: typeof this.config.animation === "object" ? this.config.animation.duration ?? 500 : 500
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
this.renderableSeries.push(lineSeries);
|
|
480
|
-
this.surface.renderableSeries.add(lineSeries);
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
/**
|
|
484
|
-
* Set new data for the chart
|
|
485
|
-
*/
|
|
486
|
-
setData(data) {
|
|
487
|
-
if (!this.surface) {
|
|
488
|
-
this.config.series = data;
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
this.clearSeries();
|
|
492
|
-
this.config.series = data;
|
|
493
|
-
this.addSeries(data);
|
|
494
|
-
}
|
|
495
|
-
/**
|
|
496
|
-
* Update specific series data
|
|
295
|
+
* Reset zoom to fit all data (zoom extents)
|
|
296
|
+
* Note: not part of the ChartInstance interface, but available on concrete chart classes.
|
|
497
297
|
*/
|
|
498
|
-
|
|
499
|
-
const dataSeries = this.dataSeries.get(seriesName);
|
|
500
|
-
if (!dataSeries) {
|
|
501
|
-
console.warn(`Series "${seriesName}" not found`);
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
const normalized = normalizeDataPoints(data);
|
|
505
|
-
const xValues = extractXValues(normalized);
|
|
506
|
-
const yValues = extractYValues(normalized);
|
|
507
|
-
dataSeries.clear();
|
|
508
|
-
dataSeries.appendRange(xValues, yValues);
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* Append data to a series
|
|
512
|
-
*/
|
|
513
|
-
appendData(seriesName, data) {
|
|
514
|
-
const dataSeries = this.dataSeries.get(seriesName);
|
|
515
|
-
if (!dataSeries) {
|
|
516
|
-
console.warn(`Series "${seriesName}" not found`);
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
const points = Array.isArray(data) ? data : [data];
|
|
520
|
-
const normalized = normalizeDataPoints(points);
|
|
521
|
-
const xValues = extractXValues(normalized);
|
|
522
|
-
const yValues = extractYValues(normalized);
|
|
523
|
-
dataSeries.appendRange(xValues, yValues);
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* Clear all series
|
|
527
|
-
*/
|
|
528
|
-
clearSeries() {
|
|
529
|
-
if (!this.surface) return;
|
|
530
|
-
this.renderableSeries.forEach((series) => {
|
|
531
|
-
this.surface.renderableSeries.remove(series);
|
|
532
|
-
series.delete();
|
|
533
|
-
});
|
|
534
|
-
this.renderableSeries = [];
|
|
535
|
-
this.dataSeries.forEach((ds) => ds.delete());
|
|
536
|
-
this.dataSeries.clear();
|
|
537
|
-
}
|
|
538
|
-
/**
|
|
539
|
-
* Update chart
|
|
540
|
-
*/
|
|
541
|
-
update() {
|
|
542
|
-
if (!this.surface) return;
|
|
543
|
-
this.applyTheme();
|
|
544
|
-
this.surface.invalidateElement();
|
|
545
|
-
}
|
|
546
|
-
/**
|
|
547
|
-
* Apply theme to line chart
|
|
548
|
-
*/
|
|
549
|
-
applyTheme() {
|
|
550
|
-
super.applyTheme();
|
|
298
|
+
resetZoom() {
|
|
551
299
|
if (!this.surface) return;
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
if (!originalColor) {
|
|
556
|
-
series.stroke = colorPalette[index % colorPalette.length];
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
/**
|
|
561
|
-
* Destroy and clean up
|
|
562
|
-
*/
|
|
563
|
-
destroy() {
|
|
564
|
-
this.clearSeries();
|
|
565
|
-
super.destroy();
|
|
566
|
-
}
|
|
567
|
-
};
|
|
568
|
-
async function createLineChart(container, config) {
|
|
569
|
-
const chart = new LineChart(config);
|
|
570
|
-
await chart.init(container);
|
|
571
|
-
return chart;
|
|
572
|
-
}
|
|
573
|
-
function getSciChartTheme2(themeName) {
|
|
574
|
-
switch (themeName) {
|
|
575
|
-
case "light":
|
|
576
|
-
return new SciChartJSLightTheme();
|
|
577
|
-
case "dark":
|
|
578
|
-
case "modern":
|
|
579
|
-
case "midnight":
|
|
580
|
-
default:
|
|
581
|
-
return new SciChartJSDarkTheme();
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
var BarChart = class extends BaseChart {
|
|
585
|
-
constructor(config) {
|
|
586
|
-
super(config);
|
|
587
|
-
this.dataSeries = /* @__PURE__ */ new Map();
|
|
588
|
-
this.renderableSeries = [];
|
|
589
|
-
this.wasmContext = null;
|
|
590
|
-
}
|
|
591
|
-
/**
|
|
592
|
-
* Create the SciChart surface for bar chart
|
|
593
|
-
*/
|
|
594
|
-
async createSurface() {
|
|
595
|
-
if (!this.container) {
|
|
596
|
-
throw new Error("Container not set");
|
|
597
|
-
}
|
|
598
|
-
const sciChartTheme = getSciChartTheme2(this.config.theme);
|
|
599
|
-
if (!this.container.id) {
|
|
600
|
-
this.container.id = this.id;
|
|
601
|
-
}
|
|
602
|
-
const { sciChartSurface, wasmContext } = await SciChartSurface.create(
|
|
603
|
-
this.container,
|
|
604
|
-
{
|
|
605
|
-
theme: sciChartTheme
|
|
606
|
-
}
|
|
607
|
-
);
|
|
608
|
-
this.surface = sciChartSurface;
|
|
609
|
-
this.wasmContext = wasmContext;
|
|
610
|
-
const xAxis = new NumericAxis(wasmContext, {
|
|
611
|
-
axisTitle: this.config.xAxis?.title,
|
|
612
|
-
drawMajorGridLines: this.config.xAxis?.gridLines?.show ?? false,
|
|
613
|
-
drawMinorGridLines: false,
|
|
614
|
-
axisTitleStyle: {
|
|
615
|
-
fontSize: 14,
|
|
616
|
-
fontFamily: this.theme.fontFamily,
|
|
617
|
-
color: this.theme.axis?.titleColor
|
|
618
|
-
},
|
|
619
|
-
labelStyle: {
|
|
620
|
-
fontSize: 12,
|
|
621
|
-
fontFamily: this.theme.fontFamily,
|
|
622
|
-
color: this.theme.axis?.labelColor
|
|
623
|
-
},
|
|
624
|
-
autoRange: EAutoRange.Always
|
|
625
|
-
});
|
|
626
|
-
const yAxis = new NumericAxis(wasmContext, {
|
|
627
|
-
axisTitle: this.config.yAxis?.title,
|
|
628
|
-
drawMajorGridLines: this.config.yAxis?.gridLines?.show ?? true,
|
|
629
|
-
drawMinorGridLines: false,
|
|
630
|
-
axisTitleStyle: {
|
|
631
|
-
fontSize: 14,
|
|
632
|
-
fontFamily: this.theme.fontFamily,
|
|
633
|
-
color: this.theme.axis?.titleColor
|
|
634
|
-
},
|
|
635
|
-
labelStyle: {
|
|
636
|
-
fontSize: 12,
|
|
637
|
-
fontFamily: this.theme.fontFamily,
|
|
638
|
-
color: this.theme.axis?.labelColor
|
|
639
|
-
},
|
|
640
|
-
autoRange: EAutoRange.Always,
|
|
641
|
-
growBy: new NumberRange(0, 0.1)
|
|
642
|
-
// Add 10% padding at top
|
|
643
|
-
});
|
|
644
|
-
if (this.config.xAxis?.min !== void 0 && this.config.xAxis?.max !== void 0) {
|
|
645
|
-
xAxis.visibleRange = new NumberRange(this.config.xAxis.min, this.config.xAxis.max);
|
|
646
|
-
xAxis.autoRange = EAutoRange.Never;
|
|
647
|
-
}
|
|
648
|
-
if (this.config.yAxis?.min !== void 0 && this.config.yAxis?.max !== void 0) {
|
|
649
|
-
yAxis.visibleRange = new NumberRange(this.config.yAxis.min, this.config.yAxis.max);
|
|
650
|
-
yAxis.autoRange = EAutoRange.Never;
|
|
651
|
-
}
|
|
652
|
-
sciChartSurface.xAxes.add(xAxis);
|
|
653
|
-
sciChartSurface.yAxes.add(yAxis);
|
|
654
|
-
if (this.config.tooltip?.enabled !== false) {
|
|
655
|
-
sciChartSurface.chartModifiers.add(
|
|
656
|
-
new RolloverModifier({
|
|
657
|
-
showTooltip: true,
|
|
658
|
-
showAxisLabel: true
|
|
659
|
-
})
|
|
660
|
-
);
|
|
661
|
-
}
|
|
662
|
-
sciChartSurface.chartModifiers.add(new ZoomPanModifier());
|
|
663
|
-
this.addSeries(this.config.series);
|
|
664
|
-
}
|
|
665
|
-
/**
|
|
666
|
-
* Add series to the chart
|
|
667
|
-
*/
|
|
668
|
-
addSeries(seriesConfigs) {
|
|
669
|
-
if (!this.surface || !this.wasmContext) return;
|
|
670
|
-
const wasmContext = this.wasmContext;
|
|
671
|
-
const colorPalette = this.theme.colorPalette ?? [];
|
|
672
|
-
const seriesCount = seriesConfigs.length;
|
|
673
|
-
const dataPointWidth = this.config.barWidth ?? 0.7;
|
|
674
|
-
seriesConfigs.forEach((seriesConfig, index) => {
|
|
675
|
-
const data = normalizeDataPoints(seriesConfig.data);
|
|
676
|
-
let xValues = extractXValues(data);
|
|
677
|
-
if (!this.config.stacked && seriesCount > 1) {
|
|
678
|
-
const offset = (index - (seriesCount - 1) / 2) * (dataPointWidth / seriesCount);
|
|
679
|
-
xValues = xValues.map((x) => x + offset);
|
|
680
|
-
}
|
|
681
|
-
const yValues = extractYValues(data);
|
|
682
|
-
const dataSeries = new XyDataSeries(wasmContext, {
|
|
683
|
-
xValues,
|
|
684
|
-
yValues,
|
|
685
|
-
dataSeriesName: seriesConfig.name
|
|
686
|
-
});
|
|
687
|
-
this.dataSeries.set(seriesConfig.name, dataSeries);
|
|
688
|
-
const color = seriesConfig.color ?? colorPalette[index % colorPalette.length] ?? "#6366f1";
|
|
689
|
-
const columnSeries = new FastColumnRenderableSeries(wasmContext);
|
|
690
|
-
columnSeries.dataSeries = dataSeries;
|
|
691
|
-
columnSeries.fill = color;
|
|
692
|
-
columnSeries.stroke = color;
|
|
693
|
-
columnSeries.strokeThickness = 0;
|
|
694
|
-
columnSeries.dataPointWidth = this.config.stacked ? dataPointWidth : dataPointWidth / seriesCount;
|
|
695
|
-
columnSeries.cornerRadius = this.config.borderRadius ?? 0;
|
|
696
|
-
if (this.config.animation !== false) {
|
|
697
|
-
columnSeries.animation = new WaveAnimation({
|
|
698
|
-
duration: typeof this.config.animation === "object" ? this.config.animation.duration ?? 500 : 500
|
|
699
|
-
});
|
|
700
|
-
}
|
|
701
|
-
columnSeries.fillLinearGradient = new GradientParams(
|
|
702
|
-
new Point(0, 0),
|
|
703
|
-
new Point(0, 1),
|
|
704
|
-
[
|
|
705
|
-
{ color, offset: 0 },
|
|
706
|
-
{ color: hexToRgba(color, 0.7), offset: 1 }
|
|
707
|
-
]
|
|
708
|
-
);
|
|
709
|
-
this.renderableSeries.push(columnSeries);
|
|
710
|
-
this.surface.renderableSeries.add(columnSeries);
|
|
711
|
-
});
|
|
712
|
-
}
|
|
713
|
-
/**
|
|
714
|
-
* Set new data for the chart
|
|
715
|
-
*/
|
|
716
|
-
setData(data) {
|
|
717
|
-
if (!this.surface) {
|
|
718
|
-
this.config.series = data;
|
|
719
|
-
return;
|
|
720
|
-
}
|
|
721
|
-
this.clearSeries();
|
|
722
|
-
this.config.series = data;
|
|
723
|
-
this.addSeries(data);
|
|
724
|
-
}
|
|
725
|
-
/**
|
|
726
|
-
* Update specific series data
|
|
727
|
-
*/
|
|
728
|
-
updateSeriesData(seriesName, data) {
|
|
729
|
-
const dataSeries = this.dataSeries.get(seriesName);
|
|
730
|
-
if (!dataSeries) {
|
|
731
|
-
console.warn(`Series "${seriesName}" not found`);
|
|
732
|
-
return;
|
|
733
|
-
}
|
|
734
|
-
const normalized = normalizeDataPoints(data);
|
|
735
|
-
const xValues = extractXValues(normalized);
|
|
736
|
-
const yValues = extractYValues(normalized);
|
|
737
|
-
dataSeries.clear();
|
|
738
|
-
dataSeries.appendRange(xValues, yValues);
|
|
739
|
-
}
|
|
740
|
-
/**
|
|
741
|
-
* Clear all series
|
|
742
|
-
*/
|
|
743
|
-
clearSeries() {
|
|
744
|
-
if (!this.surface) return;
|
|
745
|
-
this.renderableSeries.forEach((series) => {
|
|
746
|
-
this.surface.renderableSeries.remove(series);
|
|
747
|
-
series.delete();
|
|
748
|
-
});
|
|
749
|
-
this.renderableSeries = [];
|
|
750
|
-
this.dataSeries.forEach((ds) => ds.delete());
|
|
751
|
-
this.dataSeries.clear();
|
|
752
|
-
}
|
|
753
|
-
/**
|
|
754
|
-
* Update chart
|
|
755
|
-
*/
|
|
756
|
-
update() {
|
|
757
|
-
if (!this.surface) return;
|
|
758
|
-
this.applyTheme();
|
|
759
|
-
this.surface.invalidateElement();
|
|
760
|
-
}
|
|
761
|
-
/**
|
|
762
|
-
* Destroy and clean up
|
|
763
|
-
*/
|
|
764
|
-
destroy() {
|
|
765
|
-
this.clearSeries();
|
|
766
|
-
super.destroy();
|
|
767
|
-
}
|
|
768
|
-
};
|
|
769
|
-
async function createBarChart(container, config) {
|
|
770
|
-
const chart = new BarChart(config);
|
|
771
|
-
await chart.init(container);
|
|
772
|
-
return chart;
|
|
773
|
-
}
|
|
774
|
-
function getSciChartTheme3(themeName) {
|
|
775
|
-
switch (themeName) {
|
|
776
|
-
case "light":
|
|
777
|
-
return new SciChartJSLightTheme();
|
|
778
|
-
case "dark":
|
|
779
|
-
case "modern":
|
|
780
|
-
case "midnight":
|
|
781
|
-
default:
|
|
782
|
-
return new SciChartJSDarkTheme();
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
var AreaChart = class extends BaseChart {
|
|
786
|
-
constructor(config) {
|
|
787
|
-
super(config);
|
|
788
|
-
this.dataSeries = /* @__PURE__ */ new Map();
|
|
789
|
-
this.renderableSeries = [];
|
|
790
|
-
this.wasmContext = null;
|
|
791
|
-
}
|
|
792
|
-
/**
|
|
793
|
-
* Create the SciChart surface for area chart
|
|
794
|
-
*/
|
|
795
|
-
async createSurface() {
|
|
796
|
-
if (!this.container) {
|
|
797
|
-
throw new Error("Container not set");
|
|
798
|
-
}
|
|
799
|
-
const sciChartTheme = getSciChartTheme3(this.config.theme);
|
|
800
|
-
if (!this.container.id) {
|
|
801
|
-
this.container.id = this.id;
|
|
300
|
+
try {
|
|
301
|
+
this.surface.zoomExtents?.();
|
|
302
|
+
} catch {
|
|
802
303
|
}
|
|
803
|
-
const { sciChartSurface, wasmContext } = await SciChartSurface.create(
|
|
804
|
-
this.container,
|
|
805
|
-
{
|
|
806
|
-
theme: sciChartTheme
|
|
807
|
-
}
|
|
808
|
-
);
|
|
809
|
-
this.surface = sciChartSurface;
|
|
810
|
-
this.wasmContext = wasmContext;
|
|
811
|
-
const xAxis = new NumericAxis(wasmContext, {
|
|
812
|
-
axisTitle: this.config.xAxis?.title,
|
|
813
|
-
drawMajorGridLines: this.config.xAxis?.gridLines?.show ?? true,
|
|
814
|
-
drawMinorGridLines: false,
|
|
815
|
-
axisTitleStyle: {
|
|
816
|
-
fontSize: 14,
|
|
817
|
-
fontFamily: this.theme.fontFamily,
|
|
818
|
-
color: this.theme.axis?.titleColor
|
|
819
|
-
},
|
|
820
|
-
labelStyle: {
|
|
821
|
-
fontSize: 12,
|
|
822
|
-
fontFamily: this.theme.fontFamily,
|
|
823
|
-
color: this.theme.axis?.labelColor
|
|
824
|
-
},
|
|
825
|
-
autoRange: EAutoRange.Always
|
|
826
|
-
});
|
|
827
|
-
const yAxis = new NumericAxis(wasmContext, {
|
|
828
|
-
axisTitle: this.config.yAxis?.title,
|
|
829
|
-
drawMajorGridLines: this.config.yAxis?.gridLines?.show ?? true,
|
|
830
|
-
drawMinorGridLines: false,
|
|
831
|
-
axisTitleStyle: {
|
|
832
|
-
fontSize: 14,
|
|
833
|
-
fontFamily: this.theme.fontFamily,
|
|
834
|
-
color: this.theme.axis?.titleColor
|
|
835
|
-
},
|
|
836
|
-
labelStyle: {
|
|
837
|
-
fontSize: 12,
|
|
838
|
-
fontFamily: this.theme.fontFamily,
|
|
839
|
-
color: this.theme.axis?.labelColor
|
|
840
|
-
},
|
|
841
|
-
autoRange: EAutoRange.Always,
|
|
842
|
-
growBy: new NumberRange(0, 0.1)
|
|
843
|
-
});
|
|
844
|
-
if (this.config.xAxis?.min !== void 0 && this.config.xAxis?.max !== void 0) {
|
|
845
|
-
xAxis.visibleRange = new NumberRange(this.config.xAxis.min, this.config.xAxis.max);
|
|
846
|
-
xAxis.autoRange = EAutoRange.Never;
|
|
847
|
-
}
|
|
848
|
-
if (this.config.yAxis?.min !== void 0 && this.config.yAxis?.max !== void 0) {
|
|
849
|
-
yAxis.visibleRange = new NumberRange(this.config.yAxis.min, this.config.yAxis.max);
|
|
850
|
-
yAxis.autoRange = EAutoRange.Never;
|
|
851
|
-
}
|
|
852
|
-
sciChartSurface.xAxes.add(xAxis);
|
|
853
|
-
sciChartSurface.yAxes.add(yAxis);
|
|
854
|
-
if (this.config.tooltip?.enabled !== false) {
|
|
855
|
-
sciChartSurface.chartModifiers.add(
|
|
856
|
-
new RolloverModifier({
|
|
857
|
-
showTooltip: true,
|
|
858
|
-
showAxisLabel: true
|
|
859
|
-
})
|
|
860
|
-
);
|
|
861
|
-
}
|
|
862
|
-
sciChartSurface.chartModifiers.add(new ZoomPanModifier());
|
|
863
|
-
sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
|
|
864
|
-
this.addSeries(this.config.series);
|
|
865
304
|
}
|
|
866
305
|
/**
|
|
867
|
-
*
|
|
868
|
-
*/
|
|
869
|
-
addSeries(seriesConfigs) {
|
|
870
|
-
if (!this.surface || !this.wasmContext) return;
|
|
871
|
-
const wasmContext = this.wasmContext;
|
|
872
|
-
const colorPalette = this.theme.colorPalette ?? [];
|
|
873
|
-
const fillOpacity = this.config.fillOpacity ?? 0.5;
|
|
874
|
-
seriesConfigs.forEach((seriesConfig, index) => {
|
|
875
|
-
const data = normalizeDataPoints(seriesConfig.data);
|
|
876
|
-
const xValues = extractXValues(data);
|
|
877
|
-
const yValues = extractYValues(data);
|
|
878
|
-
const dataSeries = new XyDataSeries(wasmContext, {
|
|
879
|
-
xValues,
|
|
880
|
-
yValues,
|
|
881
|
-
dataSeriesName: seriesConfig.name
|
|
882
|
-
});
|
|
883
|
-
this.dataSeries.set(seriesConfig.name, dataSeries);
|
|
884
|
-
const color = seriesConfig.color ?? colorPalette[index % colorPalette.length] ?? "#6366f1";
|
|
885
|
-
const areaSeries = new FastMountainRenderableSeries(wasmContext, {
|
|
886
|
-
dataSeries,
|
|
887
|
-
stroke: color,
|
|
888
|
-
strokeThickness: this.config.lineWidth ?? 2,
|
|
889
|
-
fill: hexToRgba(color, fillOpacity),
|
|
890
|
-
...this.config.animation !== false && {
|
|
891
|
-
animation: new SweepAnimation({
|
|
892
|
-
duration: typeof this.config.animation === "object" ? this.config.animation.duration ?? 500 : 500
|
|
893
|
-
})
|
|
894
|
-
}
|
|
895
|
-
});
|
|
896
|
-
areaSeries.fillLinearGradient = new GradientParams(
|
|
897
|
-
new Point(0, 0),
|
|
898
|
-
new Point(0, 1),
|
|
899
|
-
[
|
|
900
|
-
{ color: hexToRgba(color, fillOpacity), offset: 0 },
|
|
901
|
-
{ color: hexToRgba(color, 0.05), offset: 1 }
|
|
902
|
-
]
|
|
903
|
-
);
|
|
904
|
-
this.renderableSeries.push(areaSeries);
|
|
905
|
-
this.surface.renderableSeries.add(areaSeries);
|
|
906
|
-
});
|
|
907
|
-
}
|
|
908
|
-
/**
|
|
909
|
-
* Set new data for the chart
|
|
306
|
+
* Export chart as image
|
|
910
307
|
*/
|
|
911
|
-
|
|
308
|
+
async exportImage(format = "png") {
|
|
912
309
|
if (!this.surface) {
|
|
913
|
-
|
|
914
|
-
return;
|
|
915
|
-
}
|
|
916
|
-
this.clearSeries();
|
|
917
|
-
this.config.series = data;
|
|
918
|
-
this.addSeries(data);
|
|
919
|
-
}
|
|
920
|
-
/**
|
|
921
|
-
* Update specific series data
|
|
922
|
-
*/
|
|
923
|
-
updateSeriesData(seriesName, data) {
|
|
924
|
-
const dataSeries = this.dataSeries.get(seriesName);
|
|
925
|
-
if (!dataSeries) {
|
|
926
|
-
console.warn(`Series "${seriesName}" not found`);
|
|
927
|
-
return;
|
|
928
|
-
}
|
|
929
|
-
const normalized = normalizeDataPoints(data);
|
|
930
|
-
const xValues = extractXValues(normalized);
|
|
931
|
-
const yValues = extractYValues(normalized);
|
|
932
|
-
dataSeries.clear();
|
|
933
|
-
dataSeries.appendRange(xValues, yValues);
|
|
934
|
-
}
|
|
935
|
-
/**
|
|
936
|
-
* Clear all series
|
|
937
|
-
*/
|
|
938
|
-
clearSeries() {
|
|
939
|
-
if (!this.surface) return;
|
|
940
|
-
this.renderableSeries.forEach((series) => {
|
|
941
|
-
this.surface.renderableSeries.remove(series);
|
|
942
|
-
series.delete();
|
|
943
|
-
});
|
|
944
|
-
this.renderableSeries = [];
|
|
945
|
-
this.dataSeries.forEach((ds) => ds.delete());
|
|
946
|
-
this.dataSeries.clear();
|
|
947
|
-
}
|
|
948
|
-
/**
|
|
949
|
-
* Update chart
|
|
950
|
-
*/
|
|
951
|
-
update() {
|
|
952
|
-
if (!this.surface) return;
|
|
953
|
-
this.applyTheme();
|
|
954
|
-
this.surface.invalidateElement();
|
|
955
|
-
}
|
|
956
|
-
/**
|
|
957
|
-
* Destroy and clean up
|
|
958
|
-
*/
|
|
959
|
-
destroy() {
|
|
960
|
-
this.clearSeries();
|
|
961
|
-
super.destroy();
|
|
962
|
-
}
|
|
963
|
-
};
|
|
964
|
-
async function createAreaChart(container, config) {
|
|
965
|
-
const chart = new AreaChart(config);
|
|
966
|
-
await chart.init(container);
|
|
967
|
-
return chart;
|
|
968
|
-
}
|
|
969
|
-
function getSciChartTheme4(themeName) {
|
|
970
|
-
switch (themeName) {
|
|
971
|
-
case "light":
|
|
972
|
-
return new SciChartJSLightTheme();
|
|
973
|
-
case "dark":
|
|
974
|
-
case "modern":
|
|
975
|
-
case "midnight":
|
|
976
|
-
default:
|
|
977
|
-
return new SciChartJSDarkTheme();
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
var defaultColorStops = [
|
|
981
|
-
{ offset: 0, color: "#000080" },
|
|
982
|
-
// Dark blue
|
|
983
|
-
{ offset: 0.2, color: "#0000ff" },
|
|
984
|
-
// Blue
|
|
985
|
-
{ offset: 0.4, color: "#00ffff" },
|
|
986
|
-
// Cyan
|
|
987
|
-
{ offset: 0.6, color: "#00ff00" },
|
|
988
|
-
// Green
|
|
989
|
-
{ offset: 0.8, color: "#ffff00" },
|
|
990
|
-
// Yellow
|
|
991
|
-
{ offset: 1, color: "#ff0000" }
|
|
992
|
-
// Red
|
|
993
|
-
];
|
|
994
|
-
var HeatmapChart = class extends BaseChart {
|
|
995
|
-
constructor(config) {
|
|
996
|
-
super(config);
|
|
997
|
-
this.heatmapDataSeries = null;
|
|
998
|
-
this.heatmapSeries = null;
|
|
999
|
-
this.wasmContext = null;
|
|
1000
|
-
}
|
|
1001
|
-
/**
|
|
1002
|
-
* Create the SciChart surface for heatmap chart
|
|
1003
|
-
*/
|
|
1004
|
-
async createSurface() {
|
|
1005
|
-
if (!this.container) {
|
|
1006
|
-
throw new Error("Container not set");
|
|
1007
|
-
}
|
|
1008
|
-
const sciChartTheme = getSciChartTheme4(this.config.theme);
|
|
1009
|
-
if (!this.container.id) {
|
|
1010
|
-
this.container.id = this.id;
|
|
310
|
+
throw new Error("Chart not initialized");
|
|
1011
311
|
}
|
|
1012
|
-
const
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
);
|
|
1018
|
-
this.surface = sciChartSurface;
|
|
1019
|
-
this.wasmContext = wasmContext;
|
|
1020
|
-
const xAxis = new NumericAxis(wasmContext, {
|
|
1021
|
-
axisTitle: this.config.xAxis?.title,
|
|
1022
|
-
drawMajorGridLines: this.config.xAxis?.gridLines?.show ?? false,
|
|
1023
|
-
drawMinorGridLines: false,
|
|
1024
|
-
axisTitleStyle: {
|
|
1025
|
-
fontSize: 14,
|
|
1026
|
-
fontFamily: this.theme.fontFamily,
|
|
1027
|
-
color: this.theme.axis?.titleColor
|
|
1028
|
-
},
|
|
1029
|
-
labelStyle: {
|
|
1030
|
-
fontSize: 12,
|
|
1031
|
-
fontFamily: this.theme.fontFamily,
|
|
1032
|
-
color: this.theme.axis?.labelColor
|
|
1033
|
-
},
|
|
1034
|
-
autoRange: EAutoRange.Always
|
|
1035
|
-
});
|
|
1036
|
-
const yAxis = new NumericAxis(wasmContext, {
|
|
1037
|
-
axisTitle: this.config.yAxis?.title,
|
|
1038
|
-
drawMajorGridLines: this.config.yAxis?.gridLines?.show ?? false,
|
|
1039
|
-
drawMinorGridLines: false,
|
|
1040
|
-
axisTitleStyle: {
|
|
1041
|
-
fontSize: 14,
|
|
1042
|
-
fontFamily: this.theme.fontFamily,
|
|
1043
|
-
color: this.theme.axis?.titleColor
|
|
1044
|
-
},
|
|
1045
|
-
labelStyle: {
|
|
1046
|
-
fontSize: 12,
|
|
1047
|
-
fontFamily: this.theme.fontFamily,
|
|
1048
|
-
color: this.theme.axis?.labelColor
|
|
1049
|
-
},
|
|
1050
|
-
autoRange: EAutoRange.Always
|
|
1051
|
-
});
|
|
1052
|
-
if (this.config.xAxis?.min !== void 0 && this.config.xAxis?.max !== void 0) {
|
|
1053
|
-
xAxis.visibleRange = new NumberRange(this.config.xAxis.min, this.config.xAxis.max);
|
|
1054
|
-
xAxis.autoRange = EAutoRange.Never;
|
|
1055
|
-
}
|
|
1056
|
-
if (this.config.yAxis?.min !== void 0 && this.config.yAxis?.max !== void 0) {
|
|
1057
|
-
yAxis.visibleRange = new NumberRange(this.config.yAxis.min, this.config.yAxis.max);
|
|
1058
|
-
yAxis.autoRange = EAutoRange.Never;
|
|
1059
|
-
}
|
|
1060
|
-
sciChartSurface.xAxes.add(xAxis);
|
|
1061
|
-
sciChartSurface.yAxes.add(yAxis);
|
|
1062
|
-
if (this.config.tooltip?.enabled !== false) {
|
|
1063
|
-
sciChartSurface.chartModifiers.add(
|
|
1064
|
-
new RolloverModifier({
|
|
1065
|
-
showTooltip: true,
|
|
1066
|
-
showAxisLabel: true
|
|
1067
|
-
})
|
|
1068
|
-
);
|
|
1069
|
-
}
|
|
1070
|
-
sciChartSurface.chartModifiers.add(new ZoomPanModifier());
|
|
1071
|
-
sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
|
|
1072
|
-
this.addHeatmapData(this.config.zValues);
|
|
1073
|
-
}
|
|
1074
|
-
/**
|
|
1075
|
-
* Add heatmap data to the chart
|
|
1076
|
-
*/
|
|
1077
|
-
addHeatmapData(zValues) {
|
|
1078
|
-
if (!this.surface || !this.wasmContext) return;
|
|
1079
|
-
const wasmContext = this.wasmContext;
|
|
1080
|
-
let min = this.config.colorMin;
|
|
1081
|
-
let max = this.config.colorMax;
|
|
1082
|
-
if (min === void 0 || max === void 0) {
|
|
1083
|
-
const flatValues = zValues.flat();
|
|
1084
|
-
min = min ?? Math.min(...flatValues);
|
|
1085
|
-
max = max ?? Math.max(...flatValues);
|
|
1086
|
-
}
|
|
1087
|
-
this.heatmapDataSeries = new UniformHeatmapDataSeries(wasmContext, {
|
|
1088
|
-
zValues,
|
|
1089
|
-
xStart: this.config.xStart ?? 0,
|
|
1090
|
-
xStep: this.config.xStep ?? 1,
|
|
1091
|
-
yStart: this.config.yStart ?? 0,
|
|
1092
|
-
yStep: this.config.yStep ?? 1
|
|
1093
|
-
});
|
|
1094
|
-
const colorStops = this.config.colorStops ?? defaultColorStops;
|
|
1095
|
-
this.heatmapSeries = new UniformHeatmapRenderableSeries(wasmContext, {
|
|
1096
|
-
dataSeries: this.heatmapDataSeries,
|
|
1097
|
-
colorMap: new HeatmapColorMap({
|
|
1098
|
-
minimum: min,
|
|
1099
|
-
maximum: max,
|
|
1100
|
-
gradientStops: colorStops
|
|
1101
|
-
})
|
|
1102
|
-
});
|
|
1103
|
-
this.surface.renderableSeries.add(this.heatmapSeries);
|
|
312
|
+
const canvas = this.container?.querySelector("canvas");
|
|
313
|
+
if (!canvas) {
|
|
314
|
+
throw new Error("Canvas not found");
|
|
315
|
+
}
|
|
316
|
+
const mimeType = format === "jpeg" ? "image/jpeg" : "image/png";
|
|
317
|
+
return canvas.toDataURL(mimeType);
|
|
1104
318
|
}
|
|
1105
319
|
/**
|
|
1106
|
-
*
|
|
320
|
+
* Add event listener
|
|
1107
321
|
*/
|
|
1108
|
-
|
|
1109
|
-
|
|
322
|
+
on(event, handler) {
|
|
323
|
+
if (!this.eventHandlers.has(event)) {
|
|
324
|
+
this.eventHandlers.set(event, /* @__PURE__ */ new Set());
|
|
325
|
+
}
|
|
326
|
+
this.eventHandlers.get(event).add(handler);
|
|
1110
327
|
}
|
|
1111
328
|
/**
|
|
1112
|
-
*
|
|
329
|
+
* Remove event listener
|
|
1113
330
|
*/
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
331
|
+
off(event, handler) {
|
|
332
|
+
const handlers = this.eventHandlers.get(event);
|
|
333
|
+
if (handlers) {
|
|
334
|
+
handlers.delete(handler);
|
|
1118
335
|
}
|
|
1119
|
-
this.clearHeatmap();
|
|
1120
|
-
this.config.zValues = zValues;
|
|
1121
|
-
this.addHeatmapData(zValues);
|
|
1122
336
|
}
|
|
1123
337
|
/**
|
|
1124
|
-
*
|
|
338
|
+
* Emit an event
|
|
1125
339
|
*/
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
340
|
+
emit(event, data) {
|
|
341
|
+
const handlers = this.eventHandlers.get(event);
|
|
342
|
+
if (handlers) {
|
|
343
|
+
handlers.forEach((handler) => handler(data));
|
|
1129
344
|
}
|
|
1130
345
|
}
|
|
1131
346
|
/**
|
|
1132
|
-
*
|
|
347
|
+
* Destroy the chart and clean up resources
|
|
1133
348
|
*/
|
|
1134
|
-
|
|
1135
|
-
if (
|
|
1136
|
-
if (this.
|
|
1137
|
-
this.
|
|
1138
|
-
this.
|
|
1139
|
-
this.heatmapSeries = null;
|
|
349
|
+
destroy() {
|
|
350
|
+
if (this.isDestroyed) return;
|
|
351
|
+
if (this.resizeObserver) {
|
|
352
|
+
this.resizeObserver.disconnect();
|
|
353
|
+
this.resizeObserver = null;
|
|
1140
354
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
this.
|
|
355
|
+
this.eventHandlers.clear();
|
|
356
|
+
if (this.surface) {
|
|
357
|
+
this.surface.delete();
|
|
358
|
+
this.surface = null;
|
|
359
|
+
}
|
|
360
|
+
if (this.container) {
|
|
361
|
+
this.container.innerHTML = "";
|
|
1144
362
|
}
|
|
363
|
+
this.isDestroyed = true;
|
|
364
|
+
this.isInitialized = false;
|
|
1145
365
|
}
|
|
1146
366
|
/**
|
|
1147
|
-
*
|
|
367
|
+
* Get current configuration
|
|
1148
368
|
*/
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
this.applyTheme();
|
|
1152
|
-
this.surface.invalidateElement();
|
|
369
|
+
getConfig() {
|
|
370
|
+
return { ...this.config };
|
|
1153
371
|
}
|
|
1154
372
|
/**
|
|
1155
|
-
*
|
|
373
|
+
* Get current theme
|
|
1156
374
|
*/
|
|
1157
|
-
|
|
1158
|
-
this.
|
|
1159
|
-
|
|
375
|
+
getTheme() {
|
|
376
|
+
return { ...this.theme };
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Check if chart is initialized
|
|
380
|
+
*/
|
|
381
|
+
isReady() {
|
|
382
|
+
return this.isInitialized && !this.isDestroyed;
|
|
1160
383
|
}
|
|
1161
384
|
};
|
|
1162
|
-
|
|
1163
|
-
const chart = new HeatmapChart(config);
|
|
1164
|
-
await chart.init(container);
|
|
1165
|
-
return chart;
|
|
1166
|
-
}
|
|
1167
|
-
var SCICHART_VERSION2 = "3.5.750";
|
|
385
|
+
var SCICHART_VERSION2 = "4.0.933";
|
|
1168
386
|
var sciChart3DConfigured = false;
|
|
1169
387
|
function ensureSciChart3DConfigured() {
|
|
1170
388
|
if (sciChart3DConfigured) return;
|
|
@@ -1174,15 +392,14 @@ function ensureSciChart3DConfigured() {
|
|
|
1174
392
|
} catch {
|
|
1175
393
|
try {
|
|
1176
394
|
SciChart3DSurface.configure({
|
|
1177
|
-
wasmUrl: `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION2}/_wasm/scichart3d.wasm
|
|
1178
|
-
dataUrl: `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION2}/_wasm/scichart3d.data`
|
|
395
|
+
wasmUrl: `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION2}/_wasm/scichart3d.wasm`
|
|
1179
396
|
});
|
|
1180
397
|
sciChart3DConfigured = true;
|
|
1181
398
|
} catch {
|
|
1182
399
|
}
|
|
1183
400
|
}
|
|
1184
401
|
}
|
|
1185
|
-
var
|
|
402
|
+
var defaultColorStops = [
|
|
1186
403
|
{ offset: 0, color: "#1e3a8a" },
|
|
1187
404
|
// Dark blue
|
|
1188
405
|
{ offset: 0.25, color: "#3b82f6" },
|
|
@@ -1279,7 +496,7 @@ var Surface3DChart = class {
|
|
|
1279
496
|
xStep: this.config.xStep ?? 1,
|
|
1280
497
|
zStep: this.config.zStep ?? 1
|
|
1281
498
|
});
|
|
1282
|
-
const colorStops = this.config.colorStops ??
|
|
499
|
+
const colorStops = this.config.colorStops ?? defaultColorStops;
|
|
1283
500
|
const colorPalette = new GradientColorPalette(wasmContext, {
|
|
1284
501
|
gradientStops: colorStops
|
|
1285
502
|
});
|
|
@@ -1382,7 +599,7 @@ async function createSurface3DChart(container, config) {
|
|
|
1382
599
|
await chart.init(container);
|
|
1383
600
|
return chart;
|
|
1384
601
|
}
|
|
1385
|
-
var SCICHART_VERSION3 = "
|
|
602
|
+
var SCICHART_VERSION3 = "4.0.933";
|
|
1386
603
|
var sciChart3DConfigured2 = false;
|
|
1387
604
|
function ensureSciChart3DConfigured2() {
|
|
1388
605
|
if (sciChart3DConfigured2) return;
|
|
@@ -1392,8 +609,7 @@ function ensureSciChart3DConfigured2() {
|
|
|
1392
609
|
} catch {
|
|
1393
610
|
try {
|
|
1394
611
|
SciChart3DSurface.configure({
|
|
1395
|
-
wasmUrl: `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION3}/_wasm/scichart3d.wasm
|
|
1396
|
-
dataUrl: `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION3}/_wasm/scichart3d.data`
|
|
612
|
+
wasmUrl: `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION3}/_wasm/scichart3d.wasm`
|
|
1397
613
|
});
|
|
1398
614
|
sciChart3DConfigured2 = true;
|
|
1399
615
|
} catch {
|
|
@@ -1641,18 +857,571 @@ async function createColumn3DChart(container, config) {
|
|
|
1641
857
|
await chart.init(container);
|
|
1642
858
|
return chart;
|
|
1643
859
|
}
|
|
860
|
+
var SCICHART_VERSION4 = "4.0.933";
|
|
861
|
+
var sciChartConfigured2 = false;
|
|
862
|
+
var configureSciChartCDN = () => {
|
|
863
|
+
if (sciChartConfigured2) return;
|
|
864
|
+
try {
|
|
865
|
+
const cdnBase = `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION4}/_wasm`;
|
|
866
|
+
SciChartSurface.configure({
|
|
867
|
+
wasmUrl: `${cdnBase}/scichart2d.wasm`,
|
|
868
|
+
dataUrl: `${cdnBase}/scichart2d.data`
|
|
869
|
+
});
|
|
870
|
+
sciChartConfigured2 = true;
|
|
871
|
+
} catch (e) {
|
|
872
|
+
console.warn("Failed to configure SciChart CDN:", e);
|
|
873
|
+
}
|
|
874
|
+
};
|
|
875
|
+
var HORIZONTAL_RESOLUTION = 360;
|
|
876
|
+
var VERTICAL_SCALE_MAX_DEFAULT = 5e3;
|
|
877
|
+
var HORIZONTAL_RESOLUTION_MULTIPLIER = 1;
|
|
878
|
+
var RESOLUTION_CONFIG = {
|
|
879
|
+
UNI: {
|
|
880
|
+
HI: { VERTICAL_RESOLUTION: 256, VERTICAL_OFFSET: 0, MIN_PEAK_ZERO: true },
|
|
881
|
+
LO: { VERTICAL_RESOLUTION: 100, VERTICAL_OFFSET: 0, MIN_PEAK_ZERO: true }
|
|
882
|
+
},
|
|
883
|
+
BI: {
|
|
884
|
+
HI: { VERTICAL_RESOLUTION: 512, VERTICAL_OFFSET: 256, MIN_PEAK_ZERO: false },
|
|
885
|
+
LO: { VERTICAL_RESOLUTION: 200, VERTICAL_OFFSET: 100, MIN_PEAK_ZERO: false }
|
|
886
|
+
}
|
|
887
|
+
};
|
|
888
|
+
var defaultPRPDColorStops = [
|
|
889
|
+
{ offset: 0, color: "transparent" },
|
|
890
|
+
{ offset: 5e-3, color: "transparent" },
|
|
891
|
+
{ offset: 9e-3, color: "transparent" },
|
|
892
|
+
{ offset: 0.01, color: "CornflowerBlue" },
|
|
893
|
+
{ offset: 0.4, color: "DarkGreen" },
|
|
894
|
+
{ offset: 0.6, color: "Chartreuse" },
|
|
895
|
+
{ offset: 0.8, color: "Yellow" },
|
|
896
|
+
{ offset: 1, color: "Red" }
|
|
897
|
+
];
|
|
898
|
+
var createPRPDTheme = () => {
|
|
899
|
+
const theme = new SciChartJSLightTheme();
|
|
900
|
+
theme.sciChartBackground = "#f9f9f9";
|
|
901
|
+
theme.gridBackgroundBrush = "grey";
|
|
902
|
+
theme.axisBandsFill = "#dcdcdc";
|
|
903
|
+
theme.majorGridLineBrush = "#888888";
|
|
904
|
+
theme.minorGridLineBrush = "transparent";
|
|
905
|
+
return theme;
|
|
906
|
+
};
|
|
907
|
+
var createLegendTheme = () => {
|
|
908
|
+
const theme = new SciChartJSLightTheme();
|
|
909
|
+
theme.sciChartBackground = "#ffffff";
|
|
910
|
+
theme.gridBackgroundBrush = "#ffffff";
|
|
911
|
+
theme.axisBandsFill = "#ffffff";
|
|
912
|
+
theme.majorGridLineBrush = "transparent";
|
|
913
|
+
theme.minorGridLineBrush = "transparent";
|
|
914
|
+
return theme;
|
|
915
|
+
};
|
|
916
|
+
function getResolutionConfig(uniBiLabel, hiLoLabel, maxPeak, minPeak, isLowResolution) {
|
|
917
|
+
const cfg = isLowResolution ? RESOLUTION_CONFIG.UNI.HI : RESOLUTION_CONFIG?.[uniBiLabel]?.[hiLoLabel] ?? RESOLUTION_CONFIG.BI.HI;
|
|
918
|
+
const newMinPeak = cfg.MIN_PEAK_ZERO ? 0 : minPeak ?? -5e3;
|
|
919
|
+
const newMaxPeak = maxPeak ?? 5e3;
|
|
920
|
+
return {
|
|
921
|
+
verticalResolution: cfg.VERTICAL_RESOLUTION,
|
|
922
|
+
verticalOffset: cfg.VERTICAL_OFFSET,
|
|
923
|
+
newMinPeak,
|
|
924
|
+
newMaxPeak,
|
|
925
|
+
isUnipolar: uniBiLabel === "UNI" || isLowResolution
|
|
926
|
+
};
|
|
927
|
+
}
|
|
928
|
+
function getPhaseColumnIndex(phaseAngle, maxPhaseAngle) {
|
|
929
|
+
const maxPhase = maxPhaseAngle || 360;
|
|
930
|
+
if (maxPhase <= 0) return 0;
|
|
931
|
+
const clampedPhase = Math.min(Math.max(phaseAngle, 0), maxPhase);
|
|
932
|
+
const ratio = clampedPhase / maxPhase;
|
|
933
|
+
return Math.min(HORIZONTAL_RESOLUTION - 1, Math.floor(ratio * (HORIZONTAL_RESOLUTION - 1)));
|
|
934
|
+
}
|
|
935
|
+
function generateSineWaveData(startX, endX, amplitude, frequency = 1, phaseShift = 0, step = 1, offset = 0) {
|
|
936
|
+
const data = [];
|
|
937
|
+
for (let x = startX; x <= endX; x += step) {
|
|
938
|
+
const rad = (x - phaseShift) * Math.PI * frequency / 180;
|
|
939
|
+
const y = offset + amplitude * Math.sin(rad);
|
|
940
|
+
data.push([x, y]);
|
|
941
|
+
}
|
|
942
|
+
return data;
|
|
943
|
+
}
|
|
944
|
+
function buildZValues(data, scalingFactor, minPeak, maxPhaseAngle, verticalScaleMax, uniBiLabel, hiLoLabel, windowingData = [], isLowResolution) {
|
|
945
|
+
const { verticalResolution, verticalOffset, newMinPeak, newMaxPeak, isUnipolar } = getResolutionConfig(uniBiLabel, hiLoLabel, verticalScaleMax, minPeak, isLowResolution);
|
|
946
|
+
const zValues = Array.from(
|
|
947
|
+
{ length: verticalResolution },
|
|
948
|
+
() => new Array(HORIZONTAL_RESOLUTION).fill(0)
|
|
949
|
+
);
|
|
950
|
+
const vResolution = newMinPeak === 0 ? verticalResolution : verticalResolution / 2;
|
|
951
|
+
const multiplier = newMaxPeak * scalingFactor / vResolution;
|
|
952
|
+
let maxValue = 0;
|
|
953
|
+
let totalCount = 0;
|
|
954
|
+
const isInsideWindow = (phaseDeg, ampVal) => {
|
|
955
|
+
if (!windowingData?.length) return false;
|
|
956
|
+
return windowingData.some(
|
|
957
|
+
(w) => phaseDeg >= w.minPhase && phaseDeg <= w.maxPhase && ampVal >= w.minAmp && ampVal <= w.maxAmp
|
|
958
|
+
);
|
|
959
|
+
};
|
|
960
|
+
data?.forEach(([phase_angle, amplitude, count]) => {
|
|
961
|
+
const colIndex = getPhaseColumnIndex(phase_angle, maxPhaseAngle);
|
|
962
|
+
const scaledAmp = Math.floor(
|
|
963
|
+
(isUnipolar ? Math.abs(amplitude) : amplitude) * scalingFactor
|
|
964
|
+
);
|
|
965
|
+
if (isInsideWindow(phase_angle, scaledAmp)) {
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
let rowIndex = Math.floor(scaledAmp / multiplier + verticalOffset);
|
|
969
|
+
rowIndex = Math.max(0, Math.min(verticalResolution - 1, rowIndex));
|
|
970
|
+
zValues[rowIndex][colIndex] += count;
|
|
971
|
+
if (Math.abs(scaledAmp) > Math.abs(maxValue)) maxValue = scaledAmp;
|
|
972
|
+
totalCount += count;
|
|
973
|
+
});
|
|
974
|
+
return {
|
|
975
|
+
zValues,
|
|
976
|
+
multiplier,
|
|
977
|
+
maxValue,
|
|
978
|
+
totalCount,
|
|
979
|
+
verticalResolution,
|
|
980
|
+
isUnipolar,
|
|
981
|
+
newMinPeak
|
|
982
|
+
};
|
|
983
|
+
}
|
|
984
|
+
var PRPDChart = class {
|
|
985
|
+
constructor(config) {
|
|
986
|
+
this.container = null;
|
|
987
|
+
// Root container (may contain sub-divs)
|
|
988
|
+
this.chartHost = null;
|
|
989
|
+
// Div where SciChartSurface is mounted
|
|
990
|
+
this.surface = null;
|
|
991
|
+
this.wasmContext = null;
|
|
992
|
+
this.isDestroyed = false;
|
|
993
|
+
// Chart components
|
|
994
|
+
this.heatmapDataSeries = null;
|
|
995
|
+
this.heatmapSeries = null;
|
|
996
|
+
this.heatmapColorMap = null;
|
|
997
|
+
this.heatmapLegend = null;
|
|
998
|
+
this.heatmapLegendDiv = null;
|
|
999
|
+
this.sineDataSeries = null;
|
|
1000
|
+
this.sineLineSeries = null;
|
|
1001
|
+
this.xAxis = null;
|
|
1002
|
+
this.yAxis = null;
|
|
1003
|
+
// Statistics
|
|
1004
|
+
this.stats = { peakValue: 0, totalCount: 0 };
|
|
1005
|
+
this.id = config.id ?? generateId("prpd");
|
|
1006
|
+
this.config = {
|
|
1007
|
+
scalingFactor: 1,
|
|
1008
|
+
unitOfMeasurement: "mVp",
|
|
1009
|
+
maxPeak: 5e3,
|
|
1010
|
+
minPeak: -5e3,
|
|
1011
|
+
maxPhaseAngle: 360,
|
|
1012
|
+
resolutionLabel: { UniBi: "BI", HiLo: "HI" },
|
|
1013
|
+
windowingData: [],
|
|
1014
|
+
yAxisRange: 5e3,
|
|
1015
|
+
isLowResolution: false,
|
|
1016
|
+
showColorPalette: true,
|
|
1017
|
+
showSineWave: true,
|
|
1018
|
+
colorMin: 0,
|
|
1019
|
+
colorMax: 100,
|
|
1020
|
+
...config
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Initialize the chart in the given container
|
|
1025
|
+
*/
|
|
1026
|
+
async init(container) {
|
|
1027
|
+
if (this.isDestroyed) {
|
|
1028
|
+
throw new Error("Cannot initialize a destroyed chart");
|
|
1029
|
+
}
|
|
1030
|
+
if (typeof container === "string") {
|
|
1031
|
+
const el = document.getElementById(container);
|
|
1032
|
+
if (!el) {
|
|
1033
|
+
throw new Error(`Container element "${container}" not found`);
|
|
1034
|
+
}
|
|
1035
|
+
this.container = el;
|
|
1036
|
+
} else {
|
|
1037
|
+
this.container = container;
|
|
1038
|
+
}
|
|
1039
|
+
if (!this.container.id) {
|
|
1040
|
+
this.container.id = this.id;
|
|
1041
|
+
}
|
|
1042
|
+
const chartGraph = this.container.querySelector(".chart-graph");
|
|
1043
|
+
this.chartHost = chartGraph ?? this.container;
|
|
1044
|
+
if (!this.chartHost.id) {
|
|
1045
|
+
this.chartHost.id = `${this.id}_host`;
|
|
1046
|
+
}
|
|
1047
|
+
await this.createSurface();
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Create the SciChart surface
|
|
1051
|
+
*/
|
|
1052
|
+
async createSurface() {
|
|
1053
|
+
if (!this.container || !this.chartHost) {
|
|
1054
|
+
throw new Error("Container not set");
|
|
1055
|
+
}
|
|
1056
|
+
configureSciChartCDN();
|
|
1057
|
+
const theme = createPRPDTheme();
|
|
1058
|
+
const { sciChartSurface, wasmContext } = await SciChartSurface.create(
|
|
1059
|
+
this.chartHost,
|
|
1060
|
+
{ theme }
|
|
1061
|
+
);
|
|
1062
|
+
this.surface = sciChartSurface;
|
|
1063
|
+
this.wasmContext = wasmContext;
|
|
1064
|
+
const verticalScaleMax = this.config.maxPeak || VERTICAL_SCALE_MAX_DEFAULT;
|
|
1065
|
+
const { zValues, multiplier, maxValue, totalCount, verticalResolution, isUnipolar } = buildZValues(
|
|
1066
|
+
this.config.data,
|
|
1067
|
+
this.config.scalingFactor,
|
|
1068
|
+
this.config.minPeak,
|
|
1069
|
+
this.config.maxPhaseAngle,
|
|
1070
|
+
verticalScaleMax,
|
|
1071
|
+
this.config.resolutionLabel?.UniBi ?? "BI",
|
|
1072
|
+
this.config.resolutionLabel?.HiLo ?? "HI",
|
|
1073
|
+
this.config.windowingData,
|
|
1074
|
+
this.config.isLowResolution
|
|
1075
|
+
);
|
|
1076
|
+
this.stats = { peakValue: maxValue, totalCount };
|
|
1077
|
+
const yAxisRange = this.config.yAxisRange || verticalScaleMax;
|
|
1078
|
+
this.xAxis = new NumericAxis(wasmContext, {
|
|
1079
|
+
autoRange: EAutoRange.Never,
|
|
1080
|
+
labelFormat: ENumericFormat.Decimal,
|
|
1081
|
+
labelPrecision: 0,
|
|
1082
|
+
labelPostfix: "\xB0",
|
|
1083
|
+
minorDelta: 2,
|
|
1084
|
+
majorDelta: 45,
|
|
1085
|
+
drawMajorBands: true,
|
|
1086
|
+
autoTicks: false,
|
|
1087
|
+
axisAlignment: EAxisAlignment.Bottom,
|
|
1088
|
+
axisTitle: "Phase Angle (\xB0)",
|
|
1089
|
+
axisTitleStyle: {
|
|
1090
|
+
fontSize: 14,
|
|
1091
|
+
fontWeight: "bold",
|
|
1092
|
+
color: "black"
|
|
1093
|
+
},
|
|
1094
|
+
visibleRange: new NumberRange(0, 360),
|
|
1095
|
+
visibleRangeLimit: new NumberRange(0, 360)
|
|
1096
|
+
});
|
|
1097
|
+
const yRange = isUnipolar ? new NumberRange(0, yAxisRange) : new NumberRange(-yAxisRange, yAxisRange);
|
|
1098
|
+
this.yAxis = new NumericAxis(wasmContext, {
|
|
1099
|
+
autoRange: EAutoRange.Never,
|
|
1100
|
+
labelFormat: ENumericFormat.Decimal,
|
|
1101
|
+
labelPrecision: 0,
|
|
1102
|
+
drawMajorBands: true,
|
|
1103
|
+
axisAlignment: EAxisAlignment.Right,
|
|
1104
|
+
axisTitle: `Amplitude (${this.config.unitOfMeasurement})`,
|
|
1105
|
+
axisTitleStyle: {
|
|
1106
|
+
fontSize: 14,
|
|
1107
|
+
fontWeight: "bold",
|
|
1108
|
+
color: "black",
|
|
1109
|
+
rotation: 270
|
|
1110
|
+
},
|
|
1111
|
+
visibleRange: yRange,
|
|
1112
|
+
visibleRangeLimit: yRange
|
|
1113
|
+
});
|
|
1114
|
+
sciChartSurface.xAxes.add(this.xAxis);
|
|
1115
|
+
sciChartSurface.yAxes.add(this.yAxis);
|
|
1116
|
+
this.createHeatmap(zValues, multiplier, verticalResolution, isUnipolar);
|
|
1117
|
+
if (this.config.showSineWave) {
|
|
1118
|
+
this.createSineWave(yAxisRange, isUnipolar);
|
|
1119
|
+
}
|
|
1120
|
+
const cursorModifier = new CursorModifier();
|
|
1121
|
+
cursorModifier.axisLabelFill = "#FFFFFF";
|
|
1122
|
+
cursorModifier.axisLabelStroke = "#000000";
|
|
1123
|
+
sciChartSurface.chartModifiers.add(
|
|
1124
|
+
cursorModifier,
|
|
1125
|
+
new RubberBandXyZoomModifier(),
|
|
1126
|
+
new ZoomExtentsModifier()
|
|
1127
|
+
);
|
|
1128
|
+
if (this.config.showColorPalette) {
|
|
1129
|
+
await this.createHeatmapLegend();
|
|
1130
|
+
}
|
|
1131
|
+
this.onStatsChange?.(this.stats);
|
|
1132
|
+
}
|
|
1133
|
+
createHeatmap(zValues, multiplier, verticalResolution, isUnipolar) {
|
|
1134
|
+
if (!this.surface || !this.wasmContext) return;
|
|
1135
|
+
const colorStops = this.config.colorStops ?? defaultPRPDColorStops;
|
|
1136
|
+
this.heatmapColorMap = new HeatmapColorMap({
|
|
1137
|
+
minimum: this.config.colorMin ?? 0,
|
|
1138
|
+
maximum: this.config.colorMax ?? 100,
|
|
1139
|
+
gradientStops: colorStops
|
|
1140
|
+
});
|
|
1141
|
+
this.heatmapDataSeries = new UniformHeatmapDataSeries(this.wasmContext, {
|
|
1142
|
+
zValues,
|
|
1143
|
+
xStart: 0,
|
|
1144
|
+
xStep: HORIZONTAL_RESOLUTION_MULTIPLIER,
|
|
1145
|
+
yStart: isUnipolar ? 0 : -1 * verticalResolution * multiplier / 2,
|
|
1146
|
+
yStep: multiplier
|
|
1147
|
+
});
|
|
1148
|
+
this.heatmapSeries = new UniformHeatmapRenderableSeries(this.wasmContext, {
|
|
1149
|
+
dataSeries: this.heatmapDataSeries,
|
|
1150
|
+
colorMap: this.heatmapColorMap
|
|
1151
|
+
});
|
|
1152
|
+
this.surface.renderableSeries.add(this.heatmapSeries);
|
|
1153
|
+
}
|
|
1154
|
+
createSineWave(yAxisRange, isUnipolar) {
|
|
1155
|
+
if (!this.surface || !this.wasmContext) return;
|
|
1156
|
+
const sineAmplitude = isUnipolar ? yAxisRange / 2 : yAxisRange;
|
|
1157
|
+
const sineOffset = isUnipolar ? yAxisRange / 2 : 0;
|
|
1158
|
+
const sineWaveData = generateSineWaveData(0, 360, sineAmplitude, 1, 0, 1, sineOffset);
|
|
1159
|
+
this.sineDataSeries = new XyDataSeries(this.wasmContext);
|
|
1160
|
+
sineWaveData.forEach(([x, y]) => this.sineDataSeries.append(x, y));
|
|
1161
|
+
this.sineLineSeries = new FastLineRenderableSeries(this.wasmContext, {
|
|
1162
|
+
dataSeries: this.sineDataSeries,
|
|
1163
|
+
stroke: "Black",
|
|
1164
|
+
strokeThickness: 3
|
|
1165
|
+
});
|
|
1166
|
+
this.surface.renderableSeries.add(this.sineLineSeries);
|
|
1167
|
+
}
|
|
1168
|
+
async createHeatmapLegend() {
|
|
1169
|
+
if (!this.container || !this.heatmapColorMap) return;
|
|
1170
|
+
this.clearHeatmapLegend();
|
|
1171
|
+
let div = this.container.querySelector(".heatmap-chart");
|
|
1172
|
+
if (!div) {
|
|
1173
|
+
div = document.createElement("div");
|
|
1174
|
+
div.className = "heatmap-chart";
|
|
1175
|
+
div.style.position = "absolute";
|
|
1176
|
+
div.style.top = "40px";
|
|
1177
|
+
div.style.left = "0px";
|
|
1178
|
+
div.style.bottom = "40px";
|
|
1179
|
+
div.style.width = "65px";
|
|
1180
|
+
div.style.pointerEvents = "none";
|
|
1181
|
+
this.container.appendChild(div);
|
|
1182
|
+
}
|
|
1183
|
+
if (!div.id) {
|
|
1184
|
+
div.id = `${this.id}_legend`;
|
|
1185
|
+
}
|
|
1186
|
+
this.heatmapLegendDiv = div;
|
|
1187
|
+
const min = this.config.colorMin ?? 0;
|
|
1188
|
+
const max = this.config.colorMax ?? 100;
|
|
1189
|
+
const { heatmapLegend } = await HeatmapLegend.create(div, {
|
|
1190
|
+
theme: createLegendTheme(),
|
|
1191
|
+
yAxisOptions: {
|
|
1192
|
+
visibleRange: new NumberRange(min, max),
|
|
1193
|
+
majorDelta: (max - min) / 5,
|
|
1194
|
+
minorDelta: (max - min) / 10,
|
|
1195
|
+
labelFormat: ENumericFormat.Decimal,
|
|
1196
|
+
labelPrecision: 0,
|
|
1197
|
+
labelPadding: 6,
|
|
1198
|
+
axisTitleGap: 8,
|
|
1199
|
+
labelStyle: { fontSize: 12, color: "#A0A0A0" },
|
|
1200
|
+
majorTickLineStyle: {
|
|
1201
|
+
color: "#A0A0A0",
|
|
1202
|
+
tickSize: 8,
|
|
1203
|
+
strokeThickness: 1
|
|
1204
|
+
},
|
|
1205
|
+
minorTickLineStyle: {
|
|
1206
|
+
color: "gray",
|
|
1207
|
+
tickSize: 5,
|
|
1208
|
+
strokeThickness: 1
|
|
1209
|
+
},
|
|
1210
|
+
axisBorder: {
|
|
1211
|
+
borderLeft: 0,
|
|
1212
|
+
borderRight: 0,
|
|
1213
|
+
borderTop: 0,
|
|
1214
|
+
borderBottom: 0,
|
|
1215
|
+
color: "transparent"
|
|
1216
|
+
}
|
|
1217
|
+
},
|
|
1218
|
+
colorMap: this.heatmapColorMap
|
|
1219
|
+
});
|
|
1220
|
+
this.heatmapLegend = heatmapLegend;
|
|
1221
|
+
}
|
|
1222
|
+
clearHeatmapLegend() {
|
|
1223
|
+
if (this.heatmapLegend) {
|
|
1224
|
+
try {
|
|
1225
|
+
this.heatmapLegend.delete();
|
|
1226
|
+
} catch (e) {
|
|
1227
|
+
}
|
|
1228
|
+
this.heatmapLegend = null;
|
|
1229
|
+
}
|
|
1230
|
+
if (this.heatmapLegendDiv) {
|
|
1231
|
+
this.heatmapLegendDiv.remove();
|
|
1232
|
+
this.heatmapLegendDiv = null;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Update chart with new data
|
|
1237
|
+
*/
|
|
1238
|
+
updateData(data) {
|
|
1239
|
+
this.config.data = data;
|
|
1240
|
+
this.refresh();
|
|
1241
|
+
}
|
|
1242
|
+
/**
|
|
1243
|
+
* Update resolution label (UNI/BI, HI/LO)
|
|
1244
|
+
*/
|
|
1245
|
+
setResolutionLabel(label) {
|
|
1246
|
+
this.config.resolutionLabel = label;
|
|
1247
|
+
this.refresh();
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Update windowing data
|
|
1251
|
+
*/
|
|
1252
|
+
setWindowingData(windowingData) {
|
|
1253
|
+
this.config.windowingData = windowingData;
|
|
1254
|
+
this.refresh();
|
|
1255
|
+
}
|
|
1256
|
+
/**
|
|
1257
|
+
* Update Y-axis range
|
|
1258
|
+
*/
|
|
1259
|
+
setYAxisRange(range) {
|
|
1260
|
+
this.config.yAxisRange = range;
|
|
1261
|
+
this.refresh();
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Set stats change callback
|
|
1265
|
+
*/
|
|
1266
|
+
onStats(callback) {
|
|
1267
|
+
this.onStatsChange = callback;
|
|
1268
|
+
}
|
|
1269
|
+
/**
|
|
1270
|
+
* Get current statistics
|
|
1271
|
+
*/
|
|
1272
|
+
getStats() {
|
|
1273
|
+
return { ...this.stats };
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* Refresh the chart with current configuration
|
|
1277
|
+
*/
|
|
1278
|
+
refresh() {
|
|
1279
|
+
if (!this.surface || !this.wasmContext) return;
|
|
1280
|
+
const verticalScaleMax = this.config.maxPeak || VERTICAL_SCALE_MAX_DEFAULT;
|
|
1281
|
+
const yAxisRange = this.config.yAxisRange || verticalScaleMax;
|
|
1282
|
+
const { zValues, multiplier, maxValue, totalCount, verticalResolution, isUnipolar } = buildZValues(
|
|
1283
|
+
this.config.data,
|
|
1284
|
+
this.config.scalingFactor,
|
|
1285
|
+
this.config.minPeak,
|
|
1286
|
+
this.config.maxPhaseAngle,
|
|
1287
|
+
verticalScaleMax,
|
|
1288
|
+
this.config.resolutionLabel?.UniBi ?? "BI",
|
|
1289
|
+
this.config.resolutionLabel?.HiLo ?? "HI",
|
|
1290
|
+
this.config.windowingData,
|
|
1291
|
+
this.config.isLowResolution
|
|
1292
|
+
);
|
|
1293
|
+
this.stats = { peakValue: maxValue, totalCount };
|
|
1294
|
+
if (this.yAxis) {
|
|
1295
|
+
const yRange = isUnipolar ? new NumberRange(0, yAxisRange) : new NumberRange(-yAxisRange, yAxisRange);
|
|
1296
|
+
this.yAxis.visibleRange = yRange;
|
|
1297
|
+
this.yAxis.visibleRangeLimit = yRange;
|
|
1298
|
+
}
|
|
1299
|
+
if (this.heatmapDataSeries) {
|
|
1300
|
+
const needNewDs = this.heatmapDataSeries.arrayHeight !== verticalResolution || this.heatmapDataSeries.arrayWidth !== HORIZONTAL_RESOLUTION;
|
|
1301
|
+
if (needNewDs) {
|
|
1302
|
+
if (this.heatmapSeries) {
|
|
1303
|
+
this.surface.renderableSeries.remove(this.heatmapSeries);
|
|
1304
|
+
this.heatmapSeries.delete();
|
|
1305
|
+
}
|
|
1306
|
+
this.heatmapDataSeries.delete();
|
|
1307
|
+
this.heatmapDataSeries = new UniformHeatmapDataSeries(this.wasmContext, {
|
|
1308
|
+
zValues,
|
|
1309
|
+
xStart: 0,
|
|
1310
|
+
xStep: HORIZONTAL_RESOLUTION_MULTIPLIER,
|
|
1311
|
+
yStart: isUnipolar ? 0 : -1 * verticalResolution * multiplier / 2,
|
|
1312
|
+
yStep: multiplier
|
|
1313
|
+
});
|
|
1314
|
+
this.heatmapSeries = new UniformHeatmapRenderableSeries(this.wasmContext, {
|
|
1315
|
+
dataSeries: this.heatmapDataSeries,
|
|
1316
|
+
colorMap: this.heatmapColorMap
|
|
1317
|
+
});
|
|
1318
|
+
this.surface.renderableSeries.add(this.heatmapSeries);
|
|
1319
|
+
} else {
|
|
1320
|
+
if (typeof this.heatmapDataSeries.setZValues === "function") {
|
|
1321
|
+
this.heatmapDataSeries.setZValues(zValues);
|
|
1322
|
+
} else {
|
|
1323
|
+
this.heatmapDataSeries.zValues = zValues;
|
|
1324
|
+
}
|
|
1325
|
+
this.heatmapDataSeries.yStart = isUnipolar ? 0 : -1 * verticalResolution * multiplier / 2;
|
|
1326
|
+
this.heatmapDataSeries.yStep = multiplier;
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
if (this.sineDataSeries && this.config.showSineWave) {
|
|
1330
|
+
this.sineDataSeries.clear();
|
|
1331
|
+
const sineAmplitude = isUnipolar ? yAxisRange / 2 : yAxisRange;
|
|
1332
|
+
const sineOffset = isUnipolar ? yAxisRange / 2 : 0;
|
|
1333
|
+
const sineWaveData = generateSineWaveData(0, 360, sineAmplitude, 1, 0, 1, sineOffset);
|
|
1334
|
+
sineWaveData.forEach(([x, y]) => this.sineDataSeries.append(x, y));
|
|
1335
|
+
}
|
|
1336
|
+
this.surface.invalidateElement();
|
|
1337
|
+
this.onStatsChange?.(this.stats);
|
|
1338
|
+
}
|
|
1339
|
+
/**
|
|
1340
|
+
* Set chart options
|
|
1341
|
+
*/
|
|
1342
|
+
setOptions(options) {
|
|
1343
|
+
this.config = { ...this.config, ...options };
|
|
1344
|
+
this.refresh();
|
|
1345
|
+
}
|
|
1346
|
+
/**
|
|
1347
|
+
* Reset zoom to full extent
|
|
1348
|
+
*/
|
|
1349
|
+
resetZoom() {
|
|
1350
|
+
if (!this.surface) return;
|
|
1351
|
+
this.surface.zoomExtents();
|
|
1352
|
+
}
|
|
1353
|
+
/**
|
|
1354
|
+
* Export chart as image
|
|
1355
|
+
*/
|
|
1356
|
+
async exportImage(format = "png") {
|
|
1357
|
+
if (!this.container) {
|
|
1358
|
+
throw new Error("Chart not initialized");
|
|
1359
|
+
}
|
|
1360
|
+
const canvas = this.container.querySelector("canvas");
|
|
1361
|
+
if (!canvas) {
|
|
1362
|
+
throw new Error("Canvas not found");
|
|
1363
|
+
}
|
|
1364
|
+
const mimeType = format === "jpeg" ? "image/jpeg" : "image/png";
|
|
1365
|
+
return canvas.toDataURL(mimeType);
|
|
1366
|
+
}
|
|
1367
|
+
/**
|
|
1368
|
+
* Get current configuration
|
|
1369
|
+
*/
|
|
1370
|
+
getConfig() {
|
|
1371
|
+
return { ...this.config };
|
|
1372
|
+
}
|
|
1373
|
+
/**
|
|
1374
|
+
* Check if chart is ready
|
|
1375
|
+
*/
|
|
1376
|
+
isReady() {
|
|
1377
|
+
return this.surface !== null && !this.isDestroyed;
|
|
1378
|
+
}
|
|
1379
|
+
/**
|
|
1380
|
+
* Destroy and clean up
|
|
1381
|
+
*/
|
|
1382
|
+
destroy() {
|
|
1383
|
+
if (this.isDestroyed) return;
|
|
1384
|
+
this.clearHeatmapLegend();
|
|
1385
|
+
if (this.sineLineSeries && this.surface) {
|
|
1386
|
+
this.surface.renderableSeries.remove(this.sineLineSeries);
|
|
1387
|
+
this.sineLineSeries.delete();
|
|
1388
|
+
this.sineLineSeries = null;
|
|
1389
|
+
}
|
|
1390
|
+
if (this.sineDataSeries) {
|
|
1391
|
+
this.sineDataSeries.delete();
|
|
1392
|
+
this.sineDataSeries = null;
|
|
1393
|
+
}
|
|
1394
|
+
if (this.heatmapSeries && this.surface) {
|
|
1395
|
+
this.surface.renderableSeries.remove(this.heatmapSeries);
|
|
1396
|
+
this.heatmapSeries.delete();
|
|
1397
|
+
this.heatmapSeries = null;
|
|
1398
|
+
}
|
|
1399
|
+
if (this.heatmapDataSeries) {
|
|
1400
|
+
this.heatmapDataSeries.delete();
|
|
1401
|
+
this.heatmapDataSeries = null;
|
|
1402
|
+
}
|
|
1403
|
+
if (this.surface) {
|
|
1404
|
+
this.surface.delete();
|
|
1405
|
+
this.surface = null;
|
|
1406
|
+
}
|
|
1407
|
+
this.isDestroyed = true;
|
|
1408
|
+
}
|
|
1409
|
+
};
|
|
1410
|
+
async function createPRPDChart(container, config) {
|
|
1411
|
+
const chart = new PRPDChart(config);
|
|
1412
|
+
await chart.init(container);
|
|
1413
|
+
return chart;
|
|
1414
|
+
}
|
|
1644
1415
|
var VERSION = "0.1.1";
|
|
1645
|
-
var
|
|
1646
|
-
var DEFAULT_WASM_URL = `https://cdn.jsdelivr.net/npm/scichart@${
|
|
1647
|
-
var DEFAULT_DATA_URL = `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION4}/_wasm/scichart2d.data`;
|
|
1416
|
+
var SCICHART_VERSION5 = "4.0.933";
|
|
1417
|
+
var DEFAULT_WASM_URL = `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION5}/_wasm/scichart2d.wasm`;
|
|
1648
1418
|
var isConfigured = false;
|
|
1649
1419
|
function autoConfigureSciChart() {
|
|
1650
1420
|
if (isConfigured) return;
|
|
1651
1421
|
try {
|
|
1652
|
-
const { SciChartSurface:
|
|
1653
|
-
|
|
1654
|
-
wasmUrl: DEFAULT_WASM_URL
|
|
1655
|
-
dataUrl: DEFAULT_DATA_URL
|
|
1422
|
+
const { SciChartSurface: SciChartSurface4 } = __require("scichart");
|
|
1423
|
+
SciChartSurface4.configure({
|
|
1424
|
+
wasmUrl: DEFAULT_WASM_URL
|
|
1656
1425
|
});
|
|
1657
1426
|
isConfigured = true;
|
|
1658
1427
|
} catch {
|
|
@@ -1661,16 +1430,15 @@ function autoConfigureSciChart() {
|
|
|
1661
1430
|
autoConfigureSciChart();
|
|
1662
1431
|
function configureSciChart(options) {
|
|
1663
1432
|
try {
|
|
1664
|
-
const { SciChartSurface:
|
|
1665
|
-
|
|
1666
|
-
wasmUrl: options.wasmUrl || DEFAULT_WASM_URL
|
|
1667
|
-
dataUrl: options.dataUrl || DEFAULT_DATA_URL
|
|
1433
|
+
const { SciChartSurface: SciChartSurface4 } = __require("scichart");
|
|
1434
|
+
SciChartSurface4.configure({
|
|
1435
|
+
wasmUrl: options.wasmUrl || DEFAULT_WASM_URL
|
|
1668
1436
|
});
|
|
1669
1437
|
isConfigured = true;
|
|
1670
1438
|
} catch {
|
|
1671
1439
|
}
|
|
1672
1440
|
}
|
|
1673
1441
|
|
|
1674
|
-
export {
|
|
1442
|
+
export { BaseChart, Column3DChart, PRPDChart, Surface3DChart, VERSION, calculateDataRange, clamp, configureSciChart, createColumn3DChart, createPRPDChart, createSurface3DChart, debounce, deepMerge, extractXValues, extractYValues, formatNumber, generateId, hexToRgba, lerp, normalizeDataPoints, parseSize, throttle };
|
|
1675
1443
|
//# sourceMappingURL=index.mjs.map
|
|
1676
1444
|
//# sourceMappingURL=index.mjs.map
|