@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.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  var chunkKATRK3C3_js = require('./chunk-KATRK3C3.js');
4
4
  var scichart = require('scichart');
5
+ var SciChartJSLightTheme = require('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 = "3.5.750";
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
  scichart.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 } = chunkKATRK3C3_js.__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
- * Export chart as image
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 scichart.SciChartJSLightTheme();
342
- case "dark":
343
- case "modern":
344
- case "midnight":
345
- default:
346
- return new scichart.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 scichart.SciChartSurface.create(
368
- this.container,
369
- {
370
- theme: sciChartTheme
371
- }
372
- );
373
- this.surface = sciChartSurface;
374
- this.wasmContext = wasmContext;
375
- const xAxis = new scichart.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: scichart.EAutoRange.Always
397
- });
398
- const yAxis = new scichart.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: scichart.EAutoRange.Always
420
- });
421
- if (this.config.xAxis?.min !== void 0 && this.config.xAxis?.max !== void 0) {
422
- xAxis.visibleRange = new scichart.NumberRange(this.config.xAxis.min, this.config.xAxis.max);
423
- xAxis.autoRange = scichart.EAutoRange.Never;
424
- }
425
- if (this.config.yAxis?.min !== void 0 && this.config.yAxis?.max !== void 0) {
426
- yAxis.visibleRange = new scichart.NumberRange(this.config.yAxis.min, this.config.yAxis.max);
427
- yAxis.autoRange = scichart.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 scichart.RolloverModifier({
434
- showTooltip: true,
435
- showAxisLabel: true
436
- })
437
- );
438
- }
439
- sciChartSurface.chartModifiers.add(new scichart.ZoomPanModifier());
440
- sciChartSurface.chartModifiers.add(new scichart.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 scichart.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 scichart.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 scichart.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 scichart.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
- updateSeriesData(seriesName, data) {
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
- const colorPalette = this.theme.colorPalette ?? [];
553
- this.renderableSeries.forEach((series, index) => {
554
- const originalColor = this.config.series[index]?.color;
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 scichart.SciChartJSLightTheme();
577
- case "dark":
578
- case "modern":
579
- case "midnight":
580
- default:
581
- return new scichart.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 scichart.SciChartSurface.create(
603
- this.container,
604
- {
605
- theme: sciChartTheme
606
- }
607
- );
608
- this.surface = sciChartSurface;
609
- this.wasmContext = wasmContext;
610
- const xAxis = new scichart.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: scichart.EAutoRange.Always
625
- });
626
- const yAxis = new scichart.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: scichart.EAutoRange.Always,
641
- growBy: new scichart.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 scichart.NumberRange(this.config.xAxis.min, this.config.xAxis.max);
646
- xAxis.autoRange = scichart.EAutoRange.Never;
647
- }
648
- if (this.config.yAxis?.min !== void 0 && this.config.yAxis?.max !== void 0) {
649
- yAxis.visibleRange = new scichart.NumberRange(this.config.yAxis.min, this.config.yAxis.max);
650
- yAxis.autoRange = scichart.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 scichart.RolloverModifier({
657
- showTooltip: true,
658
- showAxisLabel: true
659
- })
660
- );
661
- }
662
- sciChartSurface.chartModifiers.add(new scichart.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 scichart.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 scichart.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 scichart.WaveAnimation({
698
- duration: typeof this.config.animation === "object" ? this.config.animation.duration ?? 500 : 500
699
- });
700
- }
701
- columnSeries.fillLinearGradient = new scichart.GradientParams(
702
- new scichart.Point(0, 0),
703
- new scichart.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 scichart.SciChartJSLightTheme();
778
- case "dark":
779
- case "modern":
780
- case "midnight":
781
- default:
782
- return new scichart.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 scichart.SciChartSurface.create(
804
- this.container,
805
- {
806
- theme: sciChartTheme
807
- }
808
- );
809
- this.surface = sciChartSurface;
810
- this.wasmContext = wasmContext;
811
- const xAxis = new scichart.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: scichart.EAutoRange.Always
826
- });
827
- const yAxis = new scichart.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: scichart.EAutoRange.Always,
842
- growBy: new scichart.NumberRange(0, 0.1)
843
- });
844
- if (this.config.xAxis?.min !== void 0 && this.config.xAxis?.max !== void 0) {
845
- xAxis.visibleRange = new scichart.NumberRange(this.config.xAxis.min, this.config.xAxis.max);
846
- xAxis.autoRange = scichart.EAutoRange.Never;
847
- }
848
- if (this.config.yAxis?.min !== void 0 && this.config.yAxis?.max !== void 0) {
849
- yAxis.visibleRange = new scichart.NumberRange(this.config.yAxis.min, this.config.yAxis.max);
850
- yAxis.autoRange = scichart.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 scichart.RolloverModifier({
857
- showTooltip: true,
858
- showAxisLabel: true
859
- })
860
- );
861
- }
862
- sciChartSurface.chartModifiers.add(new scichart.ZoomPanModifier());
863
- sciChartSurface.chartModifiers.add(new scichart.MouseWheelZoomModifier());
864
- this.addSeries(this.config.series);
865
304
  }
866
305
  /**
867
- * Add series to the chart
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 scichart.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 scichart.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 scichart.SweepAnimation({
892
- duration: typeof this.config.animation === "object" ? this.config.animation.duration ?? 500 : 500
893
- })
894
- }
895
- });
896
- areaSeries.fillLinearGradient = new scichart.GradientParams(
897
- new scichart.Point(0, 0),
898
- new scichart.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
- setData(data) {
308
+ async exportImage(format = "png") {
912
309
  if (!this.surface) {
913
- this.config.series = data;
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 scichart.SciChartJSLightTheme();
973
- case "dark":
974
- case "modern":
975
- case "midnight":
976
- default:
977
- return new scichart.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 { sciChartSurface, wasmContext } = await scichart.SciChartSurface.create(
1013
- this.container,
1014
- {
1015
- theme: sciChartTheme
1016
- }
1017
- );
1018
- this.surface = sciChartSurface;
1019
- this.wasmContext = wasmContext;
1020
- const xAxis = new scichart.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: scichart.EAutoRange.Always
1035
- });
1036
- const yAxis = new scichart.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: scichart.EAutoRange.Always
1051
- });
1052
- if (this.config.xAxis?.min !== void 0 && this.config.xAxis?.max !== void 0) {
1053
- xAxis.visibleRange = new scichart.NumberRange(this.config.xAxis.min, this.config.xAxis.max);
1054
- xAxis.autoRange = scichart.EAutoRange.Never;
1055
- }
1056
- if (this.config.yAxis?.min !== void 0 && this.config.yAxis?.max !== void 0) {
1057
- yAxis.visibleRange = new scichart.NumberRange(this.config.yAxis.min, this.config.yAxis.max);
1058
- yAxis.autoRange = scichart.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 scichart.RolloverModifier({
1065
- showTooltip: true,
1066
- showAxisLabel: true
1067
- })
1068
- );
1069
- }
1070
- sciChartSurface.chartModifiers.add(new scichart.ZoomPanModifier());
1071
- sciChartSurface.chartModifiers.add(new scichart.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 scichart.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 scichart.UniformHeatmapRenderableSeries(wasmContext, {
1096
- dataSeries: this.heatmapDataSeries,
1097
- colorMap: new scichart.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
- * Set new data for the chart (for heatmap, this updates zValues)
320
+ * Add event listener
1107
321
  */
