@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-DWzDIVQ9.d.mts → index-QzUVGlSo.d.mts} +68 -66
- package/dist/{index-DWzDIVQ9.d.ts → index-QzUVGlSo.d.ts} +68 -66
- package/dist/index.d.mts +110 -186
- package/dist/index.d.ts +110 -186
- package/dist/index.js +695 -892
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +695 -886
- package/dist/index.mjs.map +1 -1
- package/dist/themes/index.d.mts +1 -1
- package/dist/themes/index.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.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
|
-
|
|
1090
|
-
|
|
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
|
-
*
|
|
329
|
+
* Remove event listener
|
|
1094
330
|
*/
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
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
|
-
*
|
|
338
|
+
* Emit an event
|
|
1106
339
|
*/
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
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
|
-
*
|
|
347
|
+
* Destroy the chart and clean up resources
|
|
1114
348
|
*/
|
|
1115
|
-
|
|
1116
|
-
if (
|
|
1117
|
-
if (this.
|
|
1118
|
-
this.
|
|
1119
|
-
this.
|
|
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
|
-
|
|
1123
|
-
|
|
1124
|
-
this.
|
|
355
|
+
this.eventHandlers.clear();
|
|
356
|
+
if (this.surface) {
|
|
357
|
+
this.surface.delete();
|
|
358
|
+
this.surface = null;
|
|
359
|
+
}
|
|
360
|
+
if (this.container) {
|
|
361
|
+
this.container.innerHTML = "";
|
|
1125
362
|
}
|
|
363
|
+
this.isDestroyed = true;
|
|
364
|
+
this.isInitialized = false;
|
|
1126
365
|
}
|
|
1127
366
|
/**
|
|
1128
|
-
*
|
|
367
|
+
* Get current configuration
|
|
1129
368
|
*/
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
this.applyTheme();
|
|
1133
|
-
this.surface.invalidateElement();
|
|
369
|
+
getConfig() {
|
|
370
|
+
return { ...this.config };
|
|
1134
371
|
}
|
|
1135
372
|
/**
|
|
1136
|
-
*
|
|
373
|
+
* Get current theme
|
|
1137
374
|
*/
|
|
1138
|
-
|
|
1139
|
-
this.
|
|
1140
|
-
|
|
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
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
return
|
|
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
|
|
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 ??
|
|
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
|
|
1589
|
-
var DEFAULT_WASM_URL = `https://cdn.jsdelivr.net/npm/scichart@${
|
|
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:
|
|
1596
|
-
|
|
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:
|
|
1608
|
-
|
|
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.
|
|
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.
|
|
1660
|
-
exports.createLineChart = createLineChart;
|
|
1463
|
+
exports.createPRPDChart = createPRPDChart;
|
|
1661
1464
|
exports.createSurface3DChart = createSurface3DChart;
|
|
1662
1465
|
exports.debounce = debounce;
|
|
1663
1466
|
exports.deepMerge = deepMerge;
|