@rfkit/charts 1.4.3 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -94,6 +94,8 @@ export function GaugeDemo() {
94
94
  - `SetSegments`
95
95
  - `SetMarker`
96
96
 
97
+ `PublishSpectrum` 支持推送内置频谱数据线,包括 `data`、`maxData`、`minData`、`avgData`、`thresholdData`、`templateData`、`backgroundNoiseData` 和 `extraData`。
98
+
97
99
  工具栏相关命名统一使用:
98
100
 
99
101
  - 工具栏枚举使用 `ToolbarItemType`
package/index.js CHANGED
@@ -4183,6 +4183,7 @@ const getDefaultData = ()=>({
4183
4183
  maxData: new Float32Array(),
4184
4184
  minData: new Float32Array(),
4185
4185
  avgData: new Float32Array(),
4186
+ thresholdData: new Float32Array(),
4186
4187
  templateData: new Float32Array(),
4187
4188
  backgroundNoiseData: new Float32Array(),
4188
4189
  waterfallData: [],
@@ -4354,7 +4355,7 @@ const UI_CONFIG = {
4354
4355
  ZOOM_MIN_RANGE: 10,
4355
4356
  POPOVER_MARGIN: 16
4356
4357
  };
4357
- const defaultConfig = {
4358
+ const setting_defaultConfig = {
4358
4359
  line: {
4359
4360
  realData: {
4360
4361
  name: 'realData',
@@ -4389,7 +4390,7 @@ const defaultConfig = {
4389
4390
  color: '#FF4C2A',
4390
4391
  thickness: 1,
4391
4392
  label: "\u95E8\u9650\u503C",
4392
- display: false
4393
+ display: true
4393
4394
  },
4394
4395
  templateData: {
4395
4396
  name: 'templateData',
@@ -4493,17 +4494,17 @@ const defaultConfig = {
4493
4494
  const setConfig = (c = {})=>{
4494
4495
  const currentConfig = JSON.parse(localStorage.getItem(KEY) || '{}');
4495
4496
  const newConfig = {
4496
- ...defaultConfig,
4497
+ ...setting_defaultConfig,
4497
4498
  ...currentConfig,
4498
4499
  ...c
4499
4500
  };
4500
4501
  localStorage.setItem(KEY, JSON.stringify(newConfig));
4501
4502
  };
4502
4503
  function getConfig(name) {
4503
- let config = defaultConfig ?? JSON.parse(localStorage.getItem(KEY) || 'null');
4504
+ let config = setting_defaultConfig ?? JSON.parse(localStorage.getItem(KEY) || 'null');
4504
4505
  if (!config) {
4505
4506
  setConfig();
4506
- config = defaultConfig;
4507
+ config = setting_defaultConfig;
4507
4508
  }
4508
4509
  return name ? config[name] : config;
4509
4510
  }
@@ -18490,7 +18491,7 @@ const resolveCursorIndexByLeft = (left, outputLength, maxPoints)=>{
18490
18491
  globalIndex: spectrum_analyzer_leftToIndex(safeLeft, maxPoints)
18491
18492
  };
18492
18493
  };
18493
- const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outputPoints, realData, maxData, minData, avgData, templateData, backgroundNoiseData, fluorescenceData, occupancyData, enablePeakStats = false, maxPeaks = 2, outputRangeStart = 0 })=>{
18494
+ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outputPoints, realData, maxData, minData, avgData, templateData, backgroundNoiseData, thresholdData, fluorescenceData, occupancyData, enablePeakStats = false, maxPeaks = 2, outputRangeStart = 0 })=>{
18494
18495
  const realDataLength = realData.length;
18495
18496
  const isLessThanDataLength = realDataLength <= outputPoints;
18496
18497
  const outputLength = isLessThanDataLength ? realDataLength : outputPoints;
@@ -18500,6 +18501,7 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18500
18501
  const hasTemplateData = templateData && templateData.length > 0;
18501
18502
  const hasOccupancyData = occupancyData && occupancyData.length > 0;
18502
18503
  const hasBackgroundNoiseData = backgroundNoiseData && backgroundNoiseData.length > 0;
18504
+ const hasThresholdData = thresholdData && thresholdData.length > 0;
18503
18505
  const hasFluorescenceStats = fluorescenceData && fluorescenceData.length > 0;
18504
18506
  const candidatePeaks = [];
18505
18507
  const applyAntennaFactor = antennaFactorSwitch ? (value1, index)=>value1 + antennaFactorData[index] : (value1)=>value1;
@@ -18511,6 +18513,7 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18511
18513
  const templateOutputData = new Float32Array(hasTemplateData ? outputLength : 0);
18512
18514
  const occupancyOutputData = new Float32Array(hasOccupancyData ? outputLength : 0);
18513
18515
  const backgroundNoiseOutputData = new Float32Array(hasBackgroundNoiseData ? outputLength : 0);
18516
+ const thresholdOutputData = new Float32Array(hasThresholdData ? outputLength : 0);
18514
18517
  let fluorescenceOutputData = new Array(hasFluorescenceStats ? outputLength : 0).fill(null);
18515
18518
  const srcIndexCache = new Uint32Array(outputLength);
18516
18519
  if (isLessThanDataLength) {
@@ -18524,6 +18527,7 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18524
18527
  if (hasTemplateData) templateOutputData[i] = templateData[i] + antennaFactor;
18525
18528
  if (hasOccupancyData) occupancyOutputData[i] = occupancyData[i];
18526
18529
  if (hasBackgroundNoiseData) backgroundNoiseOutputData[i] = backgroundNoiseData[i] + antennaFactor;
18530
+ if (hasThresholdData) thresholdOutputData[i] = thresholdData[i] + antennaFactor;
18527
18531
  if (hasFluorescenceStats) {
18528
18532
  const fluorescence = fluorescenceData[i];
18529
18533
  const newFluorescence = new Map;
@@ -18539,6 +18543,7 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18539
18543
  if (hasTemplateData) templateOutputData.set(templateData);
18540
18544
  if (hasOccupancyData) occupancyOutputData.set(occupancyData);
18541
18545
  if (hasBackgroundNoiseData) backgroundNoiseOutputData.set(backgroundNoiseData);
18546
+ if (hasThresholdData) thresholdOutputData.set(thresholdData);
18542
18547
  if (hasFluorescenceStats) fluorescenceOutputData = fluorescenceData;
18543
18548
  }
18544
18549
  if (enablePeakStats) for(let i = 0; i < realDataLength; i++){
@@ -18600,6 +18605,10 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18600
18605
  const backgroundNoiseValue = backgroundNoiseData[realMaxIdx];
18601
18606
  backgroundNoiseOutputData[i] = applyAntennaFactor(backgroundNoiseValue, realMaxIdx);
18602
18607
  }
18608
+ if (hasThresholdData) {
18609
+ const thresholdValue = thresholdData[realMaxIdx];
18610
+ thresholdOutputData[i] = applyAntennaFactor(thresholdValue, realMaxIdx);
18611
+ }
18603
18612
  if (hasFluorescenceStats) {
18604
18613
  const fluorescence = fluorescenceData[realMaxIdx];
18605
18614
  const newFluorescence = new Map;
@@ -18625,6 +18634,7 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18625
18634
  templateOutputData,
18626
18635
  occupancyOutputData,
18627
18636
  backgroundNoiseOutputData,
18637
+ thresholdOutputData,
18628
18638
  srcIndexCache,
18629
18639
  fluorescenceOutputData
18630
18640
  };
@@ -18777,6 +18787,7 @@ class SpectrumAnalyzer {
18777
18787
  templateData;
18778
18788
  occupancyData;
18779
18789
  backgroundNoiseData;
18790
+ thresholdData;
18780
18791
  waterfallData;
18781
18792
  srcIndexCache;
18782
18793
  realOutputData;
@@ -18786,6 +18797,7 @@ class SpectrumAnalyzer {
18786
18797
  templateOutputData;
18787
18798
  occupancyOutputData;
18788
18799
  backgroundNoiseOutputData;
18800
+ thresholdOutputData;
18789
18801
  waterfallOutputData;
18790
18802
  scanProgress;
18791
18803
  lastIndex;
@@ -18801,6 +18813,7 @@ class SpectrumAnalyzer {
18801
18813
  ["occupancy"]: false,
18802
18814
  ["template"]: false,
18803
18815
  ["backgroundNoise"]: false,
18816
+ ["threshold"]: false,
18804
18817
  ["extra"]: false
18805
18818
  };
18806
18819
  hasPendingData = false;
@@ -19121,6 +19134,7 @@ class SpectrumAnalyzer {
19121
19134
  this.clearMetricsBuffers();
19122
19135
  this.templateData = new Float32Array;
19123
19136
  this.backgroundNoiseData = new Float32Array;
19137
+ this.thresholdData = new Float32Array;
19124
19138
  this.waterfallData = Array.from({
19125
19139
  length: waterfallMaxFrames
19126
19140
  }, ()=>{
@@ -19142,6 +19156,7 @@ class SpectrumAnalyzer {
19142
19156
  this.templateOutputData = new Float32Array;
19143
19157
  this.occupancyOutputData = new Float32Array;
19144
19158
  this.backgroundNoiseOutputData = new Float32Array;
19159
+ this.thresholdOutputData = new Float32Array;
19145
19160
  this.fluorescenceData = enableFluorescence ? new Uint32Array(maxPoints * FLUORESCENCE.LEVEL_RANGE) : new Uint32Array(0);
19146
19161
  this.fluorescenceMaxCount = 0;
19147
19162
  this.fluorescenceUpdateCounter = 0;
@@ -19157,6 +19172,7 @@ class SpectrumAnalyzer {
19157
19172
  ["occupancy"]: false,
19158
19173
  ["template"]: false,
19159
19174
  ["backgroundNoise"]: false,
19175
+ ["threshold"]: false,
19160
19176
  ["extra"]: false
19161
19177
  };
19162
19178
  this.hasPendingData = false;
@@ -19168,6 +19184,7 @@ class SpectrumAnalyzer {
19168
19184
  avgData: this.avgData,
19169
19185
  templateData: this.templateData,
19170
19186
  backgroundNoiseData: this.backgroundNoiseData,
19187
+ thresholdData: this.thresholdData,
19171
19188
  extraData: this.extraData,
19172
19189
  srcIndexCache: this.srcIndexCache,
19173
19190
  processTimes: 0,
@@ -19236,6 +19253,19 @@ class SpectrumAnalyzer {
19236
19253
  });
19237
19254
  this.setPendingFlag("backgroundNoise", false);
19238
19255
  }
19256
+ setThresholdData(data) {
19257
+ if (!data || 0 === data.length) {
19258
+ this.thresholdData = new Float32Array(0);
19259
+ this.setPendingFlag("threshold", false);
19260
+ return;
19261
+ }
19262
+ this.thresholdData = new Float32Array(data);
19263
+ if (!this.hasProcessedData || this.isProcessing) return void this.setPendingFlag("threshold", true);
19264
+ this.notifySpectrumUpdate({
19265
+ thresholdData: this.resampleSingleData(this.thresholdData)
19266
+ });
19267
+ this.setPendingFlag("threshold", false);
19268
+ }
19239
19269
  updateTemplateOverData(forceFullCalculation = false, incrementalRange) {
19240
19270
  if (!this.templateData || 0 === this.templateData.length) {
19241
19271
  this.cachedExceedingDatas = [];
@@ -19267,9 +19297,9 @@ class SpectrumAnalyzer {
19267
19297
  return templateOverData;
19268
19298
  }
19269
19299
  resampleDataSeries() {
19270
- const { antennaFactorData, antennaFactorSwitch, maxData, minData, avgData, templateData, occupancyData, backgroundNoiseData, config: { maxPoints, outputPoints } } = this;
19300
+ const { antennaFactorData, antennaFactorSwitch, maxData, minData, avgData, templateData, occupancyData, backgroundNoiseData, thresholdData, config: { maxPoints, outputPoints } } = this;
19271
19301
  const activeAntennaFactorData = antennaFactorSwitch ? antennaFactorData : new Float32Array(maxPoints);
19272
- const { realOutputData, srcIndexCache, maxOutputData, minOutputData, avgOutputData, templateOutputData, occupancyOutputData, backgroundNoiseOutputData } = resampleMultiple({
19302
+ const { realOutputData, srcIndexCache, maxOutputData, minOutputData, avgOutputData, templateOutputData, occupancyOutputData, backgroundNoiseOutputData, thresholdOutputData } = resampleMultiple({
19273
19303
  antennaFactorData: activeAntennaFactorData,
19274
19304
  antennaFactorSwitch,
19275
19305
  outputPoints,
@@ -19280,6 +19310,7 @@ class SpectrumAnalyzer {
19280
19310
  templateData: templateData && templateData.length > 0 ? this.getOutputData(templateData) : void 0,
19281
19311
  occupancyData: occupancyData && occupancyData.length > 0 ? this.getOutputData(occupancyData) : void 0,
19282
19312
  backgroundNoiseData: backgroundNoiseData && backgroundNoiseData.length > 0 ? this.getOutputData(backgroundNoiseData) : void 0,
19313
+ thresholdData: thresholdData && thresholdData.length > 0 ? this.getOutputData(thresholdData) : void 0,
19283
19314
  enablePeakStats: this.config.processing.enablePeakStats,
19284
19315
  maxPeaks: this.config.peakDetection.maxPeaks,
19285
19316
  outputRangeStart: this.config.outputRange.start
@@ -19292,6 +19323,7 @@ class SpectrumAnalyzer {
19292
19323
  this.templateOutputData = templateOutputData || new Float32Array;
19293
19324
  this.occupancyOutputData = occupancyOutputData || new Float32Array;
19294
19325
  this.backgroundNoiseOutputData = backgroundNoiseOutputData || new Float32Array;
19326
+ this.thresholdOutputData = thresholdOutputData || new Float32Array;
19295
19327
  const fluorescenceOutput = this.getFluorescenceOutputData(realOutputData.length);
19296
19328
  return {
19297
19329
  realData: realOutputData,
@@ -19301,6 +19333,7 @@ class SpectrumAnalyzer {
19301
19333
  templateData: templateOutputData,
19302
19334
  occupancyData: occupancyOutputData,
19303
19335
  backgroundNoiseData: backgroundNoiseOutputData,
19336
+ thresholdData: thresholdOutputData,
19304
19337
  fluorescenceData: fluorescenceOutput,
19305
19338
  fluorescenceMaxCount: this.fluorescenceMaxCount,
19306
19339
  extraData: this.extraOutputData,
@@ -19390,7 +19423,7 @@ class SpectrumAnalyzer {
19390
19423
  }
19391
19424
  setPendingFlag(type, value1) {
19392
19425
  this.pendingDataFlags[type] = value1;
19393
- this.hasPendingData = this.pendingDataFlags["occupancy"] || this.pendingDataFlags["template"] || this.pendingDataFlags["backgroundNoise"] || this.pendingDataFlags["extra"];
19426
+ this.hasPendingData = this.pendingDataFlags["occupancy"] || this.pendingDataFlags["template"] || this.pendingDataFlags["backgroundNoise"] || this.pendingDataFlags["threshold"] || this.pendingDataFlags["extra"];
19394
19427
  }
19395
19428
  resampleSingleData(sourceData) {
19396
19429
  const { srcIndexCache } = this;
@@ -19418,6 +19451,10 @@ class SpectrumAnalyzer {
19418
19451
  pendingOutput.backgroundNoiseData = this.resampleSingleData(this.backgroundNoiseData);
19419
19452
  this.setPendingFlag("backgroundNoise", false);
19420
19453
  }
19454
+ if (this.pendingDataFlags["threshold"] && this.thresholdData.length > 0) {
19455
+ pendingOutput.thresholdData = this.resampleSingleData(this.thresholdData);
19456
+ this.setPendingFlag("threshold", false);
19457
+ }
19421
19458
  if (this.pendingDataFlags["extra"] && Object.keys(this.extraData).length > 0) {
19422
19459
  this.extraOutputData = resampleExtraData(this.extraData, this.antennaFactorData, this.antennaFactorSwitch, this.srcIndexCache, this.getOutputData.bind(this));
19423
19460
  pendingOutput.extraData = this.extraOutputData;
@@ -19458,7 +19495,7 @@ class SpectrumAnalyzer {
19458
19495
  return outputData;
19459
19496
  }
19460
19497
  getAllRawData(left) {
19461
- const { realOutputData, maxOutputData, minOutputData, avgOutputData, templateOutputData, occupancyOutputData, backgroundNoiseOutputData, waterfallOutputData, extraOutputData, srcIndexCache } = this;
19498
+ const { realOutputData, maxOutputData, minOutputData, avgOutputData, templateOutputData, occupancyOutputData, backgroundNoiseOutputData, thresholdOutputData, waterfallOutputData, extraOutputData, srcIndexCache } = this;
19462
19499
  realOutputData.timestamp = this.realData.timestamp;
19463
19500
  const rawData = {
19464
19501
  realData: this.realData,
@@ -19468,6 +19505,7 @@ class SpectrumAnalyzer {
19468
19505
  templateData: this.templateData,
19469
19506
  occupancyData: this.occupancyData,
19470
19507
  backgroundNoiseData: this.backgroundNoiseData,
19508
+ thresholdData: this.thresholdData,
19471
19509
  waterfallData: this.waterfallData,
19472
19510
  extraData: this.extraData
19473
19511
  };
@@ -19480,6 +19518,7 @@ class SpectrumAnalyzer {
19480
19518
  templateData: templateOutputData,
19481
19519
  occupancyData: occupancyOutputData,
19482
19520
  backgroundNoiseData: backgroundNoiseOutputData,
19521
+ thresholdData: thresholdOutputData,
19483
19522
  fluorescenceData: this.getFluorescenceOutputData(realOutputData.length),
19484
19523
  waterfallData: waterfallOutputData,
19485
19524
  extraData: extraOutputData,
@@ -19638,7 +19677,7 @@ class SeriesManager {
19638
19677
  return true;
19639
19678
  }
19640
19679
  }
19641
- const events_SeriesEventName = {
19680
+ const SeriesEventName = {
19642
19681
  UPDATED: 'series:updated',
19643
19682
  ADDED: 'series:added',
19644
19683
  REMOVED: 'series:removed',
@@ -19689,7 +19728,7 @@ function subscribeToSeries(globalID, event, listener) {
19689
19728
  if (data.globalID === globalID) listener(data);
19690
19729
  });
19691
19730
  }
19692
- function events_emitSeriesEvent(event, data) {
19731
+ function emitSeriesEvent(event, data) {
19693
19732
  seriesEvents.emit(event, data);
19694
19733
  }
19695
19734
  var modes_SeriesMode = /*#__PURE__*/ function(SeriesMode) {
@@ -19750,7 +19789,7 @@ function getNextMode(currentMode) {
19750
19789
  function setSeriesMode(globalID, mode) {
19751
19790
  seriesModes.set(globalID, mode);
19752
19791
  const modeConfig = SERIES_MODES[mode];
19753
- events_emitSeriesEvent(events_SeriesEventName.MODE_CHANGED, {
19792
+ emitSeriesEvent(SeriesEventName.MODE_CHANGED, {
19754
19793
  globalID,
19755
19794
  mode,
19756
19795
  config: modeConfig
@@ -19768,7 +19807,7 @@ function initSeriesSubscription(renderer) {
19768
19807
  return null;
19769
19808
  }
19770
19809
  const subscriptions = [];
19771
- subscriptions.push(subscribeToSeries(globalID, events_SeriesEventName.UPDATED, (data)=>{
19810
+ subscriptions.push(subscribeToSeries(globalID, SeriesEventName.UPDATED, (data)=>{
19772
19811
  const correctType = getCorrectSeriesType(globalID, data.seriesName);
19773
19812
  const configWithCorrectType = {
19774
19813
  ...data.config,
@@ -19777,13 +19816,13 @@ function initSeriesSubscription(renderer) {
19777
19816
  renderer.setSeries(configWithCorrectType, true);
19778
19817
  renderer.state.chart?.draw();
19779
19818
  }));
19780
- subscriptions.push(subscribeToSeries(globalID, events_SeriesEventName.MODE_CHANGED, ()=>{
19819
+ subscriptions.push(subscribeToSeries(globalID, SeriesEventName.MODE_CHANGED, ()=>{
19781
19820
  renderer.initSeries();
19782
19821
  }));
19783
- subscriptions.push(subscribeToSeries(globalID, events_SeriesEventName.TYPE_OVERRIDE_CHANGED, ()=>{
19822
+ subscriptions.push(subscribeToSeries(globalID, SeriesEventName.TYPE_OVERRIDE_CHANGED, ()=>{
19784
19823
  renderer.initSeries();
19785
19824
  }));
19786
- subscriptions.push(subscribeToSeries(globalID, events_SeriesEventName.BATCH_UPDATED, (data)=>{
19825
+ subscriptions.push(subscribeToSeries(globalID, SeriesEventName.BATCH_UPDATED, (data)=>{
19787
19826
  data.configs.forEach((config)=>{
19788
19827
  const correctType = getCorrectSeriesType(globalID, config.name);
19789
19828
  const configWithCorrectType = {
@@ -19794,7 +19833,7 @@ function initSeriesSubscription(renderer) {
19794
19833
  });
19795
19834
  renderer.state.chart?.draw();
19796
19835
  }));
19797
- subscriptions.push(subscribeToSeries(globalID, events_SeriesEventName.RESET, ()=>{
19836
+ subscriptions.push(subscribeToSeries(globalID, SeriesEventName.RESET, ()=>{
19798
19837
  if (renderer.state.series) renderer.state.series = {};
19799
19838
  renderer.initSeries();
19800
19839
  }));
@@ -19806,7 +19845,7 @@ const chartTypeSeriesOverrides = new Map();
19806
19845
  function setChartTypeSeriesOverride(globalID, seriesName, type) {
19807
19846
  if (!chartTypeSeriesOverrides.has(globalID)) chartTypeSeriesOverrides.set(globalID, new Map());
19808
19847
  chartTypeSeriesOverrides.get(globalID)?.set(seriesName, type);
19809
- events_emitSeriesEvent(events_SeriesEventName.TYPE_OVERRIDE_CHANGED, {
19848
+ emitSeriesEvent(SeriesEventName.TYPE_OVERRIDE_CHANGED, {
19810
19849
  globalID,
19811
19850
  seriesName,
19812
19851
  type
@@ -19815,7 +19854,7 @@ function setChartTypeSeriesOverride(globalID, seriesName, type) {
19815
19854
  function clearChartTypeSeriesOverrides(globalID) {
19816
19855
  const hadOverrides = chartTypeSeriesOverrides.has(globalID);
19817
19856
  chartTypeSeriesOverrides.delete(globalID);
19818
- if (hadOverrides) events_emitSeriesEvent(events_SeriesEventName.TYPE_OVERRIDE_CHANGED, {
19857
+ if (hadOverrides) emitSeriesEvent(SeriesEventName.TYPE_OVERRIDE_CHANGED, {
19819
19858
  globalID
19820
19859
  });
19821
19860
  }
@@ -19879,16 +19918,18 @@ function getSeriesMap(globalID) {
19879
19918
  return seriesMap;
19880
19919
  }
19881
19920
  function mergeSeriesConfig(config, existing) {
19921
+ const defaultConfig = getSeriesConfig()[config.name];
19882
19922
  const defaults = {
19883
- label: '',
19884
- display: true,
19923
+ label: defaultConfig?.label ?? '',
19924
+ color: defaultConfig?.color,
19925
+ display: defaultConfig?.display ?? true,
19885
19926
  type: __WEBPACK_EXTERNAL_MODULE__rfkit_renderer_d3372451__.GraphicType.Line,
19886
- thickness: 1
19927
+ thickness: defaultConfig?.thickness ?? 1
19887
19928
  };
19888
19929
  return {
19889
19930
  name: config.name,
19890
19931
  label: config.label ?? existing?.label ?? defaults.label,
19891
- color: config.color ?? existing?.color ?? (()=>{
19932
+ color: config.color ?? existing?.color ?? defaults.color ?? (()=>{
19892
19933
  throw new Error(`Series "${config.name}" does not exist and must have a color defined`);
19893
19934
  })(),
19894
19935
  display: config.display ?? existing?.display ?? defaults.display,
@@ -19896,14 +19937,21 @@ function mergeSeriesConfig(config, existing) {
19896
19937
  thickness: config.thickness ?? existing?.thickness ?? defaults.thickness
19897
19938
  };
19898
19939
  }
19940
+ function upsertSeriesConfig(manager, finalConfig, existing) {
19941
+ if (!existing) return void manager.addSeries(finalConfig);
19942
+ manager.setSeriesProperty(finalConfig.name, 'label', finalConfig.label);
19943
+ manager.setSeriesProperty(finalConfig.name, 'color', finalConfig.color);
19944
+ manager.setSeriesProperty(finalConfig.name, 'thickness', finalConfig.thickness);
19945
+ manager.setSeriesProperty(finalConfig.name, 'display', finalConfig.display);
19946
+ manager.setSeriesProperty(finalConfig.name, 'type', finalConfig.type);
19947
+ }
19899
19948
  function updateSeries(globalID, config) {
19900
19949
  if (!config?.name) return;
19901
19950
  const manager = getSeriesManager(globalID);
19902
19951
  const existing = manager.getSeries(config.name);
19903
19952
  const finalConfig = mergeSeriesConfig(config, existing);
19904
- if (existing) manager.removeSeries(config.name);
19905
- manager.addSeries(finalConfig);
19906
- events_emitSeriesEvent(events_SeriesEventName.UPDATED, {
19953
+ upsertSeriesConfig(manager, finalConfig, existing);
19954
+ emitSeriesEvent(SeriesEventName.UPDATED, {
19907
19955
  globalID,
19908
19956
  seriesName: config.name,
19909
19957
  config: {
@@ -19930,10 +19978,32 @@ function resetSeries(globalID) {
19930
19978
  thickness: config.thickness
19931
19979
  });
19932
19980
  });
19933
- events_emitSeriesEvent(events_SeriesEventName.RESET, {
19981
+ emitSeriesEvent(SeriesEventName.RESET, {
19934
19982
  globalID
19935
19983
  });
19936
19984
  }
19985
+ function batchUpdateSeries(globalID, configs) {
19986
+ const manager = getSeriesManager(globalID);
19987
+ const updatedConfigs = [];
19988
+ configs.forEach((config)=>{
19989
+ if (!config?.name) return;
19990
+ const existing = manager.getSeries(config.name);
19991
+ const finalConfig = mergeSeriesConfig(config, existing);
19992
+ upsertSeriesConfig(manager, finalConfig, existing);
19993
+ updatedConfigs.push({
19994
+ name: finalConfig.name,
19995
+ label: finalConfig.label,
19996
+ color: finalConfig.color,
19997
+ thickness: finalConfig.thickness,
19998
+ display: finalConfig.display,
19999
+ type: finalConfig.type
20000
+ });
20001
+ });
20002
+ if (updatedConfigs.length > 0) emitSeriesEvent(SeriesEventName.BATCH_UPDATED, {
20003
+ globalID,
20004
+ configs: updatedConfigs
20005
+ });
20006
+ }
19937
20007
  function getSeriesWithGraphicType(globalID) {
19938
20008
  const seriesMap = getSeriesMap(globalID);
19939
20009
  const result = new Map();
@@ -20522,32 +20592,32 @@ function useSeriesManager(globalID, options = {}) {
20522
20592
  const unsubscribers = [];
20523
20593
  if (subscribeToMode) {
20524
20594
  setMode(getSeriesMode(globalID));
20525
- const unsubscribeMode = subscribeToSeries(globalID, events_SeriesEventName.MODE_CHANGED, (data)=>{
20595
+ const unsubscribeMode = subscribeToSeries(globalID, SeriesEventName.MODE_CHANGED, (data)=>{
20526
20596
  setMode(data.mode);
20527
20597
  });
20528
20598
  unsubscribers.push(unsubscribeMode);
20529
20599
  }
20530
20600
  if (subscribeToData) {
20531
- const unsubscribeUpdated = subscribeToSeries(globalID, events_SeriesEventName.UPDATED, (data)=>{
20601
+ const unsubscribeUpdated = subscribeToSeries(globalID, SeriesEventName.UPDATED, (data)=>{
20532
20602
  if (watchSeries && !watchSeries.includes(data.seriesName)) return;
20533
20603
  forceUpdate();
20534
20604
  });
20535
20605
  unsubscribers.push(unsubscribeUpdated);
20536
- const unsubscribeAdded = subscribeToSeries(globalID, events_SeriesEventName.ADDED, (data)=>{
20606
+ const unsubscribeAdded = subscribeToSeries(globalID, SeriesEventName.ADDED, (data)=>{
20537
20607
  if (watchSeries && !watchSeries.includes(data.seriesName)) return;
20538
20608
  forceUpdate();
20539
20609
  });
20540
20610
  unsubscribers.push(unsubscribeAdded);
20541
- const unsubscribeRemoved = subscribeToSeries(globalID, events_SeriesEventName.REMOVED, (data)=>{
20611
+ const unsubscribeRemoved = subscribeToSeries(globalID, SeriesEventName.REMOVED, (data)=>{
20542
20612
  if (watchSeries && !watchSeries.includes(data.seriesName)) return;
20543
20613
  forceUpdate();
20544
20614
  });
20545
20615
  unsubscribers.push(unsubscribeRemoved);
20546
- const unsubscribeBatchUpdated = subscribeToSeries(globalID, events_SeriesEventName.BATCH_UPDATED, ()=>{
20616
+ const unsubscribeBatchUpdated = subscribeToSeries(globalID, SeriesEventName.BATCH_UPDATED, ()=>{
20547
20617
  forceUpdate();
20548
20618
  });
20549
20619
  unsubscribers.push(unsubscribeBatchUpdated);
20550
- const unsubscribeReset = subscribeToSeries(globalID, events_SeriesEventName.RESET, ()=>{
20620
+ const unsubscribeReset = subscribeToSeries(globalID, SeriesEventName.RESET, ()=>{
20551
20621
  forceUpdate();
20552
20622
  });
20553
20623
  unsubscribers.push(unsubscribeReset);
@@ -20576,21 +20646,14 @@ function useSeriesForComponent(globalID) {
20576
20646
  subscribeToData: true
20577
20647
  });
20578
20648
  }
20579
- const stableOrderMap = new Map();
20580
- function getStableOrder(globalID, currentNames) {
20581
- const stored = stableOrderMap.get(globalID) || [];
20582
- const needsUpdate = 0 === stored.length || currentNames.some((name)=>!stored.includes(name)) || stored.some((name)=>!currentNames.includes(name));
20583
- if (needsUpdate) {
20584
- const newOrder = [
20585
- ...stored.filter((name)=>currentNames.includes(name)),
20586
- ...currentNames.filter((name)=>!stored.includes(name))
20587
- ];
20588
- stableOrderMap.set(globalID, newOrder);
20589
- return newOrder;
20590
- }
20591
- return stored;
20649
+ const DEFAULT_SERIES_ORDER = Object.values(getSeriesConfig()).map((config)=>config.name);
20650
+ function getStableOrder(currentNames) {
20651
+ return [
20652
+ ...DEFAULT_SERIES_ORDER.filter((name)=>currentNames.includes(name)),
20653
+ ...currentNames.filter((name)=>!DEFAULT_SERIES_ORDER.includes(name))
20654
+ ];
20592
20655
  }
20593
- function useFilteredSeries(globalID, filter) {
20656
+ function useFilteredSeries_useFilteredSeries(globalID, filter) {
20594
20657
  const { series } = useSeriesManager(globalID);
20595
20658
  const { state: { series: { legendExternal } } } = useStore_useStore();
20596
20659
  const filteredData = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>{
@@ -20599,12 +20662,8 @@ function useFilteredSeries(globalID, filter) {
20599
20662
  if (config.name === constants_SeriesType.TemplateData) return false;
20600
20663
  return filter ? filter(config) : true;
20601
20664
  });
20602
- if (!globalID) return filtered.map((config, index)=>({
20603
- ...config,
20604
- originalIndex: index
20605
- }));
20606
20665
  const currentNames = filtered.map((s)=>s.name);
20607
- const stableOrder = getStableOrder(globalID, currentNames);
20666
+ const stableOrder = getStableOrder(currentNames);
20608
20667
  const orderMap = new Map(stableOrder.map((name, i)=>[
20609
20668
  name,
20610
20669
  i
@@ -20620,8 +20679,7 @@ function useFilteredSeries(globalID, filter) {
20620
20679
  }, [
20621
20680
  series,
20622
20681
  legendExternal,
20623
- filter,
20624
- globalID
20682
+ filter
20625
20683
  ]);
20626
20684
  return filteredData;
20627
20685
  }
@@ -21153,7 +21211,7 @@ const StationInfoPanel = ({ stationInfo })=>{
21153
21211
  const panels_StationInfoPanel = /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].memo(StationInfoPanel);
21154
21212
  const FrequencyDataBoard = ({ left, updateKey, onChange, showStationInfo = true })=>{
21155
21213
  const { state: { axisY, axisX: { frequencyFormat, unit }, globalID } } = useStore_useStore();
21156
- const filteredSeries = useFilteredSeries(globalID, (config)=>false !== config.display);
21214
+ const filteredSeries = useFilteredSeries_useFilteredSeries(globalID, (config)=>false !== config.display);
21157
21215
  const calculateIndex = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((values, series, sampledIndex, rawValue)=>{
21158
21216
  if (!values || 0 === values.length) return null;
21159
21217
  const safeSampledIndex = Math.max(0, Math.min(values.length - 1, Math.floor(sampledIndex)));
@@ -21207,6 +21265,7 @@ const FrequencyDataBoard = ({ left, updateKey, onChange, showStationInfo = true
21207
21265
  maxData: snapshot.maxData,
21208
21266
  minData: snapshot.minData,
21209
21267
  avgData: snapshot.avgData,
21268
+ thresholdData: snapshot.thresholdData,
21210
21269
  templateData: snapshot.templateData,
21211
21270
  occupancyData: snapshot.occupancyData,
21212
21271
  backgroundNoiseData: snapshot.backgroundNoiseData,
@@ -21217,6 +21276,7 @@ const FrequencyDataBoard = ({ left, updateKey, onChange, showStationInfo = true
21217
21276
  maxData: snapshot.rawData?.maxData,
21218
21277
  minData: snapshot.rawData?.minData,
21219
21278
  avgData: snapshot.rawData?.avgData,
21279
+ thresholdData: snapshot.rawData?.thresholdData,
21220
21280
  templateData: snapshot.rawData?.templateData,
21221
21281
  occupancyData: snapshot.rawData?.occupancyData,
21222
21282
  backgroundNoiseData: snapshot.rawData?.backgroundNoiseData,
@@ -23483,7 +23543,7 @@ class Spectrum extends BaseRenderer {
23483
23543
  const { color = SERIES[name]?.color, thickness = 1, display = false } = merged;
23484
23544
  const nextSeriesConfig = {
23485
23545
  name,
23486
- label: config.label,
23546
+ label: merged.label,
23487
23547
  type: resolvedType || __WEBPACK_EXTERNAL_MODULE__rfkit_renderer_d3372451__.GraphicType.Line,
23488
23548
  color,
23489
23549
  thickness,
@@ -23497,7 +23557,7 @@ class Spectrum extends BaseRenderer {
23497
23557
  if (!skipEventEmit && globalID) try {
23498
23558
  updateSeries(globalID, {
23499
23559
  name,
23500
- label: config.label || name,
23560
+ label: nextSeriesConfig.label || name,
23501
23561
  color,
23502
23562
  thickness,
23503
23563
  display,
@@ -23915,36 +23975,24 @@ const SeriesControl_SeriesControl = ({ type })=>{
23915
23975
  const SeriesControl = SeriesControl_SeriesControl;
23916
23976
  const SeriesDisplayControl = ()=>{
23917
23977
  const { state: { globalID, series: seriesConfig } } = useStore_useStore();
23918
- const filteredSeries = useFilteredSeries(globalID);
23919
- const { forceUpdate } = useSeriesForComponent(globalID);
23978
+ const filteredSeries = useFilteredSeries_useFilteredSeries(globalID);
23920
23979
  (0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
23921
23980
  if (!globalID || !seriesConfig?.forceDisplay) return;
23922
23981
  const hiddenSeries = filteredSeries.filter((item)=>!item.display);
23923
- if (hiddenSeries.length > 0) {
23924
- hiddenSeries.forEach(({ name })=>{
23925
- updateSeries(globalID, {
23926
- name,
23927
- display: true
23928
- });
23929
- });
23930
- forceUpdate();
23931
- }
23982
+ if (hiddenSeries.length > 0) batchUpdateSeries(globalID, hiddenSeries.map(({ name })=>({
23983
+ name,
23984
+ display: true
23985
+ })));
23932
23986
  }, [
23933
23987
  globalID,
23934
23988
  seriesConfig?.forceDisplay,
23935
23989
  filteredSeries.length
23936
23990
  ]);
23937
23991
  const updateSeriesDisplay = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((updates)=>{
23938
- updates.forEach(({ name, display })=>{
23939
- updateSeries(globalID, {
23940
- name,
23941
- display
23942
- });
23943
- });
23944
- forceUpdate();
23992
+ if (!globalID || 0 === updates.length) return;
23993
+ batchUpdateSeries(globalID, updates);
23945
23994
  }, [
23946
- globalID,
23947
- forceUpdate
23995
+ globalID
23948
23996
  ]);
23949
23997
  const handleSeriesToggle = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((seriesName, display)=>{
23950
23998
  updateSeriesDisplay([
@@ -29617,10 +29665,11 @@ function useSpectrumAnalyzer(props) {
29617
29665
  }, []);
29618
29666
  const { updateTemplateOverData } = useTemplateComparison();
29619
29667
  const handleSpectrumUpdate = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((data)=>{
29620
- if (data.realData || data.templateData || data.backgroundNoiseData) updateSpectrum({
29668
+ if (data.realData || data.templateData || data.backgroundNoiseData || 'thresholdData' in data) updateSpectrum({
29621
29669
  minData: data.minData,
29622
29670
  maxData: data.maxData,
29623
29671
  avgData: data.avgData,
29672
+ thresholdData: data.thresholdData,
29624
29673
  backgroundNoiseData: data.backgroundNoiseData,
29625
29674
  realData: data.realData,
29626
29675
  templateData: data.templateData
@@ -29715,6 +29764,7 @@ function useSpectrumAnalyzer(props) {
29715
29764
  break;
29716
29765
  case constants_PSType.Spectrum:
29717
29766
  if (e.data) analyzer.current.process(e);
29767
+ if ('thresholdData' in e) analyzer.current.setThresholdData(e.thresholdData);
29718
29768
  if (e.maxData) analyzer.current.setMaxData(e.maxData);
29719
29769
  if (e.minData) analyzer.current.setMinData(e.minData);
29720
29770
  if (e.avgData) analyzer.current.setAvgData(e.avgData);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rfkit/charts",
3
- "version": "1.4.3",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "description": "Chart components for wireless monitoring web applications",
6
6
  "exports": {
@@ -53,6 +53,7 @@ export interface PublishSpectrum {
53
53
  maxData?: Float32Array;
54
54
  minData?: Float32Array;
55
55
  avgData?: Float32Array;
56
+ thresholdData?: Float32Array;
56
57
  backgroundNoiseData?: Float32Array;
57
58
  templateData?: Float32Array;
58
59
  templateTolerance?: number;