Skip to content

Export of spectrum analyzer data to Csv file #779

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,9 @@ <h4>Workspace</h4>
<option value="5">Auto</option>
</select>
</div>

<div id="spectrumExport" data-toggle="tooltip" title="Export spectrum to CSV">
<button id="btn-spectrum-export" type="button">Export to Csv</button>
</div>
<div id="analyserResize" class="btn-nobg view-analyser-fullscreen" data-toggle="tooltip" title="Zoom Analyser Window">
<span class="glyphicon glyphicon-resize-full"></span>
<span class="glyphicon glyphicon-resize-small"></span>
Expand Down
102 changes: 51 additions & 51 deletions public/js/webworkers/csv-export-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,59 @@ importScripts("/js/lodash.min.js");

onmessage = function(event) {

/**
* Converts `null` and other empty non-numeric values to empty string.
*
* @param {object} value is not a number
* @returns {string}
*/
function normalizeEmpty(value) {
return !!value ? value : "";
}
/**
* Converts `null` and other empty non-numeric values to empty string.
*
* @param {object} value is not a number
* @returns {string}
*/
function normalizeEmpty(value) {
return !!value ? value : "";
}

/**
* @param {array} columns
* @returns {string}
*/
function joinColumns(columns) {
return _(columns)
.map(value =>
_.isNumber(value)
? value
: stringDelim + normalizeEmpty(value) + stringDelim)
.join(opts.columnDelimiter);
}
/**
* @param {array} columns
* @returns {string}
*/
function joinColumns(columns) {
return _(columns)
.map(value =>
_.isNumber(value)
? value
: stringDelim + normalizeEmpty(value) + stringDelim)
.join(opts.columnDelimiter);
}

/**
* Converts `null` entries in columns and other empty non-numeric values to NaN value string.
*
* @param {array} columns
* @returns {string}
*/
function joinColumnValues(columns) {
return _(columns)
.map(value =>
(_.isNumber(value) || _.value)
? value
: "NaN")
.join(opts.columnDelimiter);
}
/**
* Converts `null` entries in columns and other empty non-numeric values to NaN value string.
*
* @param {array} columns
* @returns {string}
*/
function joinColumnValues(columns) {
return _(columns)
.map(value =>
(_.isNumber(value) || _.value)
? value
: "NaN")
.join(opts.columnDelimiter);
}

let opts = event.data.opts,
stringDelim = opts.quoteStrings
? opts.stringDelimiter
: "",
mainFields = _([joinColumns(event.data.fieldNames)])
.concat(_(event.data.frames)
.flatten()
.map(row => joinColumnValues(row))
.value())
.join("\n"),
headers = _(event.data.sysConfig)
.map((value, key) => joinColumns([key, value]))
.join("\n"),
result = headers + "\n" + mainFields;
let opts = event.data.opts,
stringDelim = opts.quoteStrings
? opts.stringDelimiter
: "",
mainFields = _([joinColumns(event.data.fieldNames)])
.concat(_(event.data.frames)
.flatten()
.map(row => joinColumnValues(row))
.value())
.join("\n"),
headers = _(event.data.sysConfig)
.map((value, key) => joinColumns([key, value]))
.join("\n"),
result = headers + "\n" + mainFields;

postMessage(result);

postMessage(result);

};
14 changes: 14 additions & 0 deletions public/js/webworkers/spectrum-export-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
onmessage = function(event) {
const columnDelimiter = event.data.opts.columnDelimiter;
const fftOutput = event.data.fftOutput;
const spectrumDataLength = fftOutput.length / 2;
const frequencyStep = 0.5 * event.data.blackBoxRate / spectrumDataLength;

let outText = "freq" + columnDelimiter + "value" + "\n";
for (let index = 0; index < spectrumDataLength; index += 10) {
const frequency = frequencyStep * index;
outText += frequency.toString() + columnDelimiter + fftOutput[index].toString() + "\n";
}

postMessage(outText);
};
26 changes: 22 additions & 4 deletions src/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -629,10 +629,28 @@ html.has-analyser-fullscreen.has-analyser
color: black;
}

.analyser #analyserResize:hover {
color: white;
cursor: pointer;
animation: ease-in 500ms;
.analyser:hover .non-shift #spectrumExport {
opacity: 1;
height: auto;
transition: opacity 500ms ease-in;
}

.analyser #spectrumExport {
height: 0;
width: 200px;
overflow: hidden;
opacity: 0;
left: 270px;
float: left;
z-index: 9;
position: absolute;
font-size: 9px;
}

