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


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56