Commit c8f12ee4 authored by Bryant's avatar Bryant

Moved all shared code for IncrementalPlot and LinechartPlot into a common...

Moved all shared code for IncrementalPlot and LinechartPlot into a common ChartPlot superclass. Also recoloring the background of both widgets now works when switching between color schemes.
parent 6377dab3
......@@ -374,7 +374,8 @@ HEADERS += src/MG.h \
src/ui/submainwindow.h \
src/ui/dockwidgettitlebareventfilter.h \
src/ui/uas/UASQuickView.h \
src/ui/uas/UASQuickViewItem.h
src/ui/uas/UASQuickViewItem.h \
src/ui/linechart/ChartPlot.h
# Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler
macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h
......@@ -541,7 +542,8 @@ SOURCES += src/main.cc \
src/ui/submainwindow.cpp \
src/ui/dockwidgettitlebareventfilter.cpp \
src/ui/uas/UASQuickViewItem.cc \
src/ui/uas/UASQuickView.cc
src/ui/uas/UASQuickView.cc \
src/ui/linechart/ChartPlot.cc
# Enable Google Earth only on Mac OS and Windows with Visual Studio compiler
macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc
......
......@@ -59,6 +59,8 @@ This file is part of the QGROUNDCONTROL project
#include "QGCFirmwareUpdate.h"
#include "QGCStatusBar.h"
#include "UASQuickView.h"
#include "QGCDataPlot2D.h"
#include "Linecharts.h"
#ifdef QGC_OSG_ENABLED
#include "Q3DWidgetFactory.h"
......
......@@ -43,7 +43,6 @@ This file is part of the QGROUNDCONTROL project
#include "UASInterface.h"
#include "UASManager.h"
#include "UASControlWidget.h"
#include "Linecharts.h"
#include "UASInfoWidget.h"
#include "WaypointList.h"
#include "CameraView.h"
......@@ -63,7 +62,6 @@ This file is part of the QGROUNDCONTROL project
#include "HDDisplay.h"
#include "WatchdogControl.h"
#include "HSIDisplay.h"
#include "QGCDataPlot2D.h"
#include "QGCRemoteControlView.h"
#include "opmapcontrol.h"
#if (defined Q_OS_MAC) | (defined _MSC_VER)
......@@ -87,6 +85,8 @@ class QGCMAVLinkMessageSender;
class QGCFirmwareUpdate;
class QSplashScreen;
class QGCStatusBar;
class Linecharts;
class QGCDataPlot2D;
/**
* @brief Main Application Window
......
......@@ -47,7 +47,7 @@ This file is part of the QGROUNDCONTROL project
QGCDataPlot2D::QGCDataPlot2D(QWidget *parent) :
QWidget(parent),
plot(new IncrementalPlot()),
plot(new IncrementalPlot(parent)),
logFile(NULL),
ui(new Ui::QGCDataPlot2D)
{
......@@ -246,27 +246,27 @@ void QGCDataPlot2D::exportSVG(QString fileName)
*/
void QGCDataPlot2D::selectFile()
{
// Open a file dialog prompting the user for the file to load.
// Note the special case for the Pixhawk.
// Open a file dialog prompting the user for the file to load.
// Note the special case for the Pixhawk.
if (ui->inputFileType->currentText().contains("pxIMU") || ui->inputFileType->currentText().contains("RAW")) {
fileName = QFileDialog::getOpenFileName(this, tr("Specify log file name"), QString(), "Logfile (*.imu *.raw)");
}
else
{
}
else
{
fileName = QFileDialog::getOpenFileName(this, tr("Specify log file name"), QString(), "Logfile (*.csv *.txt *.log)");
}
// Check if the user hit cancel, which results in a Null string.
// If this is the case, we just stop.
if (fileName.isNull())
{
return;
}
// Check if the user hit cancel, which results in a Null string.
// If this is the case, we just stop.
if (fileName.isNull())
{
return;
}
// Now attempt to open the file
// Now attempt to open the file
QFileInfo fileInfo(fileName);
if (!fileInfo.isReadable())
{
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText("Could not open file");
......@@ -276,8 +276,8 @@ void QGCDataPlot2D::selectFile()
msgBox.exec();
ui->filenameLabel->setText(tr("Could not open %1").arg(fileInfo.baseName()+"."+fileInfo.completeSuffix()));
}
else
{
else
{
ui->filenameLabel->setText(tr("Opened %1").arg(fileInfo.completeBaseName()+"."+fileInfo.completeSuffix()));
// Open and import the file
loadFile();
......@@ -561,7 +561,7 @@ void QGCDataPlot2D::loadCsvLog(QString file, QString xAxisName, QString yAxisFil
bool QGCDataPlot2D::calculateRegression()
{
// TODO: Add support for quadratic / cubic curve fitting
return calculateRegression(ui->xRegressionComboBox->currentText(), ui->yRegressionComboBox->currentText(), "linear");
return calculateRegression(ui->xRegressionComboBox->currentText(), ui->yRegressionComboBox->currentText(), "linear");
}
/**
......@@ -580,14 +580,14 @@ bool QGCDataPlot2D::calculateRegression(QString xName, QString yName, QString me
ui->yRegressionComboBox->setCurrentIndex(curveNames.indexOf(yName));
}
// Create a couple of arrays for us to use to temporarily store some of the data from the plot.
// These arrays are allocated on the heap as they are far too big to go in the stack and will
// cause an overflow.
// TODO: Look into if this would be better done by having a getter return const double pointers instead
// of using memcpy().
// Create a couple of arrays for us to use to temporarily store some of the data from the plot.
// These arrays are allocated on the heap as they are far too big to go in the stack and will
// cause an overflow.
// TODO: Look into if this would be better done by having a getter return const double pointers instead
// of using memcpy().
const int size = 100000;
double *x = new double[size];
double *y = new double[size];
double *x = new double[size];
double *y = new double[size];
int copied = plot->data(yName, x, y, size);
if (method == "linear") {
......@@ -604,8 +604,8 @@ bool QGCDataPlot2D::calculateRegression(QString xName, QString yName, QString me
plot->setStyleText("lines");
// x-value of the current rightmost x position in the plot
plot->appendData(tr("regression %1-%2").arg(xName, yName), plot->invTransform(QwtPlot::xBottom, plot->width() - plot->width()*0.08f), (a + b*plot->invTransform(QwtPlot::xBottom, plot->width() - plot->width() * 0.08f)));
result = true;
result = true;
} else {
function = tr("Linear regression failed. (Limit: %1 data points. Try with less)").arg(size);
}
......
#include "ChartPlot.h"
#include "MainWindow.h"
const int ChartPlot::numBaseColors = 20;
ChartPlot::ChartPlot(QWidget *parent):
QwtPlot(parent)/*,
symbolWidth(1.2f),
curveWidth(1.0f),
gridWidth(0.8f),
scaleWidth(1.0f)*/
{
// for (int i = 0; i < numBaseColors; ++i)
// {
// colors[i] = baseColors[i];
// }
// Set up the colorscheme used by this plotter.
// nextColor = 0;
// Set the grid. The colorscheme was already set in generateColorScheme().
grid = new QwtPlotGrid;
grid->enableXMin(true);
grid->attach(this);
// // Enable zooming
zoomer = new ScrollZoomer(canvas());
colors = QList<QColor>();
nextColor = 0;
///> Color map for plots, includes 20 colors
///> Map will start from beginning when the first 20 colors are exceeded
colors.append(QColor(242,255,128));
colors.append(QColor(70,80,242));
colors.append(QColor(232,33,47));
colors.append(QColor(116,251,110));
colors.append(QColor(81,183,244));
colors.append(QColor(234,38,107));
colors.append(QColor(92,247,217));
colors.append(QColor(151,59,239));
colors.append(QColor(231,72,28));
colors.append(QColor(236,48,221));
colors.append(QColor(75,133,243));
colors.append(QColor(203,254,121));
colors.append(QColor(104,64,240));
colors.append(QColor(200,54,238));
colors.append(QColor(104,250,138));
colors.append(QColor(235,43,165));
colors.append(QColor(98,248,176));
colors.append(QColor(161,252,116));
colors.append(QColor(87,231,246));
colors.append(QColor(230,126,23));
// Now that all objects have been initialized, color everything.
applyColorScheme(((MainWindow*)parent)->getStyle());
// And make sure we're listening for future style changes
connect(parent, SIGNAL(styleChanged(MainWindow::QGC_MAINWINDOW_STYLE)),
this, SLOT(applyColorScheme(MainWindow::QGC_MAINWINDOW_STYLE)));
}
ChartPlot::~ChartPlot()
{
}
QColor ChartPlot::getNextColor()
{
/* Return current color and increment counter for next round */
nextColor++;
if(nextColor >= colors.count()) nextColor = 0;
return colors[nextColor++];
}
QColor ChartPlot::getColorForCurve(QString id)
{
return curves.value(id)->pen().color();
}
void ChartPlot::shuffleColors()
{
foreach (QwtPlotCurve* curve, curves)
{
QPen pen(curve->pen());
pen.setColor(getNextColor());
curve->setPen(pen);
}
}
void ChartPlot::applyColorScheme(MainWindow::QGC_MAINWINDOW_STYLE style)
{
// Generate the color list for curves
for (int i = 0; i < numBaseColors; ++i)
{
if (style == MainWindow::QGC_MAINWINDOW_STYLE_LIGHT) {
// colors[i] = baseColors[i].lighter(150);
}
else
{
// colors[i] = baseColors[i].darker(150);
}
}
// Configure the rest of the UI colors based on the current theme.
if (style == MainWindow::QGC_MAINWINDOW_STYLE_LIGHT)
{
// Set the coloring of the area selector for zooming.
zoomer->setRubberBandPen(QPen(Qt::darkRed, 3.0f, Qt::DotLine));
zoomer->setTrackerPen(QPen(Qt::darkRed));
// Set canvas background
setCanvasBackground(QColor(0xFF, 0xFF, 0xFF));
// Configure the plot grid.
grid->setMinPen(QPen(QColor(0x55, 0x55, 0x55), 0.8f, Qt::DotLine));
grid->setMajPen(QPen(QColor(0x22, 0x22, 0x22), 0.8f, Qt::DotLine));
}
else
{
// Set the coloring of the area selector for zooming.
zoomer->setRubberBandPen(QPen(Qt::red, 3.0f, Qt::DotLine));
zoomer->setTrackerPen(QPen(Qt::red));
// Set canvas background
setCanvasBackground(QColor(0, 0, 0));
// Configure the plot grid.
grid->setMinPen(QPen(QColor(0xAA, 0xAA, 0xAA), 0.8f, Qt::DotLine));
grid->setMajPen(QPen(QColor(0xDD, 0xDD, 0xDD), 0.8f, Qt::DotLine));
}
// And finally refresh the widget to make sure all color changes are redrawn.
replot();
}
#ifndef CHARTPLOT_H
#define CHARTPLOT_H
#include <qwt_plot.h>
#include <qwt_plot_grid.h>
#include "MainWindow.h"
#include "ScrollZoomer.h"
class ChartPlot : public QwtPlot
{
Q_OBJECT
public:
ChartPlot(QWidget *parent = NULL);
virtual ~ChartPlot();
/** @brief Get next color of color map */
QColor getNextColor();
/** @brief Get color for curve id */
QColor getColorForCurve(QString id);
/** @brief Reset color map */
void shuffleColors();
protected:
const static int numBaseColors;
QList<QColor> colors; ///< Colormap for curves
int nextColor; ///< Next index in color map
QMap<QString, QwtPlotCurve* > curves; ///< Plot curves
ScrollZoomer* zoomer; ///< Zoomer class for widget
QwtPlotGrid* grid; ///< Plot grid
protected slots:
/** @brief Generate coloring for this plot canvas based on current window theme */
void applyColorScheme(MainWindow::QGC_MAINWINDOW_STYLE style);
};
#endif // CHARTPLOT_H
......@@ -84,7 +84,7 @@ const double* CurveData::y() const
}
IncrementalPlot::IncrementalPlot(QWidget *parent):
QwtPlot(parent),
ChartPlot(parent),
symbolWidth(1.2f),
curveWidth(1.0f),
gridWidth(0.8f),
......@@ -92,11 +92,7 @@ IncrementalPlot::IncrementalPlot(QWidget *parent):
symmetric(false)
{
setAutoReplot(false);
setFrameStyle(QFrame::NoFrame);
setLineWidth(0);
setStyleText("solid crosses");
setCanvasLineWidth(2);
plotLayout()->setAlignCanvasToScales(true);
......@@ -112,40 +108,8 @@ IncrementalPlot::IncrementalPlot(QWidget *parent):
resetScaling();
// enable zooming
zoomer = new ScrollZoomer(canvas());
zoomer->setRubberBandPen(QPen(Qt::red, 1.5f, Qt::DotLine));
zoomer->setTrackerPen(QPen(Qt::red));
//zoomer->setZoomBase(QwtDoubleRect());
legend = NULL;
colors = QList<QColor>();
nextColor = 0;
///> Color map for plots, includes 20 colors
///> Map will start from beginning when the first 20 colors are exceeded
colors.append(QColor(242,255,128));
colors.append(QColor(70,80,242));
colors.append(QColor(232,33,47));
colors.append(QColor(116,251,110));
colors.append(QColor(81,183,244));
colors.append(QColor(234,38,107));
colors.append(QColor(92,247,217));
colors.append(QColor(151,59,239));
colors.append(QColor(231,72,28));
colors.append(QColor(236,48,221));
colors.append(QColor(75,133,243));
colors.append(QColor(203,254,121));
colors.append(QColor(104,64,240));
colors.append(QColor(200,54,238));
colors.append(QColor(104,250,138));
colors.append(QColor(235,43,165));
colors.append(QColor(98,248,176));
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)));
}
......@@ -202,7 +166,7 @@ void IncrementalPlot::showLegend(bool show)
*/
void IncrementalPlot::setStyleText(QString style)
{
foreach (QwtPlotCurve* curve, d_curve) {
foreach (QwtPlotCurve* curve, curves) {
// Style of datapoints
if (style.toLower().contains("circles")) {
curve->setSymbol(QwtSymbol(QwtSymbol::Ellipse,
......@@ -308,9 +272,9 @@ void IncrementalPlot::appendData(QString key, double *x, double *y, int size)
data = d_data.value(key);
}
if (!d_curve.contains(key)) {
if (!curves.contains(key)) {
curve = new QwtPlotCurve(key);
d_curve.insert(key, curve);
curves.insert(key, curve);
curve->setStyle(QwtPlotCurve::NoCurve);
curve->setPaintAttribute(QwtPlotCurve::PaintFiltered);
......@@ -320,7 +284,7 @@ void IncrementalPlot::appendData(QString key, double *x, double *y, int size)
curve->attach(this);
} else {
curve = d_curve.value(key);
curve = curves.value(key);
}
data->append(x, y, size);
......@@ -374,7 +338,7 @@ void IncrementalPlot::appendData(QString key, double *x, double *y, int size)
canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
// FIXME Check if here all curves should be drawn
// QwtPlotCurve* plotCurve;
// foreach(plotCurve, d_curve)
// foreach(plotCurve, curves)
// {
// plotCurve->draw(0, curve->dataSize()-1);
// }
......@@ -421,30 +385,12 @@ bool IncrementalPlot::gridEnabled()
return grid->isVisible();
}
QList<QColor> IncrementalPlot::getColorMap()
{
return colors;
}
QColor IncrementalPlot::getNextColor()
{
/* Return current color and increment counter for next round */
nextColor++;
if(nextColor >= colors.count()) nextColor = 0;
return colors[nextColor++];
}
QColor IncrementalPlot::getColorForCurve(QString id)
{
return d_curve.value(id)->pen().color();
}
void IncrementalPlot::removeData()
{
foreach (QwtPlotCurve* curve, d_curve) {
foreach (QwtPlotCurve* curve, curves) {
delete curve;
}
d_curve.clear();
curves.clear();
foreach (CurveData* data, d_data) {
delete data;
......
......@@ -35,9 +35,8 @@ This file is part of the QGROUNDCONTROL project
#include <qwt_array.h>
#include <qwt_plot.h>
#include <qwt_legend.h>
#include <qwt_plot_grid.h>
#include <QMap>
#include "ScrollZoomer.h"
#include "ChartPlot.h"
class QwtPlotCurve;
......@@ -73,7 +72,7 @@ private:
* 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
class IncrementalPlot : public ChartPlot
{
Q_OBJECT
public:
......@@ -81,15 +80,6 @@ public:
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();
......@@ -135,11 +125,7 @@ protected slots:
protected:
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
......@@ -148,7 +134,6 @@ protected:
private:
QMap<QString, CurveData* > d_data; ///< Data points
QMap<QString, QwtPlotCurve* > d_curve; ///< Plot curves
};
#endif /* INCREMENTALPLOT_H */
......@@ -22,6 +22,7 @@
#include <LinechartPlot.h>
#include <MG.h>
#include <QPaintEngine>
#include "ChartPlot.h"
#include "QGC.h"
......@@ -31,7 +32,8 @@
* @param parent The parent widget
* @param interval The maximum interval for which data is stored (default: 30 minutes) in milliseconds
**/
LinechartPlot::LinechartPlot(QWidget *parent, int plotid, quint64 interval): QwtPlot(parent),
LinechartPlot::LinechartPlot(QWidget *parent, int plotid, quint64 interval):
ChartPlot(parent),
minTime(0),
lastTime(0),
maxTime(100),
......@@ -59,33 +61,6 @@ LinechartPlot::LinechartPlot(QWidget *parent, int plotid, quint64 interval): Qwt
yScaleEngine = new QwtLinearScaleEngine();
setAxisScaleEngine(QwtPlot::yLeft, yScaleEngine);
/* Create color map */
colors = QList<QColor>();
nextColor = 0;
///> Color map for plots, includes 20 colors
///> Map will start from beginning when the first 20 colors are exceeded
colors.append(QColor(242,255,128));
colors.append(QColor(70,80,242));
colors.append(QColor(232,33,47));
colors.append(QColor(116,251,110));
colors.append(QColor(81,183,244));
colors.append(QColor(234,38,107));
colors.append(QColor(92,247,217));
colors.append(QColor(151,59,239));
colors.append(QColor(231,72,28));
colors.append(QColor(236,48,221));
colors.append(QColor(75,133,243));
colors.append(QColor(203,254,121));
colors.append(QColor(104,64,240));
colors.append(QColor(200,54,238));
colors.append(QColor(104,250,138));
colors.append(QColor(235,43,165));
colors.append(QColor(98,248,176));
colors.append(QColor(161,252,116));
colors.append(QColor(87,231,246));
colors.append(QColor(230,126,23));
setAutoReplot(false);
// Set grid
......@@ -397,19 +372,6 @@ void LinechartPlot::addCurve(QString id)
emit curveAdded(id);
}
QColor LinechartPlot::getNextColor()
{
/* Return current color and increment counter for next round */
nextColor++;
if(nextColor >= colors.count()) nextColor = 0;
return colors[nextColor++];
}
QColor LinechartPlot::getColorForCurve(QString id)
{
return curves.value(id)->pen().color();
}
/**
* @brief Set the time window for the plot
* The time window defines which data is shown in the plot.
......
......@@ -47,7 +47,7 @@ This file is part of the PIXHAWK project
#include <qwt_scale_engine.h>
#include <qwt_array.h>
#include <qwt_plot.h>
#include <ScrollZoomer.h>
#include "ChartPlot.h"
#include "MG.h"
class TimeScaleDraw: public QwtScaleDraw
......@@ -63,36 +63,6 @@ public:
};
/**
* @brief Zoomer for plot
*/
class Zoomer: public ScrollZoomer
{
public:
Zoomer(QwtPlotCanvas *canvas) : ScrollZoomer(canvas) {}
virtual void rescale() {
QwtScaleWidget *scaleWidget = plot()->axisWidget(yAxis());
QwtScaleDraw *sd = scaleWidget->scaleDraw();
int minExtent = 0;
if ( zoomRectIndex() > 0 ) {
// When scrolling in vertical direction
// the plot is jumping in horizontal direction
// because of the different widths of the labels
// So we better use a fixed extent.
minExtent = sd->spacing() + sd->majTickLength() + 1;
minExtent += sd->labelSize(scaleWidget->font(), 1000).width();
}
sd->setMinimumExtent(minExtent);
ScrollZoomer::rescale();
}
};
/**
* @brief Data container
......@@ -181,7 +151,7 @@ private:
/**
* @brief Time series plot
**/
class LinechartPlot : public QwtPlot
class LinechartPlot : public ChartPlot
{
Q_OBJECT
public:
......@@ -269,29 +239,10 @@ public slots:
void setAverageWindow(int windowSize);
void removeTimedOutCurves();
/** @brief Reset color map */
void shuffleColors()
{
foreach (QwtPlotCurve* curve, curves)
{
QPen pen(curve->pen());
pen.setColor(getNextColor());
curve->setPen(pen);
}
}
public:
QColor getColorForCurve(QString id);
protected:
QMap<QString, QwtPlotCurve*> curves;
QMap<QString, TimeSeriesData*> data;
QMap<QString, QwtScaleMap*> scaleMaps;
QMap<QString, quint64> lastUpdate;
ScrollZoomer* zoomer;
QList<QColor> colors;
int nextColor;
//static const quint64 MAX_STORAGE_INTERVAL = Q_UINT64_C(300000);
static const quint64 MAX_STORAGE_INTERVAL = Q_UINT64_C(0); ///< The maximum interval which is stored
......@@ -325,7 +276,6 @@ protected:
// Methods
void addCurve(QString id);
QColor getNextColor();
void showEvent(QShowEvent* event);
void hideEvent(QHideEvent* event);
......
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