Skip to content
Snippets Groups Projects
Commit 58e30039 authored by Mirko Wächter's avatar Mirko Wächter
Browse files

Merge branch 'barchart' into 'master'

Barchart add-on for plotter gui-plugin

The plotter now has a dropdown menu to change the visualization style from curves to bars. 
The bars are dynamically scaled and added and receive the data in the same time as the curves.
The colors of bars and curves match.
Adding more styles in the future is easily possible due to stacked layout and singular distribution of data.

See merge request !3
parents 405c5820 c102db37
No related branches found
No related tags found
No related merge requests found
......@@ -35,12 +35,16 @@
#include <qwt_legend.h>
#include <qwt_legend_item.h>
#include <qwt_series_data.h>
#include <qwt_thermo.h>
#include <qwt_scale_draw.h>
//QT
#include <QTimer>
#include <QTime>
#include <QSettings>
#include <QDir>
#include <QStackedLayout>
#include <QTextEdit>
#include <boost/date_time/posix_time/posix_time.hpp>
......@@ -65,7 +69,8 @@ namespace armarx
setTag("Plotter");
ui.setupUi(getWidget());
timer = new QTimer(getWidget());
//bars = new std::vector<QwtThermo*>();
barlayout = new QHBoxLayout;
////////////////
// Setup Plotter
///////////////
......@@ -89,6 +94,17 @@ namespace armarx
dialog = new ArmarXPlotterDialog(getWidget(), NULL);
loggingDir = (QDir::currentPath());
dialog->ui.editLoggingDirectory->setText(loggingDir);
graphStyle = ui.CBgraphStyle->currentIndex();
stackedLayout = new QStackedLayout(ui.verticalLayout);
stackedLayout->addWidget(ui.qwtPlot);
QWidget* barsWidget = new QWidget(getWidget());
barsWidget->setLayout(barlayout);
barsWidget->setAccessibleName("barsWidget");
stackedLayout->addWidget(barsWidget);
getWidget()->setLayout(stackedLayout);
}
ArmarXPlotter::~ArmarXPlotter()
......@@ -126,6 +142,8 @@ namespace armarx
connect(ui.btnLogToFile, SIGNAL(toggled(bool)), this, SLOT(toggleLogging(bool)));
connect(ui.CBgraphStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(onGraphStyleChanged(int)));
if (!QMetaObject::invokeMethod(this, "setupCurves"))
{
ARMARX_WARNING << "Failed to invoke enable";
......@@ -189,6 +207,7 @@ namespace armarx
ui.btnLogToFile->setChecked(false);
curves.clear();
ui.qwtPlot->detachItems();
clearBarList();
}
setupCurves();
......@@ -215,7 +234,7 @@ namespace armarx
{
logstream << "Timestamp";
for (auto& channel : selectedChannels)
for (auto & channel : selectedChannels)
{
logstream << "," << channel.toStdString();
}
......@@ -229,6 +248,31 @@ namespace armarx
}
}
void ArmarXPlotter::onGraphStyleChanged(int idx)
{
if (graphStyle != idx)
{
graphStyle = idx;
stackedLayout->setCurrentIndex(graphStyle);
switch (idx)
{
case 0: //curves can have various scalings
ui.BTNAutoScale->setDisabled(false);
break;
case 1: //bar chart only autoscale possible
ui.BTNAutoScale->setDisabled(true);
break;
default:
break;
}
}
}
void ArmarXPlotter::pollingExec()
{
ScopedLock lock(dataMutex);
......@@ -341,11 +385,18 @@ namespace armarx
QwtSeriesData<QPointF>* pointSeries = new QwtPointSeriesData(pointList);
if (curves.find(it->first) != curves.end())
if (curves.find(it->first) != curves.end() && bars.find(it->first) != bars.end())
{
QwtPlotCurve* curve = curves[it->first];
curve->setData(pointSeries);
QwtThermo* bar = bars[it->first];
bar->setValue(pointList.first().y());
bar->setRange(curve->minYValue(), (curve->maxYValue())); //this autoscales the graph
}
}
......@@ -383,7 +434,6 @@ namespace armarx
ui.qwtPlot->setAxisAutoScale(QwtPlot::yLeft, toggled);
ui.qwtPlot->replot();
}
void ArmarXPlotter::plottingPaused(bool toggled)
......@@ -445,11 +495,42 @@ namespace armarx
return curve;
}
QwtThermo* ArmarXPlotter::createBar(const QString& label)
{
//creates a widget containing a bar chart and a label
//with the fill color of chart same as its curve
QwtThermo* bar = new QwtThermo(getWidget());
bar->setAccessibleName(label);
bar->setFillBrush(QBrush(QColor(Qt::GlobalColor((bars.size() + 7) % 15))));
bar->setStyleSheet("* { background-color: rgb(240, 240, 240); }"); //neccessary because white is a picked fill color
QTextEdit* lab = new QTextEdit(label, getWidget());
lab->setStyleSheet("* { background-color: rgb(240, 240, 240); }");
lab->setLineWrapMode(QTextEdit::WidgetWidth);
lab->setTextInteractionFlags(0);
lab->setFrameStyle(0);
int linecount = lab->document()->blockCount();
lab->setMaximumHeight(70 * linecount);
lab->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(bar);
layout->addWidget(lab);
QWidget* widget = new QWidget(layout->widget());
widget->setLayout(layout);
barlayout->addWidget(widget);
return bar;
}
void ArmarXPlotter::setupCurves()
{
{
ScopedLock lock(dataMutex);
for (int i = 0; i < selectedChannels.size(); i++)
{
ARMARX_VERBOSE << "Channel: " << selectedChannels.at(i).toStdString() << flush;
......@@ -462,6 +543,11 @@ namespace armarx
{
QwtPlotCurve* curve = createCurve(selectedChannels.at(i));
curves[selectedChannels.at(i).toStdString()] = curve;
QwtThermo* bar = createBar(selectedChannels.at(i));
bars[selectedChannels.at(i).toStdString()] = bar;
}
else
{
......@@ -481,12 +567,16 @@ namespace armarx
ARMARX_INFO << key << ": " << *VariantPtr::dynamicCast(e.second);
QwtPlotCurve* curve = createCurve(QString::fromStdString(key));
curves[key] = curve;
QwtThermo* bar = createBar(QString::fromStdString(key));
bars[key] = bar;
}
}
}
}
ui.qwtPlot->replot();
}
timer->start(updateInterval);
......@@ -499,6 +589,23 @@ namespace armarx
pollingTask->start();
}
void ArmarXPlotter::clearBarList()
{
//maybe comparing new and old selected list better than doing a new one every time?
QLayoutItem* child;
int containedItems = barlayout->count() - 1;
for (int i = containedItems; i >= 0 ; i--) //must be done in this order due to internal implementation of layout item numbering
{
child = barlayout->itemAt(i);
barlayout->removeItem(child);
delete(child->widget());
}
bars.clear();
}
std::map<string, VariantPtr> ArmarXPlotter::getData(const QStringList& channels, GraphDataMap& dataMaptoAppend)
{
map< std::string, DataFieldIdentifierBaseList > channelsSplittedByObserver;
......@@ -591,7 +698,7 @@ namespace armarx
// ARMARX_IMPORTANT << id;
auto dict = JSONObject::ConvertToBasicVariantMap(json, var);
for (const auto& e : dict)
for (const auto & e : dict)
{
std::string key = id + "." + e.first;
// ARMARX_INFO << key << ": " << *VariantPtr::dynamicCast(e.second);
......@@ -631,7 +738,7 @@ namespace armarx
{
logstream << (time - logStartTime).toMilliSecondsDouble();
for (const auto& elem : dataMaptoAppend)
for (const auto & elem : dataMaptoAppend)
{
logstream << "," /*<< elem.first << ","*/ << elem.second->getOutputValueOnly();
}
......@@ -641,4 +748,5 @@ namespace armarx
}
}
......@@ -48,6 +48,8 @@
//forward declarations
class QwtPlotCurve;
class QwtThermo;
class QStackedLayout;
namespace armarx
{
......@@ -72,7 +74,7 @@ namespace armarx
*/
class ARMARXCOMPONENT_IMPORT_EXPORT
ArmarXPlotter:
public ArmarXComponentWidgetController
public ArmarXComponentWidgetController
{
Q_OBJECT
public:
......@@ -118,6 +120,7 @@ namespace armarx
*/
void onCloseWidget(QCloseEvent* event);
QwtPlotCurve* createCurve(const QString& label);
QwtThermo* createBar(const QString& label);
signals:
public slots:
......@@ -129,6 +132,7 @@ namespace armarx
void plottingPaused(bool toggled);
void configDone();
void toggleLogging(bool toggled);
void onGraphStyleChanged(int idx);
private slots:
void setupCurves();
......@@ -152,6 +156,13 @@ namespace armarx
int pollingInterval;
std::ofstream logstream;
IceUtil::Time logStartTime;
int graphStyle;
QStackedLayout* stackedLayout;
QHBoxLayout* barlayout;
std::map<std::string, QwtThermo*> bars;
void clearBarList();
};
}
......
......@@ -32,16 +32,7 @@
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>3</number>
</property>
<item>
......@@ -111,6 +102,20 @@
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="CBgraphStyle">
<item>
<property name="text">
<string>Curve</string>
</property>
</item>
<item>
<property name="text">
<string>Bar chart</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
......@@ -132,7 +137,7 @@
<customwidget>
<class>QwtPlot</class>
<extends>QFrame</extends>
<header location="global">qwt/qwt_plot.h</header>
<header>qwt_plot.h</header>
<container>1</container>
</customwidget>
</customwidgets>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment