@rm-graph/core 0.1.1 → 0.1.3

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