Skip to content
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

Data export #111

Merged
merged 12 commits into from
Dec 16, 2024
3 changes: 3 additions & 0 deletions lumberjack.pro
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ INCLUDEPATH += src \
plugins/cobsr

SOURCES += \
src/data_source_manager.cpp \
src/fft_sampler.cpp \
src/fft_widget.cpp \
src/helpers.cpp \
Expand All @@ -44,6 +45,7 @@ SOURCES += \
src/plot_widget.cpp \
src/main.cpp \
src/mainwindow.cpp \
src/plugins/plugin_exporter.cpp \
src/plugins/plugin_importer.cpp \
src/plugins/plugin_registry.cpp \
src/widgets/about_dialog.cpp \
Expand All @@ -59,6 +61,7 @@ SOURCES += \
src/widgets/timeline_widget.cpp

HEADERS += \
src/data_source_manager.hpp \
src/mainwindow.h \
src/fft_sampler.hpp \
src/fft_widget.hpp \
Expand Down
9 changes: 6 additions & 3 deletions lumberjack_resource.rc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <windows.h>

IDI_ICON1 ICON DISCARDABLE "C:\\lumberjack\\logo\\lumberjack.ico"
IDI_ICON1 ICON ".\\logo\\lumberjack.ico"

VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,0,0,0
Expand All @@ -11,9 +11,9 @@ VS_VERSION_INFO VERSIONINFO
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS__WINDOWS32
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0x0L
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
Expand All @@ -26,6 +26,9 @@ VS_VERSION_INFO VERSIONINFO
VALUE "OriginalFilename", "lumberjack.exe\0"
VALUE "ProductName", "lumberjack\0"
VALUE "ProductVersion", "0.0.0.0\0"
VALUE "InternalName", "\0"
VALUE "Comments", "\0"
VALUE "LegalTrademarks", "\0"
END
END
BLOCK "VarFileInfo"
Expand Down
7 changes: 5 additions & 2 deletions plugins/csv_exporter/csv_exporter.pro
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
QT += gui
QT += gui widgets

TEMPLATE = lib
DEFINES += CSV_EXPORTER_LIBRARY
Expand All @@ -15,11 +15,14 @@ INCLUDEPATH += \
HEADERS += \
csv_exporter_global.h \
lumberjack_csv_exporter.hpp \
../../src/data_series.hpp \
../../src/plugins/plugin_base.hpp \
../../src/plugins/plugin_exporter.hpp \

SOURCES += \
lumberjack_csv_exporter.cpp
lumberjack_csv_exporter.cpp \
../../src/data_series.cpp \
../../src/plugins/plugin_exporter.cpp

# Default rules for deployment.
unix {
Expand Down
197 changes: 196 additions & 1 deletion plugins/csv_exporter/lumberjack_csv_exporter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "lumberjack_csv_exporter.hpp"
#include <QFile>

#include "lumberjack_csv_exporter.hpp"


LumberjackCSVExporter::LumberjackCSVExporter()
Expand All @@ -18,3 +19,197 @@ QStringList LumberjackCSVExporter::supportedFileTypes() const
return fileTypes;
}


bool LumberjackCSVExporter::beforeExport(void)
{
// TODO: Set export options
return true;
}


/*
* Export the provided series to a CSV file
*/
bool LumberjackCSVExporter::exportData(QList<DataSeriesPointer> &series, QStringList &errors)
{
if (m_filename.isEmpty())
{
errors.append(tr("Filename is empty"));
return false;
}

QFile outputFile(m_filename);

if (!outputFile.open(QIODevice::WriteOnly) || !outputFile.isOpen() || !outputFile.isWritable())
{
errors.append(tr("Could not open file for writing"));
return false;
}

// Copy across data series
m_data.clear();
m_indices.clear();

for (auto s : series)
{
if (!s.isNull())
{
m_data.append(s);
m_indices.append(0);
}
}

QStringList row;

// Write header row
row = headerRow();
outputFile.write(rowToString(row));

if (m_unitsRow)
{
row = unitsRow();
outputFile.write(rowToString(row));
}

bool valid = true;

while (valid)
{
row = nextDataRow(valid);

if (valid)
{
outputFile.write(rowToString(row));
}
}

outputFile.close();

return true;
}


QByteArray LumberjackCSVExporter::rowToString(QStringList &row) const
{
QString data = row.join(m_delimiter).trimmed() + "\n";

return data.toLatin1();
}


/**
* @brief LumberjackCSVExporter::headerRow - Generate a header row for the exported dataset
* @return
*/
QStringList LumberjackCSVExporter::headerRow(void) const
{
QStringList header;

header << tr("Timestamp");

for (auto series : m_data)
{
if (series.isNull()) continue;

header.append(series->getLabel());
}

return header;
}


/**
* @brief LumberjackCSVExporter::unitsRow - Generate a units row for the exported dataset
* @return
*/
QStringList LumberjackCSVExporter::unitsRow(void) const
{
QStringList units;

units << QString("");

for (auto series : m_data)
{
if (series.isNull()) continue;

units.append(series->getUnits());
}

return units;
}


