@rfkit/charts 1.4.3 → 1.5.1

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`。`thresholdData` 不传 `segmentOffset` / `offset` 时按整条门限替换;传入 `segmentOffset` 或 `offset` 时按局部门限写入。
98
+
97
99
  工具栏相关命名统一使用:
98
100
 
99
101
  - 工具栏枚举使用 `ToolbarItemType`
@@ -7,6 +7,7 @@ export declare const UI_CONFIG: {
7
7
  /** Popover 边距 */
8
8
  readonly POPOVER_MARGIN: 16;
9
9
  };
10
+ export declare const SPECTRUM_THRESHOLD_COLOR = "#A855F7";
10
11
  export interface LineConfig {
11
12
  name: string;
12
13
  color: string;
package/index.js CHANGED
@@ -1413,6 +1413,10 @@ var __webpack_modules__ = {
1413
1413
  }
1414
1414
  }
1415
1415
 
1416
+ [data-rfkit-charts-root] .border-primary\\/50 {
1417
+ border-color: var(--primary);
1418
+ }
1419
+
1416
1420
  @supports (color: color-mix(in lab, red, red)) {
1417
1421
  [data-rfkit-charts-root] .border-primary\\/50 {
1418
1422
  border-color: color-mix(in oklab, var(--primary) 50%, transparent);
@@ -4183,6 +4187,7 @@ const getDefaultData = ()=>({
4183
4187
  maxData: new Float32Array(),
4184
4188
  minData: new Float32Array(),
4185
4189
  avgData: new Float32Array(),
4190
+ thresholdData: new Float32Array(),
4186
4191
  templateData: new Float32Array(),
4187
4192
  backgroundNoiseData: new Float32Array(),
4188
4193
  waterfallData: [],
@@ -4354,7 +4359,8 @@ const UI_CONFIG = {
4354
4359
  ZOOM_MIN_RANGE: 10,
4355
4360
  POPOVER_MARGIN: 16
4356
4361
  };
4357
- const defaultConfig = {
4362
+ const SPECTRUM_THRESHOLD_COLOR = '#A855F7';
4363
+ const setting_defaultConfig = {
4358
4364
  line: {
4359
4365
  realData: {
4360
4366
  name: 'realData',
@@ -4386,10 +4392,10 @@ const defaultConfig = {
4386
4392
  },
4387
4393
  thresholdData: {
4388
4394
  name: 'thresholdData',
4389
- color: '#FF4C2A',
4395
+ color: SPECTRUM_THRESHOLD_COLOR,
4390
4396
  thickness: 1,
4391
4397
  label: "\u95E8\u9650\u503C",
4392
- display: false
4398
+ display: true
4393
4399
  },
4394
4400
  templateData: {
4395
4401
  name: 'templateData',
@@ -4493,17 +4499,17 @@ const defaultConfig = {
4493
4499
  const setConfig = (c = {})=>{
4494
4500
  const currentConfig = JSON.parse(localStorage.getItem(KEY) || '{}');
4495
4501
  const newConfig = {
4496
- ...defaultConfig,
4502
+ ...setting_defaultConfig,
4497
4503
  ...currentConfig,
4498
4504
  ...c
4499
4505
  };
4500
4506
  localStorage.setItem(KEY, JSON.stringify(newConfig));
4501
4507
  };
4502
4508
  function getConfig(name) {
4503
- let config = defaultConfig ?? JSON.parse(localStorage.getItem(KEY) || 'null');
4509
+ let config = setting_defaultConfig ?? JSON.parse(localStorage.getItem(KEY) || 'null');
4504
4510
  if (!config) {
4505
4511
  setConfig();
4506
- config = defaultConfig;
4512
+ config = setting_defaultConfig;
4507
4513
  }
4508
4514
  return name ? config[name] : config;
4509
4515
  }
@@ -18490,7 +18496,7 @@ const resolveCursorIndexByLeft = (left, outputLength, maxPoints)=>{
18490
18496
  globalIndex: spectrum_analyzer_leftToIndex(safeLeft, maxPoints)
18491
18497
  };
18492
18498
  };
18493
- const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outputPoints, realData, maxData, minData, avgData, templateData, backgroundNoiseData, fluorescenceData, occupancyData, enablePeakStats = false, maxPeaks = 2, outputRangeStart = 0 })=>{
18499
+ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outputPoints, realData, maxData, minData, avgData, templateData, backgroundNoiseData, thresholdData, fluorescenceData, occupancyData, enablePeakStats = false, maxPeaks = 2, outputRangeStart = 0 })=>{
18494
18500
  const realDataLength = realData.length;
18495
18501
  const isLessThanDataLength = realDataLength <= outputPoints;
18496
18502
  const outputLength = isLessThanDataLength ? realDataLength : outputPoints;
@@ -18500,6 +18506,7 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18500
18506
  const hasTemplateData = templateData && templateData.length > 0;
18501
18507
  const hasOccupancyData = occupancyData && occupancyData.length > 0;
18502
18508
  const hasBackgroundNoiseData = backgroundNoiseData && backgroundNoiseData.length > 0;
18509
+ const hasThresholdData = thresholdData && thresholdData.length > 0;
18503
18510
  const hasFluorescenceStats = fluorescenceData && fluorescenceData.length > 0;
18504
18511
  const candidatePeaks = [];
18505
18512
  const applyAntennaFactor = antennaFactorSwitch ? (value1, index)=>value1 + antennaFactorData[index] : (value1)=>value1;
@@ -18511,6 +18518,7 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18511
18518
  const templateOutputData = new Float32Array(hasTemplateData ? outputLength : 0);
18512
18519
  const occupancyOutputData = new Float32Array(hasOccupancyData ? outputLength : 0);
18513
18520
  const backgroundNoiseOutputData = new Float32Array(hasBackgroundNoiseData ? outputLength : 0);
18521
+ const thresholdOutputData = new Float32Array(hasThresholdData ? outputLength : 0);
18514
18522
  let fluorescenceOutputData = new Array(hasFluorescenceStats ? outputLength : 0).fill(null);
18515
18523
  const srcIndexCache = new Uint32Array(outputLength);
18516
18524
  if (isLessThanDataLength) {
@@ -18524,6 +18532,7 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18524
18532
  if (hasTemplateData) templateOutputData[i] = templateData[i] + antennaFactor;
18525
18533
  if (hasOccupancyData) occupancyOutputData[i] = occupancyData[i];
18526
18534
  if (hasBackgroundNoiseData) backgroundNoiseOutputData[i] = backgroundNoiseData[i] + antennaFactor;
18535
+ if (hasThresholdData) thresholdOutputData[i] = thresholdData[i] + antennaFactor;
18527
18536
  if (hasFluorescenceStats) {
18528
18537
  const fluorescence = fluorescenceData[i];
18529
18538
  const newFluorescence = new Map;
@@ -18539,6 +18548,7 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18539
18548
  if (hasTemplateData) templateOutputData.set(templateData);
18540
18549
  if (hasOccupancyData) occupancyOutputData.set(occupancyData);
18541
18550
  if (hasBackgroundNoiseData) backgroundNoiseOutputData.set(backgroundNoiseData);
18551
+ if (hasThresholdData) thresholdOutputData.set(thresholdData);
18542
18552
  if (hasFluorescenceStats) fluorescenceOutputData = fluorescenceData;
18543
18553
  }
18544
18554
  if (enablePeakStats) for(let i = 0; i < realDataLength; i++){
@@ -18600,6 +18610,10 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18600
18610
  const backgroundNoiseValue = backgroundNoiseData[realMaxIdx];
18601
18611
  backgroundNoiseOutputData[i] = applyAntennaFactor(backgroundNoiseValue, realMaxIdx);
18602
18612
  }
18613
+ if (hasThresholdData) {
18614
+ const thresholdValue = thresholdData[realMaxIdx];
18615
+ thresholdOutputData[i] = applyAntennaFactor(thresholdValue, realMaxIdx);
18616
+ }
18603
18617
  if (hasFluorescenceStats) {
18604
18618
  const fluorescence = fluorescenceData[realMaxIdx];
18605
18619
  const newFluorescence = new Map;
@@ -18625,6 +18639,7 @@ const resampleMultiple = ({ antennaFactorData, antennaFactorSwitch = false, outp
18625
18639
  templateOutputData,
18626
18640
  occupancyOutputData,
18627
18641
  backgroundNoiseOutputData,
18642
+ thresholdOutputData,
18628
18643
  srcIndexCache,
18629
18644
  fluorescenceOutputData
18630
18645
  };
@@ -18777,6 +18792,7 @@ class SpectrumAnalyzer {
18777
18792
  templateData;
18778
18793
  occupancyData;
18779
18794
  backgroundNoiseData;
18795
+ thresholdData;
18780
18796
  waterfallData;
18781
18797
  srcIndexCache;
18782
18798
  realOutputData;
@@ -18786,6 +18802,7 @@ class SpectrumAnalyzer {
18786
18802
  templateOutputData;
18787
18803
  occupancyOutputData;
18788
18804
  backgroundNoiseOutputData;
18805
+ thresholdOutputData;
18789
18806
  waterfallOutputData;
18790
18807
  scanProgress;
18791
18808
  lastIndex;
@@ -18801,6 +18818,7 @@ class SpectrumAnalyzer {
18801
18818
  ["occupancy"]: false,
18802
18819
  ["template"]: false,
18803
18820
  ["backgroundNoise"]: false,
18821
+ ["threshold"]: false,
18804
18822
  ["extra"]: false
18805
18823
  };
18806
18824
  hasPendingData = false;
@@ -18834,13 +18852,9 @@ class SpectrumAnalyzer {
18834
18852
  if (!data?.length) return;
18835
18853
  this.isProcessing = true;
18836
18854
  this.hasProcessedData = true;
18837
- let index = offset;
18838
- if (this.segments.length) {
18839
- const segment = this.segments[segmentOffset];
18840
- if (!segment) throw new DataValidationError(ERROR_MESSAGES.INVALID_SEGMENT(segmentOffset));
18841
- index = segment.startIndex + offset;
18842
- this.scanProgress = (index + data.length) / this.config.maxPoints;
18843
- } else if (data.length !== this.config.maxPoints) this.updateMaxPoints(data.length);
18855
+ const index = this.resolveGlobalIndex(segmentOffset, offset);
18856
+ if (this.segments.length) this.scanProgress = (index + data.length) / this.config.maxPoints;
18857
+ else if (data.length !== this.config.maxPoints) this.updateMaxPoints(data.length);
18844
18858
  if (fluorescenceData && void 0 !== fluorescenceMaxCount) {
18845
18859
  this.fluorescenceData = fluorescenceData;
18846
18860
  this.fluorescenceMaxCount = fluorescenceMaxCount;
@@ -18880,6 +18894,7 @@ class SpectrumAnalyzer {
18880
18894
  }
18881
18895
  initializeSegments(segments) {
18882
18896
  if (!segments?.length) throw new DataValidationError(ERROR_MESSAGES.EMPTY_SEGMENTS);
18897
+ const prevMaxPoints = this.config.maxPoints;
18883
18898
  let totalPoints = 0;
18884
18899
  this.segments = segments.map((segment)=>{
18885
18900
  const { startFrequency, stopFrequency, stepFrequency } = segment;
@@ -18896,7 +18911,17 @@ class SpectrumAnalyzer {
18896
18911
  startIndex
18897
18912
  };
18898
18913
  });
18899
- this.updateMaxPoints(totalPoints);
18914
+ this.updateMaxPoints(totalPoints, false);
18915
+ if (prevMaxPoints === totalPoints) {
18916
+ this.config = {
18917
+ ...this.config,
18918
+ outputRange: {
18919
+ start: 0,
18920
+ end: totalPoints
18921
+ }
18922
+ };
18923
+ this.reset(false);
18924
+ }
18900
18925
  }
18901
18926
  setAntennaFactor(d) {
18902
18927
  const { antennaFactorData, config: { maxPoints } } = this;
@@ -19120,7 +19145,9 @@ class SpectrumAnalyzer {
19120
19145
  this.allocateMetricsBuffers();
19121
19146
  this.clearMetricsBuffers();
19122
19147
  this.templateData = new Float32Array;
19148
+ this.occupancyData = new Float32Array;
19123
19149
  this.backgroundNoiseData = new Float32Array;
19150
+ this.clearThresholdDataState();
19124
19151
  this.waterfallData = Array.from({
19125
19152
  length: waterfallMaxFrames
19126
19153
  }, ()=>{
@@ -19157,6 +19184,7 @@ class SpectrumAnalyzer {
19157
19184
  ["occupancy"]: false,
19158
19185
  ["template"]: false,
19159
19186
  ["backgroundNoise"]: false,
19187
+ ["threshold"]: false,
19160
19188
  ["extra"]: false
19161
19189
  };
19162
19190
  this.hasPendingData = false;
@@ -19168,6 +19196,7 @@ class SpectrumAnalyzer {
19168
19196
  avgData: this.avgData,
19169
19197
  templateData: this.templateData,
19170
19198
  backgroundNoiseData: this.backgroundNoiseData,
19199
+ thresholdData: this.thresholdData,
19171
19200
  extraData: this.extraData,
19172
19201
  srcIndexCache: this.srcIndexCache,
19173
19202
  processTimes: 0,
@@ -19236,6 +19265,33 @@ class SpectrumAnalyzer {
19236
19265
  });
19237
19266
  this.setPendingFlag("backgroundNoise", false);
19238
19267
  }
19268
+ setThresholdData(data, options) {
19269
+ if (!data || 0 === data.length) return void this.clearThresholdDataState();
19270
+ const sourceData = data instanceof Float32Array ? data : new Float32Array(data);
19271
+ if (options) {
19272
+ const index = this.resolveGlobalIndex(options.segmentOffset ?? 0, options.offset ?? 0);
19273
+ this.validateInput(sourceData, index);
19274
+ if (this.thresholdData.length !== this.config.maxPoints) {
19275
+ const next = new Float32Array(this.config.maxPoints);
19276
+ next.fill(SPECTRUM.INITIAL_VALUE);
19277
+ if (this.thresholdData.length > 0) next.set(this.thresholdData.subarray(0, this.config.maxPoints));
19278
+ this.thresholdData = next;
19279
+ }
19280
+ this.thresholdData.set(sourceData, index);
19281
+ } else {
19282
+ const normalized = new Float32Array(this.config.maxPoints);
19283
+ normalized.fill(SPECTRUM.INITIAL_VALUE);
19284
+ normalized.set(sourceData.subarray(0, this.config.maxPoints));
19285
+ this.thresholdData = normalized;
19286
+ }
19287
+ if (!this.hasProcessedData || this.isProcessing) return void this.setPendingFlag("threshold", true);
19288
+ const thresholdOutputData = this.resampleSingleData(this.thresholdData);
19289
+ this.thresholdOutputData = thresholdOutputData;
19290
+ this.notifySpectrumUpdate({
19291
+ thresholdData: thresholdOutputData
19292
+ });
19293
+ this.setPendingFlag("threshold", false);
19294
+ }
19239
19295
  updateTemplateOverData(forceFullCalculation = false, incrementalRange) {
19240
19296
  if (!this.templateData || 0 === this.templateData.length) {
19241
19297
  this.cachedExceedingDatas = [];
@@ -19266,10 +19322,23 @@ class SpectrumAnalyzer {
19266
19322
  }
19267
19323
  return templateOverData;
19268
19324
  }
19325
+ resolveGlobalIndex(segmentOffset = 0, offset = 0) {
19326
+ if (this.segments.length) {
19327
+ const segment = this.segments[segmentOffset];
19328
+ if (!segment) throw new DataValidationError(ERROR_MESSAGES.INVALID_SEGMENT(segmentOffset));
19329
+ return segment.startIndex + offset;
19330
+ }
19331
+ return offset;
19332
+ }
19333
+ clearThresholdDataState() {
19334
+ this.thresholdData = new Float32Array(0);
19335
+ this.thresholdOutputData = new Float32Array(0);
19336
+ this.setPendingFlag("threshold", false);
19337
+ }
19269
19338
  resampleDataSeries() {
19270
- const { antennaFactorData, antennaFactorSwitch, maxData, minData, avgData, templateData, occupancyData, backgroundNoiseData, config: { maxPoints, outputPoints } } = this;
19339
+ const { antennaFactorData, antennaFactorSwitch, maxData, minData, avgData, templateData, occupancyData, backgroundNoiseData, thresholdData, config: { maxPoints, outputPoints } } = this;
19271
19340
  const activeAntennaFactorData = antennaFactorSwitch ? antennaFactorData : new Float32Array(maxPoints);
19272
- const { realOutputData, srcIndexCache, maxOutputData, minOutputData, avgOutputData, templateOutputData, occupancyOutputData, backgroundNoiseOutputData } = resampleMultiple({
19341
+ const { realOutputData, srcIndexCache, maxOutputData, minOutputData, avgOutputData, templateOutputData, occupancyOutputData, backgroundNoiseOutputData, thresholdOutputData } = resampleMultiple({
19273
19342
  antennaFactorData: activeAntennaFactorData,
19274
19343
  antennaFactorSwitch,
19275
19344
  outputPoints,
@@ -19280,6 +19349,7 @@ class SpectrumAnalyzer {
19280
19349
  templateData: templateData && templateData.length > 0 ? this.getOutputData(templateData) : void 0,
19281
19350
  occupancyData: occupancyData && occupancyData.length > 0 ? this.getOutputData(occupancyData) : void 0,
19282
19351
  backgroundNoiseData: backgroundNoiseData && backgroundNoiseData.length > 0 ? this.getOutputData(backgroundNoiseData) : void 0,
19352
+ thresholdData: thresholdData && thresholdData.length > 0 ? this.getOutputData(thresholdData) : void 0,
19283
19353
  enablePeakStats: this.config.processing.enablePeakStats,
19284
19354
  maxPeaks: this.config.peakDetection.maxPeaks,
19285
19355
  outputRangeStart: this.config.outputRange.start
@@ -19292,6 +19362,7 @@ class SpectrumAnalyzer {
19292
19362
  this.templateOutputData = templateOutputData || new Float32Array;
19293
19363
  this.occupancyOutputData = occupancyOutputData || new Float32Array;
19294
19364
  this.backgroundNoiseOutputData = backgroundNoiseOutputData || new Float32Array;
19365
+ this.thresholdOutputData = thresholdOutputData || new Float32Array;
19295
19366
  const fluorescenceOutput = this.getFluorescenceOutputData(realOutputData.length);
19296
19367
  return {
19297
19368
  realData: realOutputData,
@@ -19301,6 +19372,7 @@ class SpectrumAnalyzer {
19301
19372
  templateData: templateOutputData,
19302
19373
  occupancyData: occupancyOutputData,
19303
19374
  backgroundNoiseData: backgroundNoiseOutputData,
19375
+ thresholdData: thresholdOutputData,
19304
19376
  fluorescenceData: fluorescenceOutput,
19305
19377
  fluorescenceMaxCount: this.fluorescenceMaxCount,
19306
19378
  extraData: this.extraOutputData,
@@ -19335,7 +19407,7 @@ class SpectrumAnalyzer {
19335
19407
  this.waterfallData.push(newData);
19336
19408
  this.waterfallOutputData.push(outputData);
19337
19409
  }
19338
- updateMaxPoints(maxPoints) {
19410
+ updateMaxPoints(maxPoints, preserveProcessedFlag = true) {
19339
19411
  if (this.config.maxPoints === maxPoints) return;
19340
19412
  this.config = {
19341
19413
  ...this.config,
@@ -19345,7 +19417,7 @@ class SpectrumAnalyzer {
19345
19417
  end: maxPoints
19346
19418
  }
19347
19419
  };
19348
- this.reset(true);
19420
+ this.reset(preserveProcessedFlag);
19349
19421
  }
19350
19422
  validateInput(data, index) {
19351
19423
  if (index < 0 || index + data.length > this.config.maxPoints) throw new IndexOutOfBoundsError(ERROR_MESSAGES.INDEX_OUT_OF_BOUNDS(index), index);
@@ -19390,7 +19462,7 @@ class SpectrumAnalyzer {
19390
19462
  }
19391
19463
  setPendingFlag(type, value1) {
19392
19464
  this.pendingDataFlags[type] = value1;
19393
- this.hasPendingData = this.pendingDataFlags["occupancy"] || this.pendingDataFlags["template"] || this.pendingDataFlags["backgroundNoise"] || this.pendingDataFlags["extra"];
19465
+ this.hasPendingData = this.pendingDataFlags["occupancy"] || this.pendingDataFlags["template"] || this.pendingDataFlags["backgroundNoise"] || this.pendingDataFlags["threshold"] || this.pendingDataFlags["extra"];
19394
19466
  }
19395
19467
  resampleSingleData(sourceData) {
19396
19468
  const { srcIndexCache } = this;
@@ -19418,6 +19490,12 @@ class SpectrumAnalyzer {
19418
19490
  pendingOutput.backgroundNoiseData = this.resampleSingleData(this.backgroundNoiseData);
19419
19491
  this.setPendingFlag("backgroundNoise", false);
19420
19492
  }
19493
+ if (this.pendingDataFlags["threshold"] && this.thresholdData.length > 0) {
19494
+ const thresholdOutputData = this.resampleSingleData(this.thresholdData);
19495
+ this.thresholdOutputData = thresholdOutputData;
19496
+ pendingOutput.thresholdData = thresholdOutputData;
19497
+ this.setPendingFlag("threshold", false);
19498
+ }
19421
19499
  if (this.pendingDataFlags["extra"] && Object.keys(this.extraData).length > 0) {
19422
19500
  this.extraOutputData = resampleExtraData(this.extraData, this.antennaFactorData, this.antennaFactorSwitch, this.srcIndexCache, this.getOutputData.bind(this));
19423
19501
  pendingOutput.extraData = this.extraOutputData;
@@ -19458,7 +19536,7 @@ class SpectrumAnalyzer {
19458
19536
  return outputData;
19459
19537
  }
19460
19538
  getAllRawData(left) {
19461
- const { realOutputData, maxOutputData, minOutputData, avgOutputData, templateOutputData, occupancyOutputData, backgroundNoiseOutputData, waterfallOutputData, extraOutputData, srcIndexCache } = this;
19539
+ const { realOutputData, maxOutputData, minOutputData, avgOutputData, templateOutputData, occupancyOutputData, backgroundNoiseOutputData, thresholdOutputData, waterfallOutputData, extraOutputData, srcIndexCache } = this;
19462
19540
  realOutputData.timestamp = this.realData.timestamp;
19463
19541
  const rawData = {
19464
19542
  realData: this.realData,
@@ -19468,6 +19546,7 @@ class SpectrumAnalyzer {
19468
19546
  templateData: this.templateData,
19469
19547
  occupancyData: this.occupancyData,
19470
19548
  backgroundNoiseData: this.backgroundNoiseData,
19549
+ thresholdData: this.thresholdData,
19471
19550
  waterfallData: this.waterfallData,
19472
19551
  extraData: this.extraData
19473
19552
  };
@@ -19480,6 +19559,7 @@ class SpectrumAnalyzer {
19480
19559
  templateData: templateOutputData,
19481
19560
  occupancyData: occupancyOutputData,
19482
19561
  backgroundNoiseData: backgroundNoiseOutputData,
19562
+ thresholdData: thresholdOutputData,
19483
19563
  fluorescenceData: this.getFluorescenceOutputData(realOutputData.length),
19484
19564
  waterfallData: waterfallOutputData,
19485
19565
  extraData: extraOutputData,
@@ -19638,7 +19718,7 @@ class SeriesManager {
19638
19718
  return true;
19639
19719
  }
19640
19720
  }
19641
- const events_SeriesEventName = {
19721
+ const SeriesEventName = {
19642
19722
  UPDATED: 'series:updated',
19643
19723
  ADDED: 'series:added',
19644
19724
  REMOVED: 'series:removed',
@@ -19689,7 +19769,7 @@ function subscribeToSeries(globalID, event, listener) {
19689
19769
  if (data.globalID === globalID) listener(data);
19690
19770
  });
19691
19771
  }
19692
- function events_emitSeriesEvent(event, data) {
19772
+ function emitSeriesEvent(event, data) {
19693
19773
  seriesEvents.emit(event, data);
19694
19774
  }
19695
19775
  var modes_SeriesMode = /*#__PURE__*/ function(SeriesMode) {
@@ -19750,7 +19830,7 @@ function getNextMode(currentMode) {
19750
19830
  function setSeriesMode(globalID, mode) {
19751
19831
  seriesModes.set(globalID, mode);
19752
19832
  const modeConfig = SERIES_MODES[mode];
19753
- events_emitSeriesEvent(events_SeriesEventName.MODE_CHANGED, {
19833
+ emitSeriesEvent(SeriesEventName.MODE_CHANGED, {
19754
19834
  globalID,
19755
19835
  mode,
19756
19836
  config: modeConfig
@@ -19768,7 +19848,7 @@ function initSeriesSubscription(renderer) {
19768
19848
  return null;
19769
19849
  }
19770
19850
  const subscriptions = [];
19771
- subscriptions.push(subscribeToSeries(globalID, events_SeriesEventName.UPDATED, (data)=>{
19851
+ subscriptions.push(subscribeToSeries(globalID, SeriesEventName.UPDATED, (data)=>{
19772
19852
  const correctType = getCorrectSeriesType(globalID, data.seriesName);
19773
19853
  const configWithCorrectType = {
19774
19854
  ...data.config,
@@ -19777,13 +19857,13 @@ function initSeriesSubscription(renderer) {
19777
19857
  renderer.setSeries(configWithCorrectType, true);
19778
19858
  renderer.state.chart?.draw();
19779
19859
  }));
19780
- subscriptions.push(subscribeToSeries(globalID, events_SeriesEventName.MODE_CHANGED, ()=>{
19860
+ subscriptions.push(subscribeToSeries(globalID, SeriesEventName.MODE_CHANGED, ()=>{
19781
19861
  renderer.initSeries();
19782
19862
  }));
19783
- subscriptions.push(subscribeToSeries(globalID, events_SeriesEventName.TYPE_OVERRIDE_CHANGED, ()=>{
19863
+ subscriptions.push(subscribeToSeries(globalID, SeriesEventName.TYPE_OVERRIDE_CHANGED, ()=>{
19784
19864
  renderer.initSeries();
19785
19865
  }));
19786
- subscriptions.push(subscribeToSeries(globalID, events_SeriesEventName.BATCH_UPDATED, (data)=>{
19866
+ subscriptions.push(subscribeToSeries(globalID, SeriesEventName.BATCH_UPDATED, (data)=>{
19787
19867
  data.configs.forEach((config)=>{
19788
19868
  const correctType = getCorrectSeriesType(globalID, config.name);
19789
19869
  const configWithCorrectType = {
@@ -19794,7 +19874,7 @@ function initSeriesSubscription(renderer) {
19794
19874
  });
19795
19875
  renderer.state.chart?.draw();
19796
19876
  }));
19797
- subscriptions.push(subscribeToSeries(globalID, events_SeriesEventName.RESET, ()=>{
19877
+ subscriptions.push(subscribeToSeries(globalID, SeriesEventName.RESET, ()=>{
19798
19878
  if (renderer.state.series) renderer.state.series = {};
19799
19879
  renderer.initSeries();
19800
19880
  }));
@@ -19806,7 +19886,7 @@ const chartTypeSeriesOverrides = new Map();
19806
19886
  function setChartTypeSeriesOverride(globalID, seriesName, type) {
19807
19887
  if (!chartTypeSeriesOverrides.has(globalID)) chartTypeSeriesOverrides.set(globalID, new Map());
19808
19888
  chartTypeSeriesOverrides.get(globalID)?.set(seriesName, type);
19809
- events_emitSeriesEvent(events_SeriesEventName.TYPE_OVERRIDE_CHANGED, {
19889
+ emitSeriesEvent(SeriesEventName.TYPE_OVERRIDE_CHANGED, {
19810
19890
  globalID,
19811
19891
  seriesName,
19812
19892
  type
@@ -19815,7 +19895,7 @@ function setChartTypeSeriesOverride(globalID, seriesName, type) {
19815
19895
  function clearChartTypeSeriesOverrides(globalID) {
19816
19896
  const hadOverrides = chartTypeSeriesOverrides.has(globalID);
19817
19897
  chartTypeSeriesOverrides.delete(globalID);
19818
- if (hadOverrides) events_emitSeriesEvent(events_SeriesEventName.TYPE_OVERRIDE_CHANGED, {
19898
+ if (hadOverrides) emitSeriesEvent(SeriesEventName.TYPE_OVERRIDE_CHANGED, {
19819
19899
  globalID
19820
19900
  });
19821
19901
  }
@@ -19879,16 +19959,18 @@ function getSeriesMap(globalID) {
19879
19959
  return seriesMap;
19880
19960
  }
19881
19961
  function mergeSeriesConfig(config, existing) {
19962
+ const defaultConfig = getSeriesConfig()[config.name];
19882
19963
  const defaults = {
19883
- label: '',
19884
- display: true,
19964
+ label: defaultConfig?.label ?? '',
19965
+ color: defaultConfig?.color,
19966
+ display: defaultConfig?.display ?? true,
19885
19967
  type: __WEBPACK_EXTERNAL_MODULE__rfkit_renderer_d3372451__.GraphicType.Line,
19886
- thickness: 1
19968
+ thickness: defaultConfig?.thickness ?? 1
19887
19969
  };
19888
19970
  return {
19889
19971
  name: config.name,
19890
19972
  label: config.label ?? existing?.label ?? defaults.label,
19891
- color: config.color ?? existing?.color ?? (()=>{
19973
+ color: config.color ?? existing?.color ?? defaults.color ?? (()=>{
19892
19974
  throw new Error(`Series "${config.name}" does not exist and must have a color defined`);
19893
19975
  })(),
19894
19976
  display: config.display ?? existing?.display ?? defaults.display,
@@ -19896,14 +19978,21 @@ function mergeSeriesConfig(config, existing) {
19896
19978
  thickness: config.thickness ?? existing?.thickness ?? defaults.thickness
19897
19979
  };
19898
19980
  }
19981
+ function upsertSeriesConfig(manager, finalConfig, existing) {
19982
+ if (!existing) return void manager.addSeries(finalConfig);
19983
+ manager.setSeriesProperty(finalConfig.name, 'label', finalConfig.label);
19984
+ manager.setSeriesProperty(finalConfig.name, 'color', finalConfig.color);
19985
+ manager.setSeriesProperty(finalConfig.name, 'thickness', finalConfig.thickness);
19986
+ manager.setSeriesProperty(finalConfig.name, 'display', finalConfig.display);
19987
+ manager.setSeriesProperty(finalConfig.name, 'type', finalConfig.type);
19988
+ }
19899
19989
  function updateSeries(globalID, config) {
19900
19990
  if (!config?.name) return;
19901
19991
  const manager = getSeriesManager(globalID);
19902
19992
  const existing = manager.getSeries(config.name);
19903
19993
  const finalConfig = mergeSeriesConfig(config, existing);
19904
- if (existing) manager.removeSeries(config.name);
19905
- manager.addSeries(finalConfig);
19906
- events_emitSeriesEvent(events_SeriesEventName.UPDATED, {
19994
+ upsertSeriesConfig(manager, finalConfig, existing);
19995
+ emitSeriesEvent(SeriesEventName.UPDATED, {
19907
19996
  globalID,
19908
19997
  seriesName: config.name,
19909
19998
  config: {
@@ -19930,10 +20019,32 @@ function resetSeries(globalID) {
19930
20019
  thickness: config.thickness
19931
20020
  });
19932
20021
  });
19933
- events_emitSeriesEvent(events_SeriesEventName.RESET, {
20022
+ emitSeriesEvent(SeriesEventName.RESET, {
19934
20023
  globalID
19935
20024
  });
19936
20025
  }
20026
+ function batchUpdateSeries(globalID, configs) {
20027
+ const manager = getSeriesManager(globalID);
20028
+ const updatedConfigs = [];
20029
+ configs.forEach((config)=>{
20030
+ if (!config?.name) return;
20031
+ const existing = manager.getSeries(config.name);
20032
+ const finalConfig = mergeSeriesConfig(config, existing);
20033
+ upsertSeriesConfig(manager, finalConfig, existing);
20034
+ updatedConfigs.push({
20035
+ name: finalConfig.name,
20036
+ label: finalConfig.label,
20037
+ color: finalConfig.color,
20038
+ thickness: finalConfig.thickness,
20039
+ display: finalConfig.display,
20040
+ type: finalConfig.type
20041
+ });
20042
+ });
20043
+ if (updatedConfigs.length > 0) emitSeriesEvent(SeriesEventName.BATCH_UPDATED, {
20044
+ globalID,
20045
+ configs: updatedConfigs
20046
+ });
20047
+ }
19937
20048
  function getSeriesWithGraphicType(globalID) {
19938
20049
  const seriesMap = getSeriesMap(globalID);
19939
20050
  const result = new Map();
@@ -20522,32 +20633,32 @@ function useSeriesManager(globalID, options = {}) {
20522
20633
  const unsubscribers = [];
20523
20634
  if (subscribeToMode) {
20524
20635
  setMode(getSeriesMode(globalID));
20525
- const unsubscribeMode = subscribeToSeries(globalID, events_SeriesEventName.MODE_CHANGED, (data)=>{
20636
+ const unsubscribeMode = subscribeToSeries(globalID, SeriesEventName.MODE_CHANGED, (data)=>{
20526
20637
  setMode(data.mode);
20527
20638
  });
20528
20639
  unsubscribers.push(unsubscribeMode);
20529
20640
  }
20530
20641
  if (subscribeToData) {
20531
- const unsubscribeUpdated = subscribeToSeries(globalID, events_SeriesEventName.UPDATED, (data)=>{
20642
+ const unsubscribeUpdated = subscribeToSeries(globalID, SeriesEventName.UPDATED, (data)=>{
20532
20643
  if (watchSeries && !watchSeries.includes(data.seriesName)) return;
20533
20644
  forceUpdate();
20534
20645
  });
20535
20646
  unsubscribers.push(unsubscribeUpdated);
20536
- const unsubscribeAdded = subscribeToSeries(globalID, events_SeriesEventName.ADDED, (data)=>{
20647
+ const unsubscribeAdded = subscribeToSeries(globalID, SeriesEventName.ADDED, (data)=>{
20537
20648
  if (watchSeries && !watchSeries.includes(data.seriesName)) return;
20538
20649
  forceUpdate();
20539
20650
  });
20540
20651
  unsubscribers.push(unsubscribeAdded);
20541
- const unsubscribeRemoved = subscribeToSeries(globalID, events_SeriesEventName.REMOVED, (data)=>{
20652
+ const unsubscribeRemoved = subscribeToSeries(globalID, SeriesEventName.REMOVED, (data)=>{
20542
20653
  if (watchSeries && !watchSeries.includes(data.seriesName)) return;
20543
20654
  forceUpdate();
20544
20655
  });
20545
20656
  unsubscribers.push(unsubscribeRemoved);
20546
- const unsubscribeBatchUpdated = subscribeToSeries(globalID, events_SeriesEventName.BATCH_UPDATED, ()=>{
20657
+ const unsubscribeBatchUpdated = subscribeToSeries(globalID, SeriesEventName.BATCH_UPDATED, ()=>{
20547
20658
  forceUpdate();
20548
20659
  });
20549
20660
  unsubscribers.push(unsubscribeBatchUpdated);
20550
- const unsubscribeReset = subscribeToSeries(globalID, events_SeriesEventName.RESET, ()=>{
20661
+ const unsubscribeReset = subscribeToSeries(globalID, SeriesEventName.RESET, ()=>{
20551
20662
  forceUpdate();
20552
20663
  });
20553
20664
  unsubscribers.push(unsubscribeReset);
@@ -20576,21 +20687,14 @@ function useSeriesForComponent(globalID) {
20576
20687
  subscribeToData: true
20577
20688
  });
20578
20689
  }
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;
20690
+ const DEFAULT_SERIES_ORDER = Object.values(getSeriesConfig()).map((config)=>config.name);
20691
+ function getStableOrder(currentNames) {
20692
+ return [
20693
+ ...DEFAULT_SERIES_ORDER.filter((name)=>currentNames.includes(name)),
20694
+ ...currentNames.filter((name)=>!DEFAULT_SERIES_ORDER.includes(name))
20695
+ ];
20592
20696
  }
20593
- function useFilteredSeries(globalID, filter) {
20697
+ function useFilteredSeries_useFilteredSeries(globalID, filter) {
20594
20698
  const { series } = useSeriesManager(globalID);
20595
20699
  const { state: { series: { legendExternal } } } = useStore_useStore();
20596
20700
  const filteredData = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>{
@@ -20599,12 +20703,8 @@ function useFilteredSeries(globalID, filter) {
20599
20703
  if (config.name === constants_SeriesType.TemplateData) return false;
20600
20704
  return filter ? filter(config) : true;
20601
20705
  });
20602
- if (!globalID) return filtered.map((config, index)=>({
20603
- ...config,
20604
- originalIndex: index
20605
- }));
20606
20706
  const currentNames = filtered.map((s)=>s.name);
20607
- const stableOrder = getStableOrder(globalID, currentNames);
20707
+ const stableOrder = getStableOrder(currentNames);
20608
20708
  const orderMap = new Map(stableOrder.map((name, i)=>[
20609
20709
  name,
20610
20710
  i
@@ -20620,8 +20720,7 @@ function useFilteredSeries(globalID, filter) {
20620
20720
  }, [
20621
20721
  series,
20622
20722
  legendExternal,
20623
- filter,
20624
- globalID
20723
+ filter
20625
20724
  ]);
20626
20725
  return filteredData;
20627
20726
  }
@@ -21153,7 +21252,7 @@ const StationInfoPanel = ({ stationInfo })=>{
21153
21252
  const panels_StationInfoPanel = /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].memo(StationInfoPanel);
21154
21253
  const FrequencyDataBoard = ({ left, updateKey, onChange, showStationInfo = true })=>{
21155
21254
  const { state: { axisY, axisX: { frequencyFormat, unit }, globalID } } = useStore_useStore();
21156
- const filteredSeries = useFilteredSeries(globalID, (config)=>false !== config.display);
21255
+ const filteredSeries = useFilteredSeries_useFilteredSeries(globalID, (config)=>false !== config.display);
21157
21256
  const calculateIndex = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((values, series, sampledIndex, rawValue)=>{
21158
21257
  if (!values || 0 === values.length) return null;
21159
21258
  const safeSampledIndex = Math.max(0, Math.min(values.length - 1, Math.floor(sampledIndex)));
@@ -21207,6 +21306,7 @@ const FrequencyDataBoard = ({ left, updateKey, onChange, showStationInfo = true
21207
21306
  maxData: snapshot.maxData,
21208
21307
  minData: snapshot.minData,
21209
21308
  avgData: snapshot.avgData,
21309
+ thresholdData: snapshot.thresholdData,
21210
21310
  templateData: snapshot.templateData,
21211
21311
  occupancyData: snapshot.occupancyData,
21212
21312
  backgroundNoiseData: snapshot.backgroundNoiseData,
@@ -21217,6 +21317,7 @@ const FrequencyDataBoard = ({ left, updateKey, onChange, showStationInfo = true
21217
21317
  maxData: snapshot.rawData?.maxData,
21218
21318
  minData: snapshot.rawData?.minData,
21219
21319
  avgData: snapshot.rawData?.avgData,
21320
+ thresholdData: snapshot.rawData?.thresholdData,
21220
21321
  templateData: snapshot.rawData?.templateData,
21221
21322
  occupancyData: snapshot.rawData?.occupancyData,
21222
21323
  backgroundNoiseData: snapshot.rawData?.backgroundNoiseData,
@@ -23483,7 +23584,7 @@ class Spectrum extends BaseRenderer {
23483
23584
  const { color = SERIES[name]?.color, thickness = 1, display = false } = merged;
23484
23585
  const nextSeriesConfig = {
23485
23586
  name,
23486
- label: config.label,
23587
+ label: merged.label,
23487
23588
  type: resolvedType || __WEBPACK_EXTERNAL_MODULE__rfkit_renderer_d3372451__.GraphicType.Line,
23488
23589
  color,
23489
23590
  thickness,
@@ -23497,7 +23598,7 @@ class Spectrum extends BaseRenderer {
23497
23598
  if (!skipEventEmit && globalID) try {
23498
23599
  updateSeries(globalID, {
23499
23600
  name,
23500
- label: config.label || name,
23601
+ label: nextSeriesConfig.label || name,
23501
23602
  color,
23502
23603
  thickness,
23503
23604
  display,
@@ -23915,36 +24016,24 @@ const SeriesControl_SeriesControl = ({ type })=>{
23915
24016
  const SeriesControl = SeriesControl_SeriesControl;
23916
24017
  const SeriesDisplayControl = ()=>{
23917
24018
  const { state: { globalID, series: seriesConfig } } = useStore_useStore();
23918
- const filteredSeries = useFilteredSeries(globalID);
23919
- const { forceUpdate } = useSeriesForComponent(globalID);
24019
+ const filteredSeries = useFilteredSeries_useFilteredSeries(globalID);
23920
24020
  (0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
23921
24021
  if (!globalID || !seriesConfig?.forceDisplay) return;
23922
24022
  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
- }
24023
+ if (hiddenSeries.length > 0) batchUpdateSeries(globalID, hiddenSeries.map(({ name })=>({
24024
+ name,
24025
+ display: true
24026
+ })));
23932
24027
  }, [
23933
24028
  globalID,
23934
24029
  seriesConfig?.forceDisplay,
23935
24030
  filteredSeries.length
23936
24031
  ]);
23937
24032
  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();
24033
+ if (!globalID || 0 === updates.length) return;
24034
+ batchUpdateSeries(globalID, updates);
23945
24035
  }, [
23946
- globalID,
23947
- forceUpdate
24036
+ globalID
23948
24037
  ]);
23949
24038
  const handleSeriesToggle = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((seriesName, display)=>{
23950
24039
  updateSeriesDisplay([
@@ -26902,6 +26991,12 @@ const FrequencyTagLine_FrequencyTagLine = (props)=>{
26902
26991
  });
26903
26992
  };
26904
26993
  const FrequencyTagLine = /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].memo(FrequencyTagLine_FrequencyTagLine);
26994
+ const LIMIT_THRESHOLD_TEXT_STYLE = {
26995
+ color: SPECTRUM_THRESHOLD_COLOR
26996
+ };
26997
+ const LIMIT_THRESHOLD_LINE_STYLE = {
26998
+ borderColor: SPECTRUM_THRESHOLD_COLOR
26999
+ };
26905
27000
  const Item_Item = ({ value: value1, onChange })=>{
26906
27001
  const { state: { axisY, limit } } = useStore_useStore();
26907
27002
  const { label, disabled } = limit;
@@ -26966,6 +27061,7 @@ const Item_Item = ({ value: value1, onChange })=>{
26966
27061
  type: "button",
26967
27062
  disabled: disabled,
26968
27063
  className: "pointer-events-auto absolute right-7 top-[-28px] z-[8] flex h-6 appearance-none items-center justify-center rounded-[var(--radius-control)] border-0 bg-secondary px-2 text-xs text-foreground",
27064
+ style: LIMIT_THRESHOLD_TEXT_STYLE,
26969
27065
  onClick: ()=>setIsEdit(true),
26970
27066
  children: [
26971
27067
  label,
@@ -26975,6 +27071,7 @@ const Item_Item = ({ value: value1, onChange })=>{
26975
27071
  ]
26976
27072
  }) : /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)("div", {
26977
27073
  className: "pointer-events-auto absolute right-7 top-[-28px] z-[8] flex h-6 items-center justify-between bg-secondary px-2 text-xs text-foreground",
27074
+ style: LIMIT_THRESHOLD_TEXT_STYLE,
26978
27075
  children: [
26979
27076
  label,
26980
27077
  "\xa0",
@@ -26986,7 +27083,8 @@ const Item_Item = ({ value: value1, onChange })=>{
26986
27083
  min: min,
26987
27084
  max: max,
26988
27085
  step: step / 5,
26989
- className: "h-auto w-14 border-none bg-transparent p-0 text-center text-primary outline-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
27086
+ className: "h-auto w-14 border-none bg-transparent p-0 text-center outline-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
27087
+ style: LIMIT_THRESHOLD_TEXT_STYLE,
26990
27088
  onKeyDown: onEnter
26991
27089
  }),
26992
27090
  /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
@@ -26996,7 +27094,8 @@ const Item_Item = ({ value: value1, onChange })=>{
26996
27094
  ]
26997
27095
  }),
26998
27096
  /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("div", {
26999
- className: "absolute right-0 top-[-0.5px] z-[8] h-0 w-full border-b border-dashed border-primary"
27097
+ className: "absolute right-0 top-[-0.5px] z-[8] h-0 w-full border-b border-dashed",
27098
+ style: LIMIT_THRESHOLD_LINE_STYLE
27000
27099
  })
27001
27100
  ]
27002
27101
  })
@@ -29539,6 +29638,16 @@ const useMarkerPublish_useMarkerPublish = ({ globalID })=>{
29539
29638
  };
29540
29639
  };
29541
29640
  const useMarkerPublish = useMarkerPublish_useMarkerPublish;
29641
+ function resolveThresholdDataOptions({ segmentOffset, offset }) {
29642
+ const options = {};
29643
+ if (void 0 !== segmentOffset) options.segmentOffset = segmentOffset;
29644
+ if (void 0 !== offset) options.offset = offset;
29645
+ return void 0 !== options.segmentOffset || void 0 !== options.offset ? options : void 0;
29646
+ }
29647
+ function setAnalyzerThresholdData(analyzer, payload) {
29648
+ if (!('thresholdData' in payload)) return;
29649
+ analyzer.setThresholdData(payload.thresholdData, resolveThresholdDataOptions(payload));
29650
+ }
29542
29651
  function useTemplateComparison() {
29543
29652
  const { state: { globalID, axisX: { frequencyFormat }, signal: { onChange } } } = useStore_useStore();
29544
29653
  const frequencyFormatRef = (0, __WEBPACK_EXTERNAL_MODULE_react__.useRef)(frequencyFormat);
@@ -29617,10 +29726,11 @@ function useSpectrumAnalyzer(props) {
29617
29726
  }, []);
29618
29727
  const { updateTemplateOverData } = useTemplateComparison();
29619
29728
  const handleSpectrumUpdate = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((data)=>{
29620
- if (data.realData || data.templateData || data.backgroundNoiseData) updateSpectrum({
29729
+ if (data.realData || data.templateData || data.backgroundNoiseData || 'thresholdData' in data) updateSpectrum({
29621
29730
  minData: data.minData,
29622
29731
  maxData: data.maxData,
29623
29732
  avgData: data.avgData,
29733
+ thresholdData: data.thresholdData,
29624
29734
  backgroundNoiseData: data.backgroundNoiseData,
29625
29735
  realData: data.realData,
29626
29736
  templateData: data.templateData
@@ -29715,6 +29825,7 @@ function useSpectrumAnalyzer(props) {
29715
29825
  break;
29716
29826
  case constants_PSType.Spectrum:
29717
29827
  if (e.data) analyzer.current.process(e);
29828
+ setAnalyzerThresholdData(analyzer.current, e);
29718
29829
  if (e.maxData) analyzer.current.setMaxData(e.maxData);
29719
29830
  if (e.minData) analyzer.current.setMinData(e.minData);
29720
29831
  if (e.avgData) analyzer.current.setAvgData(e.avgData);
@@ -0,0 +1,6 @@
1
+ export declare const LIMIT_THRESHOLD_TEXT_STYLE: {
2
+ color: "#A855F7";
3
+ };
4
+ export declare const LIMIT_THRESHOLD_LINE_STYLE: {
5
+ borderColor: "#A855F7";
6
+ };
@@ -0,0 +1,8 @@
1
+ import type { PublishSpectrum } from '../../../types';
2
+ export type SpectrumThresholdDataOptions = Pick<PublishSpectrum, 'segmentOffset' | 'offset'>;
3
+ export declare function resolveThresholdDataOptions({ segmentOffset, offset }: SpectrumThresholdDataOptions): SpectrumThresholdDataOptions | undefined;
4
+ type ThresholdDataTarget = {
5
+ setThresholdData: (data?: PublishSpectrum['thresholdData'], options?: SpectrumThresholdDataOptions) => void;
6
+ };
7
+ export declare function setAnalyzerThresholdData(analyzer: ThresholdDataTarget, payload: PublishSpectrum): void;
8
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rfkit/charts",
3
- "version": "1.4.3",
3
+ "version": "1.5.1",
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;