Skip to content

Commit

Permalink
Added plots export.
Browse files Browse the repository at this point in the history
  • Loading branch information
Amine Mzoughi committed Jan 24, 2020
1 parent 1529e6a commit e7e43a5
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 79 deletions.
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ find_package(Qt5Core REQUIRED)
find_package(Qt5SerialPort REQUIRED)
find_package(Qt5PrintSupport REQUIRED)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -std=gnu++0x")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -Wpedantic -g -O0 -std=gnu++0x")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -Wall -Wextra -Wpedantic -std=gnu++0x")

# QWT
INCLUDE(FindQwt.cmake)
find_library(Qwt REQUIRED)
Expand All @@ -20,7 +24,8 @@ include_directories(.)
# ==============================================================================
# Source
# ==============================================================================
set(APP_SOURCE main.cpp Waterfallplot.cpp)
set(APP_SOURCE main.cpp Waterfallplot.cpp ExportDialog.cpp)
set(UISrcs ExportDialog.ui)

# ==============================================================================
# Target
Expand Down
61 changes: 61 additions & 0 deletions ExportDialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "ExportDialog.h"

#include "ui_ExportDialog.h"

struct ExportDialog::Internals
{
Ui::ExportDialog Ui;
};

ExportDialog::ExportDialog(QWidget* const parent) :
QDialog(parent),
m_Internals(new ExportDialog::Internals)
{
m_Internals->Ui.setupUi(this);

connect(m_Internals->Ui.ButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(m_Internals->Ui.ButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(m_Internals->Ui.PlotsList, &QListWidget::itemChanged,
this, [this](QListWidgetItem* item)
{
if (item->checkState() == Qt::Checked)
{
item->setBackgroundColor(QColor("#ffffb2"));
}
else
{
item->setBackgroundColor(QColor("#ffffff"));
}
});

QStringList plotsList;
plotsList << "Horizontal Plot" << "Vertical Plot" << "Waterfall Plot";
m_Internals->Ui.PlotsList->addItems(plotsList);

for (int i = 0; i < m_Internals->Ui.PlotsList->count(); ++i)
{
QListWidgetItem* item = m_Internals->Ui.PlotsList->item(i);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(Qt::Unchecked);
}
}

ExportDialog::~ExportDialog()
{
delete m_Internals;
}

bool ExportDialog::getExportHorizontalCurve() const
{
return m_Internals->Ui.PlotsList->item(0)->checkState() == Qt::Checked;
}

bool ExportDialog::getExportVerticalCurve() const
{
return m_Internals->Ui.PlotsList->item(1)->checkState() == Qt::Checked;
}

bool ExportDialog::getExportWaterfallCurve() const
{
return m_Internals->Ui.PlotsList->item(2)->checkState() == Qt::Checked;
}
26 changes: 26 additions & 0 deletions ExportDialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef EXPORTDIALOG_H
#define EXPORTDIALOG_H

#include <QDialog>

class ExportDialog : public QDialog
{
Q_OBJECT
typedef QDialog Superclass;

public:
explicit ExportDialog(QWidget* const parent = nullptr);
~ExportDialog() override;

bool getExportWaterfallCurve() const;
bool getExportHorizontalCurve() const;
bool getExportVerticalCurve() const;

private:
Q_DISABLE_COPY(ExportDialog)

struct Internals;
Internals* m_Internals;
};

#endif // EXPORTDIALOG_H
67 changes: 67 additions & 0 deletions ExportDialog.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ExportDialog</class>
<widget class="QDialog" name="ExportDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Plots to export</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListWidget" name="PlotsList"/>
</item>
<item>
<widget class="QDialogButtonBox" name="ButtonBox">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>ButtonBox</sender>
<signal>accepted()</signal>
<receiver>ExportDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>ButtonBox</sender>
<signal>rejected()</signal>
<receiver>ExportDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
94 changes: 64 additions & 30 deletions Waterfallplot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ Waterfallplot::Waterfallplot(QWidget* parent) :
m_plotHorCurve(new QwtPlot),
m_plotVertCurve(new QwtPlot),
m_plotSpectrogram(new QwtPlot),
m_horCurve(new QwtPlotCurve),
m_vertCurve(new QwtPlotCurve),
m_picker(new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn, m_plotSpectrogram->canvas())),
m_panner(new QwtPlotPanner(m_plotSpectrogram->canvas())),
Expand All @@ -152,19 +150,6 @@ Waterfallplot::Waterfallplot(QWidget* parent) :
m_plotVertCurve->setAutoReplot(false);
m_plotSpectrogram->setAutoReplot(false);

/* Horizontal Curve */
m_horCurve->attach(m_plotHorCurve);
m_horCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
//m_curve->setTitle("");
//m_curve->setPen(...); // pen : color + width
m_horCurve->setStyle(QwtPlotCurve::Lines);
//m_curve->setSymbol(new QwtSymbol(QwtSymbol::Style...,Qt::NoBrush, QPen..., QSize(5, 5)));

/* Vertical Curve */
m_vertCurve->attach(m_plotVertCurve);
m_vertCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
m_vertCurve->setStyle(QwtPlotCurve::Lines);

m_spectrogram->setRenderThreadCount(0); // use system specific thread count
m_spectrogram->setCachePolicy(QwtPlotRasterItem::PaintCache);
m_spectrogram->attach(m_plotSpectrogram);
Expand Down Expand Up @@ -230,8 +215,6 @@ Waterfallplot::Waterfallplot(QWidget* parent) :
//m_plot->setAxisLabelRotation(QwtPlot::yLeft, -50.0);
//m_plot->setAxisLabelAlignment(QwtPlot::yLeft, Qt::AlignLeft | Qt::AlignBottom);

m_plotVertCurve->setAxisScaleDraw(QwtPlot::yLeft, new WaterfallTimeScaleDraw(*this));

// test color bar...
m_plotSpectrogram->enableAxis(QwtPlot::yRight);
QwtScaleWidget* axis = m_plotSpectrogram->axisWidget(QwtPlot::yRight);
Expand Down Expand Up @@ -336,27 +319,16 @@ void Waterfallplot::setDataDimensions(double dXMin, double dXMax,
m_data = new WaterfallData<double>(dXMin, dXMax, historyExtent, layerPoints);
m_spectrogram->setData(m_data); // NB: owner of the data is m_spectrogram !

setupCurves();
freeCurvesData();

m_horCurveXAxisData = new double[layerPoints];
m_horCurveYAxisData = new double[layerPoints];
m_vertCurveXAxisData = new double[historyExtent];
m_vertCurveYAxisData = new double[historyExtent];
allocateCurvesData();

// After changing data dimensions, we need to reset curves markers
// to show the last received data on the horizontal axis and the history
// of the middle point
m_markerX = (dXMax - dXMin) / 2;
m_markerY = historyExtent - 1;

// generate curve X axis data
const double dx = (dXMax - dXMin) / layerPoints; // x spacing
m_horCurveXAxisData[0] = dXMin;
for (size_t x = 1u; x < layerPoints; ++x)
{
m_horCurveXAxisData[x] = m_horCurveXAxisData[x - 1] + dx;
}

// scale x
m_plotHorCurve->setAxisScale(QwtPlot::xBottom, dXMin, dXMax);
m_plotSpectrogram->setAxisScale(QwtPlot::xBottom, dXMin, dXMax);
Expand Down Expand Up @@ -523,7 +495,9 @@ void Waterfallplot::clear()
m_data->clear();
}

setupCurves();
freeCurvesData();
allocateCurvesData();
}

