StaticPlotterWidgetController.cpp
Go to the documentation of this file.
2
3#include <QStackedLayout>
4
6#pragma GCC diagnostic push
7#pragma GCC diagnostic ignored "-Wpedantic"
8#include <qwt_legend.h>
9#include <qwt_legend_label.h>
10#include <qwt_plot_canvas.h>
11#include <qwt_plot_magnifier.h>
12#include <qwt_plot_panner.h>
13#include <qwt_series_data.h>
14#pragma GCC diagnostic pop
15#include <QToolBar>
16
17namespace armarx
18{
19
21
22 {
23 ui.setupUi(getWidget());
24 plotter = new QwtPlot(ui.plotWidget);
25 QStackedLayout* stackedLayout = new QStackedLayout(ui.plotWidget);
26 stackedLayout->addWidget(plotter);
27 ////////////////
28 // Setup Plotter
29 ///////////////
30 // panning with the left mouse button
31 (void)new QwtPlotPanner(plotter->canvas());
32
33 // zoom in/out with the wheel
34 /*QwtPlotMagnifier* magnifier = */ new QwtPlotMagnifier(plotter->canvas());
35
36 // plotter->canvas()->setPaintAttribute(QwtPlotCanvas::BackingStore, false); //increases performance for incremental drawing
37
38 QwtLegend* legend = new QwtLegend;
39 legend->setDefaultItemMode(QwtLegendData::Mode::Checkable);
40 plotter->insertLegend(legend, QwtPlot::BottomLegend);
41
42
43 plotter->setAxisTitle(QwtPlot::xBottom, "Time (in sec)");
44 plotter->enableAxis(QwtPlot::yLeft, true);
45
46 // plotter->enableAxis(QwtPlot::yRight, true);
47 plotter->setAxisAutoScale(QwtPlot::yLeft, true);
48 plotter->setAxisAutoScale(QwtPlot::xBottom, true);
49 plotter->setAutoReplot();
50
51 // plotter->setCanvasBackground(* new QBrush(Qt::white));
52
53 connect(plotter,
54 SIGNAL(legendChecked(QwtPlotItem*, bool)),
55 SLOT(showCurve(QwtPlotItem*, bool)));
56
57 connect(this, SIGNAL(plotAdded(QString)), this, SLOT(addToPlotList(QString)));
58
59 connect(ui.listWidgetPlots,
60 SIGNAL(currentTextChanged(QString)),
61 this,
62 SLOT(changePlot(QString)));
63
64 // connect(&timer, SIGNAL(timeout()), this, SLOT(updateGraph()));
65 // stackedLayout = new QStackedLayout(widget);
66 // stackedLayout->addWidget(plotter);
67 }
68
69 void
71 {
72 usingTopic("StaticPlotter");
73 // offeringTopic("StaticPlotter");
74 }
75
76 void
78 {
79 // topicPrx = getTopic<StaticPlotterInterfacePrx>("StaticPlotter");
80 // task = new SimpleRunningTask<>([&]
81 // {
82 // sleep(1);
83 // ARMARX_INFO << "Sending";
84
85 // Vector2fSeq data {{1, 0},
86 // {200, 300},
87 // {300, 100}
88 // };
89 // Vector2fSeq data2 {{1, 0},
90 // {200, 500},
91 // {340, 600}
92 // };
93 // topicPrx->addPlot("TestCurve", {{"curve", data}, {"curve2", data2}});
94 // topicPrx->addPlotWithTimestampVector("TestCurve2", {0, 1, 2}, {{"curve", {1, 45, 8}}});
95 // });
96 // task->start();
97 }
98
99 void
101 {
102 item->setVisible(on);
103 QwtLegend* lgd = qobject_cast<QwtLegend*>(plotter->legend());
104
105 QList<QWidget*> legendWidgets = lgd->legendWidgets(plotter->itemToInfo(item));
106
107 if (legendWidgets.size() == 1)
108 {
109 QwtLegendLabel* legendLabel = qobject_cast<QwtLegendLabel*>(legendWidgets[0]);
110
111 if (legendLabel)
112 {
113 legendLabel->setChecked(on);
114 }
115 }
116 plotter->replot();
117 }
118
119 void
121 {
122 ui.listWidgetPlots->clear();
123 plotter->detachItems();
124 plotter->replot();
125 std::unique_lock lock(dataMutex);
126 plotsMap.clear();
127 }
128
129 void
131 {
132 if (ui.listWidgetPlots->findItems(plotName, Qt::MatchExactly).isEmpty())
133 {
134 ui.listWidgetPlots->addItem(plotName);
135 }
136 else if (ui.listWidgetPlots->currentItem() != NULL &&
137 ui.listWidgetPlots->currentItem()->text() == plotName)
138 {
139 changePlot(plotName);
140 }
141 }
142
143 void
145 {
146 if (plotName.isEmpty())
147 {
148 return;
149 }
150 std::unique_lock lock(dataMutex);
151 auto it = plotsMap.find(plotName);
152 if (it == plotsMap.end())
153 {
154 ARMARX_INFO << "Did not find plot with name " << plotName;
155 return;
156 }
157 ARMARX_INFO << "Changing plot";
158 plotter->detachItems();
159 int i = 0;
160 for (auto& elem : it->second)
161 {
162 Vector2fSeq points = elem.second;
163 QVector<QPointF> pointList;
164 pointList.reserve(points.size());
165
166 for (Vector2f& point : points)
167 {
168 pointList.push_back({point.e0, point.e1});
169 }
170 QwtSeriesData<QPointF>* pointSeries = new QwtPointSeriesData(pointList);
171 QwtPlotCurve* curve = createCurve(QString::fromStdString(elem.first),
172 QColor(Qt::GlobalColor(i % 15 + 7)));
173 curve->setData(pointSeries);
174 curve->attach(plotter);
175 showCurve(curve, true);
176 i++;
177 }
178 plotter->replot();
179 }
180
181 void
183 {
184 }
185
186 void
188 {
189 }
190
191 void
192 StaticPlotterWidgetController::addPlot(const std::string& plotName,
193 const StringVector2fSeqDict& plotsData,
194 const Ice::Current&)
195 {
196 ARMARX_CHECK_EXPRESSION(!plotName.empty());
197 ARMARX_CHECK_EXPRESSION(!plotsData.empty());
198 QString qplotName = QString::fromStdString(plotName);
199 {
200 std::unique_lock lock(dataMutex);
201 plotsMap[qplotName] = plotsData;
202 }
203 emit plotAdded(qplotName);
204 }
205
206 void
208 const Ice::FloatSeq& timestamps,
209 const StringFloatSeqDict& plotsData,
210 const Ice::Current& c)
211 {
212 StringVector2fSeqDict plotsDataMap;
213 for (auto& elem : plotsData)
214 {
215 Vector2fSeq data;
216 ARMARX_CHECK_EQUAL(timestamps.size(), elem.second.size());
217 for (size_t i = 0; i < timestamps.size(); ++i)
218 {
219 data.push_back({timestamps.at(i), elem.second.at(i)});
220 }
221 plotsDataMap[elem.first] = data;
222 }
223 addPlot(plotName, plotsDataMap, c);
224 }
225
226 QwtPlotCurve*
227 StaticPlotterWidgetController::createCurve(const QString& label, QColor color)
228 {
229 QwtPlotCurve* curve = new QwtPlotCurve(label);
230 curve->setRenderHint(QwtPlotItem::RenderAntialiased);
231 curve->setPen(color);
232 curve->setStyle(QwtPlotCurve::Lines);
233 curve->setPaintAttribute(QwtPlotCurve::ClipPolygons, true);
234
235 // showCurve(curve, true);
236 return curve;
237 }
238
239 QPointer<QWidget>
241 {
242 if (customToolbar)
243 {
244 if (parent != customToolbar->parent())
245 {
246 customToolbar->setParent(parent);
247 }
248
249 return customToolbar;
250 }
251
252 customToolbar = new QToolBar(parent);
253 customToolbar->setIconSize(QSize(16, 16));
254 customToolbar->addAction(
255 QIcon(":/icons/Trash.svg"), "Delete Plots", this, SLOT(clearPlots()));
256
257 return customToolbar;
258 }
259
260} // namespace armarx
constexpr T c
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
void onInitComponent() override
Pure virtual hook for the subclass.
QPointer< QWidget > getCustomTitlebarWidget(QWidget *parent) override
getTitleToolbar returns a pointer to the a toolbar widget of this controller.
void loadSettings(QSettings *settings) override
Implement to load the settings that are part of the GUI configuration.
void saveSettings(QSettings *settings) override
Implement to save the settings as part of the GUI configuration.
void addPlot(const std::string &plotName, const StringVector2fSeqDict &plotsData, const Ice::Current &) override
void plotAdded(QString plotName)
void onConnectComponent() override
Pure virtual hook for the subclass.
void addPlotWithTimestampVector(const std::string &plotName, const Ice::FloatSeq &timestamps, const StringFloatSeqDict &plotsData, const Ice::Current &) override
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
This file offers overloads of toIce() and fromIce() functions for STL container types.