1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "Plot2d_ViewFrame.h"
25 #include "Plot2d_Prs.h"
26 #include "Plot2d_Curve.h"
27 #include "Plot2d_PlotItems.h"
28 #include "Plot2d_FitDataDlg.h"
29 #include "Plot2d_ViewWindow.h"
30 #include "Plot2d_SetupViewDlg.h"
31 #include "Plot2d_AnalyticalCurveDlg.h"
32 #include "Plot2d_AnalyticalCurve.h"
33 #include "Plot2d_ToolTip.h"
35 #include "SUIT_Tools.h"
36 #include "SUIT_Session.h"
37 #include "SUIT_MessageBox.h"
38 #include "SUIT_ResourceMgr.h"
39 #include "SUIT_Application.h"
41 #include <QApplication>
43 #include <QToolButton>
45 #include <QColorDialog>
49 #include <QPaintDevice>
51 #include <QMouseEvent>
52 #include <QContextMenuEvent>
56 #include <QXmlStreamWriter>
57 #include <QXmlStreamReader>
60 #include <qwt_plot_layout.h>
61 #include <qwt_plot_canvas.h>
62 #include <qwt_scale_div.h>
63 #include <qwt_plot_marker.h>
64 #include <qwt_plot_curve.h>
65 #include <qwt_plot_grid.h>
66 #include <qwt_scale_engine.h>
67 #include <qwt_plot_zoomer.h>
68 #include <qwt_curve_fitter.h>
74 #include <qwt_legend.h>
75 #include <qwt_scale_widget.h>
77 #define DEFAULT_LINE_WIDTH 0 // (default) line width
78 #define DEFAULT_MARKER_SIZE 9 // default marker size
79 #define MIN_RECT_SIZE 11 // min sensibility area size
81 #define FITALL_EVENT ( QEvent::User + 9999 )
83 const char* imageZoomCursor[] = {
88 "................................",
89 "................................",
90 ".#######........................",
91 "..aaaaaaa.......................",
92 "................................",
93 ".............#####..............",
94 "...........##.aaaa##............",
95 "..........#.aa.....a#...........",
96 ".........#.a.........#..........",
97 ".........#a..........#a.........",
98 "........#.a...........#.........",
99 "........#a............#a........",
100 "........#a............#a........",
101 "........#a............#a........",
102 "........#a............#a........",
103 ".........#...........#.a........",
104 ".........#a..........#a.........",
105 ".........##.........#.a.........",
106 "........#####.....##.a..........",
107 ".......###aaa#####.aa...........",
108 "......###aa...aaaaa.......#.....",
109 ".....###aa................#a....",
110 "....###aa.................#a....",
111 "...###aa...............#######..",
112 "....#aa.................aa#aaaa.",
113 ".....a....................#a....",
114 "..........................#a....",
115 "...........................a....",
116 "................................",
117 "................................",
118 "................................",
119 "................................"};
121 const char* imageCrossCursor[] = {
126 "................................",
127 "................................",
128 "................................",
129 "................................",
130 "................................",
131 "................................",
132 "................................",
133 "...............#................",
134 "...............#a...............",
135 "...............#a...............",
136 "...............#a...............",
137 "...............#a...............",
138 "...............#a...............",
139 "...............#a...............",
140 "...............#a...............",
141 ".......#################........",
142 "........aaaaaaa#aaaaaaaaa.......",
143 "...............#a...............",
144 "...............#a...............",
145 "...............#a...............",
146 "...............#a...............",
147 "...............#a...............",
148 "...............#a...............",
149 "...............#a...............",
150 "................a...............",
151 "................................",
152 "................................",
153 "................................",
154 "................................",
155 "................................",
156 "................................",
157 "................................"};
172 Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title )
173 : QWidget (parent, 0),
174 myOperation( NoOpId ),
176 myShowLegend( true ), myLegendPos( 1 ), myLegendFont("Helvetic",12),
177 myLegendColor(Qt::black),
178 myMarkerSize( DEFAULT_MARKER_SIZE ),
179 myBackground( Qt::white ),
180 myTitle( "" ), myXTitle( "" ), myYTitle( "" ), myY2Title( "" ),
181 myTitleEnabled( true ), myXTitleEnabled( true ),
182 myYTitleEnabled( true ), myY2TitleEnabled (true),
183 myXGridMajorEnabled( true ), myYGridMajorEnabled( true ), myY2GridMajorEnabled( true ),
184 myXGridMinorEnabled( false ), myYGridMinorEnabled( false ), myY2GridMinorEnabled( false ),
185 myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myY2GridMaxMajor( 8 ),
186 myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ), myY2GridMaxMinor( 5 ),
187 myXMode( 0 ), myYMode( 0 ),myNormLMin(false), myNormLMax(false), myNormRMin(false), myNormRMax(false),
188 mySecondY( false ), myIsDefTitle( true )
190 setObjectName( title );
191 myRNormAlgo = new Plot2d_NormalizeAlgorithm(this);
192 myLNormAlgo = new Plot2d_NormalizeAlgorithm(this);
194 QVBoxLayout* aLayout = new QVBoxLayout( this );
195 aLayout->setMargin(0);
196 myPlot = new Plot2d_Plot2d( this );
197 new Plot2d_ToolTip( this );
199 aLayout->addWidget( myPlot );
202 connect( myPlot, SIGNAL( legendClicked( QwtPlotItem* ) ),
203 this, SIGNAL( legendClicked( QwtPlotItem* ) ) );
206 /* connect( myPlot->axisWidget( QwtPlot::xBottom ), SIGNAL( scaleDivChanged() ),
207 myPlot, SLOT( onScaleDivChanged() ) );
208 connect( myPlot->axisWidget( QwtPlot::yLeft ), SIGNAL( scaleDivChanged() ),
209 myPlot, SLOT( onScaleDivChanged() ) );
211 connect( myPlot->axisWidget( QwtPlot::yRight ), SIGNAL( scaleDivChanged() ),
212 myPlot, SLOT( onScaleDivChanged() ) );*/
214 /* Initial Setup - get from the preferences */
217 myPlot->setMargin( 5 );
218 setCurveType( myCurveType, false );
219 setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, false );
220 setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
221 myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, false );
223 setTitle( myTitleEnabled, myTitle, MainTitle, false );
224 setTitle( myXTitleEnabled, myXTitle, XTitle, false );
225 setTitle( myYTitleEnabled, myYTitle, YTitle, false );
228 setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
229 setHorScaleMode( myXMode, false );
230 setVerScaleMode( myYMode, false );
231 setBackgroundColor( myBackground );
232 setLegendPos( myLegendPos );
233 setLegendFont( myLegendFont );
234 setLegendFontColor( myLegendColor );
235 showLegend( myShowLegend, false );
239 resize( (int)(0.8 * parent->width()), (int)(0.8 * parent->height()) );
241 QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
242 QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
243 myXDistance = xMap.s2() - xMap.s1();
244 myYDistance = yMap.s2() - yMap.s1();
247 QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
248 myYDistance2 = yMap2.s2() - yMap2.s1();
250 myPlot->canvas()->installEventFilter( this );
255 Plot2d_ViewFrame::~Plot2d_ViewFrame()
259 Gets window's central widget
261 QWidget* Plot2d_ViewFrame::getViewWidget()
263 return (QWidget*)myPlot;
266 Actually this method just re-displays all curves which are presented in the viewer
268 void Plot2d_ViewFrame::DisplayAll()
272 foreach ( Plot2d_Object* o, olist )
273 updateObject( o, false );
275 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
278 Removes all curves from the view
280 void Plot2d_ViewFrame::EraseAll()
282 objectList anObjects;
283 getObjects( anObjects );
284 eraseObjects( anObjects, false );
287 // 1)- Erase all the intermittent segments who connect curves
289 int nbSeg = myIntermittentSegmentList.size();
292 for (int iseg=0; iseg < nbSeg; iseg++)
294 QwtPlotCurve *segment = myIntermittentSegmentList[iseg];
296 segment->detach(); // erase in QwtPlot window
299 myIntermittentSegmentList.clear();
302 // 2)- Erase all curves points markers
304 int nbMark = myMarkerList.size();
307 for (int imar=0; imar < nbMark; imar++)
309 QwtPlotMarker *marker = myMarkerList[imar];
311 marker->detach(); // erase in QwtPlot window
314 myMarkerList.clear();
317 // The graphic view's picker
318 Plot2d_QwtPlotPicker *picker = myPlot->getPicker();
320 // Clear points markers list and associations (marker,tooltip)
322 picker->pMarkers.clear(); // QList<QwtPlotMarker*>
323 picker->pMarkersToolTip.clear(); // QMap<QwtPlotMarker*, QwtText>
326 // 3)- Erase all QwtPlotCurve associated with the Plot2d_Curve
328 int nbCur1 = myQwtPlotCurveList.size();
331 for (int icur=0; icur < nbCur1; icur++)
333 QwtPlotItem *curve0 = myQwtPlotCurveList[icur];
334 QwtPlotCurve *curve = static_cast<QwtPlotCurve*>(curve0);
341 myQwtPlotCurveList.clear();
344 // 4)- Erase all curves Plot2d_Curve
346 int nbCur = myPlot2dCurveList.size();
349 for (int icur=0; icur < nbCur; icur++)
351 Plot2d_Curve *curve = myPlot2dCurveList[icur];
358 myPlot2dCurveList.clear();
361 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
364 Redraws viewframe contents
366 void Plot2d_ViewFrame::Repaint()
373 void Plot2d_ViewFrame::Display( const Plot2d_Prs* prs )
375 if ( !prs || prs->IsNull() )
378 setEnableAxis( QwtPlot::yRight, prs->isSecondY() ); // VSR: is it correct? maybe we should only enable second Y axis if required
380 // display all objects from presentation
381 objectList anObjects = prs->getObjects();
382 displayObjects( anObjects );
383 setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, true );
384 setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
385 myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, true );
386 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
392 void Plot2d_ViewFrame::Erase( const Plot2d_Prs* prs, const bool )
394 if ( !prs || prs->IsNull() )
397 // erase all objects from presentation
398 objectList anObjects = prs->getObjects();
399 eraseObjects( anObjects );
400 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
403 bool Plot2d_ViewFrame::eventFilter( QObject* watched, QEvent* e )
405 if ( watched == myPlot->canvas() ) {
406 int aType = e->type();
408 case QEvent::MouseMove: {
409 QMouseEvent* me = (QMouseEvent*)e;
410 if ( me && ( me->buttons() != 0 || me->button() != 0 ) ) {
411 QMouseEvent m( QEvent::MouseMove, me->pos(), me->button(),
412 me->buttons(), me->modifiers() );
413 if ( plotMouseMoved( m ) )
418 case QEvent::MouseButtonPress: {
419 QMouseEvent* me = (QMouseEvent*)e;
420 if ( me && ( me->buttons() != 0 || me->button() != 0 ) ) {
421 QMouseEvent m( QEvent::MouseButtonPress, me->pos(), me->button(),
422 me->buttons(), me->modifiers() );
423 plotMousePressed( m );
427 case QEvent::MouseButtonRelease: {
428 QMouseEvent* me = (QMouseEvent*)e;
429 if ( me && ( me->buttons() != 0 || me->button() != 0 ) ) {
430 QMouseEvent m( QEvent::MouseButtonRelease, me->pos(), me->button(),
431 me->buttons(), me->modifiers() );
432 plotMouseReleased( m );
436 case QEvent::ContextMenu:
438 // Do nothing because context menu is called from MouseRelease
442 return QWidget::eventFilter( watched, e );
448 void Plot2d_ViewFrame::setTitle( const QString& title )
450 setTitle( myTitleEnabled, title, MainTitle, true );
451 myIsDefTitle = false;
457 QString Plot2d_ViewFrame::getTitle() const
463 Reads Plot2d view settings from the preferences
465 void Plot2d_ViewFrame::readPreferences()
467 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
469 myCurveType = resMgr->integerValue( "Plot2d", "CurveType", myCurveType );
470 setCurveType( resMgr->integerValue( "Plot2d", "CurveType", myCurveType ) );
472 myShowLegend = resMgr->booleanValue( "Plot2d", "ShowLegend", myShowLegend );
473 myLegendPos = resMgr->integerValue( "Plot2d", "LegendPos", myLegendPos );
474 myLegendFont = resMgr->fontValue( "Plot2d", "LegendFont", myLegendFont );
475 myLegendColor = resMgr->colorValue( "Plot2d", "LegendFontColor", myLegendColor );
476 myMarkerSize = resMgr->integerValue( "Plot2d", "MarkerSize", myMarkerSize );
477 myBackground = resMgr->colorValue( "Plot2d", "Background", myBackground );
479 myTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowTitle", myTitleEnabled );
480 myXTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
481 myYTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
482 myY2TitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
484 myXGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
485 myYGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
486 myY2GridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
488 myXGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
489 myYGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
490 myY2GridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
492 myXGridMaxMajor = resMgr->integerValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
493 myYGridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
495 myY2GridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorRightGridMax", myY2GridMaxMajor );
497 myXGridMaxMinor = resMgr->integerValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
498 myYGridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
500 myY2GridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myY2GridMaxMinor );
502 setHorScaleMode( qMax( 0, qMin( 1, resMgr->integerValue( "Plot2d", "HorScaleMode", myXMode ) ) ), false );
503 setVerScaleMode( qMax( 0, qMin( 1, resMgr->integerValue( "Plot2d", "VerScaleMode", myYMode ) ) ), false );
504 setNormLMinMode( resMgr->booleanValue( "Plot2d", "VerNormLMinMode", myNormLMin ) );
505 setNormLMaxMode( resMgr->booleanValue( "Plot2d", "VerNormLMaxMode", myNormLMax ) );
506 setNormRMinMode( resMgr->booleanValue( "Plot2d", "VerNormRMinMode", myNormRMin ) );
507 setNormRMaxMode( resMgr->booleanValue( "Plot2d", "VerNormRMaxMode", myNormRMax ) );
508 QColor c = resMgr->colorValue( "Plot2d", "DeviationMarkerColor", QColor(255,0,0));
509 myPlot->setProperty(PLOT2D_DEVIATION_COLOR, c);
510 myPlot->setProperty(PLOT2D_DEVIATION_LW,
511 resMgr->integerValue( "Plot2d", "DeviationMarkerLineWidth", 1));
512 myPlot->setProperty(PLOT2D_DEVIATION_TS,
513 resMgr->integerValue( "Plot2d", "DeviationMarkerTickSize", 2));
518 Writes Plot2d view settings to the preferences
520 void Plot2d_ViewFrame::writePreferences()
522 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
524 resMgr->setValue( "Plot2d", "CurveType", myCurveType );
525 resMgr->setValue( "Plot2d", "ShowLegend", myShowLegend );
526 resMgr->setValue( "Plot2d", "LegendPos", myLegendPos );
527 resMgr->setValue( "Plot2d", "LegendFont", myLegendFont );
528 resMgr->setValue( "Plot2d", "LegendFontColor", myLegendColor );
529 resMgr->setValue( "Plot2d", "MarkerSize", myMarkerSize );
530 resMgr->setValue( "Plot2d", "Background", myBackground );
531 resMgr->setValue( "Plot2d", "ShowTitle", myTitleEnabled );
532 resMgr->setValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
533 resMgr->setValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
535 resMgr->setValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
537 resMgr->setValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
538 resMgr->setValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
539 resMgr->setValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
540 resMgr->setValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
542 resMgr->setValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
543 resMgr->setValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
545 resMgr->setValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
546 resMgr->setValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
548 resMgr->setValue( "Plot2d", "HorScaleMode", myXMode );
552 resMgr->setValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
553 resMgr->setValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
554 resMgr->setValue( "Plot2d", "VerRightMajorGridMax", myY2GridMaxMajor );
555 resMgr->setValue( "Plot2d", "VerRightMinorGridMax", myY2GridMaxMinor );
558 resMgr->setValue( "Plot2d", "VerScaleMode", myYMode );
559 resMgr->setValue( "Plot2d", "VerNormLMinMode", myNormLMin );
560 resMgr->setValue( "Plot2d", "VerNormLMaxMode", myNormLMax );
561 resMgr->setValue( "Plot2d", "VerNormRMinMode", myNormRMin );
562 resMgr->setValue( "Plot2d", "VerNormRMaxMode", myNormRMax );
566 Prints mouse cursor coordinates into string
568 QString Plot2d_ViewFrame::getInfo( const QPoint& pnt )
572 bool xFound = false, yFound = false;
573 double xCoord, yCoord;
574 const QwtScaleDiv* aXscale = myPlot->axisScaleDiv( QwtPlot::xBottom );
575 aTicks = aXscale->ticks( QwtScaleDiv::MajorTick );
576 for ( i = 0; i < aTicks.count(); i++ ) {
577 double majXmark = aTicks[i];
578 int xmark = myPlot->transform( QwtPlot::xBottom, majXmark );
579 if ( xmark-2 == pnt.x() ) {
586 aTicks = aXscale->ticks( QwtScaleDiv::MinorTick );
587 for ( i = 0; i < aTicks.count(); i++ ) {
588 double minXmark = aTicks[i];
589 int xmark = myPlot->transform( QwtPlot::xBottom, minXmark );
590 if ( xmark-2 == pnt.x() ) {
597 const QwtScaleDiv* aYscale = myPlot->axisScaleDiv( QwtPlot::yLeft );
598 aTicks = aYscale->ticks( QwtScaleDiv::MajorTick );
599 for ( i = 0; i < aTicks.count(); i++ ) {
600 double majYmark = aTicks[i];
601 int ymark = myPlot->transform( QwtPlot::yLeft, majYmark );
602 if ( ymark-2 == pnt.y() ) {
609 aTicks = aYscale->ticks( QwtScaleDiv::MinorTick );
610 for ( i = 0; i < aTicks.count(); i++ ) {
611 double minYmark = aTicks[i];
612 int ymark = myPlot->transform( QwtPlot::yLeft, minYmark );
613 if ( ymark-2 == pnt.y() ) {
621 QString strX = QString::number( xFound ? xCoord : myPlot->invTransform( QwtPlot::xBottom, pnt.x() ) ).trimmed();
624 QString strY = QString::number( yFound ? yCoord : myPlot->invTransform( QwtPlot::yLeft, pnt.y() ) ).trimmed();
630 bool yFound2 = false;
633 const QwtScaleDiv* aYscale2 = myPlot->axisScaleDiv( QwtPlot::yRight );
634 aTicks = aYscale2->ticks( QwtScaleDiv::MajorTick );
635 for ( i = 0; i < aTicks.count(); i++ ) {
636 double majYmark = aTicks[i];
637 int ymark = myPlot->transform( QwtPlot::yRight, majYmark );
638 if ( ymark-2 == pnt.y() ) {
645 aTicks = aYscale2->ticks( QwtScaleDiv::MinorTick );
646 for ( i = 0; i < aTicks.count(); i++ ) {
647 double minYmark = aTicks[i];
648 int ymark = myPlot->transform( QwtPlot::yRight, minYmark );
649 if ( ymark-2 == pnt.y() ) {
656 QString strY2 = QString::number( yFound2 ? yCoord2 :
657 myPlot->invTransform( QwtPlot::yRight, pnt.y() ) ).trimmed();
660 info = tr("INF_COORDINATES_SOME_Y").arg( strX ).arg( strY ).arg( strY2 );
663 info = tr("INF_COORDINATES").arg( strX ).arg( strY );
669 * Display curves of the list of lists by systems and components
670 * - the first level list contains NbSytems lists of second level
671 * - a second level list contains NbComponents curves
672 * | system 1 | system 2 | ..... | system N |
673 * | compo1 compo2 ... compoM | compo1 compo2 ... compoM | ..... | compo1 compo2 ... compoM |
675 * Draw points markers and create associated tooltips.
676 * Draw connection segments (intermittent line) between all the curves of a component.
677 * \return the list of underlying plot curve that defines the complex cuve at once. In case of success the vector is at least of size 1. The first one is the curve used by the legend.
679 QVector< QVector<QwtPlotCurve *> > Plot2d_ViewFrame::displayPlot2dCurveList( const QList< QList<Plot2d_Curve*> >& sysCoCurveList,
681 const QList< QList<bool> >& sides)
683 //std::cout << "Plot2d_ViewFrame::displayPlot2dCurveList() 1" << std::endl;
686 int nbSystem = sysCoCurveList.size();
688 // Composants number by system
689 int nbComponent = (sysCoCurveList.at(0)).size();
691 // Total number of curves
693 // 1)- Construction of a list by component and by system
695 // | component 1 | component 2 | ..... | component M |
696 // | syst1 syst2 ... systN | syst1 syst2 ... systN | ..... | syst1 syst2 ... systN |
698 QList<Plot2d_Curve*> plot2dCurveCoSysList;
699 QList<bool> sidesList;
700 for (int icom = 0; icom < nbComponent; icom++)
702 for (int isys = 0; isys < nbSystem; isys++)
704 // The system curves list
705 const QList<Plot2d_Curve*>& sysCurveList=sysCoCurveList.at(isys);
706 plot2dCurveCoSysList.append(sysCurveList.at(icom));
708 const QList<bool>& sysSideList=sides.at(isys);
709 sidesList.append(sysSideList.at(icom));
712 // 2)- Display list curves by a component's curves group
713 // Draw connection segments (intermittent line) between the curves
714 QVector< QVector<QwtPlotCurve *> > ret=displayPlot2dCurveList( plot2dCurveCoSysList, nbSystem, displayLegend, sidesList);
715 // 3)- Size of graduations labels and texts under X axis
716 QwtScaleWidget *wid = myPlot->axisWidget( QwtPlot::xBottom);
717 wid->setTitle(" "); // to make the names readable under X axis.
718 QFont xFont = myPlot->axisFont(QwtPlot::xBottom);
719 xFont.setPointSize(8);
720 myPlot->setAxisFont(QwtPlot::xBottom, xFont);
726 * Display list of curves by group of consecutive curves.
728 * Draw points markers and create associated tooltips
729 * Draw connection segments (intermittent line) between the curves
730 * \param [in] sides sorted as in \b curveList. If true->right if false->left
731 * \return the list of underlying plot curve that defines the complex cuve at once. In case of success the vector is at least of size 1. The first one is the curve used by the legend.
733 QVector< QVector<QwtPlotCurve *> > Plot2d_ViewFrame::displayPlot2dCurveList( const QList<Plot2d_Curve*>& curveList,
735 bool displayLegend, const QList< bool >& sides)
737 // Consider the new legend's entries
738 // (PB: to update the legend we must remove it and put a new QwtLegend in the QwtPlot)
739 myPlot->insertLegend( (QwtLegend*)NULL); // we remove here, we shall put at the end
741 int nbAllCurves = curveList.size();
742 int nbGroups = nbAllCurves / groupSize;
743 QVector< QVector<QwtPlotCurve *> > vectCurve(nbGroups);
745 int icur1, icur2; // curves indices in a group
747 // I)- Compute X range and Y range for all the curves' points of all groups
748 // In the graphic view, set the Y range 's bounds for all groups of curves
750 // For all groups of curves
751 double XallGroupMin=std::numeric_limits<double>::max(), XallGroupMax=-std::numeric_limits<double>::max();
752 double YRightallGroupMin=std::numeric_limits<double>::max(), YRightallGroupMax=-std::numeric_limits<double>::max();
753 double YLeftallGroupMin=std::numeric_limits<double>::max(), YLeftallGroupMax=-std::numeric_limits<double>::max();
755 for (ig=0; ig < nbGroups; ig++) //*1*
757 icur2 = icur1 + groupSize -1;
759 // For all curves in one group
760 double XgroupMin, XgroupMax;
761 double YgroupMin, YgroupMax;
764 double XcurveMin, XcurveMax;
765 double YcurveMin, YcurveMax;
770 // Compute X range and Y range for all the curves' points in the group
772 for (icur=icur1; icur <= icur2; icur++) //*2*
774 Plot2d_Curve *plot2dCurve = curveList.at(icur);
777 nbPoints = plot2dCurve->getData( &Xval, &Yval); // dynamic allocation
779 for (int ip=0; ip < nbPoints; ip++)
781 if (ip == 0) // first point
783 XcurveMin = Xval[ip]; XcurveMax = Xval[ip];
784 YcurveMin = Yval[ip]; YcurveMax = Yval[ip];
788 if (Xval[ip] < XcurveMin) XcurveMin = Xval[ip];
789 else if (Xval[ip] > XcurveMax) XcurveMax = Xval[ip];
790 if (Yval[ip] < YcurveMin) YcurveMin = Yval[ip];
791 else if (Yval[ip] > YcurveMax) YcurveMax = Yval[ip];
797 if (icur == icur1) // first curve
799 XgroupMin = XcurveMin; XgroupMax = XcurveMax;
800 YgroupMin = YcurveMin; YgroupMax = YcurveMax;
804 if (XcurveMin < XgroupMin) XgroupMin = XcurveMin;
805 if (XcurveMax > XgroupMax) XgroupMax = XcurveMax;
806 if (YcurveMin < YgroupMin) YgroupMin = YcurveMin;
807 if (YcurveMax > YgroupMax) YgroupMax = YcurveMax;
811 if (XgroupMin < XallGroupMin) XallGroupMin = XgroupMin;
812 if (XgroupMax > XallGroupMax) XallGroupMax = XgroupMax;
815 if (YgroupMin < YRightallGroupMin) YRightallGroupMin = YgroupMin;
816 if (YgroupMax > YRightallGroupMax) YRightallGroupMax = YgroupMax;
820 if (YgroupMin < YLeftallGroupMin) YLeftallGroupMin = YgroupMin;
821 if (YgroupMax > YLeftallGroupMax) YLeftallGroupMax = YgroupMax;
823 // First curve of the following group
826 // Set the XY range 's bounds for all groups of curves
827 if(YRightallGroupMin!=std::numeric_limits<double>::max())
829 double deltaY = YRightallGroupMax - YRightallGroupMin;
830 YRightallGroupMin-=0.05*deltaY; YRightallGroupMax+= 0.05*deltaY;
831 myPlot->setAxisScale( QwtPlot::yRight, YRightallGroupMin,YRightallGroupMax);
833 if(YLeftallGroupMin!=std::numeric_limits<double>::max())
835 double deltaY = YLeftallGroupMax - YLeftallGroupMin;
836 YLeftallGroupMin-=0.05*deltaY; YLeftallGroupMax+= 0.05*deltaY;
837 myPlot->setAxisScale( QwtPlot::yLeft, YLeftallGroupMin, YLeftallGroupMax);
839 // II)- Drawing curves, points markers and connection segments
842 for (ig=0; ig < nbGroups; ig++)
844 // 1)- Graphical attributs of group's curves
846 // Graphical attributes of the first group's curve
848 Plot2d_Curve *plot2dCurve1 = curveList.at(icur1);
850 QColor color1 = plot2dCurve1->getColor();
851 Plot2d::LineType linetype1 = plot2dCurve1->getLine();
852 int lineWidth1 = plot2dCurve1->getLineWidth();
853 QwtSymbol::Style symbolStyle1 = plot2dCurve1->getMarkerStyle();
854 // We attribute to the current group's curve, the color, the line's kind
855 // and the marker's kind of the first group's curve
857 for (icur=icur1+1; icur<icur1+groupSize; icur++)
859 Plot2d_Curve *plot2dCurve = curveList.at(icur);
861 plot2dCurve->setColor(color1);
862 plot2dCurve->setLine(linetype1,lineWidth1);
863 plot2dCurve->setMarkerStyle(symbolStyle1);
866 // 2)- Display the group's curves
868 for (icur=icur1; icur<icur1+groupSize; icur++)
870 Plot2d_Curve *plot2dCurve = curveList.at(icur);
872 QString title = plot2dCurve->getVerTitle();
873 std::string std_title = title.toStdString();
874 // Create the graphic curve (QwtPlotCurve) et display it in the drawing zone
876 displayCurve(plot2dCurve);
878 // Get the graphic curve
879 QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve *>(getPlotObject(plot2dCurve));
880 vectCurve[ig].push_back(plotCurve);
881 // Modify the points' markers
882 QwtSymbol symbol(plotCurve->symbol()) ;
883 symbol.setStyle(symbolStyle1);
884 symbol.setPen(QPen(color1,lineWidth1));
885 //symbol.setBrush( QBrush( color1));
886 //QSize size = 0.5*(symbol.size());
887 //symbol.setSize(size);
889 plotCurve->setPen(QPen(color1,lineWidth1));
890 plotCurve->setSymbol(symbol);
894 //std::cout << " courbe d'indice " << icur << " sans entree dans la legende" << std::endl;
896 // The curve must not have legend's entry
897 plotCurve->setItemAttribute( QwtPlotItem::Legend, false);
901 plotCurve->setItemAttribute( QwtPlotItem::Legend, true);
905 // 3)- Intermittent segments to connect all the group's curves
912 double Xseg[2], Yseg[2];
913 Plot2d_Curve *plot2dCurve1 = curveList.at(icur1);
914 bool side = sides.at(icur1);
915 // Last point of the first curve
916 nbPoints = plot2dCurve1->getData( &Xval, &Yval); // dynamic allocation
917 Xseg[0] = Xval[ nbPoints -1];
918 Yseg[0] = Yval[ nbPoints -1];
922 for (icur=icur1+1; icur<icur1+groupSize; icur++)
924 Plot2d_Curve *plot2dCurve = curveList.at(icur);
926 // First curve's point
927 nbPoints = plot2dCurve->getData( &Xval, &Yval);
931 vectCurve[ig].push_back(createSegment(Xseg,Yseg,2,Qt::DotLine,lineWidth1,color1,QwtSymbol::NoSymbol,side));
933 // Last curve's point
934 Xseg[0] = Xval[ nbPoints -1];
935 Yseg[0] = Yval[ nbPoints -1];
940 // First curve of the following group
946 // Consider the new legend's entries
947 if(!curveList.empty())
948 showLegend( true, true); // show, update
955 * Create and display an y=f(x) curve of points
957 * toDraw : true => Display the created curve
958 * Draw the points'markers and create associated tooltips
960 Plot2d_Curve* Plot2d_ViewFrame::createPlot2dCurve( QString & title,
962 QList<double> & xList,
963 QList<double> & yList,
964 QList<QString> & tooltipList,
965 Plot2d::LineType lineKind,
968 QwtSymbol::Style markerKind,
969 Plot2d_QwtPlotPicker* picker,
973 //std::cout << "Plot2d_ViewFrame::createPlot2dCurve()" << std::endl;
975 // Mathematical curve
976 Plot2d_Curve* plot2dCurve = new Plot2d_Curve();
978 // To deallocate in EraseAll()
979 myPlot2dCurveList.append( plot2dCurve);
981 int nbPoint = xList.size();
985 for (int ip=0; ip < nbPoint; ip++)
989 tooltip = tooltipList.at(ip);
991 plot2dCurve->addPoint( xVal, yVal, tooltip);
994 plot2dCurve->setVerTitle( title);
995 plot2dCurve->setVerUnits( unit);
996 if (lineColor.isValid())
998 plot2dCurve->setColor( lineColor);
1000 plot2dCurve->setLine( lineKind, lineWidth);
1001 plot2dCurve->setMarkerStyle( markerKind);
1002 plot2dCurve->setMarkerSize(1);
1004 // Graphical curve (QwtPlotCurve) in the drawing zone (QwtPlot) myPlot
1009 myPlot->insertLegend( (QwtLegend*)NULL);
1011 displayCurve( plot2dCurve);
1013 // Get the graphical curve
1014 QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve *>( getPlotObject( plot2dCurve));
1018 if (lineColor.isValid())
1020 //std::cout << " valid color" << std::endl;
1021 theColor = lineColor;
1025 //std::cout << " valid color" << std::endl;
1026 QPen pen = plotCurve->pen();
1027 theColor = pen.color();
1030 // Modify points' markers
1031 QwtSymbol symbol (plotCurve->symbol()) ;
1032 symbol.setStyle( markerKind);
1034 if (markerKind != QwtSymbol::NoSymbol)
1036 symbol.setPen( QPen( theColor, lineWidth));
1037 symbol.setBrush( QBrush( theColor));
1038 QSize size = 2.0*(symbol.size()); //0.5
1039 symbol.setSize(size);
1042 plotCurve->setSymbol( symbol);
1043 plotCurve->setStyle( QwtPlotCurve::Lines);
1044 plotCurve->setPen( QPen( theColor, lineWidth));
1046 // The curve must not have legend's entry
1047 plotCurve->setItemAttribute( QwtPlotItem::Legend, false);
1056 QColor Plot2d_ViewFrame::getPlot2dCurveColor( Plot2d_Curve* plot2dCurve)
1059 // Get graphical curve
1060 QwtPlotCurve* plotCurve = dynamic_cast<QwtPlotCurve *>( getPlotObject( plot2dCurve));
1062 QPen pen = plotCurve->pen();
1063 QColor color = pen.color();
1070 * Create and display a segment with nbPoint=2 points
1072 QwtPlotCurve *Plot2d_ViewFrame::createSegment( double *X, double *Y, int nbPoint,
1073 Qt::PenStyle lineKind,
1076 QwtSymbol::Style markerKind, bool side)
1078 QwtPlotCurve* aPCurve = new QwtPlotCurve();
1080 aPCurve->setData( X, Y, nbPoint);
1082 aPCurve->setPen( QPen( lineColor, lineWidth, lineKind));
1084 aSymbol.setStyle( markerKind);
1085 aPCurve->setSymbol( aSymbol);
1087 // The segment must not have legend's entry
1088 aPCurve->setItemAttribute( QwtPlotItem::Legend, false);
1090 aPCurve->attach(myPlot);
1091 aPCurve->setYAxis(side ? QwtPlot::yRight : QwtPlot::yLeft);
1092 // To deallocate in EraseAll()
1093 myIntermittentSegmentList.append(aPCurve);
1098 Adds curve into view
1100 void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update )
1102 QwtPlotItem* anItem = displayObject( curve, update );
1103 // To deallocate in EraseAll()
1104 myQwtPlotCurveList.append( anItem);
1108 Adds curves into view
1110 void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update )
1113 foreach ( Plot2d_Curve* curve, curves )
1115 displayObjects( objects, update );
1121 void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
1123 eraseObject( curve, update );
1129 void Plot2d_ViewFrame::eraseCurves( const curveList& curves, bool update )
1132 foreach ( Plot2d_Curve* curve, curves )
1134 eraseObjects( objects, update );
1138 Updates curves attributes
1140 void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
1142 updateObject( curve, update );
1145 void Plot2d_ViewFrame::processFiltering(bool update)
1147 CurveDict aCurves = getCurves();
1148 AlgoPlot2dInputData aLData, aRData;
1149 CurveDict::iterator it;
1150 for ( it = aCurves.begin(); it != aCurves.end(); it++ ) {
1151 Plot2d_Object* objItem = it.value();
1152 if (objItem->getYAxis() == QwtPlot::yRight)
1153 aRData.append(objItem);
1155 aLData.append(objItem);
1158 // Normalization by left Y axis
1159 if (!myNormLMin && !myNormLMax)
1160 myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeNone);
1161 if(myNormLMin && myNormLMax)
1162 myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMinMax);
1164 myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMin);
1166 myLNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMax);
1168 myLNormAlgo->setInput(aLData);
1169 myLNormAlgo->execute();
1171 // Normalization by right Y axis
1172 if (!myNormRMin && !myNormRMax)
1173 myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeNone);
1174 if(myNormRMin && myNormRMax)
1175 myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMinMax);
1177 myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMin);
1179 myRNormAlgo->setNormalizationMode(Plot2d_NormalizeAlgorithm::NormalizeToMax);
1181 myRNormAlgo->setInput(aRData);
1182 myRNormAlgo->execute();
1184 for ( it = aCurves.begin(); it != aCurves.end(); it++) {
1185 QwtPlotCurve* item = it.key();
1186 Plot2d_Object* objItem = it.value();
1187 updatePlotItem(objItem, item);
1194 Gets lsit of displayed curves
1196 int Plot2d_ViewFrame::getCurves( curveList& curves ) const
1200 CurveDict aCurves = getCurves();
1201 CurveDict::iterator it;
1202 for ( it = aCurves.begin(); it != aCurves.end(); it++ )
1203 curves << it.value();
1204 return curves.count();
1207 CurveDict Plot2d_ViewFrame::getCurves() const
1210 ObjectDict::const_iterator it = myObjects.begin(), aLast = myObjects.end();
1211 for ( ; it != aLast; it++ ) {
1212 QwtPlotItem* anItem = it.key();
1213 if ( anItem && anItem->rtti() == QwtPlotItem::Rtti_PlotCurve ) {
1214 QwtPlotCurve* aPCurve = dynamic_cast<QwtPlotCurve*>( anItem );
1215 Plot2d_Curve* aCurve = dynamic_cast<Plot2d_Curve*>( it.value() );
1216 if ( aPCurve && aCurve )
1217 curves.insert( aPCurve, aCurve );
1224 Adds object into view
1226 QwtPlotItem* Plot2d_ViewFrame::displayObject( Plot2d_Object* object, bool update )
1228 QwtPlotItem* anItem = 0;
1232 if ( object->getYAxis() == QwtPlot::yRight )
1235 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
1236 // it crashes if switched to X/Y logarithmic mode, when one or more points have
1237 // non-positive X/Y coordinate
1238 if ( myXMode && object->getMinX() <= 0. )
1239 setHorScaleMode( 0, false );
1240 if ( myYMode && object->getMinY() <= 0. )
1241 setVerScaleMode( 0, false );
1243 if ( object->isAutoAssign() )
1244 object->autoFill( myPlot );
1246 if ( hasPlotObject( object ) ) {
1247 processFiltering(update);
1248 updateObject( object, update );
1251 anItem = object->createPlotItem();
1252 anItem->attach( myPlot );
1253 myObjects.insert( anItem, object );
1254 //myPlot->setCurveYAxis(curveKey, curve->getYAxis());
1256 if ( object->rtti() == QwtPlotItem::Rtti_PlotCurve )
1258 Plot2d_Curve* aCurve = dynamic_cast<Plot2d_Curve*>( object );
1262 //aCurve->setMarkerSize( myMarkerSize );
1264 if (aCurve->getMarkerSize() == 0)
1266 aCurve->setMarkerSize( myMarkerSize );
1269 processFiltering(update);
1270 updatePlotItem( aCurve, anItem );
1271 setCurveType( getPlotCurve( aCurve ), myCurveType );
1276 myPlot->updateYAxisIdentifiers();
1279 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1284 Adds objects into view
1286 void Plot2d_ViewFrame::displayObjects( const objectList& objects, bool update )
1288 //myPlot->setUpdatesEnabled( false ); // call this function deprecate update of legend
1289 foreach ( Plot2d_Object* object, objects )
1290 displayObject( object, false );
1292 //myPlot->setUpdatesEnabled( true );
1301 void Plot2d_ViewFrame::eraseObject( Plot2d_Object* object, bool update )
1306 if ( hasPlotObject( object ) ) {
1307 QwtPlotItem* anObject = getPlotObject( object );
1308 eraseBasicObject(anObject,update);
1310 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1313 void Plot2d_ViewFrame::eraseBasicObject( QwtPlotItem *object, bool update )
1319 myObjects.remove(object);
1321 myPlot->updateYAxisIdentifiers();
1329 void Plot2d_ViewFrame::eraseObjects( const objectList& objects, bool update )
1331 foreach ( Plot2d_Object* object, objects )
1332 eraseObject( object, false );
1337 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1340 void Plot2d_ViewFrame::eraseBasicObjects( const QList<QwtPlotItem*> &objects, bool update)
1342 foreach ( QwtPlotItem* object, objects )
1343 eraseBasicObject( object, false );
1347 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1351 Updates objects attributes
1353 void Plot2d_ViewFrame::updateObject( Plot2d_Object* object, bool update )
1357 if ( hasPlotObject( object ) ) {
1358 QwtPlotItem* anItem = getPlotObject( object );
1361 updatePlotItem(object, anItem );
1362 anItem->setVisible( true );
1365 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1370 Gets lsit of displayed curves
1372 int Plot2d_ViewFrame::getObjects( objectList& objects ) const
1376 ObjectDict::const_iterator it;
1377 for ( it = myObjects.begin(); it != myObjects.end(); it++ )
1378 objects << it.value();
1379 return objects.count();
1383 Returns true if the curve is visible
1385 bool Plot2d_ViewFrame::isVisible( Plot2d_Object* object ) const
1387 return object && hasPlotObject( object ) && getPlotObject( object )->isVisible();
1393 void Plot2d_ViewFrame::updateLegend( const Plot2d_Prs* prs )
1395 if ( !prs || prs->IsNull() )
1398 ObjectDict::iterator it = myObjects.begin();
1399 Plot2d_Object* anObj;
1400 for (; it != myObjects.end(); ++it ) {
1402 if ( hasPlotObject( anObj ) )
1403 getPlotObject( anObj )->setTitle( !anObj->getName().isEmpty() ?
1404 anObj->getName() : anObj->getVerTitle() );
1411 void Plot2d_ViewFrame::updateLegend() {
1412 if ( myPlot->getLegend() ) {
1413 ObjectDict::iterator it = myObjects.begin();
1414 for( ; it != myObjects.end(); ++it )
1415 it.key()->updateLegend(myPlot->getLegend());
1421 Fits the view to see all data
1423 void Plot2d_ViewFrame::fitAll()
1425 // Postpone fitAll operation until QwtPlot geometry
1426 // has been fully defined
1427 if ( !myPlot->polished() ){
1428 QApplication::postEvent( this, new QEvent( (QEvent::Type)FITALL_EVENT ) );
1432 myPlot->setAxisAutoScale( QwtPlot::yLeft );
1433 myPlot->setAxisAutoScale( QwtPlot::xBottom );
1436 double xmin, xmax, y1min, y1max, y2min, y2max;
1437 getFitRangeByCurves(xmin, xmax, y1min, y1max, y2min, y2max);
1439 myPlot->setAxisScale( QwtPlot::xBottom, xmin, xmax );
1440 myPlot->setAxisScale( QwtPlot::yLeft, y1min, y1max );
1443 myPlot->setAxisAutoScale( QwtPlot::yRight );
1445 myPlot->setAxisScale( QwtPlot::yRight, y2min, y2max );
1448 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1452 Fits the view to rectangle area (pixels)
1454 void Plot2d_ViewFrame::fitArea( const QRect& area )
1456 QRect rect = area.normalized();
1457 if ( rect.width() < MIN_RECT_SIZE ) {
1458 rect.setWidth( MIN_RECT_SIZE );
1459 rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
1461 if ( rect.height() < MIN_RECT_SIZE ) {
1462 rect.setHeight( MIN_RECT_SIZE );
1463 rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
1465 myPlot->setAxisScale( QwtPlot::yLeft,
1466 myPlot->invTransform( QwtPlot::yLeft, rect.top() ),
1467 myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
1469 myPlot->setAxisScale( QwtPlot::yRight,
1470 myPlot->invTransform( QwtPlot::yRight, rect.top() ),
1471 myPlot->invTransform( QwtPlot::yRight, rect.bottom() ) );
1472 myPlot->setAxisScale( QwtPlot::xBottom,
1473 myPlot->invTransform( QwtPlot::xBottom, rect.left() ),
1474 myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
1476 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1480 "Fit Data" command for TUI interface
1482 void Plot2d_ViewFrame::fitData(const int mode,
1483 const double xMin, const double xMax,
1484 const double yMin, const double yMax,
1485 double y2Min, double y2Max)
1487 if ( mode == 0 || mode == 2 ) {
1488 myPlot->setAxisScale( QwtPlot::yLeft, yMin, yMax );
1490 myPlot->setAxisScale( QwtPlot::yRight, y2Min, y2Max );
1492 if ( mode == 0 || mode == 1 )
1493 myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax );
1495 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
1499 Gets current fit ranges for view frame
1501 void Plot2d_ViewFrame::getFitRanges(double& xMin,double& xMax,
1502 double& yMin, double& yMax,
1503 double& y2Min, double& y2Max)
1505 int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).transform( myPlot->canvasMap( QwtPlot::xBottom ).s1() );
1506 int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).transform( myPlot->canvasMap( QwtPlot::xBottom ).s2() );
1507 int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).transform( myPlot->canvasMap( QwtPlot::yLeft ).s1() );
1508 int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).transform( myPlot->canvasMap( QwtPlot::yLeft ).s2() );
1509 xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
1510 xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
1511 yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
1512 yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
1516 int iyMin = myPlot->canvasMap( QwtPlot::yRight ).transform( myPlot->canvasMap( QwtPlot::yRight ).s1() );
1517 int iyMax = myPlot->canvasMap( QwtPlot::yRight ).transform( myPlot->canvasMap( QwtPlot::yRight ).s2() );
1518 y2Min = myPlot->invTransform(QwtPlot::yRight, iyMin);
1519 y2Max = myPlot->invTransform(QwtPlot::yRight, iyMax);
1524 Gets current fit ranges by Curves
1526 void Plot2d_ViewFrame::getFitRangeByCurves(double& xMin, double& xMax,
1527 double& yMin, double& yMax,
1528 double& y2Min, double& y2Max)
1530 bool emptyV1 = true, emptyV2 = true;
1531 if ( !myObjects.isEmpty() ) {
1532 ObjectDict::const_iterator it = myObjects.begin();
1533 for ( ; it != myObjects.end(); it++ ) {
1534 bool isV2 = it.value()->getYAxis() == QwtPlot::yRight;
1535 if ( !it.value()->isEmpty() ) {
1536 if ( emptyV1 && emptyV2 ) {
1548 isV2 ? emptyV2 = false : emptyV1 = false;
1549 xMin = qMin( xMin, it.value()->getMinX() );
1550 xMax = qMax( xMax, it.value()->getMaxX() );
1552 y2Min = qMin( y2Min, it.value()->getMinY() );
1553 y2Max = qMax( y2Max, it.value()->getMaxY() );
1556 yMin = qMin( yMin, it.value()->getMinY() );
1557 yMax = qMax( yMax, it.value()->getMaxY() );
1561 if ( xMin == xMax ) {
1562 xMin = xMin == 0. ? -1. : xMin - xMin/10.;
1563 xMax = xMax == 0. ? 1. : xMax + xMax/10.;
1565 if ( yMin == yMax ) {
1566 yMin = yMin == 0. ? -1. : yMin - yMin/10.;
1567 yMax = yMax == 0. ? 1 : yMax + yMax/10.;
1569 if ( y2Min == y2Max ) {
1570 y2Min = y2Min == 0. ? -1. : y2Min - y2Min/10.;
1571 y2Max = y2Max == 0. ? 1 : y2Max + y2Max/10.;
1575 if ( emptyV1 && emptyV2 ) {
1576 xMin = isModeHorLinear() ? 0. : 1.;
1577 xMax = isModeHorLinear() ? 1000. : 1e5;
1580 yMin = isModeVerLinear() ? 0. : 1.;
1581 yMax = isModeVerLinear() ? 1000. : 1e5;
1584 y2Min = isModeVerLinear() ? 0. : 1.;
1585 y2Max = isModeVerLinear() ? 1000. : 1e5;
1590 Tests if it is necessary to start operation on mouse action
1592 int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
1594 int btn = me.button() | me.modifiers();
1595 const int zoomBtn = Qt::ControlModifier | Qt::LeftButton;
1596 const int panBtn = Qt::ControlModifier | Qt::MidButton;
1597 const int fitBtn = Qt::ControlModifier | Qt::RightButton;
1600 if ( btn == zoomBtn ) {
1601 QPixmap zoomPixmap (imageZoomCursor);
1602 QCursor zoomCursor (zoomPixmap);
1603 myPlot->canvas()->setCursor( zoomCursor );
1606 else if ( btn == panBtn ) {
1607 myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
1610 else if ( btn == fitBtn ) {
1611 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1618 "Settings" toolbar action slot
1620 void Plot2d_ViewFrame::onSettings()
1622 #ifdef TEST_AUTOASSIGN
1623 typedef QMap<int,int> IList;
1624 typedef QMap<QString,int> SList;
1627 cols[ "red-min" ] = 1000;
1628 cols[ "red-max" ] = -1;
1629 cols[ "green-min" ] = 1000;
1630 cols[ "green-max" ] = -1;
1631 cols[ "blue-min" ] = 1000;
1632 cols[ "blue-max" ] = -1;
1633 for ( unsigned i = 0; i < 10000; i++ ) {
1634 QwtSymbol::Style typeMarker;
1636 Qt::PenStyle typeLine;
1637 myPlot->getNextMarker( typeMarker, color, typeLine );
1638 if ( mars.contains(typeMarker) )
1639 mars[ typeMarker ] = mars[ typeMarker ]+1;
1641 mars[ typeMarker ] = 0;
1642 if ( lins.contains(typeLine) )
1643 lins[ typeLine ] = lins[ typeLine ]+1;
1645 lins[ typeLine ] = 0;
1646 if ( cols[ "red-max" ] < color.red() )
1647 cols[ "red-max" ] = color.red();
1648 if ( cols[ "red-min" ] > color.red() )
1649 cols[ "red-min" ] = color.red();
1650 if ( cols[ "green-max" ] < color.green() )
1651 cols[ "green-max" ] = color.green();
1652 if ( cols[ "green-min" ] > color.green() )
1653 cols[ "green-min" ] = color.green();
1654 if ( cols[ "blue-max" ] < color.blue() )
1655 cols[ "blue-max" ] = color.blue();
1656 if ( cols[ "blue-min" ] > color.blue() )
1657 cols[ "blue-min" ] = color.blue();
1661 Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true, mySecondY );
1662 dlg->setMainTitle( myTitleEnabled, myTitle );
1663 dlg->setXTitle( myXTitleEnabled, myXTitle );
1664 dlg->setYTitle( myYTitleEnabled, myYTitle );
1666 dlg->setY2Title( myY2TitleEnabled, myY2Title );
1667 dlg->setCurveType( myCurveType );
1668 dlg->setLegend( myShowLegend, myLegendPos, myLegendFont, myLegendColor );
1669 dlg->setMarkerSize( myMarkerSize );
1670 dlg->setBackgroundColor( myBackground );
1671 dlg->setScaleMode(myXMode, myYMode);
1672 dlg->setLMinNormMode(myNormLMin);
1673 dlg->setLMaxNormMode(myNormLMax);
1674 dlg->setRMinNormMode(myNormRMin);
1675 dlg->setRMaxNormMode(myNormRMax);
1677 QVariant v = myPlot->property(PLOT2D_DEVIATION_LW);
1678 int lw = v.isValid() ? v.toInt() : 1;
1680 v = myPlot->property(PLOT2D_DEVIATION_TS);
1681 int ts = v.isValid() ? v.toInt() : 2;
1683 v = myPlot->property(PLOT2D_DEVIATION_COLOR);
1684 QColor cl = v.isValid() ? v.value<QColor>() : QColor(255,0,0);
1686 dlg->setDeviationMarkerLw(lw);
1687 dlg->setDeviationMarkerTs(ts);
1688 dlg->setDeviationMarkerCl(cl);
1691 dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
1692 myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ),
1693 myY2GridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yRight ) );
1694 dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
1695 myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ),
1696 myY2GridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yRight ) );
1697 if ( dlg->exec() == QDialog::Accepted ) {
1698 // horizontal axis title
1699 setTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), XTitle, false );
1700 // vertical left axis title
1701 setTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), YTitle, false );
1702 if (mySecondY) // vertical right axis title
1703 setTitle( dlg->isY2TitleEnabled(), dlg->getY2Title(), Y2Title, false );
1706 if( dlg->isMainTitleEnabled() && myTitle != dlg->getMainTitle() )
1707 myIsDefTitle = false;
1708 setTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), MainTitle, true );
1710 if ( myCurveType != dlg->getCurveType() ) {
1711 setCurveType( dlg->getCurveType(), false );
1714 if ( myShowLegend != dlg->isLegendEnabled() ) {
1715 showLegend( dlg->isLegendEnabled(), false );
1717 if ( myLegendPos != dlg->getLegendPos() ) {
1718 setLegendPos( dlg->getLegendPos() );
1720 if ( myLegendFont != dlg->getLegendFont() ) {
1721 setLegendFont( dlg->getLegendFont() );
1723 if ( myLegendColor != dlg->getLegendColor() ) {
1724 setLegendFontColor( dlg->getLegendColor() );
1728 if ( myMarkerSize != dlg->getMarkerSize() ) {
1729 setMarkerSize( dlg->getMarkerSize(), false );
1732 if ( myBackground != dlg->getBackgroundColor() ) {
1733 setBackgroundColor( dlg->getBackgroundColor() );
1736 bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled,
1737 aY2GridMajorEnabled, aY2GridMinorEnabled;
1738 int aXGridMaxMajor, aXGridMaxMinor, aYGridMaxMajor, aYGridMaxMinor,
1739 aY2GridMaxMajor, aY2GridMaxMinor;
1740 dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor,
1741 aY2GridMajorEnabled, aY2GridMaxMajor);
1742 dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor,
1743 aY2GridMinorEnabled, aY2GridMaxMinor);
1744 setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
1745 setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor,
1746 aY2GridMajorEnabled, aY2GridMaxMajor, aY2GridMinorEnabled, aY2GridMaxMinor, false );
1747 if ( myXMode != dlg->getXScaleMode() ) {
1748 setHorScaleMode( dlg->getXScaleMode() );
1750 if ( myYMode != dlg->getYScaleMode() ) {
1751 setVerScaleMode( dlg->getYScaleMode() );
1753 if ( myNormLMin != dlg->getLMinNormMode() ) {
1754 setNormLMinMode( dlg->getLMinNormMode() );
1756 if ( myNormLMax != dlg->getLMaxNormMode() ) {
1757 setNormLMaxMode( dlg->getLMaxNormMode() );
1759 if ( myNormRMin != dlg->getRMinNormMode() ) {
1760 setNormRMinMode( dlg->getRMinNormMode() );
1762 if ( myNormRMax != dlg->getRMaxNormMode() ) {
1763 setNormRMaxMode( dlg->getRMaxNormMode() );
1766 myPlot->setProperty(PLOT2D_DEVIATION_COLOR,
1767 dlg->getDeviationMarkerCl());
1768 myPlot->setProperty(PLOT2D_DEVIATION_LW,
1769 dlg->getDeviationMarkerLw());
1770 myPlot->setProperty(PLOT2D_DEVIATION_TS,
1771 dlg->getDeviationMarkerTs());
1776 // update preferences
1777 if ( dlg->isSetAsDefault() )
1784 "Analytical Curves" toolbar action slot
1786 void Plot2d_ViewFrame::onAnalyticalCurve()
1788 #ifndef DISABLE_PYCONSOLE
1789 Plot2d_AnalyticalCurveDlg dlg( this, this );
1791 updateAnalyticalCurves();
1795 void Plot2d_ViewFrame::addAnalyticalCurve( Plot2d_AnalyticalCurve* theCurve)
1797 #ifndef DISABLE_PYCONSOLE
1798 myAnalyticalCurves.append(theCurve);
1802 void Plot2d_ViewFrame::removeAnalyticalCurve( Plot2d_AnalyticalCurve* theCurve)
1804 #ifndef DISABLE_PYCONSOLE
1805 theCurve->setAction(Plot2d_AnalyticalCurve::ActRemoveFromView);
1810 Update Analytical curve
1812 void Plot2d_ViewFrame::updateAnalyticalCurve(Plot2d_AnalyticalCurve* c, bool updateView)
1814 #ifndef DISABLE_PYCONSOLE
1816 QwtScaleDiv* div = myPlot->axisScaleDiv(QwtPlot::xBottom);
1817 c->setRangeBegin(div->lowerBound());
1818 c->setRangeEnd(div->upperBound());
1820 c->setMarkerSize(myMarkerSize);
1821 QwtPlotItem* item = c->plotItem();
1823 switch( c->getAction() ) {
1824 case Plot2d_AnalyticalCurve::ActAddInView:
1825 if( c->isActive() ) {
1826 c->updatePlotItem();
1827 item->attach( myPlot );
1830 c->setAction(Plot2d_AnalyticalCurve::ActNothing);
1833 case Plot2d_AnalyticalCurve::ActUpdateInView:
1835 c->updatePlotItem();
1842 c->setAction(Plot2d_AnalyticalCurve::ActNothing);
1844 case Plot2d_AnalyticalCurve::ActRemoveFromView:
1847 myAnalyticalCurves.removeAll(c);
1858 Update Analytical curves
1860 void Plot2d_ViewFrame::updateAnalyticalCurves()
1862 #ifndef DISABLE_PYCONSOLE
1863 AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
1864 for( ; it != myAnalyticalCurves.end(); it++) {
1865 updateAnalyticalCurve(*it);
1872 Return list of the alalytical curves.
1874 AnalyticalCurveList Plot2d_ViewFrame::getAnalyticalCurves() const
1876 return myAnalyticalCurves;
1880 Get analytical curve by plot item.
1882 Plot2d_AnalyticalCurve* Plot2d_ViewFrame::getAnalyticalCurve(QwtPlotItem * theItem) {
1883 #ifndef DISABLE_PYCONSOLE
1884 AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
1885 for( ; it != myAnalyticalCurves.end(); it++) {
1886 if((*it)->plotItem() == theItem);
1894 "Fit Data" command slot
1896 void Plot2d_ViewFrame::onFitData()
1898 Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this, mySecondY );
1899 double xMin,xMax,yMin,yMax,y2Min,y2Max;
1900 getFitRanges(xMin,xMax,yMin,yMax,y2Min,y2Max);
1902 dlg->setRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1903 if ( dlg->exec() == QDialog::Accepted ) {
1904 int mode = dlg->getRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1905 fitData(mode,xMin,xMax,yMin,yMax,y2Min,y2Max);
1908 updateAnalyticalCurves();
1912 Change background color
1914 void Plot2d_ViewFrame::onChangeBackground()
1916 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
1917 if ( selColor.isValid() ) {
1918 setBackgroundColor( selColor );
1925 void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
1927 myCurveType = curveType;
1928 CurveDict aCurves = getCurves();
1929 CurveDict::iterator it = aCurves.begin();
1930 for ( ; it != aCurves.end(); it++ ) {
1931 QwtPlotCurve* crv = it.key();
1933 setCurveType( crv, myCurveType );
1937 emit vpCurveChanged();
1943 int Plot2d_ViewFrame::getCurveType() const
1950 \param curveKey - curve id
1951 \param title - new title
1953 void Plot2d_ViewFrame::setCurveTitle( Plot2d_Curve* curve, const QString& title )
1955 setObjectTitle( curve, title );
1960 \param object - object id
1961 \param title - new title
1963 void Plot2d_ViewFrame::setObjectTitle( Plot2d_Object* object, const QString& title )
1965 if ( object && hasPlotObject( object ) )
1966 getPlotObject( object )->setTitle( title );
1972 void Plot2d_ViewFrame::showLegend( bool show, bool update )
1974 myShowLegend = show;
1975 if ( myShowLegend ) {
1976 QwtLegend* legend = myPlot->legend();
1978 legend = new QwtLegend( myPlot );
1979 legend->setFrameStyle( QFrame::Box | QFrame::Sunken );
1981 legend->setItemMode( QwtLegend::ClickableItem );
1982 myPlot->insertLegend( legend );
1983 setLegendPos( myLegendPos );
1984 setLegendFont( myLegendFont );
1985 setLegendFontColor( myLegendColor );
1988 myPlot->insertLegend( 0 );
1994 Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
1996 void Plot2d_ViewFrame::setLegendPos( int pos )
1999 QwtLegend* legend = myPlot->legend();
2003 myPlot->insertLegend( legend, QwtPlot::LeftLegend );
2006 myPlot->insertLegend( legend, QwtPlot::RightLegend );
2009 myPlot->insertLegend( legend, QwtPlot::TopLegend );
2012 myPlot->insertLegend( legend, QwtPlot::BottomLegend );
2019 Gets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
2021 int Plot2d_ViewFrame::getLegendPos() const
2029 void Plot2d_ViewFrame::setLegendFont( const QFont& fnt )
2032 QwtLegend* legend = myPlot->legend();
2034 legend->setFont(fnt);
2041 QFont Plot2d_ViewFrame::getLegendFont() const
2043 return myLegendFont;
2047 Gets legend font color
2049 QColor Plot2d_ViewFrame::getLegendFontColor() const
2051 return myLegendColor;
2055 Sets legend font color
2057 void Plot2d_ViewFrame::setLegendFontColor( const QColor& col )
2059 myLegendColor = col;
2060 QwtLegend* legend = myPlot->legend();
2062 QPalette pal = legend->palette();
2063 pal.setColor( QPalette::Text, col );
2064 legend->setPalette( pal );
2069 Sets new marker size
2071 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
2073 if ( myMarkerSize != size )
2075 myMarkerSize = size;
2076 CurveDict aCurves = getCurves();
2077 CurveDict::iterator it = aCurves.begin();
2078 for ( ; it != aCurves.end(); it++ ) {
2079 QwtPlotCurve* crv = it.key();
2082 QwtSymbol aSymbol = crv->symbol();
2083 aSymbol.setSize( myMarkerSize, myMarkerSize );
2084 crv->setSymbol( aSymbol );
2086 it.value()->setMarkerSize( myMarkerSize );
2095 Gets new marker size
2097 int Plot2d_ViewFrame::getMarkerSize() const
2099 return myMarkerSize;
2103 Sets background color
2105 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
2107 myBackground = color;
2108 myPlot->canvas()->setPalette( myBackground );
2109 myPlot->setPalette( myBackground );
2110 if ( myPlot->getLegend() ) {
2111 QPalette aPal = myPlot->getLegend()->palette();
2112 for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
2113 aPal.setColor( QPalette::Base, myBackground );
2114 aPal.setColor( QPalette::Background, myBackground );
2116 myPlot->getLegend()->setPalette( aPal );
2122 Gets background color
2124 QColor Plot2d_ViewFrame::backgroundColor() const
2126 return myBackground;
2129 Sets hor.axis grid parameters
2131 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax,
2132 bool xMinorEnabled, const int xMinorMax,
2135 myXGridMajorEnabled = xMajorEnabled;
2136 myXGridMinorEnabled = xMinorEnabled;
2137 myXGridMaxMajor = xMajorMax;
2138 myXGridMaxMinor = xMinorMax;
2140 myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
2141 myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
2143 QwtPlotGrid* grid = myPlot->grid();
2144 if ( myPlot->axisScaleDiv( QwtPlot::xBottom ) )
2145 grid->setXDiv( *myPlot->axisScaleDiv( QwtPlot::xBottom ) );
2146 grid->enableX( myXGridMajorEnabled );
2147 grid->enableXMin( myXGridMinorEnabled );
2153 Sets ver.axis grid parameters
2155 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax,
2156 bool yMinorEnabled, const int yMinorMax,
2157 bool y2MajorEnabled, const int y2MajorMax,
2158 bool y2MinorEnabled, const int y2MinorMax,
2161 myYGridMajorEnabled = yMajorEnabled;
2162 myYGridMinorEnabled = yMinorEnabled;
2163 myYGridMaxMajor = yMajorMax;
2164 myYGridMaxMinor = yMinorMax;
2167 myY2GridMajorEnabled = y2MajorEnabled;
2168 myY2GridMinorEnabled = y2MinorEnabled;
2169 myY2GridMaxMajor = y2MajorMax;
2170 myY2GridMaxMinor = y2MinorMax;
2172 myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
2173 myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
2176 myPlot->setAxisMaxMajor( QwtPlot::yRight, myY2GridMaxMajor );
2177 myPlot->setAxisMaxMinor( QwtPlot::yRight, myY2GridMaxMinor );
2180 QwtPlotGrid* grid = myPlot->grid();
2181 if ( myPlot->axisScaleDiv( QwtPlot::yLeft ) )
2182 grid->setYDiv( *myPlot->axisScaleDiv( QwtPlot::yLeft ) );
2185 if (myYGridMajorEnabled) {
2186 grid->enableY( myYGridMajorEnabled );
2187 grid->enableYMin( myYGridMinorEnabled );
2189 else if (myY2GridMajorEnabled) {
2190 if ( myPlot->axisScaleDiv( QwtPlot::yRight ) )
2191 grid->setYDiv( *myPlot->axisScaleDiv( QwtPlot::yRight ) );
2192 grid->enableY( myY2GridMajorEnabled );
2193 grid->enableYMin( myY2GridMinorEnabled );
2196 grid->enableY( false );
2197 grid->enableYMin( false );
2201 grid->enableY( myYGridMajorEnabled );
2202 grid->enableYMin( myYGridMinorEnabled );
2209 Sets title for some axis
2211 void Plot2d_ViewFrame::setTitle( bool enabled, const QString& title,
2212 ObjectType type, bool update )
2216 myTitleEnabled = enabled;
2218 myPlot->setTitle( myTitleEnabled ? myTitle : QString() );
2221 myXTitleEnabled = enabled;
2223 myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString() );
2226 myYTitleEnabled = enabled;
2228 myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString() );
2231 myY2TitleEnabled = enabled;
2233 myPlot->setAxisTitle( QwtPlot::yRight, myY2TitleEnabled ? myY2Title : QString() );
2242 Sets title for some axis
2244 QString Plot2d_ViewFrame::getTitle( ObjectType type ) const
2249 title = myTitle; break;
2251 title = myXTitle; break;
2253 title = myYTitle; break;
2255 title = myY2Title; break;
2262 Sets font for Plot2d object : title or axis
2264 void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update)
2268 myPlot->title().setFont(font);
2271 myPlot->axisTitle(QwtPlot::xBottom).setFont(font); break;
2273 myPlot->axisTitle(QwtPlot::yLeft).setFont(font); break;
2275 myPlot->axisTitle(QwtPlot::yRight).setFont(font); break;
2277 myPlot->setAxisFont(QwtPlot::xBottom, font); break;
2279 myPlot->setAxisFont(QwtPlot::yLeft, font); break;
2281 myPlot->setAxisFont(QwtPlot::yRight, font); break;
2288 Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
2290 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
2292 if ( myXMode == mode )
2295 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
2296 // it crashes if switched to X/Y logarithmic mode, when one or more points have
2297 // non-positive X/Y coordinate
2298 if ( mode && !isXLogEnabled() ){
2299 SUIT_MessageBox::warning(this, tr("WARNING"), tr("WRN_XLOG_NOT_ALLOWED"));
2305 myPlot->setLogScale(QwtPlot::xBottom, myXMode != 0);
2309 emit vpModeHorChanged();
2313 Gets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
2315 int Plot2d_ViewFrame::getHorScaleMode() const
2321 Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
2323 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
2325 if ( myYMode == mode )
2328 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
2329 // it crashes if switched to X/Y logarithmic mode, when one or more points have
2330 // non-positive X/Y coordinate
2331 if ( mode && !isYLogEnabled() ){
2332 SUIT_MessageBox::warning(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"));
2337 myPlot->setLogScale(QwtPlot::yLeft, myYMode != 0);
2339 myPlot->setLogScale( QwtPlot::yRight, myYMode != 0 );
2343 emit vpModeVerChanged();
2347 Gets scale mode for vertical axis: 0 - linear, 1 - logarithmic
2349 int Plot2d_ViewFrame::getVerScaleMode() const
2355 Sets normalization mode to the global maximum by left Y axis
2357 void Plot2d_ViewFrame::setNormLMaxMode( bool mode, bool update )
2359 if ( myNormLMax == mode )
2363 processFiltering(true);
2366 emit vpNormLModeChanged();
2370 Gets normalization mode to the global maximum by left Y axis
2372 bool Plot2d_ViewFrame::getNormLMaxMode() const
2378 Sets normalization mode to the global minimum by left Y axis
2380 void Plot2d_ViewFrame::setNormLMinMode( bool mode, bool update )
2382 if ( myNormLMin == mode )
2386 processFiltering(true);
2389 emit vpNormLModeChanged();
2393 Gets normalization mode to the global minimum by left Y axis
2395 bool Plot2d_ViewFrame::getNormLMinMode() const
2401 Sets normalization mode to the global maximum by right Y axis
2403 void Plot2d_ViewFrame::setNormRMaxMode( bool mode, bool update )
2405 if ( myNormRMax == mode )
2409 processFiltering(true);
2412 emit vpNormRModeChanged();
2416 Gets normalization mode to the global maximum by right Y axis
2418 bool Plot2d_ViewFrame::getNormRMaxMode() const
2424 Sets normalization mode to the global minimum by right Y axis
2426 void Plot2d_ViewFrame::setNormRMinMode( bool mode, bool update )
2428 if ( myNormRMin == mode )
2432 processFiltering(true);
2435 emit vpNormRModeChanged();
2439 Gets normalization mode to the global minimum by right Y axis
2441 bool Plot2d_ViewFrame::getNormRMinMode() const
2447 Return, scale mode for horizontal axis
2449 bool Plot2d_ViewFrame::isModeHorLinear()
2451 return (myXMode == 0 ? true : false);
2455 Return, scale mode for vertical axis
2457 bool Plot2d_ViewFrame::isModeVerLinear()
2459 return (myYMode == 0 ? true : false);
2463 Return \c True if curves are normalize to the global maximum by left Y axis
2465 bool Plot2d_ViewFrame::isNormLMaxMode()
2467 return (myNormLMax ? true : false);
2471 Return \c True if curves are normalize to the global minimum by left Y axis
2473 bool Plot2d_ViewFrame::isNormLMinMode()
2475 return (myNormLMin ? true : false);
2479 Return \c True if curves are normalize to the global maximum by right Y axis
2481 bool Plot2d_ViewFrame::isNormRMaxMode()
2483 return (myNormRMax ? true : false);
2487 Return \c True if curves are normalize to the global minimum by right Y axis
2489 bool Plot2d_ViewFrame::isNormRMinMode()
2491 return (myNormRMin ? true : false);
2495 Return \c True if legend is shown
2497 bool Plot2d_ViewFrame::isLegendShow() const
2499 return myShowLegend;
2503 Slot, called when user presses mouse button
2505 void Plot2d_ViewFrame::plotMousePressed( const QMouseEvent& me )
2507 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
2509 aParent->putInfo(getInfo(me.pos()));
2510 if ( myOperation == NoOpId )
2511 myOperation = testOperation( me );
2512 if ( myOperation != NoOpId ) {
2514 if ( myOperation == GlPanId ) {
2515 myPlot->setAxisScale( QwtPlot::yLeft,
2516 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2,
2517 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2 );
2518 myPlot->setAxisScale( QwtPlot::xBottom,
2519 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2,
2520 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
2522 myPlot->setAxisScale( QwtPlot::yRight,
2523 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2,
2524 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2 );
2529 int btn = me.button() | me.modifiers();
2530 if (btn == Qt::RightButton) {
2531 QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
2532 me.pos(), me.button(), me.buttons(), me.modifiers() );
2533 // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
2534 parent()->eventFilter(this, aEvent);
2540 Slot, called when user moves mouse
2542 bool Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
2544 int dx = me.pos().x() - myPnt.x();
2545 int dy = me.pos().y() - myPnt.y();
2548 if ( myOperation != NoOpId) {
2549 if ( myOperation == ZoomId ) {
2550 this->incrementalZoom( dx, dy );
2554 else if ( myOperation == PanId ) {
2555 this->incrementalPan( dx, dy );
2561 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
2563 aParent->putInfo(getInfo(me.pos()));
2568 Slot, called when user releases mouse
2570 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
2572 if ( myOperation == NoOpId && me.button() == Qt::RightButton && me.modifiers() != Qt::ControlModifier )
2574 QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
2575 me.pos(), me.globalPos() );
2576 emit contextMenuRequested( &aEvent );
2579 updateAnalyticalCurves();
2581 myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
2582 myPlot->defaultPicker();
2584 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
2586 aParent->putInfo(tr("INF_READY"));
2587 myOperation = NoOpId;
2590 Slot, called when user wheeling mouse
2592 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
2594 QwtPlotLayout* pl = myPlot->plotLayout();
2596 // compute zooming factor
2597 double aDelta = event->delta();
2598 double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.;
2600 bool scaleXBottom = pl->scaleRect(QwtPlot::xBottom).contains( event->pos() ) ||
2601 pl->canvasRect().contains( event->pos() );
2602 bool scaleYLeft = pl->scaleRect(QwtPlot::yLeft).contains( event->pos() ) ||
2603 pl->canvasRect().contains( event->pos() );
2604 bool scaleYRight = mySecondY && ( pl->scaleRect(QwtPlot::yRight).contains( event->pos() ) ||
2605 pl->canvasRect().contains( event->pos() ) );
2607 // scale x bottom axis
2608 if ( scaleXBottom ) {
2609 QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
2610 if ( xMap.s2() - xMap.s1() > 1.0e-12 || aScale > 1 )
2611 myPlot->setAxisScale( QwtPlot::xBottom, xMap.s1(), xMap.s1() + aScale*(xMap.s2() - xMap.s1()) );
2614 // scale y left axis
2616 QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
2617 if ( yMap.s2() - yMap.s1() > 1.0e-12 || aScale > 1 )
2618 myPlot->setAxisScale( QwtPlot::yLeft, yMap.s1(), yMap.s1() + aScale*(yMap.s2() - yMap.s1()) );
2621 // scale y right axis (note: mySecondY value is checked above)
2622 if ( scaleYRight ) {
2623 QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yRight );
2624 if ( yMap.s2() - yMap.s1() > 10e-12 || aScale > 1 )
2625 myPlot->setAxisScale( QwtPlot::yRight, yMap.s1(), yMap.s1() + aScale*(yMap.s2() - yMap.s1()) );
2631 if ( myPlot->zoomer() ) myPlot->zoomer()->setZoomBase();
2632 // store current mouse position
2633 myPnt = event->pos();
2634 // update analytical curves
2635 updateAnalyticalCurves();
2639 Returns qwt plot curve if it is existed in map of curves and 0 otherwise
2641 QwtPlotCurve* Plot2d_ViewFrame::getPlotCurve( Plot2d_Curve* curve ) const
2643 return dynamic_cast<QwtPlotCurve*>( getPlotObject( curve ) );
2646 Returns true if qwt plot curve is existed in map of curves and false otherwise
2648 bool Plot2d_ViewFrame::hasPlotCurve( Plot2d_Curve* curve ) const
2650 return hasPlotObject( curve );
2654 Returns qwt plot curve if it is existed in map of curves and 0 otherwise
2656 QwtPlotItem* Plot2d_ViewFrame::getPlotObject( Plot2d_Object* object ) const
2658 ObjectDict::const_iterator it = myObjects.begin();
2659 for ( ; it != myObjects.end(); it++ ) {
2660 if ( it.value() == object )
2666 Returns true if qwt plot curve is existed in map of curves and false otherwise
2668 bool Plot2d_ViewFrame::hasPlotObject( Plot2d_Object* object ) const
2670 ObjectDict::const_iterator it = myObjects.begin();
2671 for ( ; it != myObjects.end(); it++ ) {
2672 if ( it.value() == object )
2681 void Plot2d_ViewFrame::setCurveType( QwtPlotCurve* curve, int curveType )
2685 if ( myCurveType == 0 )
2686 curve->setStyle( QwtPlotCurve::Dots );//QwtCurve::NoCurve
2687 else if ( myCurveType == 1 ) {
2688 curve->setStyle( QwtPlotCurve::Lines );
2689 curve->setCurveAttribute( QwtPlotCurve::Fitted, false );
2691 else if ( myCurveType == 2 ) {
2692 curve->setStyle( QwtPlotCurve::Lines );
2693 QwtSplineCurveFitter* fitter = new QwtSplineCurveFitter();
2694 fitter->setSplineSize( 250 );
2695 curve->setCurveAttribute( QwtPlotCurve::Fitted, true );
2696 curve->setCurveFitter( fitter );
2701 View operations : Pan view
2703 void Plot2d_ViewFrame::onViewPan()
2705 QCursor panCursor (Qt::SizeAllCursor);
2706 myPlot->canvas()->setCursor( panCursor );
2707 myOperation = PanId;
2710 View operations : Zoom view
2712 void Plot2d_ViewFrame::onViewZoom()
2714 QPixmap zoomPixmap (imageZoomCursor);
2715 QCursor zoomCursor (zoomPixmap);
2716 myPlot->canvas()->setCursor( zoomCursor );
2717 myOperation = ZoomId;
2720 View operations : Fot All
2722 void Plot2d_ViewFrame::onViewFitAll()
2727 View operations : Fit Area
2729 void Plot2d_ViewFrame::onViewFitArea()
2731 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
2732 myOperation = FitAreaId;
2733 myPlot->setPickerMousePattern( Qt::LeftButton );
2736 View operations : Global panning
2738 void Plot2d_ViewFrame::onViewGlobalPan()
2740 QPixmap globalPanPixmap (imageCrossCursor);
2741 QCursor glPanCursor (globalPanPixmap);
2742 myPlot->canvas()->setCursor( glPanCursor );
2743 myPlot->setLogScale(QwtPlot::xBottom, false);
2744 myPlot->setLogScale(QwtPlot::yLeft, false);
2746 myPlot->setLogScale(QwtPlot::yRight, false);
2748 QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
2749 QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
2751 myXDistance = xMap.s2() - xMap.s1();
2752 myYDistance = yMap.s2() - yMap.s1();
2755 QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
2756 myYDistance2 = yMap2.s2() - yMap2.s1();
2759 myOperation = GlPanId;
2763 Precaution for logarithmic X scale
2765 bool Plot2d_ViewFrame::isXLogEnabled() const
2767 bool allPositive = true;
2768 ObjectDict::const_iterator it = myObjects.begin();
2769 for ( ; allPositive && it != myObjects.end(); it++ )
2770 allPositive = ( it.value()->getMinX() > 0. );
2775 Precaution for logarithmic Y scale
2777 bool Plot2d_ViewFrame::isYLogEnabled() const
2779 bool allPositive = true;
2780 ObjectDict::const_iterator it = myObjects.begin();
2781 for ( ; allPositive && it != myObjects.end(); it++ )
2782 allPositive = ( it.value()->getMinY() > 0. );
2789 void Plot2d_ViewFrame::setEnableAxis( QwtPlot::Axis theAxis, bool isEnable )
2791 if ( myPlot->axisEnabled( theAxis ) == isEnable )
2793 myPlot->enableAxis( theAxis, isEnable );
2794 if ( theAxis == QwtPlot::yRight )
2795 mySecondY = isEnable;
2798 class Plot2d_QwtPlotZoomer : public QwtPlotZoomer
2801 Plot2d_QwtPlotZoomer( int xAxis, int yAxis, QwtPlotCanvas* canvas )
2802 : QwtPlotZoomer( xAxis, yAxis, canvas )
2804 qApp->installEventFilter( this );
2805 // now picker working after only a button pick.
2806 // after click on button FitArea in toolbar of the ViewFrame.
2808 ~Plot2d_QwtPlotZoomer() {};
2814 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
2815 : QwtPlot( parent ),
2816 myIsPolished( false )
2818 // Create alternative scales
2819 setAxisScaleDraw( QwtPlot::yLeft, new Plot2d_ScaleDraw() );
2820 setAxisScaleDraw( QwtPlot::xBottom, new Plot2d_ScaleDraw() );
2821 setAxisScaleDraw( QwtPlot::yRight, new Plot2d_ScaleDraw() );
2823 myPlotZoomer = new Plot2d_QwtPlotZoomer( QwtPlot::xBottom, QwtPlot::yLeft, canvas() );
2824 myPlotZoomer->setSelectionFlags( QwtPicker::DragSelection | QwtPicker::CornerToCorner );
2825 myPlotZoomer->setTrackerMode( QwtPicker::AlwaysOff );
2826 myPlotZoomer->setRubberBand( QwtPicker::RectRubberBand );
2827 myPlotZoomer->setRubberBandPen( QColor( Qt::green ) );
2831 // auto scaling by default
2832 setAxisAutoScale( QwtPlot::yLeft );
2833 setAxisAutoScale( QwtPlot::yRight );
2834 setAxisAutoScale( QwtPlot::xBottom );
2838 myGrid = new QwtPlotGrid();
2839 QPen aMajPen = myGrid->majPen();
2840 aMajPen.setStyle( Qt::DashLine );
2841 myGrid->setPen( aMajPen );
2843 myGrid->enableX( false );
2844 myGrid->enableXMin( false );
2845 myGrid->enableY( false );
2846 myGrid->enableYMin( false );
2848 myGrid->attach( this );
2850 setMouseTracking( false );
2851 canvas()->setMouseTracking( true );
2853 myPlotZoomer->setEnabled( true );
2854 myPlotZoomer->setZoomBase();
2856 setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) );
2859 Plot2d_Plot2d::~Plot2d_Plot2d()
2864 \set axis scale engine - linear or log10
2866 void Plot2d_Plot2d::setLogScale( int axisId, bool log10 )
2869 setAxisScaleEngine( axisId, new QwtLog10ScaleEngine() );
2871 setAxisScaleEngine( axisId, new QwtLinearScaleEngine() );
2875 Recalculates and redraws Plot 2d view
2877 void Plot2d_Plot2d::replot()
2879 // the following code is intended to enable only axes
2880 // that are really used by displayed objects
2881 bool enableXBottom = false, enableXTop = false;
2882 bool enableYLeft = false, enableYRight = false;
2883 const QwtPlotItemList& items = itemList();
2884 QwtPlotItemIterator it;
2885 for ( it = items.begin(); it != items.end(); it++ ) {
2886 QwtPlotItem* item = *it;
2888 enableXBottom |= item->xAxis() == QwtPlot::xBottom;
2889 enableXTop |= item->xAxis() == QwtPlot::xTop;
2890 enableYLeft |= item->yAxis() == QwtPlot::yLeft;
2891 enableYRight |= item->yAxis() == QwtPlot::yRight;
2894 enableAxis( QwtPlot::xBottom, enableXBottom );
2895 enableAxis( QwtPlot::xTop, enableXTop );
2896 enableAxis( QwtPlot::yLeft, enableYLeft );
2897 enableAxis( QwtPlot::yRight, enableYRight );
2899 updateLayout(); // to fix bug(?) of Qwt - view is not updated when title is changed
2906 QwtLegend* Plot2d_Plot2d::getLegend()
2908 #if QWT_VERSION < 0x040200
2911 return legend(); /* mpv: porting to the Qwt 4.2.0 */
2916 \return the recommended size for the widget
2918 QSize Plot2d_Plot2d::sizeHint() const
2920 return QwtPlot::minimumSizeHint();
2924 return minimum size for qwt plot
2926 QSize Plot2d_Plot2d::minimumSizeHint() const
2928 return QSize( 0, 0 );
2929 // QSize aSize = QwtPlot::minimumSizeHint();
2930 // return QSize(aSize.width()*3/4, aSize.height());
2933 void Plot2d_Plot2d::defaultPicker()
2935 myPlotZoomer->setMousePattern( QwtEventPattern::MouseSelect1,
2936 Qt::RightButton, Qt::ControlModifier ); // zooming button
2937 for ( int i = QwtEventPattern::MouseSelect2; i < QwtEventPattern::MouseSelect6; i++ )
2938 myPlotZoomer->setMousePattern( i, Qt::NoButton, Qt::NoButton );
2941 void Plot2d_Plot2d::setPickerMousePattern( int button, int state )
2943 myPlotZoomer->setMousePattern( QwtEventPattern::MouseSelect1, button, state );
2947 * Set the point picker associated with a graphic view
2949 void Plot2d_Plot2d::setPicker( Plot2d_QwtPlotPicker *picker)
2955 * Create marker and tooltip associed with a point
2957 QwtPlotMarker* Plot2d_Plot2d::createMarkerAndTooltip( QwtSymbol symbol,
2961 Plot2d_QwtPlotPicker *picker)
2963 QwtPlotMarker* aPlotMarker = new QwtPlotMarker();
2965 aPlotMarker->setSymbol( symbol ); // symbol must have a color
2966 aPlotMarker->setLabelAlignment( Qt::AlignTop);
2967 aPlotMarker->setXValue(X);
2968 aPlotMarker->setYValue(Y);
2970 aPlotMarker->attach(this);
2972 // Associate a tooltip with the point's marker
2973 // PB: how to obtain a tooltip with a rectangular frame ?
2974 //QwtText tooltip ("X=" + QString::number(X) + " Y=" + QString::number(Y) );
2976 QwtText text (tooltip);
2977 //QColor tooltipColor( 245, 222, 179); // Wheat -RGB (0 a 255)
2978 QColor tooltipColor( 253, 245, 230); // OldLace
2979 text.setBackgroundBrush( QBrush(tooltipColor)); //, Qt::SolidPattern));
2982 picker->pMarkers.append( aPlotMarker);
2983 picker->pMarkersToolTip[ aPlotMarker] = text;
2988 bool Plot2d_Plot2d::polished() const
2990 return myIsPolished;
2993 QwtPlotGrid* Plot2d_Plot2d::grid() const
2998 QwtPlotZoomer* Plot2d_Plot2d::zoomer() const
3000 return myPlotZoomer;
3004 Slot: checks the current labels format and change it if needed
3006 void Plot2d_Plot2d::onScaleDivChanged()
3008 QwtScaleWidget* aSW = 0;
3009 if ( ( aSW = dynamic_cast<QwtScaleWidget*>(sender()) ) ) {
3011 switch ( aSW->alignment() ) {
3012 case QwtScaleDraw::BottomScale:
3013 axisId = QwtPlot::xBottom;
3015 case QwtScaleDraw::LeftScale:
3016 axisId = QwtPlot::yLeft;
3018 case QwtScaleDraw::RightScale:
3019 axisId = QwtPlot::yRight;
3025 if ( axisId >= 0 ) {
3026 QwtScaleMap map = canvasMap(axisId);
3027 double aDist = fabs(map.s2()-map.s1()) / (axisMaxMajor(axisId)*axisMaxMinor(axisId));
3030 aDistStr.sprintf("%e",aDist);
3031 int aPrecision = aDistStr.right(aDistStr.length()-aDistStr.indexOf('e')-2).toInt();
3033 QwtScaleDraw* aQwtSD = axisScaleDraw(axisId);
3034 Plot2d_ScaleDraw* aPlot2dSD = dynamic_cast<Plot2d_ScaleDraw*>(aQwtSD);
3035 if ( ( !aPlot2dSD && aPrecision > 6 ) || ( aPlot2dSD && aPlot2dSD->precision() != aPrecision ) )
3036 setAxisScaleDraw( axisId, new Plot2d_ScaleDraw(*aQwtSD, 'f', aPrecision) );
3042 Updates identifiers of Y axis type in the legend.
3044 void Plot2d_Plot2d::updateYAxisIdentifiers()
3046 bool enableYLeft = false, enableYRight = false;
3047 const QwtPlotItemList& items = itemList();
3048 QwtPlotItemIterator it;
3049 for ( it = items.begin(); it != items.end(); it++ ) {
3050 QwtPlotItem* item = *it;
3052 enableYLeft |= item->yAxis() == QwtPlot::yLeft;
3053 enableYRight |= item->yAxis() == QwtPlot::yRight;
3057 // if several curves are attached to different axes
3058 // display corresponding identifiers in the legend,
3059 // otherwise hide them
3060 for ( it = items.begin(); it != items.end(); it++ ) {
3061 QwtPlotItem* item = *it;
3062 if ( Plot2d_QwtPlotCurve* aPCurve = dynamic_cast<Plot2d_QwtPlotCurve*>( item ) )
3063 aPCurve->setYAxisIdentifierEnabled( enableYLeft && enableYRight );
3064 if ( item && item->isVisible() && legend() )
3065 item->updateLegend( legend() );
3070 Sets the flag saying that QwtPlot geometry has been fully defined.
3072 void Plot2d_Plot2d::polish()
3075 myIsPolished = true;
3078 // Methods to manage axis graduations
3080 /* Create definition and graduations of axes
3082 void Plot2d_Plot2d::createAxisScaleDraw()
3084 myScaleDraw = new Plot2d_AxisScaleDraw( this);
3088 /* Stock X axis's ticks in the drawing zone
3090 void Plot2d_Plot2d::applyTicks()
3092 myScaleDraw->applyTicks();
3096 /* Unactivate automatic ticks drawing (call to method Plot2d_AxisScaleDraw::draw() )
3098 * - number call to ticks drawing (for information) : numcall
3100 void Plot2d_Plot2d::unactivAxisScaleDraw( int numcall)
3102 // Memorize X axis (myScaleDraw already exists) in the drawing zone
3103 //setAxisScaleDraw( QwtPlot::xBottom, myScaleDraw); // heritage of QwtPlot
3105 myScaleDraw->unactivTicksDrawing( numcall);
3109 /* Draw ticks and labels on X axis of the drawing zone
3110 * Draw systems' names under the X axis of the drawing zone
3111 * Draw vertical segments between X axis's intervals of the systems
3113 * - left and right margins for ticks : XLeftMargin, XRightMargin
3114 * - for each named system :
3115 * positions and labels for ticks on X axis : devicesPosLabelTicks
3117 * The true drawings will be realized by the method Plot2d_AxisScaleDraw::draw()
3120 void Plot2d_Plot2d::displayXTicksAndLabels(
3121 double XLeftMargin, double XRightMargin,
3122 const QList< QPair< QString, QMap<double, QString> > > & devicesPosLabelTicks)
3123 // name position label
3126 //std::cout << "Plot2d_Plot2d::displayXTicksAndLabels() 1" << std::endl;
3128 int nbDevices = devicesPosLabelTicks.size();
3130 //std::cout << " Nombre de systemes = " << nbDevices << std::endl;
3131 if (nbDevices == 0) return;
3133 // For drawing systems' names, their positions must be in the allTicks list
3134 // (cf class Plot2d_AxisScaleDraw)
3136 // Liste of ticks' positions and systems' names
3137 QList<double> allTicks;
3139 double devXmin, devXmax; // X interval of a system
3140 double gapXmin, gapXmax; // X interval between two systems
3141 double devLabPos; // Label's position of a system
3142 double segmentPos; // Position of the vertical segment between current system and the next
3144 // 1)- Search for the system whose X interval is the most to the left
3147 double XminMin = 1.e+12;
3151 for (int idev=0; idev < nbDevices; idev++)
3153 QPair< QString, QMap<double,QString> > paire = devicesPosLabelTicks.at(idev);
3155 QString deviceLabel = paire.first;
3157 // Ticks' map of the system
3158 QMap<double,QString> devPosLabelTicks = paire.second;
3160 QList<double> posTicks = devPosLabelTicks.keys();
3162 // List's items increasing sorting
3163 qSort( posTicks.begin(), posTicks.end() ); // iterators
3165 // X interval for the system
3166 devXmin = posTicks.first();
3167 devXmax = posTicks.last();
3169 if (devXmin < XminMin)
3177 // 2)- Ticks, systems' names, verticals segments
3179 for (int idev=0; idev < nbDevices; idev++)
3181 QPair< QString, QMap<double,QString> > paire = devicesPosLabelTicks.at(idev);
3183 QString deviceLabel = paire.first;
3185 std::string std_label = deviceLabel.toStdString();
3186 //const char *c_label = std_label.c_str();
3187 //std::cout << " deviceLabel: |" << c_label << "|" << std::endl;
3189 // Ticks' map of the system
3190 QMap<double,QString> devPosLabelTicks = paire.second;
3192 int nbTicks = devPosLabelTicks.size();
3194 QList<double> posTicks = devPosLabelTicks.keys();
3196 // List's items increasing sorting
3197 qSort( posTicks.begin(), posTicks.end() ); // iterators
3199 // X interval for the system
3200 devXmin = posTicks.first();
3201 devXmax = posTicks.last();
3203 // Stock ticks' positions and labels on X axis
3207 for (int itic=0; itic < nbTicks; itic++)
3209 pos = posTicks.at(itic);
3210 label = devPosLabelTicks[pos];
3212 myScaleDraw->setLabelTick( pos, label, false);
3214 std::string std_label = label.toStdString();
3215 //const char *c_label = std_label.c_str();
3216 //std::cout << " tick " << itic << " : pos= " << pos << ", label= |" << c_label << "|" << std::endl;
3218 allTicks.append( posTicks);
3220 // Compute the position of the system's label
3221 if (idev == ileftDev)
3223 devLabPos = devXmin + 0.25*(devXmax - devXmin);
3227 devLabPos = devXmin + 0.50*(devXmax - devXmin);
3229 allTicks.append( devLabPos);
3231 // Stock position and name of the system under X axis
3232 myScaleDraw->setLabelTick( devLabPos, deviceLabel, true);
3236 // Create the vertical segment between the current system and the next
3238 segmentPos = gapXmin + 0.5*(gapXmax - gapXmin);
3240 createSeparationLine( segmentPos);
3245 // List's items increasing sorting
3246 qSort( allTicks.begin(), allTicks.end() ); // iterators
3248 // Stock the interval of X's values
3249 double lowerBound = allTicks.first() - XLeftMargin;
3250 double upperBound = allTicks.last() + XRightMargin;
3251 myScaleDraw->setInterval( lowerBound, upperBound);
3253 // For each system, stock the position of the X's ticks and those of the name
3254 myScaleDraw->setTicks( allTicks); // do not draw the ticks
3256 // Memorize the X axis in the drawing zone
3257 setAxisScaleDraw( QwtPlot::xBottom, myScaleDraw); // heritage of QwtPlot
3259 //std::cout << "Plot2d_Plot2d::displayXTicksAndLabels() 1" << std::endl;
3263 /* Create vertical segment between two curves
3265 void Plot2d_Plot2d::createSeparationLine( double Xpos)
3267 QwtPlotMarker* aPlotMarker = new QwtPlotMarker();
3269 aPlotMarker->setLineStyle( QwtPlotMarker::VLine);
3270 aPlotMarker->setXValue( Xpos);
3271 aPlotMarker->setLinePen( QPen(Qt::black));
3272 aPlotMarker->attach(this); // Add to drawing zone
3273 // To deallocate in EraseAll()
3274 mySeparationLineList.append( aPlotMarker);
3277 void Plot2d_Plot2d::clearSeparationLineList()
3279 mySeparationLineList.clear();
3283 Creates presentation of object
3284 Default implementation is empty
3286 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
3292 Copies preferences from other viewframe
3293 \param vf - other view frame
3295 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
3300 myCurveType = vf->myCurveType;
3301 myShowLegend = vf->myShowLegend;
3302 myLegendPos = vf->myLegendPos;
3303 myMarkerSize = vf->myMarkerSize;
3304 myBackground = vf->myBackground;
3305 myTitle = vf->myTitle;
3306 myXTitle = vf->myXTitle;
3307 myYTitle = vf->myYTitle;
3308 myY2Title = vf->myY2Title;
3309 myTitleEnabled = vf->myTitleEnabled;
3310 myXTitleEnabled = vf->myXTitleEnabled;
3311 myYTitleEnabled = vf->myYTitleEnabled;
3312 myY2TitleEnabled = vf->myY2TitleEnabled;
3313 myXGridMajorEnabled = vf->myXGridMajorEnabled;
3314 myYGridMajorEnabled = vf->myYGridMajorEnabled;
3315 myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
3316 myXGridMinorEnabled = vf->myXGridMinorEnabled;
3317 myYGridMinorEnabled = vf->myYGridMinorEnabled;
3318 myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
3319 myXGridMaxMajor = vf->myXGridMaxMajor;
3320 myYGridMaxMajor = vf->myYGridMaxMajor;
3321 myY2GridMaxMajor = vf->myY2GridMaxMajor;
3322 myXGridMaxMinor = vf->myXGridMaxMinor;
3323 myYGridMaxMinor = vf->myYGridMaxMinor;
3324 myY2GridMaxMinor = vf->myY2GridMaxMinor;
3325 myXMode = vf->myXMode;
3326 myYMode = vf->myYMode;
3327 mySecondY = vf->mySecondY;
3331 Updates titles according to curves
3333 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
3334 void Plot2d_ViewFrame::updateTitles()
3336 ObjectDict::iterator it = myObjects.begin();
3337 QStringList aXTitles;
3338 QStringList aYTitles;
3339 QStringList aY2Titles;
3340 QStringList aXUnits;
3341 QStringList aYUnits;
3342 QStringList aY2Units;
3343 QStringList aTables;
3346 Plot2d_Object* anObject;
3347 for ( ; it != myObjects.end(); it++ ) {
3348 // collect titles and units from all curves...
3349 anObject = it.value();
3350 QString xTitle = anObject->getHorTitle().trimmed();
3351 QString yTitle = anObject->getVerTitle().trimmed();
3352 QString xUnits = anObject->getHorUnits().trimmed();
3353 QString yUnits = anObject->getVerUnits().trimmed();
3355 if ( anObject->getYAxis() == QwtPlot::yLeft ) {
3356 if ( !aYTitles.contains( yTitle ) )
3357 aYTitles.append( yTitle );
3358 if ( !aYUnits.contains( yUnits ) )
3359 aYUnits.append( yUnits );
3362 if ( !aY2Titles.contains( yTitle ) )
3363 aY2Titles.append( yTitle );
3364 if ( !aY2Units.contains( yUnits ) )
3365 aY2Units.append( yUnits );
3367 if ( !aXTitles.contains( xTitle ) )
3368 aXTitles.append( xTitle );
3369 if ( !aXUnits.contains( xUnits ) )
3370 aXUnits.append( xUnits );
3372 QString aName = anObject->getTableTitle();
3373 if( !aName.isEmpty() && !aTables.contains( aName ) )
3374 aTables.append( aName );
3377 // ... and update plot 2d view
3378 QString xUnits, yUnits, y2Units;
3379 if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
3380 xUnits = BRACKETIZE( aXUnits[0] );
3381 if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
3382 yUnits = BRACKETIZE( aYUnits[0] );
3383 if ( aY2Units.count() == 1 && !aY2Units[0].isEmpty())
3384 y2Units = BRACKETIZE( aY2Units[0] );
3385 QString xTitle, yTitle, y2Title;
3386 if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
3387 xTitle = aXTitles[0];
3388 if ( aYTitles.count() == 1 )
3389 yTitle = aYTitles[0];
3390 if ( mySecondY && aY2Titles.count() == 1 )
3391 y2Title = aY2Titles[0];
3393 if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
3395 if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
3397 if ( !y2Title.isEmpty() && !y2Units.isEmpty() )
3400 setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, true );
3401 setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true );
3403 setTitle( myY2TitleEnabled, y2Title + y2Units, Y2Title, true );
3405 setTitle( true, aTables.join("; "), MainTitle, true );
3409 Outputs content of viewframe to file
3410 \param file - file name
3411 \param format - file format
3413 bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
3422 QPaintDevice* pd = 0;
3423 if( format=="PS" || format=="EPS" )
3425 QPrinter* pr = new QPrinter( QPrinter::HighResolution );
3426 pr->setPageSize( QPrinter::A4 );
3427 pr->setOutputFileName( file );
3428 pr->setPrintProgram( "" );
3434 myPlot->print( *pd );
3444 * Print Plot2d window
3446 void Plot2d_ViewFrame::printPlot( QPainter* p, const QRect& rect,
3447 const QwtPlotPrintFilter& filter ) const
3449 myPlot->print( p, rect, filter );
3453 \return string with all visual parameters
3455 QString Plot2d_ViewFrame::getVisualParameters()
3458 return getXmlVisualParameters();
3461 RNV: Old case, now visual parameters stored in the XML format.
3463 double xmin, xmax, ymin, ymax, y2min, y2max;
3464 getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max );
3466 //Store font in the visual parameters string as:
3468 // ...*FontFamily|FontSize|B|I|U|r:g:b*...
3470 retStr.sprintf( "%d*%d*%d*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e*%s|%i|%i|%i|%i|%i:%i:%i",
3471 myXMode, myYMode, mySecondY, xmin, xmax, ymin, ymax, y2min, y2max,
3472 qPrintable(myLegendFont.family()), myLegendFont.pointSize(),myLegendFont.bold(),
3473 myLegendFont.italic(), myLegendFont.underline(),myLegendColor.red(),
3474 myLegendColor.green(), myLegendColor.blue());
3476 //store all Analytical curves
3477 //store each curve in the following format
3478 // ...*Name|isActive|Expresion|NbInervals|isAutoAssign[|MarkerType|LineType|LineWidth|r:g:b]
3479 // parameters in the [ ] is optional in case if isAutoAssign == true
3480 AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
3481 Plot2d_AnalyticalCurve* c = 0;
3483 for( ; it != myAnalyticalCurves.end(); it++) {
3486 QString curveString("");
3487 isAuto = c->isAutoAssign();
3488 curveString.sprintf("*%s|%i|%s|%i|%i",
3489 qPrintable(c->getName()),
3491 qPrintable(c->getExpression()),
3492 c->getNbIntervals(),
3495 retStr+=curveString;
3497 QString optCurveString("");
3498 optCurveString.sprintf("|%i|%i|%i|%i:%i:%i",
3499 (int)c->getMarker(),
3502 c->getColor().red(),
3503 c->getColor().green(),
3504 c->getColor().blue());
3505 retStr+=optCurveString;
3508 retStr += QString( "*%1" ).arg( Qtx::colorToString( backgroundColor() ) );
3514 Restores all visual parameters from string
3516 void Plot2d_ViewFrame::setVisualParameters( const QString& parameters )
3518 if(setXmlVisualParameters(parameters))
3522 QStringList paramsLst = parameters.split( '*' );
3523 if ( paramsLst.size() >= 9 ) {
3524 double ymin, ymax, y2min, y2max;
3525 myXMode = paramsLst[0].toInt();
3526 myYMode = paramsLst[1].toInt();
3527 mySecondY = (bool)paramsLst[2].toInt();
3528 xmin = paramsLst[3].toDouble();
3529 xmax = paramsLst[4].toDouble();
3530 ymin = paramsLst[5].toDouble();
3531 ymax = paramsLst[6].toDouble();
3532 y2min = paramsLst[7].toDouble();
3533 y2max = paramsLst[8].toDouble();
3536 setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
3537 setHorScaleMode( myXMode, /*update=*/false );
3538 setVerScaleMode( myYMode, /*update=*/false );
3541 QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
3542 myYDistance2 = yMap2.s2() - yMap2.s1();
3545 fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
3546 fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
3549 //Restore legend font
3550 if(paramsLst.size() >= 10) {
3551 QStringList fontList = paramsLst[9].split( '|' );
3552 if(fontList.size() == 6) {
3553 myLegendFont = QFont(fontList[0]);
3554 myLegendFont.setPointSize(fontList[1].toInt());
3555 myLegendFont.setBold(fontList[2].toInt());
3556 myLegendFont.setItalic(fontList[3].toInt());
3557 myLegendFont.setUnderline(fontList[4].toInt());
3558 QStringList colorList = fontList[5].split(":");
3559 setLegendFont( myLegendFont );
3561 if(colorList.size() == 3) {
3562 myLegendColor = QColor(colorList[0].toInt(),
3563 colorList[1].toInt(),
3564 colorList[2].toInt());
3565 setLegendFontColor( myLegendColor );
3570 //Restore all Analytical curves
3571 int startCurveIndex = 10;
3572 if( paramsLst.size() >= startCurveIndex+1 ) {
3573 for( int i=startCurveIndex; i<paramsLst.size() ; i++ ) {
3574 QStringList curveLst = paramsLst[i].split("|");
3575 if( curveLst.size() == 5 || curveLst.size() == 9 ) {
3576 Plot2d_AnalyticalCurve* c = new Plot2d_AnalyticalCurve();
3577 c->setName(curveLst[0]);
3578 c->setActive(curveLst[1].toInt());
3579 c->setExpression(curveLst[2]);
3580 c->setNbIntervals(curveLst[3].toLong());
3581 c->setAutoAssign(curveLst[4].toInt());
3582 if( !c->isAutoAssign() ) {
3583 c->setMarker((Plot2d::MarkerType)curveLst[5].toInt());
3584 c->setLine((Plot2d::LineType)curveLst[6].toInt());
3585 c->setLineWidth(curveLst[7].toInt());
3586 QStringList colorList = curveLst[8].split(":");
3587 if( colorList.size() == 3 ) {
3588 c->setColor(QColor(colorList[0].toInt(),
3589 colorList[1].toInt(),
3590 colorList[2].toInt()));
3593 c->autoFill( myPlot );
3595 addAnalyticalCurve(c);
3596 updateAnalyticalCurve(c);
3598 else if( curveLst.size() == 1 ) {
3599 // background color can be set here
3601 if ( Qtx::stringToColor( paramsLst[i], c ) )
3602 setBackgroundColor( c );
3610 Store visual parameters in xml format.
3612 QString Plot2d_ViewFrame::getXmlVisualParameters() {
3614 QXmlStreamWriter aWriter(&retStr);
3615 aWriter.setAutoFormatting(true);
3618 aWriter.writeStartDocument();
3619 aWriter.writeStartElement("ViewState");
3620 aWriter.writeStartElement("Range");
3621 double xmin, xmax, ymin, ymax, y2min, y2max;
3622 getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max );
3623 aWriter.writeAttribute("Xmin", QString("").sprintf("%.12e",xmin));
3624 aWriter.writeAttribute("Xmax", QString("").sprintf("%.12e",xmax));
3625 aWriter.writeAttribute("Ymin", QString("").sprintf("%.12e",ymin));
3626 aWriter.writeAttribute("Ymax", QString("").sprintf("%.12e",ymax));
3627 aWriter.writeAttribute("Y2min", QString("").sprintf("%.12e",y2min));
3628 aWriter.writeAttribute("Y2max", QString("").sprintf("%.12e",y2max));
3629 aWriter.writeEndElement();
3632 aWriter.writeStartElement("DisplayMode");
3633 aWriter.writeAttribute("SecondAxis", QString("").sprintf("%d",mySecondY));
3634 aWriter.writeStartElement("ScaleMode");
3635 aWriter.writeAttribute("Xscale", QString("").sprintf("%d",myXMode));
3636 aWriter.writeAttribute("Yscale", QString("").sprintf("%d",myYMode));
3637 aWriter.writeEndElement();
3638 aWriter.writeStartElement("NormalizationMode");
3639 aWriter.writeAttribute("LeftMin", QString("").sprintf("%d",myNormLMin));
3640 aWriter.writeAttribute("LeftMax", QString("").sprintf("%d",myNormLMax));
3641 aWriter.writeAttribute("RightMin", QString("").sprintf("%d",myNormRMin));
3642 aWriter.writeAttribute("RightMax", QString("").sprintf("%d",myNormRMax));
3643 aWriter.writeEndElement();
3644 aWriter.writeEndElement();
3647 aWriter.writeStartElement("Legend");
3648 aWriter.writeAttribute("Visibility", QString("").sprintf("%d", myShowLegend));
3649 aWriter.writeStartElement("LegendFont");
3650 aWriter.writeAttribute("Family", myLegendFont.family());
3651 aWriter.writeAttribute("Size", QString("").sprintf("%d",myLegendFont.pointSize()));
3652 aWriter.writeAttribute("Bold", QString("").sprintf("%d",myLegendFont.bold()));
3653 aWriter.writeAttribute("Italic", QString("").sprintf("%d",myLegendFont.italic()));
3654 aWriter.writeAttribute("Underline", QString("").sprintf("%d",myLegendFont.underline()));
3655 aWriter.writeAttribute("R", QString("").sprintf("%d",myLegendColor.red()));
3656 aWriter.writeAttribute("G", QString("").sprintf("%d",myLegendColor.green()));
3657 aWriter.writeAttribute("B", QString("").sprintf("%d",myLegendColor.blue()));
3658 aWriter.writeEndElement();
3659 aWriter.writeEndElement();
3662 aWriter.writeStartElement("AnalyticalCurves");
3663 AnalyticalCurveList::iterator it = myAnalyticalCurves.begin();
3664 Plot2d_AnalyticalCurve* c = 0;
3667 for( ; it != myAnalyticalCurves.end(); it++) {
3670 aWriter.writeStartElement(QString("AnalyticalCurve_%1").arg(id));
3671 isAuto = c->isAutoAssign();
3672 aWriter.writeAttribute("Name",c->getName());
3673 aWriter.writeAttribute("IsActive", QString("").sprintf("%d", c->isActive()));
3674 aWriter.writeAttribute("Expression", c->getExpression());
3675 aWriter.writeAttribute("NbIntervals", QString("").sprintf("%d", c->getNbIntervals()));
3676 aWriter.writeAttribute("isAuto", QString("").sprintf("%d",isAuto));
3678 aWriter.writeAttribute("Marker", QString("").sprintf("%d",(int)c->getMarker()));
3679 aWriter.writeAttribute("Line", QString("").sprintf("%d",(int)c->getLine()));
3680 aWriter.writeAttribute("LineWidth", QString("").sprintf("%d",c->getLineWidth()));
3681 aWriter.writeAttribute("R", QString("").sprintf("%d",c->getColor().red()));
3682 aWriter.writeAttribute("G", QString("").sprintf("%d",c->getColor().green()));
3683 aWriter.writeAttribute("B", QString("").sprintf("%d",c->getColor().blue()));
3685 aWriter.writeEndElement();
3688 aWriter.writeEndElement(); //AnalyticalCurve
3691 aWriter.writeStartElement(QString("Background").arg(id));
3692 aWriter.writeStartElement(QString("BackgroundColor").arg(id));
3693 aWriter.writeAttribute("R", QString("").sprintf("%d",backgroundColor().red()));
3694 aWriter.writeAttribute("G", QString("").sprintf("%d",backgroundColor().green()));
3695 aWriter.writeAttribute("B", QString("").sprintf("%d",backgroundColor().blue()));
3696 aWriter.writeEndElement();
3697 aWriter.writeEndElement();
3700 aWriter.writeEndDocument();
3704 Restore visual parameters from xml format.
3706 bool Plot2d_ViewFrame::setXmlVisualParameters(const QString& parameters) {
3707 QXmlStreamReader aReader(parameters);
3708 double xmin, xmax, ymin, ymax, y2min, y2max;
3709 bool leftMin,leftMax,rightMin,rightMax;
3710 leftMin = leftMax = rightMin = rightMax = false;
3711 while(!aReader.atEnd()) {
3713 if (aReader.isStartElement()) {
3714 QXmlStreamAttributes aAttr = aReader.attributes();
3715 if(aReader.name() == "Range") {
3716 xmin = aAttr.value("Xmin").toString().toDouble();
3717 xmax = aAttr.value("Xmax").toString().toDouble();
3718 ymin = aAttr.value("Ymin").toString().toDouble();
3719 ymax = aAttr.value("Ymax").toString().toDouble();
3720 y2min = aAttr.value("Y2min").toString().toDouble();
3721 y2max = aAttr.value("Y2max").toString().toDouble();
3722 } else if(aReader.name() == "DisplayMode") {
3723 mySecondY = aAttr.value("Y2max").toString().toDouble();
3724 } else if(aReader.name() == "ScaleMode") {
3725 myXMode = aAttr.value("Xscale").toString().toInt();
3726 myYMode = aAttr.value("Yscale").toString().toInt();
3727 } else if(aReader.name() == "NormalizationMode") {
3728 leftMin = (bool)aAttr.value("LeftMin").toString().toInt();
3729 leftMax = (bool)aAttr.value("LeftMax").toString().toInt();
3730 rightMin = (bool)aAttr.value("RightMin").toString().toInt();
3731 rightMax = (bool)aAttr.value("RightMax").toString().toInt();
3732 } else if(aReader.name() == "Legend") {
3733 myShowLegend = (bool)aAttr.value("Visibility").toString().toInt();
3734 } else if (aReader.name() == "LegendFont") {
3735 myLegendFont = QFont(aAttr.value("Family").toString());
3736 myLegendFont.setPointSize(aAttr.value("Size").toString().toInt());
3737 myLegendFont.setBold((bool)aAttr.value("Bold").toString().toInt());
3738 myLegendFont.setItalic((bool)aAttr.value("Italic").toString().toInt());
3739 myLegendFont.setUnderline((bool)aAttr.value("Underline").toString().toInt());
3740 myLegendColor = QColor(aAttr.value("R").toString().toInt(),
3741 aAttr.value("G").toString().toInt(),
3742 aAttr.value("B").toString().toInt());
3743 setLegendFontColor( myLegendColor );
3744 setLegendFont(myLegendFont);
3745 } else if(aReader.name().toString().indexOf("AnalyticalCurve_") >= 0) {
3746 Plot2d_AnalyticalCurve* c = new Plot2d_AnalyticalCurve();
3747 c->setName(aAttr.value("Name").toString());
3748 c->setActive((bool)aAttr.value("IsActive").toString().toInt());
3749 c->setExpression(aAttr.value("Expression").toString());
3750 c->setNbIntervals(aAttr.value("NbIntervals").toString().toLong());
3751 c->setAutoAssign((bool)aAttr.value("isAuto").toString().toInt());
3752 if( !c->isAutoAssign() ) {
3753 c->setMarker((Plot2d::MarkerType)aAttr.value("Marker").toString().toInt());
3754 c->setLine((Plot2d::LineType)aAttr.value("Line").toString().toInt());
3755 c->setLineWidth(aAttr.value("LineWidth").toString().toInt());
3756 c->setColor(QColor(aAttr.value("R").toString().toInt(),
3757 aAttr.value("G").toString().toInt(),
3758 aAttr.value("B").toString().toInt()));
3760 c->autoFill( myPlot );
3762 addAnalyticalCurve(c);
3763 updateAnalyticalCurve(c);
3764 } else if(aReader.name().toString() == "BackgroundColor") {
3765 setBackgroundColor(QColor(aAttr.value("R").toString().toInt(),
3766 aAttr.value("G").toString().toInt(),
3767 aAttr.value("B").toString().toInt()));
3772 if(aReader.hasError())
3776 setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
3777 setHorScaleMode( myXMode, /*update=*/false );
3778 setVerScaleMode( myYMode, /*update=*/false );
3780 QwtScaleMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
3781 myYDistance2 = yMap2.s2() - yMap2.s1();
3783 setNormLMinMode(leftMin);
3784 setNormLMaxMode(leftMax);
3785 setNormRMinMode(rightMin);
3786 setNormRMaxMode(rightMax);
3788 showLegend( myShowLegend, false );
3790 fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
3795 Incremental zooming operation
3797 void Plot2d_ViewFrame::incrementalPan( const int incrX, const int incrY ) {
3798 QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
3799 QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
3801 myPlot->setAxisScale( QwtPlot::yLeft,
3802 myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s1() )-incrY ),
3803 myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s2() )-incrY ) );
3804 myPlot->setAxisScale( QwtPlot::xBottom,
3805 myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s1() )-incrX ),
3806 myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s2() )-incrX ) );
3808 QwtScaleMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
3809 myPlot->setAxisScale( QwtPlot::yRight,
3810 myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s1() )-incrY ),
3811 myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s2() )-incrY ) );
3817 Incremental panning operation
3819 void Plot2d_ViewFrame::incrementalZoom( const int incrX, const int incrY ) {
3820 QwtScaleMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
3821 QwtScaleMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
3823 myPlot->setAxisScale( QwtPlot::yLeft, yMap.s1(),
3824 myPlot->invTransform( QwtPlot::yLeft, yMap.transform( yMap.s2() ) + incrY ) );
3825 myPlot->setAxisScale( QwtPlot::xBottom, xMap.s1(),
3826 myPlot->invTransform( QwtPlot::xBottom, xMap.transform( xMap.s2() ) - incrX ) );
3828 QwtScaleMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
3829 myPlot->setAxisScale( QwtPlot::yRight, y2Map.s1(),
3830 myPlot->invTransform( QwtPlot::yRight, y2Map.transform( y2Map.s2() ) + incrY ) );
3838 void Plot2d_ViewFrame::updatePlotItem(Plot2d_Object* theObject, QwtPlotItem* theItem) {
3839 theObject->updatePlotItem( theItem );
3840 Plot2d_Curve* c = dynamic_cast<Plot2d_Curve*>(theObject);
3841 QwtPlotCurve* cu = dynamic_cast<QwtPlotCurve*>(theItem);
3842 Plot2d_NormalizeAlgorithm* aNormAlgo;
3844 if(c->getYAxis() == QwtPlot::yRight)
3845 aNormAlgo = myRNormAlgo;
3847 aNormAlgo = myLNormAlgo;
3848 if(aNormAlgo->getNormalizationMode() != Plot2d_NormalizeAlgorithm::NormalizeNone) {
3849 AlgoPlot2dOutputData aResultData = aNormAlgo->getOutput();
3850 AlgoPlot2dOutputData::iterator itTmp = aResultData.find(theObject);
3852 int size = itTmp.value().size();
3853 xNew = new double[size];
3854 yNew = new double[size];
3856 for (; j < size; ++j) {
3857 xNew[j] = itTmp.value().at(j).first;
3858 yNew[j] = itTmp.value().at(j).second;
3860 cu->setData(xNew, yNew,j);
3863 if(aNormAlgo->getNormalizationMode() != Plot2d_NormalizeAlgorithm::NormalizeNone) {
3864 QString name = c->getName().isEmpty() ? c->getVerTitle() : c->getName();
3865 name = name + QString("(B=%1, K=%2)");
3866 name = name.arg(aNormAlgo->getBkoef(c)).arg(aNormAlgo->getKkoef(c));
3876 QwtPlotCanvas* Plot2d_ViewFrame::getPlotCanvas() const
3878 return myPlot ? myPlot->canvas() : 0;
3882 return closest curve if it exist, else 0
3884 Plot2d_Curve* Plot2d_ViewFrame::getClosestCurve( QPoint p, double& distance, int& index ) const
3886 CurveDict aCurves = getCurves();
3887 CurveDict::iterator it = aCurves.begin();
3888 Plot2d_Curve* pCurve = 0;
3890 for ( ; it != aCurves.end(); it++ ) {
3891 QwtPlotCurve* aCurve = it.key();
3895 int i = aCurve->closestPoint( p, &d );
3896 if ( index > -1 && ( distance < 0 || d < distance ) ) {
3897 pCurve = it.value();
3906 \brief Deselect all analytical curves.
3908 void Plot2d_ViewFrame::deselectAnalyticalCurves() {
3909 foreach(Plot2d_AnalyticalCurve* c, myAnalyticalCurves) {
3910 c->setSelected(false);
3915 \brief Deselect all objects, except analytical curves.
3917 void Plot2d_ViewFrame::deselectObjects() {
3918 ObjectDict::const_iterator it = myObjects.begin(), aLast = myObjects.end();
3919 for ( ; it != aLast; it++ ) {
3920 it.value()->setSelected(false);
3924 #define INCREMENT_FOR_OP 10
3927 Performs incremental panning to the left
3929 void Plot2d_ViewFrame::onPanLeft()
3931 this->incrementalPan( -INCREMENT_FOR_OP, 0 );
3932 updateAnalyticalCurves();
3936 Performs incremental panning to the right
3938 void Plot2d_ViewFrame::onPanRight()
3940 this->incrementalPan( INCREMENT_FOR_OP, 0 );
3941 updateAnalyticalCurves();
3945 Performs incremental panning to the top
3947 void Plot2d_ViewFrame::onPanUp()
3949 this->incrementalPan( 0, -INCREMENT_FOR_OP );
3950 updateAnalyticalCurves();
3954 Performs incremental panning to the bottom
3956 void Plot2d_ViewFrame::onPanDown()
3958 this->incrementalPan( 0, INCREMENT_FOR_OP );
3959 updateAnalyticalCurves();
3963 Performs incremental zooming in
3965 void Plot2d_ViewFrame::onZoomIn()
3967 this->incrementalZoom( INCREMENT_FOR_OP, INCREMENT_FOR_OP );
3968 updateAnalyticalCurves();
3972 Performs incremental zooming out
3974 void Plot2d_ViewFrame::onZoomOut()
3976 this->incrementalZoom( -INCREMENT_FOR_OP, -INCREMENT_FOR_OP );
3977 updateAnalyticalCurves();
3981 Schedules a FitAll operation by putting it to the application's
3982 event queue. This ensures that other important events (show, resize, etc.)
3983 are processed first.
3985 void Plot2d_ViewFrame::customEvent( QEvent* ce )
3987 if ( ce->type() == FITALL_EVENT )
3993 * Return Plot2d_Object by the QwtPlotItem
3996 Plot2d_Object* Plot2d_ViewFrame::getPlotObject( QwtPlotItem* plotItem ) const {
3998 ObjectDict::const_iterator it = myObjects.begin();
3999 for( ; it != myObjects.end(); ++it ) {
4000 if ( it.key() == plotItem ) {
4007 Plot2d_ScaleDraw::Plot2d_ScaleDraw( char f, int prec )
4015 Plot2d_ScaleDraw::Plot2d_ScaleDraw( const QwtScaleDraw& scaleDraw, char f, int prec )
4016 : QwtScaleDraw(scaleDraw),
4023 QwtText Plot2d_ScaleDraw::label( double value ) const
4025 QwtScaleMap m = map();
4026 QString str1 = QwtScaleDraw::label( m.s1() ).text();
4027 QString str2 = QwtScaleDraw::label( m.s2() ).text();
4028 if ( str1 == str2 ) {
4029 double aDist = fabs(map().s2()-map().s1())/5;
4031 while (aDist < 1 ) {
4035 if ( precision > 0 && value > 0 )
4036 return QLocale::system().toString( value,'f', precision );
4039 return QwtScaleDraw::label( value );
4042 Plot2d_YScaleDraw::Plot2d_YScaleDraw()
4047 QwtText Plot2d_YScaleDraw::label( double value ) const
4049 // Axis labels format
4050 QString strD = QString( "%1").arg( value, 10, 'e', 3); // format 10.3e
4052 return QwtText( strD);
4055 /* Definition of X axis graduations
4057 const QString Plot2d_AxisScaleDraw::DEVICE_FONT = QString("Times");
4058 const int Plot2d_AxisScaleDraw::DEVICE_FONT_SIZE = 12;
4059 const int Plot2d_AxisScaleDraw::DEVICE_BY = 40;
4061 Plot2d_AxisScaleDraw::Plot2d_AxisScaleDraw( Plot2d_Plot2d* plot)
4066 setLabelAlignment(Qt::AlignRight);
4067 setLabelRotation(45.);
4071 myActivTicksDrawing = true;
4072 myNumTicksDrawingCall = 1;
4076 Plot2d_AxisScaleDraw::~Plot2d_AxisScaleDraw()
4081 /* Unactivate automatic ticks drawing
4083 void Plot2d_AxisScaleDraw::unactivTicksDrawing( int numcall)
4085 myActivTicksDrawing = false;
4086 myNumTicksDrawingCall = numcall;
4090 /* Draw X ticks and labels.
4091 * Draw systems names under X axis.
4092 * Overload the same name QwtScaleDraw method.
4093 * (PB: who call automaticaly this method)
4095 void Plot2d_AxisScaleDraw::draw( QPainter* painter, const QPalette & palette) const
4097 //std::cout << "Plot2d_AxisScaleDraw::draw() : activ= " << myActivTicksDrawing
4098 // << " numcall= " << myNumTicksDrawingCall << std::endl;
4100 if (!myActivTicksDrawing) return;
4102 //std::cout << "Plot2d_AxisScaleDraw::draw()" << std::endl;
4104 QList<double> major_ticks = scaleDiv().ticks(QwtScaleDiv::MajorTick);
4105 QList<double> medium_ticks = scaleDiv().ticks(QwtScaleDiv::MediumTick);
4106 QList<double> minor_ticks = scaleDiv().ticks(QwtScaleDiv::MinorTick);
4108 medium_ticks.clear();
4109 minor_ticks.clear();
4110 major_ticks.clear();
4112 major_ticks.append( myTicks);
4113 myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MajorTick, major_ticks);
4114 myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MediumTick, medium_ticks);
4115 myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MinorTick, minor_ticks);
4116 QwtScaleDraw *scale = myPlot->axisScaleDraw(QwtPlot::xBottom);
4117 ((Plot2d_AxisScaleDraw*)(scale))->applyTicks();
4119 QwtScaleDraw::draw( painter, palette);
4121 for (int i = 0; i < myTicks.size(); i++)
4123 drawLabel( painter, myTicks[i]);
4126 //std::cout << "Ok for Plot2d_AxisScaleDraw::draw()" << std::endl;
4130 QwtText Plot2d_AxisScaleDraw::label( double value) const
4132 if (myLabelX.contains(value))
4133 return myLabelX[value];
4135 return QwtText(QString::number(value, 'f', 1));
4139 /* Stock position and label of a X tick
4141 void Plot2d_AxisScaleDraw::setLabelTick( double value, QString label, bool isDevice)
4143 //qDebug()<< "setLabelTick ( " << value << ","<< label <<" )";
4146 // For systems names under X axis
4147 myLabelDevice[value] = label;
4151 // For X axis graduations
4152 myLabelX[value] = label;
4157 /* Stock ticks positions of a system, and draw them
4159 void Plot2d_AxisScaleDraw::setTicks(const QList<double> aTicks)
4161 //std::cout << " Plot2d_AxisScaleDraw::setTicks()" << std::endl;
4168 void Plot2d_AxisScaleDraw::setInterval(double lowerBound, double upperBound)
4170 myLowerBound = lowerBound;
4171 myUpperBound = upperBound;
4172 myPlot->setAxisScale( QwtPlot::xBottom, myLowerBound, myUpperBound );
4176 /* Stock X ticks in drawing zone
4178 void Plot2d_AxisScaleDraw::applyTicks()
4180 //std::cout << " Plot2d_AxisScaleDraw::applyTicks()" << std::endl;
4182 QList<double> major_ticks = scaleDiv().ticks(QwtScaleDiv::MajorTick);
4183 QList<double> medium_ticks = scaleDiv().ticks(QwtScaleDiv::MediumTick);
4184 QList<double> minor_ticks = scaleDiv().ticks(QwtScaleDiv::MinorTick);
4186 medium_ticks.clear();
4187 minor_ticks.clear();
4189 myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MajorTick, myTicks);
4190 myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MediumTick, medium_ticks);
4191 myPlot->axisScaleDiv(QwtPlot::xBottom)->setTicks(QwtScaleDiv::MinorTick, minor_ticks);
4193 QwtScaleDiv* aScaleDiv = (QwtScaleDiv*) &scaleDiv();
4195 aScaleDiv->setTicks(QwtScaleDiv::MajorTick, myTicks);
4196 aScaleDiv->setTicks(QwtScaleDiv::MediumTick, medium_ticks);
4197 aScaleDiv->setTicks(QwtScaleDiv::MinorTick, minor_ticks);
4199 if (myLowerBound != -1 && myUpperBound != -1)
4200 aScaleDiv->setInterval(myLowerBound, myUpperBound);
4202 //for (int i = 0; i < myTicks.size(); i++){
4203 // QPoint p = labelPosition( i );
4204 // qDebug() << i<< ") applyTicks -> LABEL" <<p;
4209 void Plot2d_AxisScaleDraw::drawLabel( QPainter* painter, double value) const
4211 //std::cout << " Plot2d_AxisScaleDraw::drawLabel( " << value << " ) : "; //<< std::endl;
4213 //qDebug() << "drawLabel ( " <<value<<" )";
4214 if ( myLabelDevice.contains(value) )
4216 QString deviceLabel = myLabelDevice[value];
4218 std::string std_label = deviceLabel.toStdString();
4219 //const char *c_label = std_label.c_str();
4220 //std::cout << " deviceLabel= |" << c_label << "|" << std::endl;
4222 QPoint p = labelPosition( value );
4223 p += QPoint(0, DEVICE_BY);
4224 QFont prevf = painter->font();
4225 //QColor prevc = (painter->pen()).color();
4227 QFont devicef( DEVICE_FONT, DEVICE_FONT_SIZE, QFont::Bold);
4229 //painter->setPen( QColor("blue") );
4230 painter->setFont( devicef );
4231 painter->drawText( p, myLabelDevice[value] );
4232 //painter->setPen( prevc );
4233 painter->setFont( prevf );
4235 if ( myLabelX.contains(value) )
4237 QString xLabel = myLabelX[value];
4239 std::string std_label = xLabel.toStdString();
4240 //const char *c_label = std_label.c_str();
4241 //std::cout << " xLabel= |" << c_label << "|" << std::endl;
4243 QwtScaleDraw::drawLabel( painter, value );
4248 void Plot2d_AxisScaleDraw::drawTick( QPainter* painter, double value, int len) const
4250 //qDebug() << "drawTick ( " <<value<<" , "<<len<<" ) " ;
4251 //qDebug() << "myLabelX" << myLabelX;
4253 if ( myLabelX.contains(value) )
4255 QwtScaleDraw::drawTick( painter, value, len);
4260 /* Management of tooltips associated with markers for curves points or others points
4262 const double Plot2d_QwtPlotPicker::BOUND_HV_SIZE = 0.2;
4264 Plot2d_QwtPlotPicker::Plot2d_QwtPlotPicker( int xAxis,
4267 RubberBand rubberBand,
4268 DisplayMode trackerMode,
4269 QwtPlotCanvas *canvas)
4270 : QwtPlotPicker( xAxis,
4275 canvas) // of drawing zone QwtPlot
4279 Plot2d_QwtPlotPicker::Plot2d_QwtPlotPicker( int xAxis,
4281 QwtPlotCanvas *canvas)
4282 : QwtPlotPicker( xAxis,
4288 Plot2d_QwtPlotPicker::~Plot2d_QwtPlotPicker()
4291 // http://www.qtcentre.org/threads/22751-How-do-i-select-a-QwtPlotMarker-using-a-QPlotPicker
4293 /* Return the tooltip associated with a point when the mouse cursor pass near
4295 QwtText Plot2d_QwtPlotPicker::trackerText( const QwtDoublePoint & pos ) const
4297 for (QList<QwtPlotMarker* >::const_iterator pMarkerIt = pMarkers.begin();
4298 pMarkerIt != pMarkers.end();
4301 QwtPlotMarker* pMarker = *pMarkerIt;
4302 if ( pMarker != NULL )
4304 QwtDoubleRect bound0 = pMarker->boundingRect();
4305 QwtDoublePoint center_bound0 = bound0.center();
4306 double left = center_bound0.x()-(BOUND_HV_SIZE/2.);
4307 double top = center_bound0.y()-(BOUND_HV_SIZE/2.);
4309 QwtDoubleRect bound( left, top , BOUND_HV_SIZE, BOUND_HV_SIZE);
4311 if( bound.contains(pos) )
4313 //QString toolTip = "X=" + QString::number( pMarker->xValue() )
4314 // + " Y=" + QString::number( pMarker->yValue() );
4315 return pMarkersToolTip[pMarker];