plotmatrix.cpp
Go to the documentation of this file.
00001 #include <qlayout.h>
00002 #include <qpen.h>
00003 #include <QSettings>
00004 #include "qwt_plot.h"
00005 #include "qwt_plot_canvas.h"
00006 #include "qwt_scale_widget.h"
00007 #include "qwt_scale_draw.h"
00008 #include "plotmatrix.h"
00009 #include "customtracker.h"
00010 
00011 static int widget_uid = 0;
00012 
00013 PlotMatrix::PlotMatrix(QString name, PlotDataMapRef &datamap, QWidget *parent ):
00014     QFrame( parent ),
00015     _mapped_data(datamap),
00016     _name(name)
00017 {
00018     _num_rows = 0;
00019     _num_cols = 0;
00020     _layout = new QGridLayout( this );
00021     _horizontal_link = true;
00022     QSettings settings;
00023 
00024     _legend_point_size = settings.value("PlotMatrix/legend_point_size", 9).toInt();
00025     updateLayout();
00026 }
00027 
00028 
00029 PlotWidget* PlotMatrix::addPlotWidget(unsigned row, unsigned col)
00030 {
00031     PlotWidget *plot = new PlotWidget( _mapped_data, this );
00032 
00033     plot->setWindowTitle(QString("PlotWidget ") + QString::number(widget_uid++));
00034 
00035     connect( plot, &PlotWidget::rectChanged,
00036              this, &PlotMatrix::on_singlePlotScaleChanged);
00037 
00038     connect( plot, &PlotWidget::legendSizeChanged,
00039              this, &PlotMatrix::on_legendSizeChanged);
00040 
00041     plot->setLegendSize( _legend_point_size );
00042 
00043     plot->setAttribute(Qt::WA_DeleteOnClose);
00044 
00045     _layout->addWidget( plot, row, col );
00046     _layout->setRowStretch(row,1);
00047     _layout->setColumnStretch(col,1);
00048 
00049     emit plotAdded(plot);
00050 
00051     return plot;
00052 }
00053 
00054 void PlotMatrix::addRow()
00055 {
00056     if( _num_rows==0 && _num_cols==0 )
00057     {
00058         addPlotWidget( 0, 0 );
00059         _num_rows = 1;
00060         _num_cols = 1;
00061     }
00062     else{
00063         for ( unsigned col = 0; col < colsCount(); col++ ) {
00064             addPlotWidget( _num_rows, col );
00065         }
00066         _num_rows++;
00067     }
00068 
00069     updateLayout();
00070 }
00071 
00072 void PlotMatrix::addColumn()
00073 {
00074     if( _num_rows==0 && _num_cols==0 )
00075     {
00076         addPlotWidget( 0, 0 );
00077         _num_rows = 1;
00078         _num_cols = 1;
00079     }
00080     else {
00081         for ( unsigned row = 0; row < rowsCount(); row++ )
00082         {
00083             addPlotWidget( row, _num_cols );
00084         }
00085         _num_cols++;
00086     }
00087     updateLayout();
00088 }
00089 
00090 void PlotMatrix::swapPlots( unsigned rowA, unsigned colA, unsigned rowB, unsigned colB)
00091 {
00092     QWidget *widgetA = _layout->itemAtPosition(rowA, colA)->widget();
00093     QWidget *widgetB = _layout->itemAtPosition(rowB, colB)->widget();
00094 
00095     _layout->removeItem( _layout->itemAtPosition(rowA, colA) );
00096     _layout->removeItem( _layout->itemAtPosition(rowB, colB) );
00097 
00098     _layout->addWidget(widgetA, rowB, colB);
00099     _layout->addWidget(widgetB, rowA, colA);
00100     updateLayout();
00101 }
00102 
00103 void PlotMatrix::removeColumn(unsigned column_to_delete)
00104 {
00105     if(_num_rows==1 && _num_cols ==1 ) {
00106         return;
00107     }
00108 
00109     for(unsigned col = column_to_delete; col< _num_cols-1; col++)
00110     {
00111         for(unsigned row=0; row< _num_rows; row++)
00112         {
00113             this->swapPlots( row, col, row, col+1);
00114         }
00115     }
00116     for(unsigned row=0; row< _num_rows; row++)
00117     {
00118         plotAt( row, _num_cols -1)->close();
00119     }
00120     _layout->setColumnStretch(_num_cols -1,0);
00121 
00122     _num_cols--;
00123     if( _num_cols == 0){
00124         _num_rows = 0;
00125     }
00126 
00127     updateLayout();
00128 
00129 }
00130 
00131 void PlotMatrix::removeRow(unsigned row_to_delete)
00132 {
00133     if(_num_rows==1 && _num_cols ==1 ) {
00134         return;
00135     }
00136     for(unsigned row = row_to_delete; row< _num_rows-1; row++)
00137     {
00138         for(unsigned col = 0; col< _num_cols; col++)
00139         {
00140             this->swapPlots( row, col, row+1, col);
00141         }
00142     }
00143     for(unsigned col=0; col< _num_cols; col++)
00144     {
00145         plotAt( _num_rows-1, col)->close();
00146     }
00147     _layout->setRowStretch(_num_rows -1,0);
00148 
00149     _num_rows--;
00150     if( _num_rows == 0){
00151         _num_cols = 0;
00152     }
00153 
00154     updateLayout();
00155 }
00156 
00157 void PlotMatrix::removeEmpty()
00158 {
00159     for( unsigned row = 0; row< rowsCount(); row++)
00160     {
00161         while( rowsCount() > 1 &&
00162                isRowEmpty( row ) &&
00163                row < rowsCount() )
00164         {
00165             removeRow( row );
00166         }
00167     }
00168 
00169     for( unsigned col = 0; col< colsCount(); col++)
00170     {
00171         while( colsCount() > 1 &&
00172                isColumnEmpty( col ) &&
00173                col < colsCount() )
00174         {
00175             removeColumn( col );
00176         }
00177     }
00178 }
00179 
00180 
00181 PlotMatrix::~PlotMatrix(){}
00182 
00183 unsigned PlotMatrix::rowsCount() const
00184 {
00185     return _num_rows;
00186 }
00187 
00188 unsigned PlotMatrix::colsCount() const
00189 {
00190     return _num_cols;
00191 }
00192 
00193 unsigned PlotMatrix::plotCount() const
00194 {
00195     return _num_rows*_num_cols;
00196 }
00197 
00198 bool PlotMatrix::isColumnEmpty( unsigned col ) const
00199 {
00200     for (int r=0; r < _layout->rowCount(); r++)
00201     {
00202         auto plot = plotAt(r, col);
00203         if( plot && ! plot->isEmpty() )  {
00204             return false;
00205         }
00206     }
00207     return true;
00208 }
00209 
00210 bool PlotMatrix::isRowEmpty(unsigned row ) const
00211 {
00212     for (int c=0; c< _layout->columnCount(); c++)
00213     {
00214         auto plot = plotAt(row, c);
00215         if( plot && ! plot->isEmpty() )  {
00216             return false;
00217         }
00218     }
00219     return true;
00220 }
00221 
00222 
00223 PlotWidget* PlotMatrix::plotAt( unsigned row, unsigned column )
00224 {
00225     QLayoutItem* item = _layout->itemAtPosition(row,column);
00226     if(item) {
00227         PlotWidget* plot = static_cast<PlotWidget*>( item->widget() );
00228         return plot;
00229     }
00230     return NULL;
00231 }
00232 
00233 const PlotWidget* PlotMatrix::plotAt( unsigned row, unsigned column ) const
00234 {
00235     QLayoutItem* item = _layout->itemAtPosition(row,column);
00236     if(item) {
00237         PlotWidget* plot = static_cast<PlotWidget*>( item->widget() );
00238         return plot;
00239     }
00240     return NULL;
00241 }
00242 
00243 PlotWidget* PlotMatrix::plotAt( unsigned index )
00244 {
00245   return plotAt(index% rowsCount(), index/rowsCount());
00246 }
00247 
00248 const PlotWidget* PlotMatrix::plotAt( unsigned index ) const
00249 {
00250    return plotAt(index% rowsCount(), index/rowsCount());
00251 }
00252 
00253 
00254 void PlotMatrix::setAxisScale(QwtPlot::Axis axisId, unsigned row, unsigned col,
00255                                double min, double max, double step )
00256 {
00257     PlotWidget *plt = plotAt( row, col );
00258     if ( plt )
00259     {
00260         plt->setAxisScale( axisId, min, max, step );
00261         plt->updateAxes();
00262     }
00263 }
00264 
00265 QDomElement PlotMatrix::xmlSaveState( QDomDocument &doc ) const
00266 {
00267     QDomElement element = doc.createElement("plotmatrix");
00268 
00269     element.setAttribute("rows", _num_rows );
00270     element.setAttribute("columns", _num_cols );
00271 
00272     for(unsigned col = 0; col< _num_cols; col++)
00273     {
00274         for(unsigned row = 0; row< _num_rows; row++)
00275         {
00276             const PlotWidget* plot = plotAt(row,col);
00277             QDomElement child = plot->xmlSaveState(doc);
00278 
00279             child.setAttribute("row", row);
00280             child.setAttribute("col", col);
00281 
00282             element.appendChild( child );
00283         }
00284     }
00285     return element;
00286 }
00287 
00288 bool PlotMatrix::xmlLoadState( QDomElement &plotmatrix )
00289 {
00290     if( !plotmatrix.hasAttribute("rows") || !plotmatrix.hasAttribute("columns") )
00291     {
00292         qWarning() << "No [rows] or [columns] attribute in <plotmatrix> XML file!";
00293         return false;
00294     }
00295     unsigned rows = plotmatrix.attribute("rows").toUInt();
00296     unsigned cols = plotmatrix.attribute("columns" ).toUInt();
00297 
00298     while( rows > _num_rows){ addRow(); }
00299     while( rows < _num_rows){ removeRow( _num_rows-1 );  }
00300 
00301     while( cols > _num_cols){ addColumn();  }
00302     while( cols < _num_cols){ removeColumn( _num_cols-1 ); }
00303 
00304     QDomElement plot_element;
00305     for (  plot_element = plotmatrix.firstChildElement( "plot" )  ;
00306            !plot_element.isNull();
00307            plot_element = plot_element.nextSiblingElement( "plot" ) )
00308     {
00309         if( !plot_element.hasAttribute("row") || !plot_element.hasAttribute("col") )
00310         {
00311             qWarning() << "No [row] or [col] attribute in <plot> XML file!";
00312             return false;
00313         }
00314         unsigned row = plot_element.attribute("row").toUInt();
00315         unsigned col = plot_element.attribute("col").toUInt();
00316 
00317         bool success = plotAt(row,col)->xmlLoadState( plot_element ) ;
00318         if( !success )
00319         {
00320             return false;
00321         }
00322     }
00323     return true;
00324 }
00325 
00326 
00327 
00328 void PlotMatrix::updateLayout()
00329 {
00330     for ( unsigned row = 0; row < rowsCount(); row++ )
00331     {
00332         alignAxes( row, QwtPlot::xBottom );
00333         alignScaleBorder( row, QwtPlot::yLeft );
00334     }
00335 
00336     for ( unsigned col = 0; col < colsCount(); col++ )
00337     {
00338         alignAxes( col, QwtPlot::yLeft );
00339         alignScaleBorder( col, QwtPlot::xBottom );
00340     }
00341 }
00342 
00343 void PlotMatrix::replot()
00344 {
00345     for ( unsigned i = 0; i< plotCount(); i++ )
00346     {
00347         PlotWidget *plot = plotAt(i);
00348         plot->replot();
00349     }
00350 }
00351 
00352 
00353 void PlotMatrix::setHorizontalLink(bool linked)
00354 {
00355     _horizontal_link = linked;
00356 }
00357 
00358 
00359 void PlotMatrix::setName(const QString &new_name)
00360 {
00361     _name = new_name;
00362 }
00363 
00364 const QString &PlotMatrix::name() const
00365 {
00366     return _name;
00367 }
00368 
00369 QGridLayout *PlotMatrix::gridLayout()
00370 {
00371     return _layout;
00372 }
00373 
00374 void PlotMatrix::maximumZoomOutHorizontal()
00375 {
00376     for ( unsigned i = 0; i< plotCount(); i++ )
00377     {
00378         PlotWidget *plot = plotAt(i);
00379         if( plot->isEmpty() == false)
00380         {
00381             plot->on_zoomOutHorizontal_triggered( false );
00382         }
00383     }
00384     replot();
00385 }
00386 
00387 void PlotMatrix::maximumZoomOutVertical()
00388 {
00389     for ( unsigned i = 0; i < plotCount(); i++ )
00390     {
00391         PlotWidget *plot = plotAt(i);
00392         if( plot->isEmpty() == false)
00393         {
00394             plot->on_zoomOutVertical_triggered(false);
00395         }
00396     }
00397     replot();
00398 }
00399 
00400 void PlotMatrix::maximumZoomOut()
00401 {
00402     for ( unsigned i = 0; i < plotCount(); i++ )
00403     {
00404         PlotWidget *plot = plotAt(i);
00405         if( plot->isEmpty() == false)
00406         {
00407             plot->zoomOut(false);
00408         }
00409     }
00410     replot();
00411 }
00412 
00413 
00414 void PlotMatrix::on_singlePlotScaleChanged(PlotWidget *modified_plot, QRectF new_range)
00415 {
00416     if( _horizontal_link )
00417     {
00418         for ( unsigned i = 0; i< plotCount(); i++ )
00419         {
00420             PlotWidget *plot = plotAt(i);
00421             if( plot->isEmpty() == false &&
00422                     modified_plot != plot &&
00423                     plot->isXYPlot() == false)
00424             {
00425                 QRectF bound_act = plot->canvasBoundingRect();
00426                 bound_act.setLeft( new_range.left() );
00427                 bound_act.setRight( new_range.right() );
00428                 plot->setZoomRectangle( bound_act, false );
00429                 plot->on_zoomOutVertical_triggered(false);
00430                 plot->replot();
00431             }
00432         }
00433     }
00434     emit undoableChange();
00435 }
00436 
00437 void PlotMatrix::on_legendSizeChanged(int point_size)
00438 {
00439     _legend_point_size = point_size;
00440 
00441     QSettings settings;
00442     settings.setValue("PlotMatrix/legend_point_size", _legend_point_size);
00443 
00444     for ( unsigned i = 0; i< plotCount(); i++ )
00445     {
00446         PlotWidget *plot = plotAt(i);
00447         plot->setLegendSize(point_size);
00448     }
00449 }
00450 
00451 void PlotMatrix::alignAxes( unsigned rowOrColumn, QwtPlot::Axis axisId )
00452 {
00453     bool iterating_rows = ( axisId == QwtPlot::yLeft || axisId == QwtPlot::yRight );
00454     const int COUNT = iterating_rows ? rowsCount() : colsCount();
00455 
00456     double maxExtent = 0;
00457 
00458     for ( unsigned i = 0; i < COUNT; i++ )
00459     {
00460       QwtPlot *p = iterating_rows? plotAt( i, rowOrColumn ) : plotAt( rowOrColumn, i );
00461       if ( p )
00462       {
00463         QwtScaleWidget *scaleWidget = p->axisWidget( axisId );
00464 
00465         QwtScaleDraw *sd = scaleWidget->scaleDraw();
00466         sd->setMinimumExtent( 0.0 );
00467 
00468         const double extent = sd->extent( scaleWidget->font() );
00469         if ( extent > maxExtent )
00470           maxExtent = extent;
00471       }
00472     }
00473 
00474     for ( unsigned i = 0; i < COUNT; i++ )
00475     {
00476       QwtPlot *p = iterating_rows? plotAt( i, rowOrColumn ) : plotAt( rowOrColumn, i );
00477       if ( p )
00478       {
00479         QwtScaleWidget *scaleWidget = p->axisWidget( axisId );
00480         scaleWidget->scaleDraw()->setMinimumExtent( maxExtent );
00481       }
00482     }
00483 }
00484 
00485 void PlotMatrix::alignScaleBorder(unsigned rowOrColumn, QwtPlot::Axis axisId )
00486 {
00487     if ( axisId == QwtPlot::yLeft || axisId == QwtPlot::yRight )
00488     {
00489         for ( unsigned col = 0; col < colsCount(); col++ )
00490         {
00491             QwtPlot *p = plotAt( rowOrColumn, col );
00492             if ( p )
00493                 p->axisWidget( axisId )->setMinBorderDist( 10, 10 );
00494         }
00495     }
00496     else if ( axisId == QwtPlot::xTop || axisId == QwtPlot::xBottom )
00497     {
00498         for ( unsigned row = 0; row < rowsCount(); row++ )
00499         {
00500             QwtPlot *p = plotAt( row, rowOrColumn );
00501             if ( p )
00502                 p->axisWidget( axisId )->setMinBorderDist( 15, 15 );
00503         }
00504     }
00505 }


plotjuggler
Author(s): Davide Faconti
autogenerated on Wed Jul 3 2019 19:28:04