1108
- setData(_data) {
1109
- console.warn("HeatmapChart.setData() - use setZValues() for updating heatmap data");
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
- * Set new z-values for the heatmap
329
+ * Remove event listener
1113
330
  */
1114
- setZValues(zValues) {
1115
- if (!this.surface) {
1116
- this.config.zValues = zValues;
1117
- return;
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
- * Update specific cell values
338
+ * Emit an event
1125
339
  */
1126
- updateCell(x, y, value) {
1127
- if (this.heatmapDataSeries) {
1128
- this.heatmapDataSeries.setZValue(x, y, value);
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
- * Clear heatmap data
347
+ * Destroy the chart and clean up resources
1133
348
  */
1134
- clearHeatmap() {
1135
- if (!this.surface) return;
1136
- if (this.heatmapSeries) {
1137
- this.surface.renderableSeries.remove(this.heatmapSeries);
1138
- this.heatmapSeries.delete();
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
- if (this.heatmapDataSeries) {
1142
- this.heatmapDataSeries.delete();
1143
- this.heatmapDataSeries = null;
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
- * Update chart
367
+ * Get current configuration
1148
368
  */
1149
- update() {
1150
- if (!this.surface) return;
1151
- this.applyTheme();
1152
- this.surface.invalidateElement();
369
+ getConfig() {
370
+ return { ...this.config };
1153
371
  }
1154
372
  /**
1155
- * Destroy and clean up
373
+ * Get current theme
1156
374
  */
1157
- destroy() {
1158
- this.clearHeatmap();
1159
- super.destroy();
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
- async function createHeatmapChart(container, config) {
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
  scichart.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 defaultColorStops2 = [
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 ?? defaultColorStops2;
499
+ const colorStops = this.config.colorStops ?? defaultColorStops;
1283
500
  const colorPalette = new scichart.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 = "3.5.750";
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
  scichart.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
+ scichart.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.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.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 scichart.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 scichart.NumericAxis(wasmContext, {
1079
+ autoRange: scichart.EAutoRange.Never,
1080
+ labelFormat: scichart.ENumericFormat.Decimal,
1081
+ labelPrecision: 0,
1082
+ labelPostfix: "\xB0",
1083
+ minorDelta: 2,
1084
+ majorDelta: 45,
1085
+ drawMajorBands: true,
1086
+ autoTicks: false,
1087
+ axisAlignment: scichart.EAxisAlignment.Bottom,
1088
+ axisTitle: "Phase Angle (\xB0)",
1089
+ axisTitleStyle: {
1090
+ fontSize: 14,
1091
+ fontWeight: "bold",
1092
+ color: "black"
1093
+ },
1094
+ visibleRange: new scichart.NumberRange(0, 360),
1095
+ visibleRangeLimit: new scichart.NumberRange(0, 360)
1096
+ });
1097
+ const yRange = isUnipolar ? new scichart.NumberRange(0, yAxisRange) : new scichart.NumberRange(-yAxisRange, yAxisRange);
1098
+ this.yAxis = new scichart.NumericAxis(wasmContext, {
1099
+ autoRange: scichart.EAutoRange.Never,
1100
+ labelFormat: scichart.ENumericFormat.Decimal,
1101
+ labelPrecision: 0,
1102
+ drawMajorBands: true,
1103
+ axisAlignment: scichart.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 scichart.CursorModifier();
1121
+ cursorModifier.axisLabelFill = "#FFFFFF";
1122
+ cursorModifier.axisLabelStroke = "#000000";
1123
+ sciChartSurface.chartModifiers.add(
1124
+ cursorModifier,
1125
+ new scichart.RubberBandXyZoomModifier(),
1126
+ new scichart.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 scichart.HeatmapColorMap({
1137
+ minimum: this.config.colorMin ?? 0,
1138
+ maximum: this.config.colorMax ?? 100,
1139
+ gradientStops: colorStops
1140
+ });
1141
+ this.heatmapDataSeries = new scichart.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 scichart.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 scichart.XyDataSeries(this.wasmContext);
1160
+ sineWaveData.forEach(([x, y]) => this.sineDataSeries.append(x, y));
1161
+ this.sineLineSeries = new scichart.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 scichart.HeatmapLegend.create(div, {
1190
+ theme: createLegendTheme(),
1191
+ yAxisOptions: {
1192
+ visibleRange: new scichart.NumberRange(min, max),
1193
+ majorDelta: (max - min) / 5,
1194
+ minorDelta: (max - min) / 10,
1195
+ labelFormat: scichart.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 scichart.NumberRange(0, yAxisRange) : new scichart.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 scichart.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 scichart.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 SCICHART_VERSION4 = "3.5.750";
1646
- var DEFAULT_WASM_URL = `https://cdn.jsdelivr.net/npm/scichart@${SCICHART_VERSION4}/_wasm/scichart2d.wasm`;
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: SciChartSurface7 } = chunkKATRK3C3_js.__require("scichart");
1653
- SciChartSurface7.configure({
1654
- wasmUrl: DEFAULT_WASM_URL,
1655
- dataUrl: DEFAULT_DATA_URL
1422
+ const { SciChartSurface: SciChartSurface4 } = chunkKATRK3C3_js.__require("scichart");
1423
+ SciChartSurface4.configure({
1424
+ wasmUrl: DEFAULT_WASM_URL
1656
1425
  });
1657
1426
  isConfigured = true;
1658
1427
  } catch {
@@ -1661,10 +1430,9 @@ function autoConfigureSciChart() {
1661
1430
  autoConfigureSciChart();
1662
1431
  function configureSciChart(options) {
1663
1432
  try {
1664
- const { SciChartSurface: SciChartSurface7 } = chunkKATRK3C3_js.__require("scichart");
1665
- SciChartSurface7.configure({
1666
- wasmUrl: options.wasmUrl || DEFAULT_WASM_URL,
1667
- dataUrl: options.dataUrl || DEFAULT_DATA_URL
1433
+ const { SciChartSurface: SciChartSurface4 } = chunkKATRK3C3_js.__require("scichart");
1434
+ SciChartSurface4.configure({
1435
+ wasmUrl: options.wasmUrl || DEFAULT_WASM_URL
1668
1436
  });
1669
1437
  isConfigured = true;
1670
1438
  } catch {
@@ -1699,22 +1467,16 @@ Object.defineProperty(exports, "SciChartSurface", {
1699
1467
  enumerable: true,
1700
1468
  get: function () { return scichart.SciChartSurface; }
1701
1469
  });
1702
- exports.AreaChart = AreaChart;
1703
- exports.BarChart = BarChart;
1704
1470
  exports.BaseChart = BaseChart;
1705
1471
  exports.Column3DChart = Column3DChart;
1706
- exports.HeatmapChart = HeatmapChart;
1707
- exports.LineChart = LineChart;
1472
+ exports.PRPDChart = PRPDChart;
1708
1473
  exports.Surface3DChart = Surface3DChart;
1709
1474
  exports.VERSION = VERSION;
1710
1475
  exports.calculateDataRange = calculateDataRange;
1711
1476
  exports.clamp = clamp;
1712
1477
  exports.configureSciChart = configureSciChart;
1713
- exports.createAreaChart = createAreaChart;
1714
- exports.createBarChart = createBarChart;
1715
1478
  exports.createColumn3DChart = createColumn3DChart;
1716
- exports.createHeatmapChart = createHeatmapChart;
1717
- exports.createLineChart = createLineChart;
1479
+ exports.createPRPDChart = createPRPDChart;
1718
1480
  exports.createSurface3DChart = createSurface3DChart;
1719
1481
  exports.debounce = debounce;
1720
1482
  exports.deepMerge = deepMerge;