time_t Waterfallplot::getLayerDate(const double y) const
Expand Down Expand Up @@ -715,6 +689,37 @@ void Waterfallplot::updateCurvesData()
}
}

void Waterfallplot::allocateCurvesData()
{
if (m_horCurveXAxisData || m_horCurveYAxisData || m_vertCurveXAxisData ||
m_vertCurveYAxisData || !m_data)
{
return;
}

const size_t layerPoints = m_data->getLayerPoints();
const double dXMin = m_data->getXMin();
const double dXMax = m_data->getXMax();
const size_t historyExtent = m_data->getMaxHistoryLength();

m_horCurveXAxisData = new double[layerPoints];
m_horCurveYAxisData = new double[layerPoints];
m_vertCurveXAxisData = new double[historyExtent];
m_vertCurveYAxisData = new double[historyExtent];

// generate curve X axis data
const double dx = (dXMax - dXMin) / layerPoints; // x spacing
m_horCurveXAxisData[0] = dXMin;
for (size_t x = 1u; x < layerPoints; ++x)
{
m_horCurveXAxisData[x] = m_horCurveXAxisData[x - 1] + dx;
}

// Reset marker to the default position
m_markerX = (dXMax - dXMin) / 2;
m_markerY = historyExtent - 1;
}

void Waterfallplot::freeCurvesData()
{
if (m_horCurveXAxisData)
Expand Down Expand Up @@ -753,6 +758,11 @@ void Waterfallplot::setPickerEnabled(const bool enabled)

bool Waterfallplot::setMarker(const double x, const double y)
{
if (!m_data)
{
return false;
}

const QwtInterval xInterval = m_data->interval(Qt::XAxis);
const QwtInterval yInterval = m_data->interval(Qt::YAxis);
if (!(xInterval.contains(x) && yInterval.contains(y)))
Expand All @@ -777,3 +787,27 @@ void Waterfallplot::selectedPoint(const QPointF& pt)
{
setMarker(pt.x(), pt.y());
}

void Waterfallplot::setupCurves()
{
m_plotHorCurve->detachItems(QwtPlotItem::Rtti_PlotCurve, true);
m_plotVertCurve->detachItems(QwtPlotItem::Rtti_PlotCurve, true);

m_horCurve = new QwtPlotCurve;
m_vertCurve = new QwtPlotCurve;

/* Horizontal Curve */
m_horCurve->attach(m_plotHorCurve);
m_horCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
//m_curve->setTitle("");
//m_curve->setPen(...); // pen : color + width
m_horCurve->setStyle(QwtPlotCurve::Lines);
//m_curve->setSymbol(new QwtSymbol(QwtSymbol::Style...,Qt::NoBrush, QPen..., QSize(5, 5)));

/* Vertical Curve */
m_vertCurve->attach(m_plotVertCurve);
m_vertCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
m_vertCurve->setStyle(QwtPlotCurve::Lines);

m_plotVertCurve->setAxisScaleDraw(QwtPlot::yLeft, new WaterfallTimeScaleDraw(*this));
}
22 changes: 12 additions & 10 deletions Waterfallplot.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ protected slots:
void selectedPoint(const QPointF& pt);

protected:
QwtPlot*const m_plotHorCurve;
QwtPlot*const m_plotVertCurve;
QwtPlot*const m_plotSpectrogram;
QwtPlotCurve* const m_horCurve;
QwtPlotCurve* const m_vertCurve;
QwtPlotPicker* const m_picker;
QwtPlotPanner* const m_panner;
QwtPlotSpectrogram* const m_spectrogram;
QwtPlotZoomer* m_zoomer;
QwtPlot* const m_plotHorCurve = nullptr;
QwtPlot* const m_plotVertCurve = nullptr;
QwtPlot* const m_plotSpectrogram = nullptr;
QwtPlotCurve* m_horCurve = nullptr;
QwtPlotCurve* m_vertCurve = nullptr;
QwtPlotPicker* const m_picker = nullptr;
QwtPlotPanner* const m_panner = nullptr;
QwtPlotSpectrogram* const m_spectrogram = nullptr;
QwtPlotZoomer* const m_zoomer = nullptr;

// later, the type can be parametrized when instanciating Waterfallplot
// m_pData will be owned (freed) by m_spectrogram
Expand All @@ -96,8 +96,10 @@ protected slots:
protected:
void updateLayout();

void updateCurvesData();
void allocateCurvesData();
void freeCurvesData();
void setupCurves();
void updateCurvesData();

private:
//Q_DISABLE_COPY(Waterfallplot)
Expand Down
Loading

0 comments on commit e7e43a5

Please sign in to comment.