Skip to content

Commit

Permalink
Merge pull request #128 from doluk/us_plot_csv
Browse files Browse the repository at this point in the history
CSV export for plots
  • Loading branch information
demeler authored Sep 2, 2024
2 parents eb02443 + 8ed6165 commit 6f21039
Show file tree
Hide file tree
Showing 11 changed files with 331 additions and 55 deletions.
19 changes: 10 additions & 9 deletions gui/images.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@
<file>images/us3-icon-48x48.png</file>
<file>images/arrow_left.png</file>
<file>images/arrow_right.png</file>
<file>images/analysis.png</file>
<file>images/editing.png</file>
<file>images/import_1.png</file>
<file>images/import_2.png</file>
<file>images/analysis_2.png</file>
<file>images/report.png</file>
<file>images/live_update.png</file>
<file>images/setup.png</file>
<file>images/new_item2.png</file>
<file>images/analysis.png</file>
<file>images/editing.png</file>
<file>images/import_1.png</file>
<file>images/import_2.png</file>
<file>images/analysis_2.png</file>
<file>images/report.png</file>
<file>images/live_update.png</file>
<file>images/setup.png</file>
<file>images/new_item2.png</file>
<file>images/table.png</file>
</qresource>
</RCC>
Binary file added gui/images/table.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
173 changes: 173 additions & 0 deletions gui/us_gui_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "us_settings.h"
#if QT_VERSION > 0x050000
#include "qwt_plot_renderer.h"
#include "us_spectrodata.h"

#endif

// Save SVG+PNG or PNG file
Expand Down Expand Up @@ -105,3 +107,174 @@ int US_GuiUtil::save_png( const QString& filename, const QwtPlot* plot )
return status;
}

int US_GuiUtil::save_csv( const QString& filename, const QwtPlot* plot )
{
int status = 0;


if ( filename.endsWith( ".csv" ) )
{ // Save the file as a CSV
// iterate over all plot items and construct the output data
QVector<QVector<QString>> export_data;
export_data.clear();
// determine axis title
QString x_axis_title = plot->axisTitle( QwtPlot::xBottom ).text();
if ( x_axis_title.isEmpty() )
{
x_axis_title = plot->axisTitle( QwtPlot::xTop ).text();
}
if ( x_axis_title.isEmpty() )
{
x_axis_title = QString("x");
}
QString y_axis_title = plot->axisTitle( QwtPlot::yLeft ).text();
if ( y_axis_title.isEmpty() )
{
y_axis_title = plot->axisTitle( QwtPlot::yRight ).text();
}
if ( y_axis_title.isEmpty() )
{
y_axis_title = QString("y");
}
int max_length = 0;
for ( QwtPlotItem* it: plot->itemList( QwtPlotItem::Rtti_PlotCurve ) )
{
if ( it->rtti() != QwtPlotItem::Rtti_PlotCurve )
{
continue;
}
QwtPlotCurve* item = static_cast<QwtPlotCurve*>(it);
// create two Vectors for x and y respective
QVector<QString> x_data;
x_data.clear();
QVector<QString> y_data;
y_data.clear();
x_data << QString("\"") + item->title().text() + " " + x_axis_title + QString("\"");
y_data << QString("\"") + item->title().text() + " " + y_axis_title + QString("\"");
const QwtSeriesData<QPointF>* data = item->data();
for (size_t i = 0; i < data->size(); i++)
{
QPointF point = data->sample(i);
x_data << QString::number(point.x());
y_data << QString::number(point.y());
}
if ( max_length < x_data.size() )
{
max_length = x_data.size();
}
if ( max_length < y_data.size() )
{
max_length = y_data.size();
}
if ( data->size() > 0 || (x_data.size() > 1 && y_data.size() > 1) )
{ // Only add data if there is data to add
export_data << x_data << y_data;
}
}
QString z_axis_title;
if ( !plot->itemList( QwtPlotItem::Rtti_PlotSpectrogram ).isEmpty() )
{
z_axis_title = plot->axisTitle( QwtPlot::yRight ).text();
if ( !(!z_axis_title.isEmpty() && z_axis_title != y_axis_title) )
{
z_axis_title = z_axis_title + " z";
}
}
for ( QwtPlotItem* it: plot->itemList( QwtPlotItem::Rtti_PlotSpectrogram ) )
{
if ( it->rtti() != QwtPlotItem::Rtti_PlotSpectrogram )
{
continue;
}
QwtPlotSpectrogram* item = static_cast<QwtPlotSpectrogram*>(it);
qDebug() << item->interval( Qt::XAxis ).minValue() << item->interval( Qt::XAxis ).maxValue();
qDebug() << item->interval( Qt::YAxis ).minValue() << item->interval( Qt::YAxis ).maxValue();
qDebug() << item->boundingRect().bottomLeft() << item->boundingRect().topRight();
US_SpectrogramData* data = dynamic_cast<US_SpectrogramData*>(item->data());
// create two Vectors for x and y respective
QSize raster_size;
QRectF rect;
// Get the raster data from US_SpectrogramData
data->initRaster( rect, raster_size );
QVector<QString> x_data;
x_data.clear();
QVector<QString> y_data;
y_data.clear();
QVector<QString> z_data;
x_data << QString("\"") + item->title().text() + " " + x_axis_title + QString("\"");
y_data << QString("\"") + item->title().text() + " " + y_axis_title + QString("\"");
z_data << QString("\"") + item->title().text() + " " + z_axis_title + QString("\"");
// Get the matrix data
int rows = raster_size.width();
int cols = raster_size.height();

for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols; ++col) {
double x, y, z;
data->value( row, col, x, y, z );
x_data << QString::number(x);
y_data << QString::number(y);
z_data << QString::number(z);
}
}

if ( max_length < x_data.size() )
{
max_length = x_data.size();
}
if ( max_length < y_data.size() )
{
max_length = y_data.size();
}
if ( max_length < z_data.size() )
{
max_length = z_data.size();
}
if ( x_data.size() > 1 && y_data.size() > 1 && z_data.size() > 1 )
{ // Only add data if there is data to add
export_data << x_data << y_data << z_data;
}
}
// iterate over all entries to ensure a proper csv format
for (auto & i : export_data)
{
if ( i.size() < max_length )
{
QVector<QString> vec = i;
for ( int jj = vec.size(); jj < max_length; jj++ )
{
vec << QString("");
}
i = vec;
}
}
// dump everything into a file
QFile myFile( filename );
if ( !myFile.open( QIODevice::WriteOnly ) )
{
qDebug() << "Could not write to file:" << filename << "Error string:" << myFile.errorString();
}
else
{
QTextStream out(&myFile);
for ( int ii = 0; ii < max_length; ii++ )
{
for ( int jj = 0; jj < export_data.size() - 1; jj++ )
{
out << export_data[ jj ][ ii ] << ", ";
}
out << export_data.last()[ ii ] << Qt::endl;
}
myFile.flush();
}

myFile.close();
}

else
{ // Mark error: filename does not end with ".csv"
status = 1;
}

return status;
}
12 changes: 12 additions & 0 deletions gui/us_gui_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
#define dataPlotClear(a) a->clear()
#endif
#include "qwt_plot.h"
#include "qwt_plot_curve.h"
#include "qwt_series_data.h"
#include <qwt_plot_spectrogram.h>
#include <qwt_raster_data.h>
#include <qwt_matrix_raster_data.h>
#include "us_extern.h"

//! \brief General GUI utilities for UltraScan
Expand Down Expand Up @@ -44,5 +49,12 @@ class US_GUI_EXTERN US_GuiUtil
//! \returns A status flag: 0 if all-ok
static int save_png( const QString&, const QwtPlot* );

//! \brief Save a plot to a CSV file
//!
//! \param filename Full path name of the file to produce
//! \param plot A pointer to the plot to save
//! \returns A status flag: 0 if all-ok
static int save_csv( const QString&, const QwtPlot* );

};
#endif
89 changes: 45 additions & 44 deletions gui/us_images.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,50 +37,51 @@ const QString US_Images::image_name( int itype )

static const struct nameMap nameMaps[] =
{
{ US3_SPLASH, "us3-splash" },
{ CHECK, "check" },
{ ARROW_BLUE, "bluearrow" },
{ ARROW_GREEN, "greenarrow" },
{ ARROW_RED, "redarrow" },
{ AXES_BOX, "box" },
{ AXES_FRAME, "frame" },
{ AXES_NONE, "none" },
{ FILE_CELL, "filecell" },
{ FILE_OPEN, "fileopen" },
{ FLOOR_DATA, "floordata" },
{ FLOOR_EMPTY, "floorempty" },
{ FLOOR_ISO, "flooriso" },
{ FLOOR_MESH, "floormesh" },
{ GRID_NONE, "grid" },
{ GRID_BACK, "gridb" },
{ GRID_CEILING, "gridc" },
{ GRID_FLOOR, "gridf" },
{ GRID_FRONT, "gridfr" },
{ GRID_LEFT, "gridl" },
{ GRID_RIGHT, "gridr" },
{ MESH_FILLED, "filledmesh" },
{ MESH_HIDDEN, "hiddenline" },
{ MESH_NODATA, "nodata" },
{ MESH_NORMALS, "normals" },
{ MESH_POLYGON, "polygon" },
{ MESH_SCATTERED, "scattered" },
{ MESH_WIRE, "wireframe" },
{ MOVIE, "movie" },
{ SAVE_CONTENT, "savecontent" },
{ ICON_PROP, "icon" },
{ QWTPLOT, "qwtplot" },
{ US3_ICON, "us3-icon-48x48" },
{ ARROW_LEFT, "arrow_left" },
{ ARROW_RIGHT, "arrow_right" },
{ SETUP_COM, "setup" },
{ ANALYSIS_COM, "analysis" },
{ EDITING_COM, "editing" },
{ ANALYSIS_COM_2, "analysis_2" },
{ LIVE_UPDATE_COM, "live_update" },
{ IMPORT_COM_1, "import_1" },
{ IMPORT_COM_2, "import_2" },
{ REPORT_COM, "report" },
{ NEW_ITEM_COM, "new_item2" }
{ US3_SPLASH, "us3-splash" },
{ CHECK, "check" },
{ ARROW_BLUE, "bluearrow" },
{ ARROW_GREEN, "greenarrow" },
{ ARROW_RED, "redarrow" },
{ AXES_BOX, "box" },
{ AXES_FRAME, "frame" },
{ AXES_NONE, "none" },
{ FILE_CELL, "filecell" },
{ FILE_OPEN, "fileopen" },
{ FLOOR_DATA, "floordata" },
{ FLOOR_EMPTY, "floorempty" },
{ FLOOR_ISO, "flooriso" },
{ FLOOR_MESH, "floormesh" },
{ GRID_NONE, "grid" },
{ GRID_BACK, "gridb" },
{ GRID_CEILING, "gridc" },
{ GRID_FLOOR, "gridf" },
{ GRID_FRONT, "gridfr" },
{ GRID_LEFT, "gridl" },
{ GRID_RIGHT, "gridr" },
{ MESH_FILLED, "filledmesh" },
{ MESH_HIDDEN, "hiddenline" },
{ MESH_NODATA, "nodata" },
{ MESH_NORMALS, "normals" },
{ MESH_POLYGON, "polygon" },
{ MESH_SCATTERED, "scattered" },
{ MESH_WIRE, "wireframe" },
{ MOVIE, "movie" },
{ SAVE_CONTENT, "savecontent" },
{ ICON_PROP, "icon" },
{ QWTPLOT, "qwtplot" },
{ US3_ICON, "us3-icon-48x48" },
{ ARROW_LEFT, "arrow_left" },
{ ARROW_RIGHT, "arrow_right" },
{ SETUP_COM, "setup" },
{ ANALYSIS_COM, "analysis" },
{ EDITING_COM, "editing" },
{ ANALYSIS_COM_2, "analysis_2" },
{ LIVE_UPDATE_COM, "live_update" },
{ IMPORT_COM_1, "import_1" },
{ IMPORT_COM_2, "import_2" },
{ REPORT_COM, "report" },
{ NEW_ITEM_COM, "new_item2" },
{ TABLE, "table" }
};

static const int nimages = sizeof( nameMaps ) / sizeof( nameMaps[ 0 ] );
Expand Down
2 changes: 1 addition & 1 deletion gui/us_images.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class US_GUI_EXTERN US_Images
MOVIE, SAVE_CONTENT, ICON_PROP,
QWTPLOT, US3_ICON, ARROW_LEFT, ARROW_RIGHT,
SETUP_COM, ANALYSIS_COM, EDITING_COM, ANALYSIS_COM_2,
IMPORT_COM_1, IMPORT_COM_2, LIVE_UPDATE_COM, NEW_ITEM_COM, REPORT_COM
IMPORT_COM_1, IMPORT_COM_2, LIVE_UPDATE_COM, NEW_ITEM_COM, REPORT_COM, TABLE
};

//! \brief Get image (embedded or from file) as a pixmap
Expand Down
Loading

0 comments on commit 6f21039

Please sign in to comment.