/**
* @brief LumberjackCSVExporter::nextDataRow - Generate the next row of data
* @param valid
* @return
*/
QStringList LumberjackCSVExporter::nextDataRow(bool &valid)
{
// TODO: Better configuration of timestamp resolution...
const double DT = 1e-6;

QStringList values;

double nextTimestamp = LONG_MAX;

int N = qMin(m_data.count(), m_indices.count());

bool dataAvailable = false;

// What is the *smallest* timestamp?
for (int ii = 0; ii < N; ii++)
{
auto series = m_data.at(ii);
uint64_t idx = m_indices.at(ii);

if (idx < series->size())
{
dataAvailable = true;

auto point = series->getDataPoint(idx);

if (point.timestamp < nextTimestamp)
{
nextTimestamp = point.timestamp;
}
}
}

// No more data available
if (!dataAvailable)
{
valid = false;
return values;
}

// Timestamp
values.append(QString::number(nextTimestamp));

// Now, iterate through each series, and see if it has a corresponding value at this timestamp
for (int ii = 0; ii < N; ii++)
{
auto series = m_data.at(ii);
uint64_t idx = m_indices.at(ii);

QString value;

if (idx < series->size())
{
auto point = series->getDataPoint(idx);

// Timestamp is within allowable range
if (point.timestamp <= (nextTimestamp + DT))
{
value = QString::number(point.value);
m_indices[ii]++;
}
}

// TODO: "Empty" value compensation?
values.append(value);
}

valid = true;
return values;
}
21 changes: 20 additions & 1 deletion plugins/csv_exporter/lumberjack_csv_exporter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,33 @@ class CSV_EXPORTER_EXPORT LumberjackCSVExporter : public ExportPlugin
virtual QString pluginDescription(void) const override { return m_description; }
virtual QString pluginVersion(void) const override { return m_version; }

// Importer plugin functionality
// Exporter plugin functionality
virtual QStringList supportedFileTypes(void) const override;

virtual bool beforeExport(void) override;
virtual bool exportData(QList<DataSeriesPointer> &series, QStringList &errors) override;

protected:
const QString m_name = "CSV Exporter";
const QString m_description = "Export data to CSV file";
const QString m_version = "0.1.0";

QList<DataSeriesPointer> m_data;
QList<uint64_t> m_indices;

// Data export options
QString m_delimiter = ",";

bool m_zeroTimestamp = false;
bool m_unitsRow = false;

// Internal helper functions
QByteArray rowToString(QStringList &row) const;
QStringList headerRow(void) const;
QStringList unitsRow(void) const;

QStringList nextDataRow(bool &valid);

};

#endif // LUMBERJACK_CSV_IMPORTER_HPP
6 changes: 3 additions & 3 deletions plugins/csv_importer/csv_importer.pro
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ INCLUDEPATH += \
../../src/plugins

HEADERS += \
../../src/data_series.hpp \
csv_import_options.hpp \
csv_importer_global.h \
import_options_dialog.hpp \
lumberjack_csv_importer.hpp \
import_options_dialog.hpp \
csv_import_options.hpp \
../../src/data_series.hpp \
../../src/plugins/plugin_base.hpp \
../../src/plugins/plugin_importer.hpp \

Expand Down
4 changes: 2 additions & 2 deletions plugins/csv_importer/lumberjack_csv_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ QStringList LumberjackCSVImporter::supportedFileTypes() const
* @brief LumberjackCSVImporter::beforeLoadData - Open configuration dialog
* @return
*/
bool LumberjackCSVImporter::beforeLoadData(void)
bool LumberjackCSVImporter::beforeImport(void)
{
CSVImportOptionsDialog dlg(m_filename);

Expand All @@ -53,7 +53,7 @@ bool LumberjackCSVImporter::beforeLoadData(void)
* @param errors -
* @return
*/
bool LumberjackCSVImporter::loadDataFile(QStringList &errors)
bool LumberjackCSVImporter::importData(QStringList &errors)
{
// Reset importer to initial conditions
m_headers.clear();
Expand Down
4 changes: 2 additions & 2 deletions plugins/csv_importer/lumberjack_csv_importer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ class CSV_IMPORTER_EXPORT LumberjackCSVImporter : public ImportPlugin
// Importer plugin functionality
virtual QStringList supportedFileTypes(void) const override;

virtual bool beforeLoadData(void) override;
virtual bool loadDataFile(QStringList &errors) override;
virtual bool beforeImport(void) override;
virtual bool importData(QStringList &errors) override;

virtual QList<QSharedPointer<DataSeries>> getDataSeries(void) const override;

Expand Down
2 changes: 2 additions & 0 deletions src/data_series.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,5 +230,7 @@ public slots:

};

typedef QSharedPointer<DataSeries> DataSeriesPointer;


#endif // DATA_SERIES_H
Loading
Loading