1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/
19 #include "Plot2d_ViewFrame.h"
21 #include "Plot2d_Prs.h"
22 #include "Plot2d_Curve.h"
23 #include "Plot2d_FitDataDlg.h"
24 #include "Plot2d_ViewWindow.h"
25 #include "Plot2d_SetupViewDlg.h"
27 #include "SUIT_Tools.h"
28 #include "SUIT_Session.h"
29 #include "SUIT_MessageBox.h"
30 #include "SUIT_ResourceMgr.h"
31 #include "SUIT_Application.h"
33 #include "qapplication.h"
35 #include <qtoolbutton.h>
37 #include <qcolordialog.h>
42 #include <qpaintdevicemetrics.h>
45 #include <qwt_plot_canvas.h>
50 #include <qwt_legend.h>
52 #define DEFAULT_LINE_WIDTH 0 // (default) line width
53 #define DEFAULT_MARKER_SIZE 9 // default marker size
54 #define MIN_RECT_SIZE 11 // min sensibility area size
56 const char* imageZoomCursor[] = {
61 "................................",
62 "................................",
63 ".#######........................",
64 "..aaaaaaa.......................",
65 "................................",
66 ".............#####..............",
67 "...........##.aaaa##............",
68 "..........#.aa.....a#...........",
69 ".........#.a.........#..........",
70 ".........#a..........#a.........",
71 "........#.a...........#.........",
72 "........#a............#a........",
73 "........#a............#a........",
74 "........#a............#a........",
75 "........#a............#a........",
76 ".........#...........#.a........",
77 ".........#a..........#a.........",
78 ".........##.........#.a.........",
79 "........#####.....##.a..........",
80 ".......###aaa#####.aa...........",
81 "......###aa...aaaaa.......#.....",
82 ".....###aa................#a....",
83 "....###aa.................#a....",
84 "...###aa...............#######..",
85 "....#aa.................aa#aaaa.",
86 ".....a....................#a....",
87 "..........................#a....",
88 "...........................a....",
89 "................................",
90 "................................",
91 "................................",
92 "................................"};
94 const char* imageCrossCursor[] = {
99 "................................",
100 "................................",
101 "................................",
102 "................................",
103 "................................",
104 "................................",
105 "................................",
106 "...............#................",
107 "...............#a...............",
108 "...............#a...............",
109 "...............#a...............",
110 "...............#a...............",
111 "...............#a...............",
112 "...............#a...............",
113 "...............#a...............",
114 ".......#################........",
115 "........aaaaaaa#aaaaaaaaa.......",
116 "...............#a...............",
117 "...............#a...............",
118 "...............#a...............",
119 "...............#a...............",
120 "...............#a...............",
121 "...............#a...............",
122 "...............#a...............",
123 "................a...............",
124 "................................",
125 "................................",
126 "................................",
127 "................................",
128 "................................",
129 "................................",
130 "................................"};
136 Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title )
137 : QWidget (parent, title, 0),
138 myOperation( NoOpId ),
140 myShowLegend( true ), myLegendPos( 1 ),
141 myMarkerSize( DEFAULT_MARKER_SIZE ),
142 myTitle( "" ), myXTitle( "" ), myYTitle( "" ), myY2Title( "" ),
143 myBackground( white ),
144 myTitleEnabled( true ), myXTitleEnabled( true ),
145 myYTitleEnabled( true ), myY2TitleEnabled (true),
146 myXGridMajorEnabled( true ), myYGridMajorEnabled( true ), myY2GridMajorEnabled( true ),
147 myXGridMinorEnabled( false ), myYGridMinorEnabled( false ), myY2GridMinorEnabled( false ),
148 myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myY2GridMaxMajor( 8 ),
149 myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ), myY2GridMaxMinor( 5 ),
150 myXMode( 0 ), myYMode( 0 ), mySecondY( false )
153 QVBoxLayout* aLayout = new QVBoxLayout( this );
154 myPlot = new Plot2d_Plot2d( this );
155 aLayout->addWidget( myPlot );
159 connect( myPlot, SIGNAL( plotMouseMoved( const QMouseEvent& ) ),
160 this, SLOT( plotMouseMoved( const QMouseEvent& ) ) );
161 connect( myPlot, SIGNAL( plotMousePressed( const QMouseEvent& ) ),
162 this, SLOT( plotMousePressed( const QMouseEvent& ) ) );
163 connect( myPlot, SIGNAL( plotMouseReleased( const QMouseEvent& ) ),
164 this, SLOT( plotMouseReleased( const QMouseEvent& ) ) );
165 //connect( myPlot, SIGNAL( legendClicked( long ) ),
166 // this, SLOT( onLegendClicked( long ) ) );
168 /* Initial Setup - get from the preferences */
171 myPlot->setMargin( 5 );
172 setCurveType( myCurveType, false );
173 setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, false );
174 setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
175 myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, false );
177 setTitle( myTitleEnabled, myTitle, MainTitle, false );
178 setTitle( myXTitleEnabled, myXTitle, XTitle, false );
179 setTitle( myYTitleEnabled, myYTitle, YTitle, false );
182 setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
183 setHorScaleMode( myXMode, false );
184 setVerScaleMode( myYMode, false );
185 setBackgroundColor( myBackground );
186 setLegendPos( myLegendPos );
187 showLegend( myShowLegend, false );
191 resize( (int)(0.8 * parent->width()), (int)(0.8 * parent->height()) );
193 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
194 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
195 myXDistance = xMap.d2() - xMap.d1();
196 myYDistance = yMap.d2() - yMap.d1();
199 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
200 myYDistance2 = yMap2.d2() - yMap2.d1();
206 Plot2d_ViewFrame::~Plot2d_ViewFrame()
210 Gets window's central widget
212 QWidget* Plot2d_ViewFrame::getViewWidget()
214 return (QWidget*)myPlot;
217 Actually this method just re-displays all curves which are presented in the viewer
219 void Plot2d_ViewFrame::DisplayAll()
221 QList<Plot2d_Curve> clist;
223 for ( int i = 0; i < (int)clist.count(); i++ ) {
224 updateCurve( clist.at( i ), false );
229 Removes all curves from the view
231 void Plot2d_ViewFrame::EraseAll()
238 Redraws viewframe contents
240 void Plot2d_ViewFrame::Repaint()
247 void Plot2d_ViewFrame::Display( const Plot2d_Prs* prs )
249 if ( !prs || prs->IsNull() )
252 if (prs->isSecondY()) {
253 myPlot->enableAxis(QwtPlot::yRight, true);
257 myPlot->enableAxis(QwtPlot::yRight, false);
261 // display all curves from presentation
262 curveList aCurves = prs->getCurves();
263 displayCurves( aCurves );
264 setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, true );
265 setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
266 myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, true );
272 void Plot2d_ViewFrame::Erase( const Plot2d_Prs* prs, const bool )
274 if ( !prs || prs->IsNull() )
277 // erase all curves from presentation
278 curveList aCurves = prs->getCurves();
279 eraseCurves( aCurves );
285 void Plot2d_ViewFrame::setTitle( const QString& title )
287 setTitle( myTitleEnabled, title, MainTitle, true );
291 Reads Plot2d view settings from the preferences
293 void Plot2d_ViewFrame::readPreferences()
295 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
297 myCurveType = resMgr->integerValue( "Plot2d", "CurveType", myCurveType );
298 setCurveType( resMgr->integerValue( "Plot2d", "CurveType", myCurveType ) );
300 myShowLegend = resMgr->booleanValue( "Plot2d", "ShowLegend", myShowLegend );
301 myLegendPos = resMgr->integerValue( "Plot2d", "LegendPos", myLegendPos );
302 myMarkerSize = resMgr->integerValue( "Plot2d", "MarkerSize", myMarkerSize );
303 myBackground = resMgr->colorValue( "Plot2d", "Background", myBackground );
305 myTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowTitle", myTitleEnabled );
306 myXTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
307 myYTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
308 myY2TitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
310 myXGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
311 myYGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
312 myY2GridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
314 myXGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
315 myYGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
316 myY2GridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
318 myXGridMaxMajor = resMgr->integerValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
319 myYGridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
321 myY2GridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorRightGridMax", myY2GridMaxMajor );
323 myXGridMaxMinor = resMgr->integerValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
324 myYGridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
326 myY2GridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myY2GridMaxMinor );
328 myXMode = resMgr->integerValue( "Plot2d", "HorScaleMode", myXMode );
329 myXMode = QMAX( 0, QMIN( 1, myXMode ) );
331 myYMode = resMgr->integerValue( "Plot2d", "VerScaleMode", myYMode );
332 myYMode = QMAX( 0, QMIN( 1, myYMode ) );
336 Writes Plot2d view settings to the preferences
338 void Plot2d_ViewFrame::writePreferences()
340 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
342 resMgr->setValue( "Plot2d", "CurveType", myCurveType );
343 resMgr->setValue( "Plot2d", "ShowLegend", myShowLegend );
344 resMgr->setValue( "Plot2d", "LegendPos", myLegendPos );
345 resMgr->setValue( "Plot2d", "MarkerSize", myMarkerSize );
346 resMgr->setValue( "Plot2d", "Background", myBackground );
347 resMgr->setValue( "Plot2d", "ShowTitle", myTitleEnabled );
348 resMgr->setValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
349 resMgr->setValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
351 resMgr->setValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
353 resMgr->setValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
354 resMgr->setValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
355 resMgr->setValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
356 resMgr->setValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
358 resMgr->setValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
359 resMgr->setValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
361 resMgr->setValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
362 resMgr->setValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
364 resMgr->setValue( "Plot2d", "HorScaleMode", myXMode );
368 resMgr->setValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
369 resMgr->setValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
370 resMgr->setValue( "Plot2d", "VerRightMajorGridMax", myY2GridMaxMajor );
371 resMgr->setValue( "Plot2d", "VerRightMinorGridMax", myY2GridMaxMinor );
374 resMgr->setValue( "Plot2d", "VerScaleMode", myYMode );
378 Prints mouse cursor coordinates into string
380 QString Plot2d_ViewFrame::getInfo( const QPoint& pnt )
383 bool xFound = false, yFound = false;
384 double xCoord, yCoord;
385 const QwtScaleDiv* aXscale = myPlot->axisScale( QwtPlot::xBottom );
386 for ( i = 0; i < aXscale->majCnt(); i++ ) {
387 double majXmark = aXscale->majMark( i );
388 int xmark = myPlot->transform( QwtPlot::xBottom, majXmark );
389 if ( xmark-2 == pnt.x() ) {
396 for ( i = 0; i < aXscale->minCnt(); i++ ) {
397 double minXmark = aXscale->minMark( i );
398 int xmark = myPlot->transform( QwtPlot::xBottom, minXmark );
399 if ( xmark-2 == pnt.x() ) {
406 const QwtScaleDiv* aYscale = myPlot->axisScale( QwtPlot::yLeft );
407 for ( i = 0; i < aYscale->majCnt(); i++ ) {
408 double majYmark = aYscale->majMark( i );
409 int ymark = myPlot->transform( QwtPlot::yLeft, majYmark );
410 if ( ymark-2 == pnt.y() ) {
417 for ( i = 0; i < aYscale->minCnt(); i++ ) {
418 double minYmark = aYscale->minMark( i );
419 int ymark = myPlot->transform( QwtPlot::yLeft, minYmark );
420 if ( ymark-2 == pnt.y() ) {
428 QString strX = QString::number( xFound ? xCoord : myPlot->invTransform( QwtPlot::xBottom, pnt.x() ) ).stripWhiteSpace();
431 QString strY = QString::number( yFound ? yCoord : myPlot->invTransform( QwtPlot::yLeft, pnt.y() ) ).stripWhiteSpace();
437 bool yFound2 = false;
440 const QwtScaleDiv* aYscale2 = myPlot->axisScale( QwtPlot::yRight );
441 for ( i = 0; i < aYscale2->majCnt(); i++ ) {
442 double majYmark = aYscale2->majMark( i );
443 int ymark = myPlot->transform( QwtPlot::yRight, majYmark );
444 if ( ymark-2 == pnt.y() ) {
451 for ( i = 0; i < aYscale2->minCnt(); i++ ) {
452 double minYmark = aYscale2->minMark( i );
453 int ymark = myPlot->transform( QwtPlot::yRight, minYmark );
454 if ( ymark-2 == pnt.y() ) {
461 QString strY2 = QString::number( yFound2 ? yCoord2 :
462 myPlot->invTransform( QwtPlot::yRight, pnt.y() ) ).stripWhiteSpace();
465 info = tr("INF_COORDINATES_SOME_Y").arg( strX ).arg( strY ).arg( strY2 );
468 info = tr("INF_COORDINATES").arg( strX ).arg( strY );
474 Converts Plot2d_Curve's marker style to Qwt marker style [ static ]
476 static QwtSymbol::Style plot2qwtMarker( Plot2d_Curve::MarkerType m )
478 QwtSymbol::Style ms = QwtSymbol::None;
480 case Plot2d_Curve::Circle:
481 ms = QwtSymbol::Ellipse; break;
482 case Plot2d_Curve::Rectangle:
483 ms = QwtSymbol::Rect; break;
484 case Plot2d_Curve::Diamond:
485 ms = QwtSymbol::Diamond; break;
486 case Plot2d_Curve::DTriangle:
487 ms = QwtSymbol::DTriangle; break;
488 case Plot2d_Curve::UTriangle:
489 ms = QwtSymbol::UTriangle; break;
490 case Plot2d_Curve::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
491 ms = QwtSymbol::RTriangle; break;
492 case Plot2d_Curve::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
493 ms = QwtSymbol::LTriangle; break;
494 case Plot2d_Curve::Cross:
495 ms = QwtSymbol::Cross; break;
496 case Plot2d_Curve::XCross:
497 ms = QwtSymbol::XCross; break;
498 case Plot2d_Curve::None:
500 ms = QwtSymbol::None; break;
506 Converts Qwt marker style to Plot2d_Curve's marker style [ static ]
508 static Plot2d_Curve::MarkerType qwt2plotMarker( QwtSymbol::Style m )
510 Plot2d_Curve::MarkerType ms = Plot2d_Curve::None;
512 case QwtSymbol::Ellipse:
513 ms = Plot2d_Curve::Circle; break;
514 case QwtSymbol::Rect:
515 ms = Plot2d_Curve::Rectangle; break;
516 case QwtSymbol::Diamond:
517 ms = Plot2d_Curve::Diamond; break;
518 case QwtSymbol::DTriangle:
519 ms = Plot2d_Curve::DTriangle; break;
520 case QwtSymbol::UTriangle:
521 ms = Plot2d_Curve::UTriangle; break;
522 case QwtSymbol::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
523 ms = Plot2d_Curve::LTriangle; break;
524 case QwtSymbol::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
525 ms = Plot2d_Curve::RTriangle; break;
526 case QwtSymbol::Cross:
527 ms = Plot2d_Curve::Cross; break;
528 case QwtSymbol::XCross:
529 ms = Plot2d_Curve::XCross; break;
530 case QwtSymbol::None:
532 ms = Plot2d_Curve::None; break;
538 Converts Plot2d_Curve's line style to Qwt line style [ static ]
540 static Qt::PenStyle plot2qwtLine( Plot2d_Curve::LineType p )
542 Qt::PenStyle ps = Qt::NoPen;
544 case Plot2d_Curve::Solid:
545 ps = Qt::SolidLine; break;
546 case Plot2d_Curve::Dash:
547 ps = Qt::DashLine; break;
548 case Plot2d_Curve::Dot:
549 ps = Qt::DotLine; break;
550 case Plot2d_Curve::DashDot:
551 ps = Qt::DashDotLine; break;
552 case Plot2d_Curve::DashDotDot:
553 ps = Qt::DashDotDotLine; break;
554 case Plot2d_Curve::NoPen:
556 ps = Qt::NoPen; break;
562 Converts Qwt line style to Plot2d_Curve's line style [ static ]
564 static Plot2d_Curve::LineType qwt2plotLine( Qt::PenStyle p )
566 Plot2d_Curve::LineType ps = Plot2d_Curve::NoPen;
569 ps = Plot2d_Curve::Solid; break;
571 ps = Plot2d_Curve::Dash; break;
573 ps = Plot2d_Curve::Dot; break;
574 case Qt::DashDotLine:
575 ps = Plot2d_Curve::DashDot; break;
576 case Qt::DashDotDotLine:
577 ps = Plot2d_Curve::DashDotDot; break;
580 ps = Plot2d_Curve::NoPen; break;
588 void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update )
593 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
594 // it crashes if switched to X/Y logarithmic mode, when one or more points have
595 // non-positive X/Y coordinate
596 if ( myXMode && curve->getMinX() <= 0. )
597 setHorScaleMode( 0, false );
598 if ( myYMode && curve->getMinY() <= 0. )
599 setVerScaleMode( 0, false );
601 if ( hasCurve( curve ) ) {
602 updateCurve( curve, update );
605 long curveKey = myPlot->insertCurve( curve->getVerTitle() );
606 myPlot->setCurveYAxis(curveKey, curve->getYAxis());
608 myCurves.insert( curveKey, curve );
609 if ( curve->isAutoAssign() ) {
610 QwtSymbol::Style typeMarker;
612 Qt::PenStyle typeLine;
613 myPlot->getNextMarker( typeMarker, color, typeLine );
614 myPlot->setCurvePen( curveKey, QPen( color, DEFAULT_LINE_WIDTH, typeLine ) );
615 myPlot->setCurveSymbol( curveKey, QwtSymbol( typeMarker,
618 QSize( myMarkerSize, myMarkerSize ) ) );
619 curve->setColor( color );
620 curve->setLine( qwt2plotLine( typeLine ) );
621 curve->setMarker( qwt2plotMarker( typeMarker ) );
624 Qt::PenStyle ps = plot2qwtLine( curve->getLine() );
625 QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
626 myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
627 myPlot->setCurveSymbol( curveKey, QwtSymbol( ms,
628 QBrush( curve->getColor() ),
629 QPen( curve->getColor() ),
630 QSize( myMarkerSize, myMarkerSize ) ) );
632 if ( myCurveType == 0 )
633 myPlot->setCurveStyle( curveKey, QwtCurve::NoCurve );
634 else if ( myCurveType == 1 )
635 myPlot->setCurveStyle( curveKey, QwtCurve::Lines );
636 else if ( myCurveType == 2 )
637 myPlot->setCurveStyle( curveKey, QwtCurve::Spline );
638 myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
646 Adds curves into view
648 void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update )
650 myPlot->setUpdatesEnabled( false );
651 QPtrListIterator<Plot2d_Curve> it(curves);
652 Plot2d_Curve* aCurve;
653 while( (aCurve = it.current()) ) {
654 displayCurve( aCurve, false );
659 myPlot->setUpdatesEnabled( true );
667 void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
671 int curveKey = hasCurve( curve );
673 myPlot->removeCurve( curveKey );
674 myCurves.remove( curveKey );
684 void Plot2d_ViewFrame::eraseCurves( const curveList& curves, bool update )
686 QPtrListIterator<Plot2d_Curve> it(curves);
687 Plot2d_Curve* aCurve;
688 while( (aCurve = it.current()) ) {
689 eraseCurve( aCurve, false );
698 Updates curves attributes
700 void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
704 int curveKey = hasCurve( curve );
706 if ( !curve->isAutoAssign() ) {
707 Qt::PenStyle ps = plot2qwtLine( curve->getLine() );
708 QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
709 myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
710 myPlot->setCurveSymbol( curveKey, QwtSymbol( ms,
711 QBrush( curve->getColor() ),
712 QPen( curve->getColor() ),
713 QSize( myMarkerSize, myMarkerSize ) ) );
714 myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
716 myPlot->setCurveTitle( curveKey, curve->getVerTitle() );
717 myPlot->curve( curveKey )->setEnabled( true );
724 Returns curve key if is is displayed in the viewer and 0 otherwise
726 int Plot2d_ViewFrame::hasCurve( Plot2d_Curve* curve )
728 QIntDictIterator<Plot2d_Curve> it( myCurves );
729 for ( ; it.current(); ++it ) {
730 if ( it.current() == curve )
731 return it.currentKey();
737 Gets lsit of displayed curves
739 int Plot2d_ViewFrame::getCurves( QList<Plot2d_Curve>& clist )
742 clist.setAutoDelete( false );
743 QIntDictIterator<Plot2d_Curve> it( myCurves );
744 for ( ; it.current(); ++it ) {
745 clist.append( it.current() );
747 return clist.count();
751 Returns true if the curve is visible
753 bool Plot2d_ViewFrame::isVisible( Plot2d_Curve* curve )
756 int key = hasCurve( curve );
758 return myPlot->curve( key )->enabled();
766 void Plot2d_ViewFrame::updateLegend( const Plot2d_Prs* prs )
768 if ( !prs || prs->IsNull() )
770 curveList aCurves = prs->getCurves();
772 QPtrListIterator<Plot2d_Curve> it(aCurves);
773 Plot2d_Curve* aCurve;
774 while( (aCurve = it.current()) ) {
775 int curveKey = hasCurve( aCurve );
777 myPlot->setCurveTitle( curveKey, aCurve->getVerTitle() );
783 Fits the view to see all data
785 void Plot2d_ViewFrame::fitAll()
787 QwtDiMap xMap1 = myPlot->canvasMap( QwtPlot::xBottom );
789 myPlot->setAxisAutoScale( QwtPlot::yLeft );
790 myPlot->setAxisAutoScale( QwtPlot::xBottom );
794 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
795 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
797 myPlot->setAxisScale( QwtPlot::xBottom,
798 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
799 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() ) );
800 myPlot->setAxisScale( QwtPlot::yLeft,
801 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
802 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() ) );
805 myPlot->setAxisAutoScale( QwtPlot::yRight );
807 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
808 myPlot->setAxisScale( QwtPlot::yRight,
809 myPlot->invTransform( QwtPlot::yRight, yMap2.i1() ),
810 myPlot->invTransform( QwtPlot::yRight, yMap2.i2() ) );
816 Fits the view to rectangle area (pixels)
818 void Plot2d_ViewFrame::fitArea( const QRect& area )
820 QRect rect = area.normalize();
821 if ( rect.width() < MIN_RECT_SIZE ) {
822 rect.setWidth( MIN_RECT_SIZE );
823 rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
825 if ( rect.height() < MIN_RECT_SIZE ) {
826 rect.setHeight( MIN_RECT_SIZE );
827 rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
829 myPlot->setAxisScale( QwtPlot::yLeft,
830 myPlot->invTransform( QwtPlot::yLeft, rect.top() ),
831 myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
833 myPlot->setAxisScale( QwtPlot::yRight,
834 myPlot->invTransform( QwtPlot::yRight, rect.top() ),
835 myPlot->invTransform( QwtPlot::yRight, rect.bottom() ) );
836 myPlot->setAxisScale( QwtPlot::xBottom,
837 myPlot->invTransform( QwtPlot::xBottom, rect.left() ),
838 myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
843 "Fit Data" command for TUI interface
845 void Plot2d_ViewFrame::fitData(const int mode,
846 const double xMin, const double xMax,
847 const double yMin, const double yMax,
848 double y2Min, double y2Max)
850 if ( mode == 0 || mode == 2 ) {
851 myPlot->setAxisScale( QwtPlot::yLeft, yMax, yMin );
853 myPlot->setAxisScale( QwtPlot::yRight, y2Max, y2Min );
855 if ( mode == 0 || mode == 1 )
856 myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax );
861 Gets current fit ranges for view frame
863 void Plot2d_ViewFrame::getFitRanges(double& xMin,double& xMax,
864 double& yMin, double& yMax,
865 double& y2Min, double& y2Max)
867 int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).i1();
868 int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).i2();
869 int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).i1();
870 int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).i2();
871 xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
872 xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
873 yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
874 yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
878 int iyMin = myPlot->canvasMap( QwtPlot::yRight ).i1();
879 int iyMax = myPlot->canvasMap( QwtPlot::yRight ).i2();
880 y2Min = myPlot->invTransform(QwtPlot::yRight, iyMin);
881 y2Max = myPlot->invTransform(QwtPlot::yRight, iyMax);
886 Tests if it is necessary to start operation on mouse action
888 int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
890 int btn = me.button() | me.state();
891 const int zoomBtn = ControlButton | LeftButton;
892 const int panBtn = ControlButton | MidButton;
893 const int fitBtn = ControlButton | RightButton;
899 QPixmap zoomPixmap (imageZoomCursor);
900 QCursor zoomCursor (zoomPixmap);
901 myPlot->canvas()->setCursor( zoomCursor );
905 myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
908 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
916 "Settings" toolbar action slot
918 void Plot2d_ViewFrame::onSettings()
920 #ifdef TEST_AUTOASSIGN
921 typedef QMap<int,int> IList;
922 typedef QMap<QString,int> SList;
925 cols[ "red-min" ] = 1000;
926 cols[ "red-max" ] = -1;
927 cols[ "green-min" ] = 1000;
928 cols[ "green-max" ] = -1;
929 cols[ "blue-min" ] = 1000;
930 cols[ "blue-max" ] = -1;
931 for ( unsigned i = 0; i < 10000; i++ ) {
932 QwtSymbol::Style typeMarker;
934 Qt::PenStyle typeLine;
935 myPlot->getNextMarker( typeMarker, color, typeLine );
936 if ( mars.contains(typeMarker) )
937 mars[ typeMarker ] = mars[ typeMarker ]+1;
939 mars[ typeMarker ] = 0;
940 if ( lins.contains(typeLine) )
941 lins[ typeLine ] = lins[ typeLine ]+1;
943 lins[ typeLine ] = 0;
944 if ( cols[ "red-max" ] < color.red() )
945 cols[ "red-max" ] = color.red();
946 if ( cols[ "red-min" ] > color.red() )
947 cols[ "red-min" ] = color.red();
948 if ( cols[ "green-max" ] < color.green() )
949 cols[ "green-max" ] = color.green();
950 if ( cols[ "green-min" ] > color.green() )
951 cols[ "green-min" ] = color.green();
952 if ( cols[ "blue-max" ] < color.blue() )
953 cols[ "blue-max" ] = color.blue();
954 if ( cols[ "blue-min" ] > color.blue() )
955 cols[ "blue-min" ] = color.blue();
959 Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true, mySecondY );
960 dlg->setMainTitle( myTitleEnabled, myTitle );
961 dlg->setXTitle( myXTitleEnabled, myXTitle );
962 dlg->setYTitle( myYTitleEnabled, myYTitle );
964 dlg->setY2Title( myY2TitleEnabled, myY2Title );
965 dlg->setCurveType( myCurveType );
966 dlg->setLegend( myShowLegend, myLegendPos );
967 dlg->setMarkerSize( myMarkerSize );
968 dlg->setBackgroundColor( myBackground );
969 dlg->setScaleMode(myXMode, myYMode);
971 dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
972 myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ),
973 myY2GridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yRight ) );
974 dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
975 myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ),
976 myY2GridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yRight ) );
977 if ( dlg->exec() == QDialog::Accepted ) {
978 // horizontal axis title
979 setTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), XTitle, false );
980 // vertical left axis title
981 setTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), YTitle, false );
982 if (mySecondY) // vertical right axis title
983 setTitle( dlg->isY2TitleEnabled(), dlg->getY2Title(), Y2Title, false );
986 setTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), MainTitle, true );
988 if ( myCurveType != dlg->getCurveType() ) {
989 setCurveType( dlg->getCurveType(), false );
992 if ( myShowLegend != dlg->isLegendEnabled() ) {
993 showLegend( dlg->isLegendEnabled(), false );
995 if ( myLegendPos != dlg->getLegendPos() ) {
996 setLegendPos( dlg->getLegendPos() );
999 if ( myMarkerSize != dlg->getMarkerSize() ) {
1000 setMarkerSize( dlg->getMarkerSize(), false );
1003 if ( myBackground != dlg->getBackgroundColor() ) {
1004 setBackgroundColor( dlg->getBackgroundColor() );
1007 bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled,
1008 aY2GridMajorEnabled, aY2GridMinorEnabled;
1009 int aXGridMaxMajor, aXGridMaxMinor, aYGridMaxMajor, aYGridMaxMinor,
1010 aY2GridMaxMajor, aY2GridMaxMinor;
1011 dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor,
1012 aY2GridMajorEnabled, aY2GridMaxMajor);
1013 dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor,
1014 aY2GridMinorEnabled, aY2GridMaxMinor);
1015 setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
1016 setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor,
1017 aY2GridMajorEnabled, aY2GridMaxMajor, aY2GridMinorEnabled, aY2GridMaxMinor, false );
1018 if ( myXMode != dlg->getXScaleMode() ) {
1019 setHorScaleMode( dlg->getXScaleMode() );
1021 if ( myYMode != dlg->getYScaleMode() ) {
1022 setVerScaleMode( dlg->getYScaleMode() );
1026 // update preferences
1027 if ( dlg->isSetAsDefault() )
1034 "Fit Data" command slot
1036 void Plot2d_ViewFrame::onFitData()
1038 Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this, mySecondY );
1039 double xMin,xMax,yMin,yMax,y2Min,y2Max;
1040 getFitRanges(xMin,xMax,yMin,yMax,y2Min,y2Max);
1042 dlg->setRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1043 if ( dlg->exec() == QDialog::Accepted ) {
1044 int mode = dlg->getRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1045 fitData(mode,xMin,xMax,yMin,yMax,y2Min,y2Max);
1051 Change background color
1053 void Plot2d_ViewFrame::onChangeBackground()
1055 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
1056 if ( selColor.isValid() ) {
1057 setBackgroundColor( selColor );
1064 void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
1066 myCurveType = curveType;
1067 QArray<long> keys = myPlot->curveKeys();
1068 for ( int i = 0; i < (int)keys.count(); i++ ) {
1069 if ( myCurveType == 0 )
1070 myPlot->setCurveStyle( keys[i], QwtCurve::Dots );//QwtCurve::NoCurve
1071 else if ( myCurveType == 1 )
1072 myPlot->setCurveStyle( keys[i], QwtCurve::Lines );
1073 else if ( myCurveType == 2 )
1074 myPlot->setCurveStyle( keys[i], QwtCurve::Spline );
1078 emit vpCurveChanged();
1083 \param curveKey - curve id
1084 \param title - new title
1086 void Plot2d_ViewFrame::setCurveTitle( int curveKey, const QString& title )
1088 if(myPlot) myPlot->setCurveTitle(curveKey, title);
1094 void Plot2d_ViewFrame::showLegend( bool show, bool update )
1096 myShowLegend = show;
1097 myPlot->setAutoLegend( myShowLegend );
1098 myPlot->enableLegend( myShowLegend );
1104 Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
1106 void Plot2d_ViewFrame::setLegendPos( int pos )
1111 myPlot->setLegendPos( Qwt::Left );
1114 myPlot->setLegendPos( Qwt::Right );
1117 myPlot->setLegendPos( Qwt::Top );
1120 myPlot->setLegendPos( Qwt::Bottom );
1126 Sets new marker size
1128 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
1130 if ( myMarkerSize != size )
1132 myMarkerSize = size;
1133 QArray<long> keys = myPlot->curveKeys();
1134 for ( int i = 0; i < (int)keys.count(); i++ )
1136 QwtPlotCurve* crv = myPlot->curve( keys[i] );
1139 QwtSymbol aSymbol = crv->symbol();
1140 aSymbol.setSize( myMarkerSize, myMarkerSize );
1141 myPlot->setCurveSymbol( keys[i], aSymbol );
1150 Sets background color
1152 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
1154 myBackground = color;
1155 //myPlot->setCanvasBackground( myBackground );
1156 myPlot->canvas()->setPalette( myBackground );
1157 myPlot->setPalette( myBackground );
1158 QPalette aPal = myPlot->getLegend()->palette();
1159 for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
1160 QPalette::ColorGroup cg = (QPalette::ColorGroup)i;
1161 aPal.setColor( cg, QColorGroup::Base, myBackground );
1162 aPal.setColor( cg, QColorGroup::Background, myBackground );
1164 myPlot->getLegend()->setPalette( aPal );
1168 Gets background color
1170 QColor Plot2d_ViewFrame::backgroundColor() const
1172 return myBackground;
1175 Sets hor.axis grid parameters
1177 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax,
1178 bool xMinorEnabled, const int xMinorMax,
1181 myXGridMajorEnabled = xMajorEnabled;
1182 myXGridMinorEnabled = xMinorEnabled;
1183 myXGridMaxMajor = xMajorMax;
1184 myXGridMaxMinor = xMinorMax;
1185 myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
1186 myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
1187 myPlot->setGridXAxis(QwtPlot::xBottom);
1188 myPlot->enableGridX( myXGridMajorEnabled );
1189 myPlot->enableGridXMin( myXGridMinorEnabled );
1194 Sets ver.axis grid parameters
1196 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax,
1197 bool yMinorEnabled, const int yMinorMax,
1198 bool y2MajorEnabled, const int y2MajorMax,
1199 bool y2MinorEnabled, const int y2MinorMax,
1202 myYGridMajorEnabled = yMajorEnabled;
1203 myYGridMinorEnabled = yMinorEnabled;
1204 myYGridMaxMajor = yMajorMax;
1205 myYGridMaxMinor = yMinorMax;
1208 myY2GridMajorEnabled = y2MajorEnabled;
1209 myY2GridMinorEnabled = y2MinorEnabled;
1210 myY2GridMaxMajor = y2MajorMax;
1211 myY2GridMaxMinor = y2MinorMax;
1213 myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
1214 myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
1217 myPlot->setAxisMaxMajor( QwtPlot::yRight, myY2GridMaxMajor );
1218 myPlot->setAxisMaxMinor( QwtPlot::yRight, myY2GridMaxMinor );
1221 myPlot->setGridYAxis(QwtPlot::yLeft);
1224 if (myYGridMajorEnabled) {
1225 myPlot->enableGridYMin(myYGridMinorEnabled);
1226 myPlot->enableGridY( myYGridMajorEnabled);
1228 else if (myY2GridMajorEnabled) {
1229 myPlot->setGridYAxis(QwtPlot::yRight);
1230 myPlot->enableGridYMin(myY2GridMinorEnabled);
1231 myPlot->enableGridY(myY2GridMajorEnabled);
1234 myPlot->enableGridYMin(false);
1235 myPlot->enableGridY(false);
1239 myPlot->enableGridY( myYGridMajorEnabled );
1240 myPlot->enableGridYMin( myYGridMinorEnabled );
1247 Sets title for some axis
1249 void Plot2d_ViewFrame::setTitle( bool enabled, const QString& title,
1250 ObjectType type, bool update )
1254 myTitleEnabled = enabled;
1256 myPlot->setTitle( myTitleEnabled ? myTitle : QString::null );
1259 myXTitleEnabled = enabled;
1261 myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString::null );
1264 myYTitleEnabled = enabled;
1266 myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString::null );
1269 myY2TitleEnabled = enabled;
1271 myPlot->setAxisTitle( QwtPlot::yRight, myY2TitleEnabled ? myY2Title : QString::null );
1278 Sets title for some axis
1280 QString Plot2d_ViewFrame::getTitle( ObjectType type ) const
1285 title = myTitle; break;
1287 title = myXTitle; break;
1289 title = myYTitle; break;
1291 title = myY2Title; break;
1296 Sets font for Plot2d object : title or axis
1298 void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update)
1302 myPlot->setTitleFont(font);
1305 myPlot->setAxisTitleFont(QwtPlot::xBottom, font); break;
1307 myPlot->setAxisTitleFont(QwtPlot::yLeft, font); break;
1309 myPlot->setAxisTitleFont(QwtPlot::yRight, font); break;
1311 myPlot->setAxisFont(QwtPlot::xBottom, font); break;
1313 myPlot->setAxisFont(QwtPlot::yLeft, font); break;
1315 myPlot->setAxisFont(QwtPlot::yRight, font); break;
1321 Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
1323 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
1325 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
1326 // it crashes if switched to X/Y logarithmic mode, when one or more points have
1327 // non-positive X/Y coordinate
1328 if ( mode && !isXLogEnabled() ){
1329 SUIT_MessageBox::warn1(this, tr("WARNING"), tr("WRN_XLOG_NOT_ALLOWED"), tr("BUT_OK"));
1335 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, myXMode != 0 );
1339 emit vpModeHorChanged();
1342 Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
1344 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
1346 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
1347 // it crashes if switched to X/Y logarithmic mode, when one or more points have
1348 // non-positive X/Y coordinate
1349 if ( mode && !isYLogEnabled() ){
1350 SUIT_MessageBox::warn1(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"), tr("BUT_OK"));
1355 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, myYMode != 0 );
1357 myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, myYMode != 0 );
1361 emit vpModeVerChanged();
1365 Return, scale mode for horizontal axis
1367 bool Plot2d_ViewFrame::isModeHorLinear()
1369 return (myXMode == 0 ? true : false);
1373 Return, scale mode for vertical axis
1375 bool Plot2d_ViewFrame::isModeVerLinear()
1377 return (myYMode == 0 ? true : false);
1380 Slot, called when user presses mouse button
1382 void Plot2d_ViewFrame::plotMousePressed(const QMouseEvent& me )
1384 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1386 aParent->putInfo(getInfo(me.pos()));
1387 if ( myOperation == NoOpId )
1388 myOperation = testOperation( me );
1389 if ( myOperation != NoOpId ) {
1391 if ( myOperation == FitAreaId ) {
1392 myPlot->setOutlineStyle( Qwt::Rect );
1394 else if ( myOperation == GlPanId ) {
1395 myPlot->setAxisScale( QwtPlot::yLeft,
1396 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2,
1397 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2 );
1398 myPlot->setAxisScale( QwtPlot::xBottom,
1399 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2,
1400 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
1402 myPlot->setAxisScale( QwtPlot::yRight,
1403 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2,
1404 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2 );
1409 int btn = me.button() | me.state();
1410 if (btn == RightButton) {
1411 QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
1412 me.pos(), btn, me.state());
1413 // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
1414 parent()->eventFilter(this, aEvent);
1419 Slot, called when user moves mouse
1421 void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
1423 int dx = me.pos().x() - myPnt.x();
1424 int dy = me.pos().y() - myPnt.y();
1426 if ( myOperation != NoOpId) {
1427 if ( myOperation == ZoomId ) {
1428 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1429 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1431 myPlot->setAxisScale( QwtPlot::yLeft,
1432 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1433 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + dy ) );
1434 myPlot->setAxisScale( QwtPlot::xBottom,
1435 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1436 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - dx ) );
1438 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1439 myPlot->setAxisScale( QwtPlot::yRight,
1440 myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ),
1441 myPlot->invTransform( QwtPlot::yRight, y2Map.i2() + dy ) );
1446 else if ( myOperation == PanId ) {
1447 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1448 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1450 myPlot->setAxisScale( QwtPlot::yLeft,
1451 myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-dy ),
1452 myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-dy ) );
1453 myPlot->setAxisScale( QwtPlot::xBottom,
1454 myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-dx ),
1455 myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-dx ) );
1457 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1458 myPlot->setAxisScale( QwtPlot::yRight,
1459 myPlot->invTransform( QwtPlot::yRight, y2Map.i1()-dy ),
1460 myPlot->invTransform( QwtPlot::yRight, y2Map.i2()-dy ) );
1467 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1469 aParent->putInfo(getInfo(me.pos()));
1473 Slot, called when user releases mouse
1475 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
1477 if ( myOperation == NoOpId && me.button() == RightButton )
1479 QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
1480 me.pos(), me.globalPos(),
1482 emit contextMenuRequested( &aEvent );
1484 if ( myOperation == FitAreaId ) {
1485 QRect rect( myPnt, me.pos() );
1488 myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
1489 myPlot->setOutlineStyle( Qwt::Triangle );
1491 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1493 aParent->putInfo(tr("INF_READY"));
1494 myOperation = NoOpId;
1497 Slot, called when user wheeling mouse
1499 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
1501 double aDelta = event->delta();
1502 double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.;
1504 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1505 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1507 myPlot->setAxisScale( QwtPlot::yLeft,
1508 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1509 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() )*aScale );
1510 myPlot->setAxisScale( QwtPlot::xBottom,
1511 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1512 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() )*aScale );
1514 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1515 myPlot->setAxisScale( QwtPlot::yRight,
1516 myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ),
1517 myPlot->invTransform( QwtPlot::yRight, y2Map.i2() )*aScale );
1520 myPnt = event->pos();
1523 View operations : Pan view
1525 void Plot2d_ViewFrame::onViewPan()
1527 QCursor panCursor (Qt::SizeAllCursor);
1528 myPlot->canvas()->setCursor( panCursor );
1529 myOperation = PanId;
1530 qApp->installEventFilter( this );
1533 View operations : Zoom view
1535 void Plot2d_ViewFrame::onViewZoom()
1537 QPixmap zoomPixmap (imageZoomCursor);
1538 QCursor zoomCursor (zoomPixmap);
1539 myPlot->canvas()->setCursor( zoomCursor );
1540 myOperation = ZoomId;
1541 qApp->installEventFilter( this );
1544 View operations : Fot All
1546 void Plot2d_ViewFrame::onViewFitAll()
1551 View operations : Fit Area
1553 void Plot2d_ViewFrame::onViewFitArea()
1555 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1556 myOperation = FitAreaId;
1557 qApp->installEventFilter( this );
1560 View operations : Global panning
1562 void Plot2d_ViewFrame::onViewGlobalPan()
1564 QPixmap globalPanPixmap (imageCrossCursor);
1565 QCursor glPanCursor (globalPanPixmap);
1566 myPlot->canvas()->setCursor( glPanCursor );
1567 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1568 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1570 myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1572 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1573 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1575 myXDistance = xMap.d2() - xMap.d1();
1576 myYDistance = yMap.d2() - yMap.d1();
1579 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
1580 myYDistance2 = yMap2.d2() - yMap2.d1();
1583 myOperation = GlPanId;
1584 qApp->installEventFilter( this );
1588 Precaution for logarithmic X scale
1590 bool Plot2d_ViewFrame::isXLogEnabled() const
1592 bool allPositive = true;
1593 QIntDictIterator<Plot2d_Curve> it( myCurves );
1594 for ( ; allPositive && it.current(); ++it ) {
1595 allPositive = ( it.current()->getMinX() > 0. );
1601 Precaution for logarithmic Y scale
1603 bool Plot2d_ViewFrame::isYLogEnabled() const
1605 bool allPositive = true;
1606 QIntDictIterator<Plot2d_Curve> it( myCurves );
1607 for ( ; allPositive && it.current(); ++it ) {
1608 allPositive = ( it.current()->getMinY() > 0. );
1616 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
1620 enableOutline( true );
1621 setOutlineStyle( Qwt::Triangle );
1622 setOutlinePen( green );
1624 setAutoLegend( false );
1625 setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
1626 enableLegend( false );
1628 enableGridX( false );
1629 enableGridXMin( false );
1630 enableGridY( false );
1631 enableGridYMin( false );
1632 // auto scaling by default
1633 setAxisAutoScale( QwtPlot::yLeft );
1634 setAxisAutoScale( QwtPlot::yRight );
1635 setAxisAutoScale( QwtPlot::xBottom );
1638 Recalculates and redraws Plot 2d view
1640 void Plot2d_Plot2d::replot()
1642 updateLayout(); // to fix bug(?) of Qwt - view is not updated when title is changed
1647 Checks if two colors are close to each other [ static ]
1648 uses COLOR_DISTANCE variable as max tolerance for comparing of colors
1650 const long COLOR_DISTANCE = 100;
1651 const int MAX_ATTEMPTS = 10;
1652 static bool closeColors( const QColor& color1, const QColor& color2 )
1654 long tol = abs( color2.red() - color1.red() ) +
1655 abs( color2.green() - color1.green() ) +
1656 abs( color2.blue() - color1.blue() );
1658 return ( tol <= COLOR_DISTANCE );
1661 Gets new unique marker for item if possible
1663 void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine )
1668 int aRed = (int)( 256.0 * rand() / RAND_MAX); // generate random color
1669 int aGreen = (int)( 256.0 * rand() / RAND_MAX); // ...
1670 int aBlue = (int)( 256.0 * rand() / RAND_MAX); // ...
1671 int aMarker = (int)( 9.0 * rand() / RAND_MAX) + 1; // 9 markers types ( not including empty )
1672 int aLine = (int)( 5.0 * rand() / RAND_MAX) + 1; // 5 line types ( not including empty )
1674 typeMarker = ( QwtSymbol::Style )aMarker;
1675 color = QColor( aRed, aGreen, aBlue );
1676 typeLine = ( Qt::PenStyle )aLine;
1679 if ( cnt == MAX_ATTEMPTS )
1682 bOk = !existMarker( typeMarker, color, typeLine );
1685 static int aMarker = -1;
1686 static int aColor = -1;
1687 static int aLine = -1;
1689 if ( myColors.isEmpty() ) {
1690 // creating colors list
1691 myColors.append( Qt::white );
1692 myColors.append( Qt::blue );
1693 myColors.append( Qt::gray );
1694 myColors.append( Qt::darkGreen );
1695 myColors.append( Qt::magenta );
1696 myColors.append( Qt::darkGray );
1697 myColors.append( Qt::red );
1698 myColors.append( Qt::darkBlue );
1699 myColors.append( Qt::darkYellow );
1700 myColors.append( Qt::cyan );
1701 myColors.append( Qt::darkRed );
1702 myColors.append( Qt::darkCyan );
1703 myColors.append( Qt::yellow );
1704 myColors.append( Qt::darkMagenta );
1705 myColors.append( Qt::green );
1706 myColors.append( Qt::black );
1709 int nbMarkers = 11; // QwtSymbol supports 11 marker types
1710 int nbLines = 6; // Qt supports 6 line types
1711 int nbColors = myColors.count(); // number of default colors supported
1713 aMarker = ( aMarker + 1 ) % nbMarkers;
1714 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1715 aColor = ( aColor + 1 ) % nbColors;
1716 aLine = ( aLine + 1 ) % nbLines;
1717 if ( aLine == Qt::NoPen ) aLine++;
1719 typeMarker = ( QwtSymbol::Style )aMarker;
1720 color = myColors[ aColor ];
1721 typeLine = ( Qt::PenStyle )aLine;
1722 if ( !existMarker( typeMarker, color, typeLine ) )
1726 for ( i = 0; i < nbMarkers; i++ ) {
1727 aMarker = ( aMarker + 1 ) % nbMarkers;
1728 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1729 for ( j = 0; j < nbColors; j++ ) {
1730 aColor = ( aColor + 1 ) % nbColors;
1731 for ( k = 0; k < nbLines; k++ ) {
1732 aLine = ( aLine + 1 ) % nbLines;
1733 if ( aLine == Qt::NoPen ) aLine++;
1734 if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
1735 typeMarker = ( QwtSymbol::Style )aMarker;
1736 color = myColors[ aColor ];
1737 typeLine = ( Qt::PenStyle )aLine;
1747 \return the default layout behavior of the widget
1749 QSizePolicy Plot2d_Plot2d::sizePolicy() const
1751 return QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
1755 \return the recommended size for the widget
1757 QSize Plot2d_Plot2d::sizeHint() const
1759 return QwtPlot::minimumSizeHint();
1763 return minimum size for qwt plot
1765 QSize Plot2d_Plot2d::minimumSizeHint() const
1767 return QSize( 0, 0 );
1768 // QSize aSize = QwtPlot::minimumSizeHint();
1769 // return QSize(aSize.width()*3/4, aSize.height());
1772 Checks if marker belongs to any enitity
1774 bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine )
1776 // getting all curves
1777 QArray<long> keys = curveKeys();
1780 if ( closeColors( color, backgroundColor() ) )
1782 for ( int i = 0; i < (int)keys.count(); i++ )
1784 QwtPlotCurve* crv = curve( keys[i] );
1786 QwtSymbol::Style aStyle = crv->symbol().style();
1787 QColor aColor = crv->pen().color();
1788 Qt::PenStyle aLine = crv->pen().style();
1789 // if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
1790 if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
1798 Creates presentation of object
1799 Default implementation is empty
1801 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
1807 Copies preferences from other viewframe
1808 \param vf - other view frame
1810 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
1815 myCurveType = vf->myCurveType;
1816 myShowLegend = vf->myShowLegend;
1817 myLegendPos = vf->myLegendPos;
1818 myMarkerSize = vf->myMarkerSize;
1819 myBackground = vf->myBackground;
1820 myTitle = vf->myTitle;
1821 myXTitle = vf->myXTitle;
1822 myYTitle = vf->myYTitle;
1823 myY2Title = vf->myY2Title;
1824 myTitleEnabled = vf->myTitleEnabled;
1825 myXTitleEnabled = vf->myXTitleEnabled;
1826 myYTitleEnabled = vf->myYTitleEnabled;
1827 myY2TitleEnabled = vf->myY2TitleEnabled;
1828 myXGridMajorEnabled = vf->myXGridMajorEnabled;
1829 myYGridMajorEnabled = vf->myYGridMajorEnabled;
1830 myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
1831 myXGridMinorEnabled = vf->myXGridMinorEnabled;
1832 myYGridMinorEnabled = vf->myYGridMinorEnabled;
1833 myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
1834 myXGridMaxMajor = vf->myXGridMaxMajor;
1835 myYGridMaxMajor = vf->myYGridMaxMajor;
1836 myY2GridMaxMajor = vf->myY2GridMaxMajor;
1837 myXGridMaxMinor = vf->myXGridMaxMinor;
1838 myYGridMaxMinor = vf->myYGridMaxMinor;
1839 myY2GridMaxMinor = vf->myY2GridMaxMinor;
1840 myXMode = vf->myXMode;
1841 myYMode = vf->myYMode;
1842 mySecondY = vf->mySecondY;
1846 Updates titles according to curves
1848 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
1849 void Plot2d_ViewFrame::updateTitles()
1851 QIntDictIterator<Plot2d_Curve> it( myCurves );
1852 QStringList aXTitles;
1853 QStringList aYTitles;
1854 QStringList aXUnits;
1855 QStringList aYUnits;
1856 QStringList aTables;
1858 while ( it.current() ) {
1859 // collect titles and units from all curves...
1860 QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
1861 QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
1862 QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
1863 QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
1865 aYTitles.append( yTitle );
1866 if ( aXTitles.find( xTitle ) == aXTitles.end() )
1867 aXTitles.append( xTitle );
1868 if ( aXUnits.find( xUnits ) == aXUnits.end() )
1869 aXUnits.append( xUnits );
1870 if ( aYUnits.find( yUnits ) == aYUnits.end() )
1871 aYUnits.append( yUnits );
1873 QString aName = it.current()->getTableTitle();
1874 if( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
1875 aTables.append( aName );
1880 // ... and update plot 2d view
1881 QString xUnits, yUnits;
1882 if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
1883 xUnits = BRACKETIZE( aXUnits[0] );
1884 if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
1885 yUnits = BRACKETIZE( aYUnits[0] );
1886 QString xTitle, yTitle;
1887 if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
1888 xTitle = aXTitles[0];
1889 if ( aYTitles.count() == 1 )
1890 yTitle = aYTitles[0];
1892 if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
1894 if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
1897 setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, true );
1898 setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true );
1899 setTitle( true, aTables.join("; "), MainTitle, true );
1903 Outputs content of viewframe to file
1904 \param file - file name
1905 \param format - file format
1907 bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
1916 QPaintDevice* pd = 0;
1919 QPrinter* pr = new QPrinter( QPrinter::HighResolution );
1920 pr->setPageSize( QPrinter::A4 );
1921 pr->setOutputToFile( true );
1922 pr->setOutputFileName( file );
1923 pr->setPrintProgram( "" );
1929 myPlot->print( *pd );
1939 \return string with all visual parameters
1941 QString Plot2d_ViewFrame::getVisualParameters()
1943 double xmin, xmax, ymin, ymax, y2min, y2max;
1944 getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max );
1946 retStr.sprintf( "%d*%d*%d*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e", myXMode,
1947 myYMode, mySecondY, xmin, xmax, ymin, ymax, y2min, y2max );
1952 Restores all visual parameters from string
1954 void Plot2d_ViewFrame::setVisualParameters( const QString& parameters )
1956 QStringList paramsLst = QStringList::split( '*', parameters, true );
1957 if ( paramsLst.size() == 9 ) {
1958 double xmin, xmax, ymin, ymax, y2min, y2max;
1959 myXMode = paramsLst[0].toInt();
1960 myYMode = paramsLst[1].toInt();
1961 mySecondY = (bool)paramsLst[2].toInt();
1962 xmin = paramsLst[3].toDouble();
1963 xmax = paramsLst[4].toDouble();
1964 ymin = paramsLst[5].toDouble();
1965 ymax = paramsLst[6].toDouble();
1966 y2min = paramsLst[7].toDouble();
1967 y2max = paramsLst[8].toDouble();
1970 setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
1971 setHorScaleMode( myXMode, /*update=*/false );
1972 setVerScaleMode( myYMode, /*update=*/false );
1975 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
1976 myYDistance2 = yMap2.d2() - yMap2.d1();
1979 fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
1980 fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );