Commit b135d321 authored by pixhawk's avatar pixhawk

Significantly improved plotting, now capturing data in linechart allows...

Significantly improved plotting, now capturing data in linechart allows limmediate processing / analysis of the whole flight
parent 96947527
price quantity
210 81
250 73
280 64
300 61
320 50
340 46
360 45
380 44
400 43
420 39
440 36
......@@ -36,6 +36,9 @@ This file is part of the QGROUNDCONTROL project
#include <QDebug>
/**
* It will only get active upon calling startCompression()
*/
LogCompressor::LogCompressor(QString logFileName, QString outFileName, int uasid) :
logFileName(logFileName),
outFileName(outFileName),
......@@ -44,7 +47,6 @@ LogCompressor::LogCompressor(QString logFileName, QString outFileName, int uasid
dataLines(1),
uasid(uasid)
{
start();
}
void LogCompressor::run()
......@@ -174,9 +176,15 @@ void LogCompressor::run()
dataLines = 1;
delete keys;
qDebug() << "Done with logfile processing";
emit finishedFile(outfile.fileName());
running = false;
}
void LogCompressor::startCompression()
{
start();
}
bool LogCompressor::isFinished()
{
return !running;
......
......@@ -5,11 +5,15 @@
class LogCompressor : public QThread
{
Q_OBJECT
public:
/** @brief Create the log compressor. It will only get active upon calling startCompression() */
LogCompressor(QString logFileName, QString outFileName="", int uasid = 0);
void startCompression();
bool isFinished();
int getDataLines();
int getCurrentLine();
protected:
void run();
QString logFileName;
......@@ -18,6 +22,12 @@ protected:
int currentDataLine;
int dataLines;
int uasid;
signals:
/** @brief This signal is emitted once a logfile has been finished writing
* @param fileName The name out the output (CSV) file
*/
void finishedFile(QString fileName);
};
#endif // LOGCOMPRESSOR_H
......@@ -145,6 +145,7 @@ void MainWindow::connectWidgets()
{
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), linechart, SLOT(addSystem(UASInterface*)));
connect(UASManager::instance(), SIGNAL(activeUASSet(int)), linechart, SLOT(selectSystem(int)));
connect(linechart, SIGNAL(logfileWritten(QString)), this, SLOT(loadDataView(QString)));
connect(mavlink, SIGNAL(receiveLossChanged(int, float)), info, SLOT(updateSendLoss(int, float)));
}
......@@ -544,6 +545,13 @@ void MainWindow::loadDataView()
centerStack->setCurrentWidget(dataplot);
}
void MainWindow::loadDataView(QString fileName)
{
clearView();
centerStack->setCurrentWidget(dataplot);
dataplot->loadFile(fileName);
}
void MainWindow::loadPilotView()
{
clearView();
......
......@@ -119,6 +119,8 @@ public slots:
void loadMAVLinkView();
/** @brief Load data view, allowing to plot flight data */
void loadDataView();
/** @brief Load data view, allowing to plot flight data */
void loadDataView(QString fileName);
/** @brief Show the online help for users */
void showHelp();
......
This diff is collapsed.
......@@ -16,11 +16,17 @@ public:
QGCDataPlot2D(QWidget *parent = 0);
~QGCDataPlot2D();
/** @brief Calculate and display regression function*/
bool calculateRegression(QString xName, QString yName, QString method="linear");
/** @brief Linear regression over data points */
int linearRegression(double *x,double *y,int n,double *a,double *b,double *r);
int linearRegression(double* x,double* y,int n,double* a,double* b,double* r);
public slots:
/** @brief Load previously selected file */
void loadFile();
/** @brief Load file with this name */
void loadFile(QString file);
/** @brief Reload a file, with filtering enabled */
void reloadFile();
void selectFile();
......@@ -29,10 +35,14 @@ public slots:
void saveCsvLog();
/** @brief Save plot to PDF or SVG */
void savePlot();
/** @brief Export PDF file */
void exportPDF(QString fileName);
/** @brief Export SVG file */
void exportSVG(QString file);
/** @brief Print or save PDF file (MacOS/Linux) */
void print();
/** @brief Calculate and display regression function*/
bool calculateRegression();
protected:
void changeEvent(QEvent *e);
......@@ -40,6 +50,7 @@ protected:
LogCompressor* compressor;
QFile* logFile;
QString fileName;
QStringList curveNames;
private:
Ui::QGCDataPlot2D *ui;
......
......@@ -6,22 +6,22 @@
<rect>
<x>0</x>
<y>0</y>
<width>807</width>
<width>1073</width>
<height>308</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="2,10,2,0,0,0,0,0,0,0,0,0,0">
<item row="0" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item row="0" column="2">
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="xAxis"/>
</item>
<item row="0" column="3">
......@@ -53,7 +53,12 @@
</item>
<item>
<property name="text">
<string>Only dots</string>
<string>Only rectangles</string>
</property>
</item>
<item>
<property name="text">
<string>Only symbols</string>
</property>
</item>
<item>
......@@ -68,7 +73,12 @@
</item>
<item>
<property name="text">
<string>Lines and dots</string>
<string>Lines and rects</string>
</property>
</item>
<item>
<property name="text">
<string>Lines and symbols</string>
</property>
</item>
<item>
......@@ -83,7 +93,7 @@
</item>
<item>
<property name="text">
<string>Dotted lines and dots</string>
<string>Dotted lines and rects</string>
</property>
</item>
<item>
......@@ -98,39 +108,91 @@
</item>
<item>
<property name="text">
<string>Dashed lines and dots</string>
<string>Dashed lines and rects</string>
</property>
</item>
</widget>
</item>
<item row="0" column="9">
<item row="0" column="7" colspan="2">
<widget class="QPushButton" name="reloadButton">
<property name="text">
<string>Reload</string>
<string>Replot</string>
</property>
</widget>
</item>
<item row="0" column="10">
<spacer name="horizontalSpacer_2">
<item row="0" column="11">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</widget>
</item>
<item row="0" column="11">
<item row="0" column="12" colspan="2">
<widget class="QPushButton" name="savePlotButton">
<property name="text">
<string>Save Plot</string>
<string>Save Image</string>
</property>
</widget>
</item>
<item row="0" column="19">
<widget class="QPushButton" name="printButton">
<property name="text">
<string>Print</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Title</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="3">
<widget class="QLineEdit" name="plotTitle"/>
</item>
<item row="1" column="5">
<widget class="QLabel" name="label_5">
<property name="text">
<string>X label</string>
</property>
</widget>
</item>
<item row="1" column="6" colspan="2">
<widget class="QLineEdit" name="plotXAxisLabel"/>
</item>
<item row="1" column="8">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Y label</string>
</property>
</widget>
</item>
<item row="1" column="9" colspan="3">
<widget class="QLineEdit" name="plotYAxisLabel"/>
</item>
<item row="1" column="12" colspan="2">
<widget class="QCheckBox" name="symmetricCheckBox">
<property name="text">
<string>Symmetric</string>
</property>
</widget>
</item>
<item row="1" column="14" colspan="2">
<widget class="QCheckBox" name="legendCheckBox">
<property name="text">
<string>Legend</string>
</property>
</widget>
</item>
<item row="1" column="16">
<widget class="QCheckBox" name="gridCheckBox">
<property name="text">
<string>Grid</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="13">
<item row="2" column="0" colspan="20">
<widget class="QFrame" name="plotFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
......@@ -140,14 +202,14 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>File</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<item row="3" column="1" colspan="2">
<widget class="QComboBox" name="inputFileType">
<item>
<property name="text">
......@@ -166,14 +228,21 @@
</item>
</widget>
</item>
<item row="2" column="3" colspan="4">
<item row="3" column="3" colspan="4">
<widget class="QLabel" name="filenameLabel">
<property name="text">
<string>Please select input file..</string>
</property>
</widget>
</item>
<item row="2" column="10">
<item row="3" column="8" colspan="2">
<widget class="QPushButton" name="selectFileButton">
<property name="text">
<string>Select file</string>
</property>
</widget>
</item>
<item row="3" column="10" colspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
......@@ -186,41 +255,60 @@
</property>
</spacer>
</item>
<item row="0" column="12">
<widget class="QPushButton" name="printButton">
<property name="text">
<string>Print</string>
<item row="3" column="12">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="2" column="12">
<widget class="QPushButton" name="saveCsvButton">
<item row="3" column="13">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Save CSV</string>
<string>Regression</string>
</property>
</widget>
</item>
<item row="2" column="9">
<widget class="QPushButton" name="selectFileButton">
<item row="3" column="14" colspan="2">
<widget class="QComboBox" name="xRegressionComboBox"/>
</item>
<item row="3" column="16" colspan="2">
<widget class="QComboBox" name="yRegressionComboBox"/>
</item>
<item row="3" column="19">
<widget class="QPushButton" name="regressionButton">
<property name="text">
<string>Select file</string>
<string>Calculate</string>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QCheckBox" name="symmetricCheckBox">
<property name="text">
<string>Symmetric</string>
<item row="3" column="18">
<widget class="QLineEdit" name="regressionOutput">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="8">
<widget class="QCheckBox" name="legendCheckBox">
<item row="0" column="14">
<widget class="QPushButton" name="saveCsvButton">
<property name="text">
<string>Legend</string>
<string>Save Data</string>
</property>
</widget>
</item>
<item row="0" column="9" colspan="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Implementation of class IncrementalPlot
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#include <qwt_plot.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_curve.h>
......@@ -9,9 +39,9 @@
#include <Scrollbar.h>
#include <ScrollZoomer.h>
#include <float.h>
#if QT_VERSION >= 0x040000
#include <qpaintengine.h>
#endif
#include <QDebug>
CurveData::CurveData():
d_count(0)
......@@ -45,18 +75,23 @@ int CurveData::size() const
return d_x.size();
}
const double *CurveData::x() const
const double* CurveData::x() const
{
return d_x.data();
}
const double *CurveData::y() const
const double* CurveData::y() const
{
return d_y.data();
}
IncrementalPlot::IncrementalPlot(QWidget *parent):
QwtPlot(parent)
QwtPlot(parent),
symbolWidth(1.2f),
curveWidth(1.0f),
gridWidth(0.8f),
scaleWidth(1.0f),
symmetric(false)
{
setAutoReplot(false);
......@@ -67,8 +102,8 @@ IncrementalPlot::IncrementalPlot(QWidget *parent):
plotLayout()->setAlignCanvasToScales(true);
QwtPlotGrid *grid = new QwtPlotGrid;
grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine));
grid = new QwtPlotGrid;
grid->setMajPen(QPen(Qt::gray, 0.8f, Qt::DotLine));
grid->attach(this);
QwtLinearScaleEngine* yScaleEngine = new QwtLinearScaleEngine();
......@@ -82,7 +117,7 @@ IncrementalPlot::IncrementalPlot(QWidget *parent):
// enable zooming
zoomer = new ScrollZoomer(canvas());
zoomer->setRubberBandPen(QPen(Qt::red, 2, Qt::DotLine));
zoomer->setRubberBandPen(QPen(Qt::red, 1.5f, Qt::DotLine));
zoomer->setTrackerPen(QPen(Qt::red));
//zoomer->setZoomBase(QwtDoubleRect());
legend = NULL;
......@@ -112,6 +147,8 @@ IncrementalPlot::IncrementalPlot(QWidget *parent):
colors.append(QColor(161,252,116));
colors.append(QColor(87,231,246));
colors.append(QColor(230,126,23));
connect(this, SIGNAL(legendChecked(QwtPlotItem*,bool)), this, SLOT(handleLegendClick(QwtPlotItem*,bool)));
}
IncrementalPlot::~IncrementalPlot()
......@@ -119,6 +156,23 @@ IncrementalPlot::~IncrementalPlot()
}
/**
* @param symmetric true will enforce that both axes have the same interval,
* centered around the data plot. A circle will thus remain a circle if true,
* if set to false it might become an ellipse because of axis scaling.
*/
void IncrementalPlot::setSymmetric(bool symmetric)
{
this->symmetric = symmetric;
updateScale(); // Updates the scaling at replots
}
void IncrementalPlot::handleLegendClick(QwtPlotItem* item, bool on)
{
item->setVisible(!on);
replot();
}
void IncrementalPlot::showLegend(bool show)
{
if (show)
......@@ -127,6 +181,7 @@ void IncrementalPlot::showLegend(bool show)
{
legend = new QwtLegend;
legend->setFrameStyle(QFrame::Box);
legend->setItemMode(QwtLegend::CheckableItem);
}
insertLegend(legend, QwtPlot::RightLegend);
}
......@@ -135,7 +190,7 @@ void IncrementalPlot::showLegend(bool show)
delete legend;
legend = NULL;
}
replot();
updateScale(); // Updates the scaling at replots
}
/**
......@@ -159,19 +214,25 @@ void IncrementalPlot::setStyleText(QString style)
if (style.toLower().contains("circles"))
{
curve->setSymbol(QwtSymbol(QwtSymbol::Ellipse,
QBrush(curve->pen().color()), curve->pen(), QSize(5, 5)) );
Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(6, 6)) );
}
else if (style.toLower().contains("crosses"))
{
curve->setSymbol(QwtSymbol(QwtSymbol::XCross,
QBrush(curve->pen().color()), curve->pen(), QSize(5, 5)) );
Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(5, 5)) );
}
else // Always show dots (style.toLower().contains("dots"))
else if (style.toLower().contains("rect"))
{
curve->setSymbol(QwtSymbol(QwtSymbol::Rect,
QBrush(curve->pen().color()), curve->pen(), QSize(1, 1)) );
Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(6, 6)) );
}
else if (style.toLower().contains("line")) // Show no symbol
{
curve->setSymbol(QwtSymbol(QwtSymbol::NoSymbol,
Qt::NoBrush, QPen(QBrush(curve->symbol().pen().color()), symbolWidth), QSize(6, 6)) );
}
curve->setPen(QPen(QBrush(curve->symbol().pen().color().darker()), curveWidth));
// Style of lines
if (style.toLower().contains("dotted"))
{
......@@ -181,19 +242,25 @@ void IncrementalPlot::setStyleText(QString style)
{
curve->setStyle(QwtPlotCurve::Lines);
}
else if (style.toLower().contains("dashed") || style.toLower().contains("solid"))
{
curve->setStyle(QwtPlotCurve::Steps);
}
else
{
curve->setStyle(QwtPlotCurve::NoCurve);
}
}
replot();
}
void IncrementalPlot::resetScaling()
{
xmin = 0;
xmax = 500;
ymin = 0;
ymax = 500;
ymin = xmin;
ymax = xmax;
setAxisScale(xBottom, xmin+xmin*0.05, xmax+xmax*0.05);
setAxisScale(yLeft, ymin+ymin*0.05, ymax+ymax*0.05);
......@@ -207,6 +274,46 @@ void IncrementalPlot::resetScaling()
ymax = DBL_MIN;
}
/**
* Updates the scale calculation and re-plots the whole plot
*/
void IncrementalPlot::updateScale()
{
const double margin = 0.05;
double xMinRange = xmin+(xmin*margin);
double xMaxRange = xmax+(xmax*margin);
double yMinRange = ymin+(ymin*margin);
double yMaxRange = ymax+(ymax*margin);
if (symmetric)
{
double xRange = xMaxRange - xMinRange;
double yRange = yMaxRange - yMinRange;
// Get the aspect ratio of the plot
float xSize = width();
if (legend != NULL) xSize -= legend->width();
float ySize = height();
float aspectRatio = xSize / ySize;
if (xRange > yRange)
{
double yCenter = yMinRange + yRange/2.0;
yMinRange = yCenter - xRange/2.0;
yMaxRange = yCenter + xRange/2.0;
}
else
{
double xCenter = xMinRange + xRange/2.0;
xMinRange = xCenter - yRange/2.0;
xMaxRange = xCenter + yRange/2.0;
}
}
setAxisScale(xBottom, xMinRange, xMaxRange);
setAxisScale(yLeft, yMinRange, yMaxRange);
zoomer->setZoomBase(true);
}
void IncrementalPlot::appendData(QString key, double x, double y)
{
appendData(key, &x, &y, 1);
......@@ -235,7 +342,7 @@ void IncrementalPlot::appendData(QString key, double *x, double *y, int size)
const QColor &c = getNextColor();
curve->setSymbol(QwtSymbol(QwtSymbol::XCross,
QBrush(c), QPen(c), QSize(5, 5)) );
QBrush(c), QPen(c, 1.2f), QSize(5, 5)) );
curve->attach(this);
}
......@@ -285,9 +392,7 @@ void IncrementalPlot::appendData(QString key, double *x, double *y, int size)
if(scaleChanged)
{
setAxisScale(xBottom, xmin+xmin*0.05, xmax+xmax*0.05);
setAxisScale(yLeft, ymin+ymin*0.05, ymax+ymax*0.05);
zoomer->setZoomBase(true);
updateScale();
}
else
{
......@@ -316,9 +421,44 @@ void IncrementalPlot::appendData(QString key, double *x, double *y, int size)
#if QT_VERSION >= 0x040000 && defined(Q_WS_X11)
canvas()->setAttribute(Qt::WA_PaintOutsidePaintEvent, false);
#endif
}
}
/**
* @return Number of copied data points, 0 on failure
*/
int IncrementalPlot::data(QString key, double* r_x, double* r_y, int maxSize)
{
int result = 0;
if (d_data.contains(key))
{
CurveData* d = d_data.value(key);
if (maxSize >= d->count())
{
result = d->count();
memcpy(r_x, d->x(), sizeof(double) * d->count());
memcpy(r_y, d->y(), sizeof(double) * d->count());
}
else
{
result = 0;
}
}
return result;
}
/**
* @param show true to show the grid, false else
*/
void IncrementalPlot::showGrid(bool show)
{
grid->setVisible(show);
replot();
}
bool IncrementalPlot::gridEnabled()
{
return grid->isVisible();
}
QList<QColor> IncrementalPlot::getColorMap()
......@@ -330,7 +470,7 @@ QColor IncrementalPlot::getNextColor()
{
/* Return current color and increment counter for next round */
nextColor++;
if(nextColor >= colors.size()) nextColor = 0;
if(nextColor >= colors.count()) nextColor = 0;
return colors[nextColor++];
}
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Defition of class IncrementalPlot
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#ifndef INCREMENTALPLOT_H
#define INCREMENTALPLOT_H
......@@ -5,21 +35,25 @@
#include <qwt_array.h>
#include <qwt_plot.h>
#include <qwt_legend.h>
#include <qwt_plot_grid.h>
#include <QMap>
#include "ScrollZoomer.h"
class QwtPlotCurve;
/**
* @brief Plot data container for growing data
*/
class CurveData
{
// A container class for growing data
public:
CurveData();
void append(double *x, double *y, int count);
/** @brief The number of datasets held in the data structure */
int count() const;
/** @brief The reserved size of the data structure in units */
int size() const;
const double *x() const;
const double *y() const;
......@@ -32,44 +66,89 @@ private:
int d_timerCount;
};
/**
* @brief Incremental plotting widget
*
* This widget plots data incrementally when new data arrives.
* It will only repaint the minimum screen content necessary to avoid
* a too high CPU consumption. It auto-scales the plot to new data.
*/
class IncrementalPlot : public QwtPlot
{
Q_OBJECT
public:
/** @brief Create a new, empty incremental plot */
IncrementalPlot(QWidget *parent = NULL);
virtual ~IncrementalPlot();
/** @brief Get color map of this plot */
QList<QColor> getColorMap();
/** @brief Get next color of color map */
QColor getNextColor();
/** @brief Get color for curve id */
QColor getColorForCurve(QString id);
/** @brief Get the state of the grid */
bool gridEnabled();
/** @brief Read out data from a curve */
int data(QString key, double* r_x, double* r_y, int maxSize);
float symbolWidth;
float curveWidth;
float gridWidth;
float scaleWidth;
public slots:
/** @brief Append one data point */
void appendData(QString key, double x, double y);
void appendData(QString key, double *x, double *y, int size);
/** @brief Append multiple data points */
void appendData(QString key, double* x, double* y, int size);
/** @brief Reset the plot scaling to the default value */
void resetScaling();
/** @brief Update the plot scale based on current data/symmetric mode */
void updateScale();
/** @brief Remove all data from the plot and repaint */
void removeData();
/** @brief Show the plot legend */
void showLegend(bool show);
/** @brief Show the plot grid */
void showGrid(bool show);
/** @brief Set new plot style */
void setStyleText(QString style);
/** @brief Set symmetric axis scaling mode */
void setSymmetric(bool symmetric);
protected slots:
/** @brief Handle the click on a legend item */
void handleLegendClick(QwtPlotItem* item, bool on);
protected:
QList<QColor> colors;
int nextColor;
ScrollZoomer* zoomer;
QwtLegend* legend;
double xmin;
double xmax;
double ymin;
double ymax;
bool symmetric; ///< Enable symmetric plotting
QList<QColor> colors; ///< Colormap for curves
int nextColor; ///< Next index in color map
ScrollZoomer* zoomer; ///< Zoomer class for widget
QwtLegend* legend; ///< Plot legend
QwtPlotGrid* grid; ///< Plot grid
double xmin; ///< Minimum x value seen
double xmax; ///< Maximum x value seen
double ymin; ///< Minimum y value seen
double ymax; ///< Maximum y value seen
private:
QMap<QString, CurveData* > d_data;
QMap<QString, QwtPlotCurve* > d_curve;
QMap<QString, CurveData* > d_data; ///< Data points
QMap<QString, QwtPlotCurve* > d_curve; ///< Plot curves
};
#endif /* INCREMENTALPLOT_H */
......@@ -136,7 +136,7 @@ d_curve(NULL)
// Enable zooming
//zoomer = new Zoomer(canvas());
zoomer = new ScrollZoomer(canvas());
zoomer->setRubberBandPen(QPen(Qt::blue, 2, Qt::DotLine));
zoomer->setRubberBandPen(QPen(Qt::blue, 1.2, Qt::DotLine));
zoomer->setTrackerPen(QPen(Qt::blue));
// Start QTimer for plot update
......@@ -314,7 +314,7 @@ QColor LinechartPlot::getNextColor()
{
/* Return current color and increment counter for next round */
nextColor++;
if(nextColor >= colors.size()) nextColor = 0;
if(nextColor >= colors.count()) nextColor = 0;
return colors[nextColor++];
}
......@@ -762,15 +762,15 @@ void TimeSeriesData::append(quint64 ms, double value)
mean = mean / static_cast<double>(qMin(averageWindow,static_cast<unsigned int>(count)));
qSort(medianList);
if (medianList.size() > 2)
if (medianList.count() > 2)
{
if (medianList.size() % 2 == 0)
if (medianList.count() % 2 == 0)
{
median = (medianList.at(medianList.size()/2) + medianList.at(medianList.size()/2+1)) / 2.0;
median = (medianList.at(medianList.count()/2) + medianList.at(medianList.count()/2+1)) / 2.0;
}
else
{
median = medianList.at(medianList.size()/2+1);
median = medianList.at(medianList.count()/2+1);
}
}
......
......@@ -141,8 +141,9 @@ void LinechartWidget::createLayout()
// Averaging spin box
averageSpinBox = new QSpinBox(this);
averageSpinBox->setValue(2);
averageSpinBox->setValue(200);
averageSpinBox->setMinimum(2);
averageSpinBox->setMaximum(9999);
layout->addWidget(averageSpinBox, 1, 2);
layout->setColumnStretch(2, 0);
connect(averageSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setAverageWindow(int)));
......@@ -306,6 +307,8 @@ void LinechartWidget::stopLogging()
logFile->close();
// Postprocess log file
compressor = new LogCompressor(logFile->fileName());
connect(compressor, SIGNAL(finishedFile(QString)), this, SIGNAL(logfileWritten(QString)));
compressor->startCompression();
}
logButton->setText(tr("Start logging"));
disconnect(logButton, SIGNAL(clicked()), this, SLOT(stopLogging()));
......
......@@ -163,6 +163,9 @@ signals:
void plotWindowPositionUpdated(quint64 position);
void plotWindowPositionUpdated(int position);
/** @brief This signal is emitted once a logfile has been finished writing */
void logfileWritten(QString fileName);
};
#endif // LINECHARTWIDGET_H
......@@ -55,6 +55,7 @@ void Linecharts::addSystem(UASInterface* uas)
addWidget(widget);
plots.insert(uas->getUASID(), widget);
connect(uas, SIGNAL(valueChanged(int,QString,double,quint64)), widget, SLOT(appendData(int,QString,double,quint64)));
connect(widget, SIGNAL(logfileWritten(QString)), this, SIGNAL(logfileWritten(QString)));
// Set system active if this is the only system
if (active)
{
......
......@@ -14,6 +14,8 @@ public:
explicit Linecharts(QWidget *parent = 0);
signals:
/** @brief This signal is emitted once a logfile has been finished writing */
void logfileWritten(QString fileName);
public slots:
/** @brief Set all plots active/inactive */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment