Skip to content

Commit 1482e2d

Browse files
demvladhaslinghuisCopilot
authored
The simple PSD spectrum comparison of one log file data (#847)
* Added sceletion of code to add PSD curves into import list by press Insert key * Added one log PSD curves into import list by press Insert key to spectrum comparison * Code issues improvement * Code style improvement * Code style improvement Co-authored-by: Mark Haslinghuis <[email protected]> * Added Add button to compare spectrums * The Import Export Clear buttons captions are changed to short Exp,Imp,Clr * The spectrums legend height is improved * The spectrum Add button is visible for PSD curve only * Using of toggle method to change css property Co-authored-by: Mark Haslinghuis <[email protected]> * Added checking of maximal imported curves count * Code refactoring: using of getCurve method instead of direct _curvesData field access in ImportedCurves * Code refactoring in graph_spectrum_plot: using getCurveColor method instaed of direct access to curvesColors array * Code refactoring in graph_imported_curves.js: added using of trim method * Semi comma issue is resolved * Added IndexError exeption * Resolved missing operator new issue * Added Ctrl+Mouse click at curves legend action to show and compare it * Code style improvement * The imported spectrums are removed by simple mouse click at the curves legend * The main curve is added into imported list when the second curve is selected for comparison * The main curve is added into imported list when the second curve is imported from external file * Imported spectrums count is increased to 6 * The spectrum comparison Add button and Insert key action are removed as lessfull * Imported PSD curves drawing start point is improved * Wrong IndexError exception is changed to RangeError * Code style improvement * The imported curves drawing start position is improved by using moveTo * Using === !== instead of == != * Improved spectrums legend vertical centering * Added comments for const values * The code refactoring for graph hasAnalyser variable condition Co-authored-by: Copilot <[email protected]> * Improved errors message for RangeError exception Co-authored-by: Copilot <[email protected]> * The comments text is improved * Code refactoring for main spectrum curve color * The spectrums legend positions setup refactoring * The code refactoring for adding main spectrum curve to imported list * Added comment for first spectrums csv file import * Locked the curves PSD spectrum selection while import has maximal curves count * Added removeCurve and other helper methods into ImportedCurves * The spectrum curve is deleted by Ctrl+Mouse click * Code refactoring: SpectrumForImport renamed to SpectrumForComparison * Code issues are resolved * Code style improvement --------- Co-authored-by: Mark Haslinghuis <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent fea0dc0 commit 1482e2d

File tree

7 files changed

+307
-109
lines changed

7 files changed

+307
-109
lines changed

index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,10 +477,10 @@ <h4>Workspace</h4>
477477
</div>
478478

479479
<div id="spectrumComparison" data-toggle="tooltip" title="Spectrum comparison">
480-
<button id="btn-spectrum-export" type="button" title="Export spectrum to CSV">Export</button>
481-
<button type="button" onclick="document.getElementById('btn-spectrum-import').click()" title="Import spectrum from CSV">Import</button>
480+
<button id="btn-spectrum-export" type="button" title="Export spectrum to CSV">Exp</button>
481+
<button type="button" onclick="document.getElementById('btn-spectrum-import').click()" title="Import spectrum from CSV">Imp</button>
482482
<input type="file" id="btn-spectrum-import" accept=".csv" style="display:none" multiple/>
483-
<button type="button" id="btn-spectrum-clear" title="Clear imported spectrums">Clear</button>
483+
<button type="button" id="btn-spectrum-clear" title="Clear imported spectrums">Clr</button>
484484
</div>
485485

486486
<div id="analyserResize" class="btn-nobg view-analyser-fullscreen" data-toggle="tooltip" title="Zoom Analyser Window">

src/graph_imported_curves.js

Lines changed: 140 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,158 @@
11
export function ImportedCurves(curvesChanged) {
2-
const maxImportCount = 5;
3-
this._curvesData = [];
2+
const MAX_IMPORT_COUNT = 6; // This value is limited by legends size and curves colors visibility. May be increased if needed by users
3+
const _curvesData = [];
44
const _that = this;
55
this.minX = Number.MAX_VALUE;
66
this.maxX = -Number.MAX_VALUE;
77
this.minY = Number.MAX_VALUE;
88
this.maxY = -Number.MAX_VALUE;
9-
9+
1010
this.curvesCount = function() {
11-
return this._curvesData.length;
11+
return _curvesData.length;
12+
};
13+
14+
this.getCurve = function(index) {
15+
if (index < _curvesData.length) {
16+
return _curvesData[index];
17+
} else {
18+
throw new RangeError(`The imported curves index (${index}) exceeds the maximum allowed value (${_curvesData.length - 1})`);
19+
}
1220
};
1321

1422
this.importCurvesFromCSV = function(files) {
15-
let importsLeft = maxImportCount - this._curvesData.length;
23+
let importsLeft = MAX_IMPORT_COUNT - _curvesData.length;
1624

17-
for (const file of files) {
18-
if (importsLeft-- == 0) {
19-
break;
20-
}
21-
const reader = new FileReader();
22-
reader.onload = function (e) {
23-
try {
24-
const stringRows = e.target.result.split("\n");
25-
26-
const header = stringRows[0].split(",");
27-
if (header.length != 2 || header[0] != "x" || header[1] != "y") {
28-
throw new SyntaxError("Wrong curves CSV data format");
29-
}
30-
31-
stringRows.shift();
32-
//remove bad last row
33-
if (stringRows.at(-1) == "") {
34-
stringRows.pop();
35-
}
36-
37-
const curvesData = stringRows.map( function(row) {
38-
const data = row.split(","),
39-
x = parseFloat(data[0]),
40-
y = parseFloat(data[1]);
41-
_that.minX = Math.min(x, _that.minX);
42-
_that.maxX = Math.max(x, _that.maxX);
43-
_that.minY = Math.min(y, _that.minY);
44-
_that.maxY = Math.max(y, _that.maxY);
45-
return {
46-
x: x,
47-
y: y,
48-
};
49-
});
50-
51-
const curve = {
52-
name: file.name.split('.')[0],
53-
points: curvesData,
54-
};
55-
_that._curvesData.push(curve);
56-
curvesChanged();
57-
} catch (e) {
58-
alert('Curves data import error: ' + e.message);
59-
return;
25+
for (const file of files) {
26+
if (importsLeft-- == 0) {
27+
break;
28+
}
29+
const reader = new FileReader();
30+
reader.onload = function (e) {
31+
try {
32+
const stringRows = e.target.result.split("\n");
33+
34+
const header = stringRows[0].split(",");
35+
if (header.length !== 2 || header[0].trim() !== "x" || header[1].trim() !== "y") {
36+
throw new SyntaxError("Wrong curves CSV data format");
6037
}
61-
};
6238

63-
reader.readAsText(file);
64-
}
39+
stringRows.shift();
40+
//remove bad last row
41+
if (stringRows.at(-1) == "") {
42+
stringRows.pop();
43+
}
44+
45+
const curvesData = stringRows.map( function(row) {
46+
const data = row.split(","),
47+
x = parseFloat(data[0].trim()),
48+
y = parseFloat(data[1].trim());
49+
_that.minX = Math.min(x, _that.minX);
50+
_that.maxX = Math.max(x, _that.maxX);
51+
_that.minY = Math.min(y, _that.minY);
52+
_that.maxY = Math.max(y, _that.maxY);
53+
return {
54+
x: x,
55+
y: y,
56+
};
57+
});
58+
59+
const curve = {
60+
name: file.name.split('.')[0],
61+
points: curvesData,
62+
};
63+
_curvesData.push(curve);
64+
curvesChanged();
65+
} catch (e) {
66+
alert('Curves data import error: ' + e.message);
67+
return;
68+
}
69+
};
70+
71+
reader.readAsText(file);
72+
}
73+
};
74+
75+
const getCurveRange = function(points) {
76+
let minX = Number.MAX_VALUE,
77+
maxX = -Number.MAX_VALUE,
78+
minY = Number.MAX_VALUE,
79+
maxY = -Number.MAX_VALUE;
80+
for (const point of points) {
81+
minX = Math.min(point.x, minX);
82+
maxX = Math.max(point.x, maxX);
83+
minY = Math.min(point.y, minY);
84+
maxY = Math.max(point.y, maxY);
85+
}
86+
return {
87+
minX: minX,
88+
maxX: maxX,
89+
minY: minY,
90+
maxY: maxY,
6591
};
92+
};
6693

67-
this.removeCurves = function() {
68-
this._curvesData.length = 0;
69-
this.minX = Number.MAX_VALUE;
70-
this.maxX = -Number.MAX_VALUE;
71-
this.minY = Number.MAX_VALUE;
72-
this.maxY = -Number.MAX_VALUE;
94+
const computeGlobalCurvesRange = function () {
95+
_that.minX = Number.MAX_VALUE;
96+
_that.maxX = -Number.MAX_VALUE;
97+
_that.minY = Number.MAX_VALUE;
98+
_that.maxY = -Number.MAX_VALUE;
99+
for (const curve of _curvesData) {
100+
_that.minX = Math.min(curve.range.minX, _that.minX);
101+
_that.maxX = Math.max(curve.range.maxX, _that.maxX);
102+
_that.minY = Math.min(curve.range.minY, _that.minY);
103+
_that.maxY = Math.max(curve.range.maxY, _that.maxY);
104+
}
105+
};
106+
107+
this.addCurve = function(points, name) {
108+
if (this.curvesCount() < MAX_IMPORT_COUNT) {
109+
const range = getCurveRange(points);
110+
_curvesData.push({
111+
name: name,
112+
points: points,
113+
range: range,
114+
});
115+
116+
this.minX = Math.min(range.minX, this.minX);
117+
this.maxX = Math.max(range.maxX, this.maxX);
118+
this.minY = Math.min(range.minY, this.minY);
119+
this.maxY = Math.max(range.maxY, this.maxY);
120+
121+
curvesChanged();
122+
}
123+
};
124+
125+
this.isNewCurve = function(name) {
126+
for (const curve of _curvesData) {
127+
if (curve.name === name) {
128+
return false;
129+
}
130+
}
131+
return true;
132+
};
133+
134+
this.removeAllCurves = function() {
135+
_curvesData.length = 0;
136+
computeGlobalCurvesRange();
73137
curvesChanged();
74138
};
139+
140+
this.removeCurve = function(name) {
141+
for (let index = 0; index < _curvesData.length; index++) {
142+
if (_curvesData[index].name === name) {
143+
_curvesData.splice(index, 1);
144+
computeGlobalCurvesRange();
145+
curvesChanged();
146+
break;
147+
}
148+
}
149+
};
150+
151+
this.isFull = function() {
152+
return this.curvesCount() === MAX_IMPORT_COUNT;
153+
};
154+
155+
this.isEmpty = function() {
156+
return this.curvesCount() === 0;
157+
};
75158
}

src/graph_legend.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ export function GraphLegend(
101101
config.selectedGraphIndex = selectedGraphIndex;
102102
config.selectedFieldIndex = selectedFieldIndex;
103103
if (onNewSelectionChange) {
104-
onNewSelectionChange();
104+
onNewSelectionChange(false, e.ctrlKey);
105105
}
106106
} else {
107-
onNewSelectionChange(true);
107+
onNewSelectionChange(true, e.ctrlKey);
108108
}
109109
}
110110
e.preventDefault();

src/graph_spectrum.js

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
2121
let analyserZoomX = 1.0 /* 100% */,
2222
analyserZoomY = 1.0 /* 100% */,
2323
dataReload = false,
24-
fftData = null;
24+
fftData = null,
25+
addSpectrumForComparison = false;
2526

2627
try {
2728
let isFullscreen = false;
@@ -47,6 +48,12 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
4748
that.resize();
4849
};
4950

51+
this.prepareSpectrumForComparison = function () {
52+
if (userSettings.spectrumType === SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY) {
53+
addSpectrumForComparison = true;
54+
}
55+
};
56+
5057
this.setInTime = function (time) {
5158
dataReload = true;
5259
return GraphSpectrumCalc.setInTime(time);
@@ -156,17 +163,38 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
156163
}
157164
};
158165

166+
this.shouldAddCurrentSpectrumBeforeReload = function () {
167+
return addSpectrumForComparison && fftData !== null && !this.isMultiSpectrum() && !dataReload;
168+
};
169+
159170
/* This function is called from the canvas drawing routines within grapher.js
160171
It is only used to record the current curve positions, collect the data and draw the
161172
analyser on screen*/
162173
this.plotSpectrum = function (fieldIndex, curve, fieldName) {
163174
// Detect change of selected field.... reload and redraw required.
164-
if (fftData == null || fieldIndex != fftData.fieldIndex || dataReload) {
175+
const isMaxCountOfImportedPSD = GraphSpectrumPlot.isImportedCurvesMaxCount() && userSettings.spectrumType === SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY;
176+
let shouldReload = fftData == null ||
177+
fieldIndex != fftData.fieldIndex && !isMaxCountOfImportedPSD || // Lock spectrum data reload while PSD curves import is full
178+
dataReload;
179+
180+
if (addSpectrumForComparison && !GraphSpectrumPlot.isNewComparedCurve(fieldName)) {
181+
GraphSpectrumPlot.removeComparedCurve(fieldName);
182+
addSpectrumForComparison = false;
183+
shouldReload = false; // Do not load if spectrum was deleted
184+
}
185+
186+
if (shouldReload) {
187+
if (this.shouldAddCurrentSpectrumBeforeReload()) {
188+
GraphSpectrumPlot.addCurrentSpectrumIntoImport(); // The main curve is added into imported list when the second curve is selected for comparison
189+
}
165190
dataReload = false;
166191
dataLoad(fieldIndex, curve, fieldName);
167192
GraphSpectrumPlot.setData(fftData, userSettings.spectrumType);
168193
}
169-
194+
if (addSpectrumForComparison) {
195+
GraphSpectrumPlot.addCurrentSpectrumIntoImport();
196+
addSpectrumForComparison = false;
197+
}
170198
that.draw(); // draw the analyser on the canvas....
171199
};
172200

@@ -354,6 +382,9 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
354382

355383
const showSpectrumsComparisonPanel = optionSelected === SPECTRUM_TYPE.FREQUENCY || optionSelected === SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY;
356384
$("#spectrumComparison").css("visibility", (showSpectrumsComparisonPanel ? "visible" : "hidden"));
385+
386+
const showAddSpectrumButton = optionSelected === SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY;
387+
$("#btn-spectrum-add").toggle(showAddSpectrumButton);
357388
})
358389
.change();
359390

@@ -438,6 +469,10 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
438469
return fileName;
439470
};
440471

472+
this.isMultiSpectrum = function() {
473+
return GraphSpectrumPlot.isMultiSpectrum();
474+
};
475+
441476
} catch (e) {
442477
console.error(`Failed to create analyser... error: ${e}`);
443478
}

0 commit comments

Comments
 (0)