diff --git a/index.html b/index.html
index ab9494e3..2724ecc6 100644
--- a/index.html
+++ b/index.html
@@ -477,10 +477,10 @@
Workspace
-
-
+
+
-
+
diff --git a/src/graph_imported_curves.js b/src/graph_imported_curves.js
index df507285..3c27dd30 100644
--- a/src/graph_imported_curves.js
+++ b/src/graph_imported_curves.js
@@ -1,75 +1,158 @@
export function ImportedCurves(curvesChanged) {
- const maxImportCount = 5;
- this._curvesData = [];
+ const MAX_IMPORT_COUNT = 6; // This value is limited by legends size and curves colors visibility. May be increased if needed by users
+ const _curvesData = [];
const _that = this;
this.minX = Number.MAX_VALUE;
this.maxX = -Number.MAX_VALUE;
this.minY = Number.MAX_VALUE;
this.maxY = -Number.MAX_VALUE;
-
+
this.curvesCount = function() {
- return this._curvesData.length;
+ return _curvesData.length;
+ };
+
+ this.getCurve = function(index) {
+ if (index < _curvesData.length) {
+ return _curvesData[index];
+ } else {
+ throw new RangeError(`The imported curves index (${index}) exceeds the maximum allowed value (${_curvesData.length - 1})`);
+ }
};
this.importCurvesFromCSV = function(files) {
- let importsLeft = maxImportCount - this._curvesData.length;
+ let importsLeft = MAX_IMPORT_COUNT - _curvesData.length;
- for (const file of files) {
- if (importsLeft-- == 0) {
- break;
- }
- const reader = new FileReader();
- reader.onload = function (e) {
- try {
- const stringRows = e.target.result.split("\n");
-
- const header = stringRows[0].split(",");
- if (header.length != 2 || header[0] != "x" || header[1] != "y") {
- throw new SyntaxError("Wrong curves CSV data format");
- }
-
- stringRows.shift();
- //remove bad last row
- if (stringRows.at(-1) == "") {
- stringRows.pop();
- }
-
- const curvesData = stringRows.map( function(row) {
- const data = row.split(","),
- x = parseFloat(data[0]),
- y = parseFloat(data[1]);
- _that.minX = Math.min(x, _that.minX);
- _that.maxX = Math.max(x, _that.maxX);
- _that.minY = Math.min(y, _that.minY);
- _that.maxY = Math.max(y, _that.maxY);
- return {
- x: x,
- y: y,
- };
- });
-
- const curve = {
- name: file.name.split('.')[0],
- points: curvesData,
- };
- _that._curvesData.push(curve);
- curvesChanged();
- } catch (e) {
- alert('Curves data import error: ' + e.message);
- return;
+ for (const file of files) {
+ if (importsLeft-- == 0) {
+ break;
+ }
+ const reader = new FileReader();
+ reader.onload = function (e) {
+ try {
+ const stringRows = e.target.result.split("\n");
+
+ const header = stringRows[0].split(",");
+ if (header.length !== 2 || header[0].trim() !== "x" || header[1].trim() !== "y") {
+ throw new SyntaxError("Wrong curves CSV data format");
}
- };
- reader.readAsText(file);
- }
+ stringRows.shift();
+ //remove bad last row
+ if (stringRows.at(-1) == "") {
+ stringRows.pop();
+ }
+
+ const curvesData = stringRows.map( function(row) {
+ const data = row.split(","),
+ x = parseFloat(data[0].trim()),
+ y = parseFloat(data[1].trim());
+ _that.minX = Math.min(x, _that.minX);
+ _that.maxX = Math.max(x, _that.maxX);
+ _that.minY = Math.min(y, _that.minY);
+ _that.maxY = Math.max(y, _that.maxY);
+ return {
+ x: x,
+ y: y,
+ };
+ });
+
+ const curve = {
+ name: file.name.split('.')[0],
+ points: curvesData,
+ };
+ _curvesData.push(curve);
+ curvesChanged();
+ } catch (e) {
+ alert('Curves data import error: ' + e.message);
+ return;
+ }
+ };
+
+ reader.readAsText(file);
+ }
+ };
+
+ const getCurveRange = function(points) {
+ let minX = Number.MAX_VALUE,
+ maxX = -Number.MAX_VALUE,
+ minY = Number.MAX_VALUE,
+ maxY = -Number.MAX_VALUE;
+ for (const point of points) {
+ minX = Math.min(point.x, minX);
+ maxX = Math.max(point.x, maxX);
+ minY = Math.min(point.y, minY);
+ maxY = Math.max(point.y, maxY);
+ }
+ return {
+ minX: minX,
+ maxX: maxX,
+ minY: minY,
+ maxY: maxY,
};
+ };
- this.removeCurves = function() {
- this._curvesData.length = 0;
- this.minX = Number.MAX_VALUE;
- this.maxX = -Number.MAX_VALUE;
- this.minY = Number.MAX_VALUE;
- this.maxY = -Number.MAX_VALUE;
+ const computeGlobalCurvesRange = function () {
+ _that.minX = Number.MAX_VALUE;
+ _that.maxX = -Number.MAX_VALUE;
+ _that.minY = Number.MAX_VALUE;
+ _that.maxY = -Number.MAX_VALUE;
+ for (const curve of _curvesData) {
+ _that.minX = Math.min(curve.range.minX, _that.minX);
+ _that.maxX = Math.max(curve.range.maxX, _that.maxX);
+ _that.minY = Math.min(curve.range.minY, _that.minY);
+ _that.maxY = Math.max(curve.range.maxY, _that.maxY);
+ }
+ };
+
+ this.addCurve = function(points, name) {
+ if (this.curvesCount() < MAX_IMPORT_COUNT) {
+ const range = getCurveRange(points);
+ _curvesData.push({
+ name: name,
+ points: points,
+ range: range,
+ });
+
+ this.minX = Math.min(range.minX, this.minX);
+ this.maxX = Math.max(range.maxX, this.maxX);
+ this.minY = Math.min(range.minY, this.minY);
+ this.maxY = Math.max(range.maxY, this.maxY);
+
+ curvesChanged();
+ }
+ };
+
+ this.isNewCurve = function(name) {
+ for (const curve of _curvesData) {
+ if (curve.name === name) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ this.removeAllCurves = function() {
+ _curvesData.length = 0;
+ computeGlobalCurvesRange();
curvesChanged();
};
+
+ this.removeCurve = function(name) {
+ for (let index = 0; index < _curvesData.length; index++) {
+ if (_curvesData[index].name === name) {
+ _curvesData.splice(index, 1);
+ computeGlobalCurvesRange();
+ curvesChanged();
+ break;
+ }
+ }
+ };
+
+ this.isFull = function() {
+ return this.curvesCount() === MAX_IMPORT_COUNT;
+ };
+
+ this.isEmpty = function() {
+ return this.curvesCount() === 0;
+ };
}
diff --git a/src/graph_legend.js b/src/graph_legend.js
index b1f95aea..36af61f4 100644
--- a/src/graph_legend.js
+++ b/src/graph_legend.js
@@ -101,10 +101,10 @@ export function GraphLegend(
config.selectedGraphIndex = selectedGraphIndex;
config.selectedFieldIndex = selectedFieldIndex;
if (onNewSelectionChange) {
- onNewSelectionChange();
+ onNewSelectionChange(false, e.ctrlKey);
}
} else {
- onNewSelectionChange(true);
+ onNewSelectionChange(true, e.ctrlKey);
}
}
e.preventDefault();
diff --git a/src/graph_spectrum.js b/src/graph_spectrum.js
index 8b82f11a..99355af8 100644
--- a/src/graph_spectrum.js
+++ b/src/graph_spectrum.js
@@ -21,7 +21,8 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
let analyserZoomX = 1.0 /* 100% */,
analyserZoomY = 1.0 /* 100% */,
dataReload = false,
- fftData = null;
+ fftData = null,
+ addSpectrumForComparison = false;
try {
let isFullscreen = false;
@@ -47,6 +48,12 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
that.resize();
};
+ this.prepareSpectrumForComparison = function () {
+ if (userSettings.spectrumType === SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY) {
+ addSpectrumForComparison = true;
+ }
+ };
+
this.setInTime = function (time) {
dataReload = true;
return GraphSpectrumCalc.setInTime(time);
@@ -156,17 +163,38 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
}
};
+ this.shouldAddCurrentSpectrumBeforeReload = function () {
+ return addSpectrumForComparison && fftData !== null && !this.isMultiSpectrum() && !dataReload;
+ };
+
/* This function is called from the canvas drawing routines within grapher.js
It is only used to record the current curve positions, collect the data and draw the
analyser on screen*/
this.plotSpectrum = function (fieldIndex, curve, fieldName) {
// Detect change of selected field.... reload and redraw required.
- if (fftData == null || fieldIndex != fftData.fieldIndex || dataReload) {
+ const isMaxCountOfImportedPSD = GraphSpectrumPlot.isImportedCurvesMaxCount() && userSettings.spectrumType === SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY;
+ let shouldReload = fftData == null ||
+ fieldIndex != fftData.fieldIndex && !isMaxCountOfImportedPSD || // Lock spectrum data reload while PSD curves import is full
+ dataReload;
+
+ if (addSpectrumForComparison && !GraphSpectrumPlot.isNewComparedCurve(fieldName)) {
+ GraphSpectrumPlot.removeComparedCurve(fieldName);
+ addSpectrumForComparison = false;
+ shouldReload = false; // Do not load if spectrum was deleted
+ }
+
+ if (shouldReload) {
+ if (this.shouldAddCurrentSpectrumBeforeReload()) {
+ GraphSpectrumPlot.addCurrentSpectrumIntoImport(); // The main curve is added into imported list when the second curve is selected for comparison
+ }
dataReload = false;
dataLoad(fieldIndex, curve, fieldName);
GraphSpectrumPlot.setData(fftData, userSettings.spectrumType);
}
-
+ if (addSpectrumForComparison) {
+ GraphSpectrumPlot.addCurrentSpectrumIntoImport();
+ addSpectrumForComparison = false;
+ }
that.draw(); // draw the analyser on the canvas....
};
@@ -354,6 +382,9 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
const showSpectrumsComparisonPanel = optionSelected === SPECTRUM_TYPE.FREQUENCY || optionSelected === SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY;
$("#spectrumComparison").css("visibility", (showSpectrumsComparisonPanel ? "visible" : "hidden"));
+
+ const showAddSpectrumButton = optionSelected === SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY;
+ $("#btn-spectrum-add").toggle(showAddSpectrumButton);
})
.change();
@@ -438,6 +469,10 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
return fileName;
};
+ this.isMultiSpectrum = function() {
+ return GraphSpectrumPlot.isMultiSpectrum();
+ };
+
} catch (e) {
console.error(`Failed to create analyser... error: ${e}`);
}
diff --git a/src/graph_spectrum_plot.js b/src/graph_spectrum_plot.js
index c1402485..beeae463 100644
--- a/src/graph_spectrum_plot.js
+++ b/src/graph_spectrum_plot.js
@@ -60,6 +60,7 @@ export const GraphSpectrumPlot = window.GraphSpectrumPlot || {
_importedSpectrums: null,
_importedPSD: null,
curvesColors : [
+ "White", // The first imported curve duplicates existing main curve, therefore it must have same white color
"Blue",
"Purple",
"DeepPink",
@@ -217,6 +218,10 @@ GraphSpectrumPlot._drawGraph = function (canvasCtx) {
}
};
+GraphSpectrumPlot.getCurveColor = function (index) {
+ return this.curvesColors[index % this.curvesColors.length];
+};
+
GraphSpectrumPlot._drawFrequencyGraph = function (canvasCtx) {
const HEIGHT = canvasCtx.canvas.height - MARGIN;
const WIDTH = canvasCtx.canvas.width;
@@ -264,12 +269,12 @@ GraphSpectrumPlot._drawFrequencyGraph = function (canvasCtx) {
const scaleX = WIDTH / MAXIMAL_PLOTTED_FREQUENCY;
const spectrumCount = this._importedSpectrums.curvesCount();
for (let spectrumNum = 0; spectrumNum < spectrumCount; spectrumNum++) {
- const curvesPonts = this._importedSpectrums._curvesData[spectrumNum].points;
- const pointsCount = curvesPonts.length;
+ const curvesPoints = this._importedSpectrums.getCurve(spectrumNum).points;
+ const pointsCount = curvesPoints.length;
canvasCtx.beginPath();
canvasCtx.lineWidth = 1;
- canvasCtx.strokeStyle = this.curvesColors[spectrumNum];
+ canvasCtx.strokeStyle = this.getCurveColor(spectrumNum);
canvasCtx.moveTo(0, HEIGHT);
const filterPointsCount = 200;
for (let pointNum = 0; pointNum < pointsCount; pointNum++) {
@@ -288,18 +293,18 @@ GraphSpectrumPlot._drawFrequencyGraph = function (canvasCtx) {
}
let middleValue = 0;
for (let i = filterStartPoint; i < filterStopPoint; i++) {
- middleValue += curvesPonts[i].y;
+ middleValue += curvesPoints[i].y;
}
middleValue /= filterPointsCount;
- canvasCtx.lineTo(curvesPonts[pointNum].x * scaleX, HEIGHT - middleValue * fftScale);
+ canvasCtx.lineTo(curvesPoints[pointNum].x * scaleX, HEIGHT - middleValue * fftScale);
}
canvasCtx.stroke();
}
//Legend draw
if (this._isFullScreen && spectrumCount > 0) {
- this._drawLegend(canvasCtx, WIDTH, HEIGHT, this._importedSpectrums._curvesData);
+ this._drawLegend(canvasCtx, WIDTH, HEIGHT, this._importedSpectrums);
}
this._drawAxisLabel(
@@ -344,6 +349,7 @@ GraphSpectrumPlot._drawPowerSpectralDensityGraph = function (canvasCtx) {
max: maxY,
};
+ const mainCurveColor = this.getCurveColor(0); // The main curve must have color like the first imported curves - White.
const ticksCount = (maxY - minY) / dbStep;
const pointsCount = this._fftData.fftLength;
const scaleX = WIDTH / MAXIMAL_PLOTTED_FREQUENCY;
@@ -352,40 +358,52 @@ GraphSpectrumPlot._drawPowerSpectralDensityGraph = function (canvasCtx) {
canvasCtx.translate(LEFT, TOP);
this._drawGradientBackground(canvasCtx, WIDTH, HEIGHT);
- canvasCtx.beginPath();
- canvasCtx.lineWidth = 1;
- canvasCtx.strokeStyle = "white";
- canvasCtx.moveTo(0, 0);
- for (let pointNum = 0; pointNum < pointsCount; pointNum++) {
- const freq = this._fftData.blackBoxRate / 2 * pointNum / pointsCount;
- if(freq > MAXIMAL_PLOTTED_FREQUENCY) {
- break;
+ const comparedSpectrumCount = this._importedPSD.curvesCount();
+
+ if (comparedSpectrumCount === 0) { // Draw main spectrum curve when there are no spectrums comparison only
+ canvasCtx.beginPath();
+ canvasCtx.lineWidth = 1;
+ canvasCtx.strokeStyle = mainCurveColor;
+ for (let pointNum = 0; pointNum < pointsCount; pointNum++) {
+ const freq = this._fftData.blackBoxRate / 2 * pointNum / pointsCount;
+ if(freq > MAXIMAL_PLOTTED_FREQUENCY) {
+ break;
+ }
+ const y = HEIGHT - (this._fftData.fftOutput[pointNum] - minY) * scaleY;
+ if (pointNum === 0) {
+ canvasCtx.moveTo(freq * scaleX, y);
+ } else {
+ canvasCtx.lineTo(freq * scaleX, y);
+ }
}
- const y = HEIGHT - (this._fftData.fftOutput[pointNum] - minY) * scaleY;
- canvasCtx.lineTo(freq * scaleX, y);
+ canvasCtx.stroke();
}
- canvasCtx.stroke();
- const spectrumCount = this._importedPSD.curvesCount();
- for (let spectrumNum = 0; spectrumNum < spectrumCount; spectrumNum++) {
- const curvesPonts = this._importedPSD._curvesData[spectrumNum].points;
+
+ for (let spectrumNum = 0; spectrumNum < comparedSpectrumCount; spectrumNum++) {
+ const curvesPoints = this._importedPSD.getCurve(spectrumNum).points;
canvasCtx.beginPath();
canvasCtx.lineWidth = 1;
- canvasCtx.strokeStyle = this.curvesColors[spectrumNum];
- canvasCtx.moveTo(0, HEIGHT);
- for (const point of curvesPonts) {
- if(point.x > MAXIMAL_PLOTTED_FREQUENCY) {
+ canvasCtx.strokeStyle = this.getCurveColor(spectrumNum);
+ let isFirstPoint = true;
+ for (const point of curvesPoints) {
+ if (point.x > MAXIMAL_PLOTTED_FREQUENCY) {
break;
}
- canvasCtx.lineTo(point.x * scaleX, HEIGHT - (point.y - minY) * scaleY);
+ if (isFirstPoint) {
+ canvasCtx.moveTo(point.x * scaleX, HEIGHT - (point.y - minY) * scaleY);
+ isFirstPoint = false;
+ } else {
+ canvasCtx.lineTo(point.x * scaleX, HEIGHT - (point.y - minY) * scaleY);
+ }
}
canvasCtx.stroke();
}
//Legend draw
- if (this._isFullScreen && spectrumCount > 0) {
- this._drawLegend(canvasCtx, WIDTH, HEIGHT, this._importedPSD._curvesData);
+ if (this._isFullScreen && comparedSpectrumCount > 0) {
+ this._drawLegend(canvasCtx, WIDTH, HEIGHT, this._importedPSD);
}
this._drawAxisLabel(
@@ -431,16 +449,19 @@ GraphSpectrumPlot._drawPowerSpectralDensityGraph = function (canvasCtx) {
};
GraphSpectrumPlot._drawLegend = function (canvasCtx, WIDTH, HEIGHT, importedCurves) {
- if (!userSettings?.analyser_legend) {
+ const left = parseFloat(userSettings?.analyser_legend?.left);
+ const top = parseFloat(userSettings?.analyser_legend?.top);
+ const width = parseFloat(userSettings?.analyser_legend?.width);
+ if (!Number.isFinite(left) || !Number.isFinite(top) || !Number.isFinite(width)) {
return;
}
- const spectrumCount = importedCurves.length,
- legendPosX = parseInt(userSettings.analyser_legend.left) / 100 * WIDTH,
- legendPosY = parseInt(userSettings.analyser_legend.top) / 100 * HEIGHT,
+ const spectrumCount = importedCurves.curvesCount(),
+ legendPosX = left / 100 * WIDTH,
+ legendPosY = top / 100 * HEIGHT,
rowHeight = 16,
padding = 4,
- legendWidth = parseInt(userSettings.analyser_legend.width) / 100 * WIDTH,
- legendHeight = spectrumCount * rowHeight + 3 * padding,
+ legendWidth = width / 100 * WIDTH,
+ legendHeight = spectrumCount * rowHeight + padding,
legendArea = new Path2D();
canvasCtx.save();
@@ -450,10 +471,11 @@ GraphSpectrumPlot._drawLegend = function (canvasCtx, WIDTH, HEIGHT, importedCurv
canvasCtx.strokeRect(legendPosX, legendPosY, legendWidth, legendHeight);
canvasCtx.font = `${this._drawingParams.fontSizeFrameLabelFullscreen}pt ${DEFAULT_FONT_FACE}`;
canvasCtx.textAlign = "left";
+ canvasCtx.textBaseline = "middle"; // Ensure proper vertical centering
for (let row = 0; row < spectrumCount; row++) {
- const curvesName = importedCurves[row].name;
- const Y = legendPosY + padding + rowHeight * (row + 1);
- canvasCtx.strokeStyle = this.curvesColors[row];
+ const curvesName = importedCurves.getCurve(row).name;
+ const Y = legendPosY + padding + rowHeight * row + rowHeight / 2; // Center text vertically
+ canvasCtx.strokeStyle = this.getCurveColor(row);
canvasCtx.strokeText(curvesName, legendPosX + padding, Y);
}
canvasCtx.restore();
@@ -1781,6 +1803,9 @@ GraphSpectrumPlot.importCurvesFromCSV = function(files) {
this._importedSpectrums.importCurvesFromCSV(files);
break;
case SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY:
+ if (this._importedPSD.curvesCount() === 0) {
+ this.addCurrentSpectrumIntoImport(); // Add current main spectrum to import for the first imported file to have same behavior like first Ctrl+Mouse click selection.
+ }
this._importedPSD.importCurvesFromCSV(files);
break;
default:
@@ -1792,10 +1817,43 @@ GraphSpectrumPlot.importCurvesFromCSV = function(files) {
GraphSpectrumPlot.removeImportedCurves = function() {
switch (this._spectrumType) {
case SPECTRUM_TYPE.FREQUENCY:
- this._importedSpectrums.removeCurves();
+ this._importedSpectrums.removeAllCurves();
break;
case SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY:
- this._importedPSD.removeCurves();
+ this._importedPSD.removeAllCurves();
break;
}
};
+
+GraphSpectrumPlot.isNewComparedCurve = function(name) {
+ return this._importedPSD.isNewCurve(name);
+};
+
+GraphSpectrumPlot.addCurrentSpectrumIntoImport = function() {
+ if (this._spectrumType === SPECTRUM_TYPE.POWER_SPECTRAL_DENSITY &&
+ this.isNewComparedCurve(this._fftData.fieldName)) {
+ const fftLength = this._fftData.fftLength;
+ const frequencyStep = 0.5 * this._fftData.blackBoxRate / fftLength;
+ const points = [];
+ for (let index = 0; index < fftLength; index++) {
+ const frequency = frequencyStep * index;
+ points.push({
+ x: frequency,
+ y: this._fftData.fftOutput[index],
+ });
+ }
+ this._importedPSD.addCurve(points, this._fftData.fieldName);
+ }
+};
+
+GraphSpectrumPlot.removeComparedCurve = function(name) {
+ this._importedPSD.removeCurve(name);
+};
+
+GraphSpectrumPlot.isMultiSpectrum = function() {
+ return !this._importedPSD.isEmpty();
+};
+
+GraphSpectrumPlot.isImportedCurvesMaxCount = function() {
+ return this._importedPSD.isFull();
+};
diff --git a/src/grapher.js b/src/grapher.js
index ca177a0b..4207fc2c 100644
--- a/src/grapher.js
+++ b/src/grapher.js
@@ -1240,10 +1240,23 @@ export function FlightLogGrapher(
};
// Add option toggling
- this.setDrawAnalyser = function (state) {
+ this.setDrawAnalyser = function (state, ctrlKey = false) {
+ if (state) {
+ if (ctrlKey) {
+ analyser.prepareSpectrumForComparison();
+ } else if (this.hasMultiSpectrumAnalyser()) {
+ analyser.removeImportedSpectrums(); // Remove imported spectrums by simple mouse click at the any curves legend
+ }
+ }
+
options.drawAnalyser = state;
};
+ // Add option toggling
+ this.hasMultiSpectrumAnalyser = function () {
+ return analyser.isMultiSpectrum();
+ };
+
// Add analyser zoom toggling
this.setAnalyser = function (state) {
analyser.setFullscreen(state);
diff --git a/src/main.js b/src/main.js
index 95a15ec9..0ae00a79 100644
--- a/src/main.js
+++ b/src/main.js
@@ -961,9 +961,18 @@ function BlackboxLogViewer() {
updateCanvasSize();
}
- function onLegendSelectionChange(toggleAnalizer) {
- hasAnalyser = toggleAnalizer ? !hasAnalyser : true;
- graph.setDrawAnalyser(hasAnalyser);
+ function onLegendSelectionChange(toggleAnalizer, ctrlKey) {
+ const lockAnalyserHide = ctrlKey || graph.hasMultiSpectrumAnalyser();
+ if (toggleAnalizer) {
+ if (lockAnalyserHide) {
+ hasAnalyser = true; // Do not hide analyser when ctrlKey is pressed or it has many spectrums
+ } else {
+ hasAnalyser = !hasAnalyser; // Toggle the analyser state
+ }
+ } else {
+ hasAnalyser = true; // Default to true when toggleAnalizer is false
+ }
+ graph.setDrawAnalyser(hasAnalyser, ctrlKey);
html.toggleClass("has-analyser", hasAnalyser);
prefs.set("hasAnalyser", hasAnalyser);
invalidateGraph();
@@ -1771,10 +1780,10 @@ function BlackboxLogViewer() {
const exportDialog = new VideoExportDialog($("#dlgVideoExport"), function(newConfig) {
videoConfig = newConfig;
-
+
prefs.set('videoConfig', newConfig);
});
-
+
exportDialog.show(
flightLog,
{