.analyser #spectrumExport select {
border-radius: 3px;
padding: 0px 5px;
color: black;
}

.analyser input#analyserZoomX {
Expand Down
11 changes: 9 additions & 2 deletions src/graph_spectrum.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
SPECTRUM_OVERDRAW_TYPE,
} from "./graph_spectrum_plot";
import { PrefStorage } from "./pref_storage";
import { SpectrumExporter } from "./spectrum-exporter";

export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
const ANALYSER_LARGE_LEFT_MARGIN = 10,
Expand Down Expand Up @@ -95,7 +96,7 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
left: `${newSize.width - 20}px`,
});
$("#analyserResize", parentElem).css({
left: `${newSize.width - 28}px`,
left: `${newSize.width - 20}px`,
});
};

Expand Down Expand Up @@ -201,7 +202,7 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {

spectrumTypeElem
.change(function () {
let optionSelected = parseInt(spectrumTypeElem.val(), 10);
const optionSelected = parseInt(spectrumTypeElem.val(), 10);

if (optionSelected != userSettings.spectrumType) {
userSettings.spectrumType = optionSelected;
Expand All @@ -224,6 +225,8 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
"onlyFullScreenException",
pidErrorVsSetpointSelected
);

$("#btn-spectrum-export").attr("disabled", optionSelected != 0);
})
.change();

Expand Down Expand Up @@ -282,6 +285,10 @@ export function FlightLogAnalyser(flightLog, canvas, analyserCanvas) {
prefs.set("userSettings", data);
});
}

this.exportSpectrumToCSV = function(onSuccess, options) {
SpectrumExporter(fftData, options).dump(onSuccess);
};
} catch (e) {
console.log(`Failed to create analyser... error:${e}`);
}
Expand Down
22 changes: 19 additions & 3 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { throttle } from "throttle-debounce";
import { MapGrapher } from "./graph_map.js";
import { FlightLogGrapher } from "./grapher.js";
import { FlightLogVideoRenderer } from "./flightlog_video_renderer.js";
import { VideoExportDialog } from "./video_export_dialog.js";
import { UserSettingsDialog } from "./user_settings_dialog.js";
import { GraphConfigurationDialog } from "./graph_config_dialog.js";
import { HeaderDialog } from "./header_dialog.js";
Expand Down Expand Up @@ -1143,17 +1142,27 @@ function BlackboxLogViewer() {
"csv",
"text/csv",
file,
performance.now()
performance.now(),
);
CsvExporter(flightLog, options).dump(onSuccess);
}

function exportSpectrumToCsv(file, options = {}) {
const onSuccess = createExportCallback(
"csv",
"text/csv",
file,
performance.now(),
);
graph.getAnalyser().exportSpectrumToCSV(onSuccess, options);
}

function exportGpx(file) {
const onSuccess = createExportCallback(
"gpx",
"GPX File",
file,
performance.now()
performance.now(),
);
GpxExporter(flightLog).dump(onSuccess);
}
Expand Down Expand Up @@ -1719,6 +1728,13 @@ function BlackboxLogViewer() {
exportCsv();
e.preventDefault();
});

$("#btn-spectrum-export").click(function (e) {
setGraphState(GRAPH_STATE_PAUSED);
exportSpectrumToCsv("bf_spectrum");
e.preventDefault();
});

$(".btn-gpx-export").click(function (e) {
setGraphState(GRAPH_STATE_PAUSED);
exportGpx();
Expand Down
42 changes: 42 additions & 0 deletions src/spectrum-exporter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @typedef {object} ExportOptions
* @property {string} columnDelimiter
* @property {string} stringDelimiter
* @property {boolean} quoteStrings
*/

/**
* @constructor
* @param {object} fftOutput
* @param {ExportOptions} [opts={}]
*/
export function SpectrumExporter(fftData, opts = {}) {
opts = _.merge(
{
columnDelimiter: ",",
quoteStrings: true,
},
opts,
);

/**
* @param {function} success is a callback triggered when export is done
*/
function dump(success) {
const worker = new Worker("/js/webworkers/spectrum-export-worker.js");

worker.onmessage = (event) => {
success(event.data);
worker.terminate();
};

worker.postMessage({fftOutput: fftData.fftOutput,
blackBoxRate: fftData.blackBoxRate,
opts: opts});
}

// exposed functions
return {
dump: dump,
};
}