plotmatrix.cpp
Go to the documentation of this file.
1 #include <qlayout.h>
2 #include <qpen.h>
3 #include <QSettings>
4 #include "qwt_plot.h"
5 #include "qwt_plot_canvas.h"
6 #include "qwt_scale_widget.h"
7 #include "qwt_scale_draw.h"
8 #include "plotmatrix.h"
9 #include "customtracker.h"
10 
11 static int widget_uid = 0;
12 
13 PlotMatrix::PlotMatrix(QString name, PlotDataMapRef &datamap, QWidget *parent ):
14  QFrame( parent ),
15  _mapped_data(datamap),
16  _name(name)
17 {
18  _num_rows = 0;
19  _num_cols = 0;
20  _layout = new QGridLayout( this );
21  _horizontal_link = true;
22  QSettings settings;
23 
24  _legend_point_size = settings.value("PlotMatrix/legend_point_size", 9).toInt();
25  updateLayout();
26 }
27 
28 
29 PlotWidget* PlotMatrix::addPlotWidget(unsigned row, unsigned col)
30 {
31  PlotWidget *plot = new PlotWidget( _mapped_data, this );
32 
33  plot->setWindowTitle(QString("PlotWidget ") + QString::number(widget_uid++));
34 
35  connect( plot, &PlotWidget::rectChanged,
37 
38  connect( plot, &PlotWidget::legendSizeChanged,
40 
42 
43  plot->setAttribute(Qt::WA_DeleteOnClose);
44 
45  _layout->addWidget( plot, row, col );
46  _layout->setRowStretch(row,1);
47  _layout->setColumnStretch(col,1);
48 
49  emit plotAdded(plot);
50 
51  return plot;
52 }
53 
55 {
56  if( _num_rows==0 && _num_cols==0 )
57  {
58  addPlotWidget( 0, 0 );
59  _num_rows = 1;
60  _num_cols = 1;
61  }
62  else{
63  for ( unsigned col = 0; col < colsCount(); col++ ) {
64  addPlotWidget( _num_rows, col );
65  }
66  _num_rows++;
67  }
68 
69  updateLayout();
70 }
71 
73 {
74  if( _num_rows==0 && _num_cols==0 )
75  {
76  addPlotWidget( 0, 0 );
77  _num_rows = 1;
78  _num_cols = 1;
79  }
80  else {
81  for ( unsigned row = 0; row < rowsCount(); row++ )
82  {
83  addPlotWidget( row, _num_cols );
84  }
85  _num_cols++;
86  }
87  updateLayout();
88 }
89 
90 void PlotMatrix::swapPlots( unsigned rowA, unsigned colA, unsigned rowB, unsigned colB)
91 {
92  QWidget *widgetA = _layout->itemAtPosition(rowA, colA)->widget();
93  QWidget *widgetB = _layout->itemAtPosition(rowB, colB)->widget();
94 
95  _layout->removeItem( _layout->itemAtPosition(rowA, colA) );
96  _layout->removeItem( _layout->itemAtPosition(rowB, colB) );
97 
98  _layout->addWidget(widgetA, rowB, colB);
99  _layout->addWidget(widgetB, rowA, colA);
100  updateLayout();
101 }
102 
103 void PlotMatrix::removeColumn(unsigned column_to_delete)
104 {
105  if(_num_rows==1 && _num_cols ==1 ) {
106  return;
107  }
108 
109  for(unsigned col = column_to_delete; col< _num_cols-1; col++)
110  {
111  for(unsigned row=0; row< _num_rows; row++)
112  {
113  this->swapPlots( row, col, row, col+1);
114  }
115  }
116  for(unsigned row=0; row< _num_rows; row++)
117  {
118  plotAt( row, _num_cols -1)->close();
119  }
120  _layout->setColumnStretch(_num_cols -1,0);
121 
122  _num_cols--;
123  if( _num_cols == 0){
124  _num_rows = 0;
125  }
126 
127  updateLayout();
128 
129 }
130 
131 void PlotMatrix::removeRow(unsigned row_to_delete)
132 {
133  if(_num_rows==1 && _num_cols ==1 ) {
134  return;
135  }
136  for(unsigned row = row_to_delete; row< _num_rows-1; row++)
137  {
138  for(unsigned col = 0; col< _num_cols; col++)
139  {
140  this->swapPlots( row, col, row+1, col);
141  }
142  }
143  for(unsigned col=0; col< _num_cols; col++)
144  {
145  plotAt( _num_rows-1, col)->close();
146  }
147  _layout->setRowStretch(_num_rows -1,0);
148 
149  _num_rows--;
150  if( _num_rows == 0){
151  _num_cols = 0;
152  }
153 
154  updateLayout();
155 }
156 
158 {
159  for( unsigned row = 0; row< rowsCount(); row++)
160  {
161  while( rowsCount() > 1 &&
162  isRowEmpty( row ) &&
163  row < rowsCount() )
164  {
165  removeRow( row );
166  }
167  }
168 
169  for( unsigned col = 0; col< colsCount(); col++)
170  {
171  while( colsCount() > 1 &&
172  isColumnEmpty( col ) &&
173  col < colsCount() )
174  {
175  removeColumn( col );
176  }
177  }
178 }
179 
180 
182 
183 unsigned PlotMatrix::rowsCount() const
184 {
185  return _num_rows;
186 }
187 
188 unsigned PlotMatrix::colsCount() const
189 {
190  return _num_cols;
191 }
192 
193 unsigned PlotMatrix::plotCount() const
194 {
195  return _num_rows*_num_cols;
196 }
197 
198 bool PlotMatrix::isColumnEmpty( unsigned col ) const
199 {
200  for (int r=0; r < _layout->rowCount(); r++)
201  {
202  auto plot = plotAt(r, col);
203  if( plot && ! plot->isEmpty() ) {
204  return false;
205  }
206  }
207  return true;
208 }
209 
210 bool PlotMatrix::isRowEmpty(unsigned row ) const
211 {
212  for (int c=0; c< _layout->columnCount(); c++)
213  {
214  auto plot = plotAt(row, c);
215  if( plot && ! plot->isEmpty() ) {
216  return false;
217  }
218  }
219  return true;
220 }
221 
222 
223 PlotWidget* PlotMatrix::plotAt( unsigned row, unsigned column )
224 {
225  QLayoutItem* item = _layout->itemAtPosition(row,column);
226  if(item) {
227  PlotWidget* plot = static_cast<PlotWidget*>( item->widget() );
228  return plot;
229  }
230  return NULL;
231 }
232 
233 const PlotWidget* PlotMatrix::plotAt( unsigned row, unsigned column ) const
234 {
235  QLayoutItem* item = _layout->itemAtPosition(row,column);
236  if(item) {
237  PlotWidget* plot = static_cast<PlotWidget*>( item->widget() );
238  return plot;
239  }
240  return NULL;
241 }
242 
243 PlotWidget* PlotMatrix::plotAt( unsigned index )
244 {
245  return plotAt(index% rowsCount(), index/rowsCount());
246 }
247 
248 const PlotWidget* PlotMatrix::plotAt( unsigned index ) const
249 {
250  return plotAt(index% rowsCount(), index/rowsCount());
251 }
252 
253 
254 void PlotMatrix::setAxisScale(QwtPlot::Axis axisId, unsigned row, unsigned col,
255  double min, double max, double step )
256 {
257  PlotWidget *plt = plotAt( row, col );
258  if ( plt )
259  {
260  plt->setAxisScale( axisId, min, max, step );
261  plt->updateAxes();
262  }
263 }
264 
265 QDomElement PlotMatrix::xmlSaveState( QDomDocument &doc ) const
266 {
267  QDomElement element = doc.createElement("plotmatrix");
268 
269  element.setAttribute("rows", _num_rows );
270  element.setAttribute("columns", _num_cols );
271 
272  for(unsigned col = 0; col< _num_cols; col++)
273  {
274  for(unsigned row = 0; row< _num_rows; row++)
275  {
276  const PlotWidget* plot = plotAt(row,col);
277  QDomElement child = plot->xmlSaveState(doc);
278 
279  child.setAttribute("row", row);
280  child.setAttribute("col", col);
281 
282  element.appendChild( child );
283  }
284  }
285  return element;
286 }
287 
288 bool PlotMatrix::xmlLoadState( QDomElement &plotmatrix )
289 {
290  if( !plotmatrix.hasAttribute("rows") || !plotmatrix.hasAttribute("columns") )
291  {
292  qWarning() << "No [rows] or [columns] attribute in <plotmatrix> XML file!";
293  return false;
294  }
295  unsigned rows = plotmatrix.attribute("rows").toUInt();
296  unsigned cols = plotmatrix.attribute("columns" ).toUInt();
297 
298  while( rows > _num_rows){ addRow(); }
299  while( rows < _num_rows){ removeRow( _num_rows-1 ); }
300 
301  while( cols > _num_cols){ addColumn(); }
302  while( cols < _num_cols){ removeColumn( _num_cols-1 ); }
303 
304  QDomElement plot_element;
305  for ( plot_element = plotmatrix.firstChildElement( "plot" ) ;
306  !plot_element.isNull();
307  plot_element = plot_element.nextSiblingElement( "plot" ) )
308  {
309  if( !plot_element.hasAttribute("row") || !plot_element.hasAttribute("col") )
310  {
311  qWarning() << "No [row] or [col] attribute in <plot> XML file!";
312  return false;
313  }
314  unsigned row = plot_element.attribute("row").toUInt();
315  unsigned col = plot_element.attribute("col").toUInt();
316 
317  bool success = plotAt(row,col)->xmlLoadState( plot_element ) ;
318  if( !success )
319  {
320  return false;
321  }
322  }
323  return true;
324 }
325 
326 
327 
329 {
330  for ( unsigned row = 0; row < rowsCount(); row++ )
331  {
332  alignAxes( row, QwtPlot::xBottom );
334  }
335 
336  for ( unsigned col = 0; col < colsCount(); col++ )
337  {
338  alignAxes( col, QwtPlot::yLeft );
340  }
341 }
342 
344 {
345  for ( unsigned i = 0; i< plotCount(); i++ )
346  {
347  PlotWidget *plot = plotAt(i);
348  plot->replot();
349  }
350 }
351 
352 
354 {
355  _horizontal_link = linked;
356 }
357 
358 
359 void PlotMatrix::setName(const QString &new_name)
360 {
361  _name = new_name;
362 }
363 
364 const QString &PlotMatrix::name() const
365 {
366  return _name;
367 }
368 
370 {
371  return _layout;
372 }
373 
375 {
376  for ( unsigned i = 0; i< plotCount(); i++ )
377  {
378  PlotWidget *plot = plotAt(i);
379  if( plot->isEmpty() == false)
380  {
381  plot->on_zoomOutHorizontal_triggered( false );
382  }
383  }
384  replot();
385 }
386 
388 {
389  for ( unsigned i = 0; i < plotCount(); i++ )
390  {
391  PlotWidget *plot = plotAt(i);
392  if( plot->isEmpty() == false)
393  {
394  plot->on_zoomOutVertical_triggered(false);
395  }
396  }
397  replot();
398 }
399 
401 {
402  for ( unsigned i = 0; i < plotCount(); i++ )
403  {
404  PlotWidget *plot = plotAt(i);
405  if( plot->isEmpty() == false)
406  {
407  plot->zoomOut(false);
408  }
409  }
410  replot();
411 }
412 
413 
414 void PlotMatrix::on_singlePlotScaleChanged(PlotWidget *modified_plot, QRectF new_range)
415 {
416  if( _horizontal_link )
417  {
418  for ( unsigned i = 0; i< plotCount(); i++ )
419  {
420  PlotWidget *plot = plotAt(i);
421  if( plot->isEmpty() == false &&
422  modified_plot != plot &&
423  plot->isXYPlot() == false)
424  {
425  QRectF bound_act = plot->canvasBoundingRect();
426  bound_act.setLeft( new_range.left() );
427  bound_act.setRight( new_range.right() );
428  plot->setZoomRectangle( bound_act, false );
429  plot->on_zoomOutVertical_triggered(false);
430  plot->replot();
431  }
432  }
433  }
434  emit undoableChange();
435 }
436 
438 {
439  _legend_point_size = point_size;
440 
441  QSettings settings;
442  settings.setValue("PlotMatrix/legend_point_size", _legend_point_size);
443 
444  for ( unsigned i = 0; i< plotCount(); i++ )
445  {
446  PlotWidget *plot = plotAt(i);
447  plot->setLegendSize(point_size);
448  }
449 }
450 
451 void PlotMatrix::alignAxes( unsigned rowOrColumn, QwtPlot::Axis axisId )
452 {
453  bool iterating_rows = ( axisId == QwtPlot::yLeft || axisId == QwtPlot::yRight );
454  const int COUNT = iterating_rows ? rowsCount() : colsCount();
455 
456  double maxExtent = 0;
457 
458  for ( unsigned i = 0; i < COUNT; i++ )
459  {
460  QwtPlot *p = iterating_rows? plotAt( i, rowOrColumn ) : plotAt( rowOrColumn, i );
461  if ( p )
462  {
463  QwtScaleWidget *scaleWidget = p->axisWidget( axisId );
464 
465  QwtScaleDraw *sd = scaleWidget->scaleDraw();
466  sd->setMinimumExtent( 0.0 );
467 
468  const double extent = sd->extent( scaleWidget->font() );
469  if ( extent > maxExtent )
470  maxExtent = extent;
471  }
472  }
473 
474  for ( unsigned i = 0; i < COUNT; i++ )
475  {
476  QwtPlot *p = iterating_rows? plotAt( i, rowOrColumn ) : plotAt( rowOrColumn, i );
477  if ( p )
478  {
479  QwtScaleWidget *scaleWidget = p->axisWidget( axisId );
480  scaleWidget->scaleDraw()->setMinimumExtent( maxExtent );
481  }
482  }
483 }
484 
485 void PlotMatrix::alignScaleBorder(unsigned rowOrColumn, QwtPlot::Axis axisId )
486 {
487  if ( axisId == QwtPlot::yLeft || axisId == QwtPlot::yRight )
488  {
489  for ( unsigned col = 0; col < colsCount(); col++ )
490  {
491  QwtPlot *p = plotAt( rowOrColumn, col );
492  if ( p )
493  p->axisWidget( axisId )->setMinBorderDist( 10, 10 );
494  }
495  }
496  else if ( axisId == QwtPlot::xTop || axisId == QwtPlot::xBottom )
497  {
498  for ( unsigned row = 0; row < rowsCount(); row++ )
499  {
500  QwtPlot *p = plotAt( row, rowOrColumn );
501  if ( p )
502  p->axisWidget( axisId )->setMinBorderDist( 15, 15 );
503  }
504  }
505 }
void maximumZoomOutVertical()
Definition: plotmatrix.cpp:387
QGridLayout * gridLayout()
Definition: plotmatrix.cpp:369
void setAxisScale(QwtPlot::Axis axisId, unsigned row, unsigned col, double min, double max, double step=0)
Definition: plotmatrix.cpp:254
X axis above the canvas.
Definition: qwt_plot.h:105
int _legend_point_size
Definition: plotmatrix.h:84
void replot() override
void setLegendSize(int size)
QDomElement xmlSaveState(QDomDocument &doc) const
Definition: plotwidget.cpp:619
bool isColumnEmpty(unsigned row) const
Definition: plotmatrix.cpp:198
virtual double extent(const QFont &) const
void rectChanged(PlotWidget *self, QRectF rect)
bool isXYPlot() const
void legendSizeChanged(int new_size)
QRectF canvasBoundingRect() const
Definition: plotwidget.cpp:821
Y axis right of the canvas.
Definition: qwt_plot.h:99
QDomElement xmlSaveState(QDomDocument &doc) const
Definition: plotmatrix.cpp:265
bool isEmpty() const
Definition: plotwidget.cpp:473
void addRow()
Definition: plotmatrix.cpp:54
A 2-D plotting widget.
Definition: qwt_plot.h:74
const QwtScaleDraw * scaleDraw() const
bool xmlLoadState(QDomElement &plotmatrix_element)
Definition: plotmatrix.cpp:288
void swapPlots(unsigned rowA, unsigned colA, unsigned rowB, unsigned colB)
Definition: plotmatrix.cpp:90
unsigned _num_rows
Definition: plotmatrix.h:77
Y axis left of the canvas.
Definition: qwt_plot.h:96
PlotWidget * plotAt(unsigned row, unsigned column)
Definition: plotmatrix.cpp:223
const QString & name() const
Definition: plotmatrix.cpp:364
const QwtScaleWidget * axisWidget(int axisId) const
unsigned plotCount() const
Definition: plotmatrix.cpp:193
void alignScaleBorder(unsigned rowOrColumn, QwtPlot::Axis axisId)
Definition: plotmatrix.cpp:485
void zoomOut(bool emit_signal)
A Widget which contains a scale.
Axis
Axis index.
Definition: qwt_plot.h:93
QGridLayout * _layout
Definition: plotmatrix.h:76
void removeRow(unsigned row_to_delete)
Definition: plotmatrix.cpp:131
unsigned colsCount() const
Definition: plotmatrix.cpp:188
void setMinBorderDist(int start, int end)
static int widget_uid
Definition: plotmatrix.cpp:11
bool isRowEmpty(unsigned row) const
Definition: plotmatrix.cpp:210
void alignAxes(unsigned rowOrColumn, QwtPlot::Axis axisId)
Definition: plotmatrix.cpp:451
void on_zoomOutVertical_triggered(bool emit_signal=true)
virtual ~PlotMatrix()
Definition: plotmatrix.cpp:181
unsigned rowsCount() const
Definition: plotmatrix.cpp:183
void on_legendSizeChanged(int point_size)
Definition: plotmatrix.cpp:437
bool _horizontal_link
Definition: plotmatrix.h:79
void on_singlePlotScaleChanged(PlotWidget *modified_plot, QRectF range)
Definition: plotmatrix.cpp:414
unsigned _num_cols
Definition: plotmatrix.h:78
void undoableChange()
QString _name
Definition: plotmatrix.h:83
bool xmlLoadState(QDomElement &element)
Definition: plotwidget.cpp:674
void on_zoomOutHorizontal_triggered(bool emit_signal=true)
PlotDataMapRef & _mapped_data
Definition: plotmatrix.h:81
void updateLayout()
Definition: plotmatrix.cpp:328
void plotAdded(PlotWidget *)
void setMinimumExtent(double)
Set a minimum for the extent.
void replot()
Definition: plotmatrix.cpp:343
void removeEmpty()
Definition: plotmatrix.cpp:157
PlotWidget * addPlotWidget(unsigned row, unsigned col)
Definition: plotmatrix.cpp:29
A class for drawing scales.
void setHorizontalLink(bool linked)
Definition: plotmatrix.cpp:353
void setName(const QString &new_name)
Definition: plotmatrix.cpp:359
PlotMatrix(QString name, PlotDataMapRef &datamap, QWidget *parent=nullptr)
Definition: plotmatrix.cpp:13
void setZoomRectangle(QRectF rect, bool emit_signal)
Definition: plotwidget.cpp:949
int i
void addColumn()
Definition: plotmatrix.cpp:72
void removeColumn(unsigned column_to_delete)
Definition: plotmatrix.cpp:103
void setAxisScale(int axisId, double min, double max, double step=0)
Disable autoscaling and specify a fixed scale for a selected axis.
void maximumZoomOut()
Definition: plotmatrix.cpp:400
void updateAxes()
Rebuild the axes scales.
void maximumZoomOutHorizontal()
Definition: plotmatrix.cpp:374
X axis below the canvas.
Definition: qwt_plot.h:102


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:17