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 "................................"};
133 //=================================================================================
134 // Plot2d_ViewFrame implementation
135 //=================================================================================
140 Plot2d_ViewFrame::Plot2d_ViewFrame( QWidget* parent, const QString& title )
141 : QWidget (parent, title, 0),
142 myOperation( NoOpId ),
144 myShowLegend( true ), myLegendPos( 1 ),
145 myMarkerSize( DEFAULT_MARKER_SIZE ),
146 myTitle( "" ), myXTitle( "" ), myYTitle( "" ), myY2Title( "" ),
147 myBackground( white ),
148 myTitleEnabled( true ), myXTitleEnabled( true ),
149 myYTitleEnabled( true ), myY2TitleEnabled (true),
150 myXGridMajorEnabled( true ), myYGridMajorEnabled( true ), myY2GridMajorEnabled( true ),
151 myXGridMinorEnabled( false ), myYGridMinorEnabled( false ), myY2GridMinorEnabled( false ),
152 myXGridMaxMajor( 8 ), myYGridMaxMajor( 8 ), myY2GridMaxMajor( 8 ),
153 myXGridMaxMinor( 5 ), myYGridMaxMinor( 5 ), myY2GridMaxMinor( 5 ),
154 myXMode( 0 ), myYMode( 0 ), mySecondY( false )
157 QVBoxLayout* aLayout = new QVBoxLayout( this );
158 myPlot = new Plot2d_Plot2d( this );
159 aLayout->addWidget( myPlot );
163 connect( myPlot, SIGNAL( plotMouseMoved( const QMouseEvent& ) ),
164 this, SLOT( plotMouseMoved( const QMouseEvent& ) ) );
165 connect( myPlot, SIGNAL( plotMousePressed( const QMouseEvent& ) ),
166 this, SLOT( plotMousePressed( const QMouseEvent& ) ) );
167 connect( myPlot, SIGNAL( plotMouseReleased( const QMouseEvent& ) ),
168 this, SLOT( plotMouseReleased( const QMouseEvent& ) ) );
169 //connect( myPlot, SIGNAL( legendClicked( long ) ),
170 // this, SLOT( onLegendClicked( long ) ) );
172 /* Initial Setup - get from the preferences */
175 myPlot->setMargin( 5 );
176 setCurveType( myCurveType, false );
177 setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, false );
178 setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
179 myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, false );
181 setTitle( myTitleEnabled, myTitle, MainTitle, false );
182 setTitle( myXTitleEnabled, myXTitle, XTitle, false );
183 setTitle( myYTitleEnabled, myYTitle, YTitle, false );
186 setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
187 setHorScaleMode( myXMode, false );
188 setVerScaleMode( myYMode, false );
189 setBackgroundColor( myBackground );
190 setLegendPos( myLegendPos );
191 showLegend( myShowLegend, false );
195 resize( (int)(0.8 * parent->width()), (int)(0.8 * parent->height()) );
197 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
198 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
199 myXDistance = xMap.d2() - xMap.d1();
200 myYDistance = yMap.d2() - yMap.d1();
203 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
204 myYDistance2 = yMap2.d2() - yMap2.d1();
210 Plot2d_ViewFrame::~Plot2d_ViewFrame()
214 Gets window's central widget
216 QWidget* Plot2d_ViewFrame::getViewWidget()
218 return (QWidget*)myPlot;
221 Actually this method just re-displays all curves which are presented in the viewer
223 void Plot2d_ViewFrame::DisplayAll()
225 QList<Plot2d_Curve> clist;
227 for ( int i = 0; i < (int)clist.count(); i++ ) {
228 updateCurve( clist.at( i ), false );
233 Removes all curves from the view
235 void Plot2d_ViewFrame::EraseAll()
242 Redraws viewframe contents
244 void Plot2d_ViewFrame::Repaint()
251 void Plot2d_ViewFrame::Display( const Plot2d_Prs* prs )
253 if ( !prs || prs->IsNull() )
256 if (prs->isSecondY()) {
257 myPlot->enableAxis(QwtPlot::yRight, true);
261 myPlot->enableAxis(QwtPlot::yRight, false);
265 // display all curves from presentation
266 curveList aCurves = prs->getCurves();
267 displayCurves( aCurves );
268 setXGrid( myXGridMajorEnabled, myXGridMaxMajor, myXGridMinorEnabled, myXGridMaxMinor, true );
269 setYGrid( myYGridMajorEnabled, myYGridMaxMajor, myYGridMinorEnabled, myYGridMaxMinor,
270 myY2GridMajorEnabled, myY2GridMaxMajor, myY2GridMinorEnabled, myY2GridMaxMinor, true );
276 void Plot2d_ViewFrame::Erase( const Plot2d_Prs* prs, const bool )
278 if ( !prs || prs->IsNull() )
281 // erase all curves from presentation
282 curveList aCurves = prs->getCurves();
283 eraseCurves( aCurves );
289 void Plot2d_ViewFrame::setTitle( const QString& title )
291 setTitle( myTitleEnabled, title, MainTitle, true );
295 Reads Plot2d view settings from the preferences
297 void Plot2d_ViewFrame::readPreferences()
299 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
301 myCurveType = resMgr->integerValue( "Plot2d", "CurveType", myCurveType );
302 setCurveType( resMgr->integerValue( "Plot2d", "CurveType", myCurveType ) );
304 myShowLegend = resMgr->booleanValue( "Plot2d", "ShowLegend", myShowLegend );
305 myLegendPos = resMgr->integerValue( "Plot2d", "LegendPos", myLegendPos );
306 myMarkerSize = resMgr->integerValue( "Plot2d", "MarkerSize", myMarkerSize );
307 myBackground = resMgr->colorValue( "Plot2d", "Background", myBackground );
309 myTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowTitle", myTitleEnabled );
310 myXTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
311 myYTitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
312 myY2TitleEnabled = resMgr->booleanValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
314 myXGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
315 myYGridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
316 myY2GridMajorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
318 myXGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
319 myYGridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
320 myY2GridMinorEnabled = resMgr->booleanValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
322 myXGridMaxMajor = resMgr->integerValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
323 myYGridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
325 myY2GridMaxMajor = resMgr->integerValue( "Plot2d", "VerMajorRightGridMax", myY2GridMaxMajor );
327 myXGridMaxMinor = resMgr->integerValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
328 myYGridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
330 myY2GridMaxMinor = resMgr->integerValue( "Plot2d", "VerMinorGridMax", myY2GridMaxMinor );
332 myXMode = resMgr->integerValue( "Plot2d", "HorScaleMode", myXMode );
333 myXMode = QMAX( 0, QMIN( 1, myXMode ) );
335 myYMode = resMgr->integerValue( "Plot2d", "VerScaleMode", myYMode );
336 myYMode = QMAX( 0, QMIN( 1, myYMode ) );
340 Writes Plot2d view settings to the preferences
342 void Plot2d_ViewFrame::writePreferences()
344 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
346 resMgr->setValue( "Plot2d", "CurveType", myCurveType );
347 resMgr->setValue( "Plot2d", "ShowLegend", myShowLegend );
348 resMgr->setValue( "Plot2d", "LegendPos", myLegendPos );
349 resMgr->setValue( "Plot2d", "MarkerSize", myMarkerSize );
350 resMgr->setValue( "Plot2d", "Background", myBackground );
351 resMgr->setValue( "Plot2d", "ShowTitle", myTitleEnabled );
352 resMgr->setValue( "Plot2d", "ShowHorTitle", myXTitleEnabled );
353 resMgr->setValue( "Plot2d", "ShowVerLeftTitle", myYTitleEnabled );
355 resMgr->setValue( "Plot2d", "ShowVerRightTitle", myY2TitleEnabled );
357 resMgr->setValue( "Plot2d", "EnableHorMajorGrid", myXGridMajorEnabled );
358 resMgr->setValue( "Plot2d", "EnableVerMajorGrid", myYGridMajorEnabled );
359 resMgr->setValue( "Plot2d", "EnableHorMinorGrid", myXGridMinorEnabled );
360 resMgr->setValue( "Plot2d", "EnableVerMinorGrid", myYGridMinorEnabled );
362 resMgr->setValue( "Plot2d", "HorMajorGridMax", myXGridMaxMajor );
363 resMgr->setValue( "Plot2d", "VerMajorGridMax", myYGridMaxMajor );
365 resMgr->setValue( "Plot2d", "HorMinorGridMax", myXGridMaxMinor );
366 resMgr->setValue( "Plot2d", "VerMinorGridMax", myYGridMaxMinor );
368 resMgr->setValue( "Plot2d", "HorScaleMode", myXMode );
372 resMgr->setValue( "Plot2d", "EnableRightVerMajorGrid", myY2GridMajorEnabled );
373 resMgr->setValue( "Plot2d", "EnableRightVerMinorGrid", myY2GridMinorEnabled );
374 resMgr->setValue( "Plot2d", "VerRightMajorGridMax", myY2GridMaxMajor );
375 resMgr->setValue( "Plot2d", "VerRightMinorGridMax", myY2GridMaxMinor );
378 resMgr->setValue( "Plot2d", "VerScaleMode", myYMode );
382 Prints mouse cursor coordinates into string
384 QString Plot2d_ViewFrame::getInfo( const QPoint& pnt )
387 bool xFound = false, yFound = false;
388 double xCoord, yCoord;
389 const QwtScaleDiv* aXscale = myPlot->axisScale( QwtPlot::xBottom );
390 for ( i = 0; i < aXscale->majCnt(); i++ ) {
391 double majXmark = aXscale->majMark( i );
392 int xmark = myPlot->transform( QwtPlot::xBottom, majXmark );
393 if ( xmark-2 == pnt.x() ) {
400 for ( i = 0; i < aXscale->minCnt(); i++ ) {
401 double minXmark = aXscale->minMark( i );
402 int xmark = myPlot->transform( QwtPlot::xBottom, minXmark );
403 if ( xmark-2 == pnt.x() ) {
410 const QwtScaleDiv* aYscale = myPlot->axisScale( QwtPlot::yLeft );
411 for ( i = 0; i < aYscale->majCnt(); i++ ) {
412 double majYmark = aYscale->majMark( i );
413 int ymark = myPlot->transform( QwtPlot::yLeft, majYmark );
414 if ( ymark-2 == pnt.y() ) {
421 for ( i = 0; i < aYscale->minCnt(); i++ ) {
422 double minYmark = aYscale->minMark( i );
423 int ymark = myPlot->transform( QwtPlot::yLeft, minYmark );
424 if ( ymark-2 == pnt.y() ) {
432 QString strX = QString::number( xFound ? xCoord : myPlot->invTransform( QwtPlot::xBottom, pnt.x() ) ).stripWhiteSpace();
435 QString strY = QString::number( yFound ? yCoord : myPlot->invTransform( QwtPlot::yLeft, pnt.y() ) ).stripWhiteSpace();
441 bool yFound2 = false;
444 const QwtScaleDiv* aYscale2 = myPlot->axisScale( QwtPlot::yRight );
445 for ( i = 0; i < aYscale2->majCnt(); i++ ) {
446 double majYmark = aYscale2->majMark( i );
447 int ymark = myPlot->transform( QwtPlot::yRight, majYmark );
448 if ( ymark-2 == pnt.y() ) {
455 for ( i = 0; i < aYscale2->minCnt(); i++ ) {
456 double minYmark = aYscale2->minMark( i );
457 int ymark = myPlot->transform( QwtPlot::yRight, minYmark );
458 if ( ymark-2 == pnt.y() ) {
465 QString strY2 = QString::number( yFound2 ? yCoord2 :
466 myPlot->invTransform( QwtPlot::yRight, pnt.y() ) ).stripWhiteSpace();
469 info = tr("INF_COORDINATES_SOME_Y").arg( strX ).arg( strY ).arg( strY2 );
472 info = tr("INF_COORDINATES").arg( strX ).arg( strY );
478 Converts Plot2d_Curve's marker style to Qwt marker style [ static ]
480 static QwtSymbol::Style plot2qwtMarker( Plot2d_Curve::MarkerType m )
482 QwtSymbol::Style ms = QwtSymbol::None;
484 case Plot2d_Curve::Circle:
485 ms = QwtSymbol::Ellipse; break;
486 case Plot2d_Curve::Rectangle:
487 ms = QwtSymbol::Rect; break;
488 case Plot2d_Curve::Diamond:
489 ms = QwtSymbol::Diamond; break;
490 case Plot2d_Curve::DTriangle:
491 ms = QwtSymbol::DTriangle; break;
492 case Plot2d_Curve::UTriangle:
493 ms = QwtSymbol::UTriangle; break;
494 case Plot2d_Curve::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
495 ms = QwtSymbol::RTriangle; break;
496 case Plot2d_Curve::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
497 ms = QwtSymbol::LTriangle; break;
498 case Plot2d_Curve::Cross:
499 ms = QwtSymbol::Cross; break;
500 case Plot2d_Curve::XCross:
501 ms = QwtSymbol::XCross; break;
502 case Plot2d_Curve::None:
504 ms = QwtSymbol::None; break;
510 Converts Qwt marker style to Plot2d_Curve's marker style [ static ]
512 static Plot2d_Curve::MarkerType qwt2plotMarker( QwtSymbol::Style m )
514 Plot2d_Curve::MarkerType ms = Plot2d_Curve::None;
516 case QwtSymbol::Ellipse:
517 ms = Plot2d_Curve::Circle; break;
518 case QwtSymbol::Rect:
519 ms = Plot2d_Curve::Rectangle; break;
520 case QwtSymbol::Diamond:
521 ms = Plot2d_Curve::Diamond; break;
522 case QwtSymbol::DTriangle:
523 ms = Plot2d_Curve::DTriangle; break;
524 case QwtSymbol::UTriangle:
525 ms = Plot2d_Curve::UTriangle; break;
526 case QwtSymbol::RTriangle: // Qwt confuses LTriangle and RTriangle :(((
527 ms = Plot2d_Curve::LTriangle; break;
528 case QwtSymbol::LTriangle: // Qwt confuses LTriangle and RTriangle :(((
529 ms = Plot2d_Curve::RTriangle; break;
530 case QwtSymbol::Cross:
531 ms = Plot2d_Curve::Cross; break;
532 case QwtSymbol::XCross:
533 ms = Plot2d_Curve::XCross; break;
534 case QwtSymbol::None:
536 ms = Plot2d_Curve::None; break;
542 Converts Plot2d_Curve's line style to Qwt line style [ static ]
544 static Qt::PenStyle plot2qwtLine( Plot2d_Curve::LineType p )
546 Qt::PenStyle ps = Qt::NoPen;
548 case Plot2d_Curve::Solid:
549 ps = Qt::SolidLine; break;
550 case Plot2d_Curve::Dash:
551 ps = Qt::DashLine; break;
552 case Plot2d_Curve::Dot:
553 ps = Qt::DotLine; break;
554 case Plot2d_Curve::DashDot:
555 ps = Qt::DashDotLine; break;
556 case Plot2d_Curve::DashDotDot:
557 ps = Qt::DashDotDotLine; break;
558 case Plot2d_Curve::NoPen:
560 ps = Qt::NoPen; break;
566 Converts Qwt line style to Plot2d_Curve's line style [ static ]
568 static Plot2d_Curve::LineType qwt2plotLine( Qt::PenStyle p )
570 Plot2d_Curve::LineType ps = Plot2d_Curve::NoPen;
573 ps = Plot2d_Curve::Solid; break;
575 ps = Plot2d_Curve::Dash; break;
577 ps = Plot2d_Curve::Dot; break;
578 case Qt::DashDotLine:
579 ps = Plot2d_Curve::DashDot; break;
580 case Qt::DashDotDotLine:
581 ps = Plot2d_Curve::DashDotDot; break;
584 ps = Plot2d_Curve::NoPen; break;
592 void Plot2d_ViewFrame::displayCurve( Plot2d_Curve* curve, bool update )
597 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
598 // it crashes if switched to X/Y logarithmic mode, when one or more points have
599 // non-positive X/Y coordinate
600 if ( myXMode && curve->getMinX() <= 0. )
601 setHorScaleMode( 0, false );
602 if ( myYMode && curve->getMinY() <= 0. )
603 setVerScaleMode( 0, false );
605 if ( hasCurve( curve ) ) {
606 updateCurve( curve, update );
609 long curveKey = myPlot->insertCurve( curve->getVerTitle() );
610 myPlot->setCurveYAxis(curveKey, curve->getYAxis());
612 myCurves.insert( curveKey, curve );
613 if ( curve->isAutoAssign() ) {
614 QwtSymbol::Style typeMarker;
616 Qt::PenStyle typeLine;
617 myPlot->getNextMarker( typeMarker, color, typeLine );
618 myPlot->setCurvePen( curveKey, QPen( color, DEFAULT_LINE_WIDTH, typeLine ) );
619 myPlot->setCurveSymbol( curveKey, QwtSymbol( typeMarker,
622 QSize( myMarkerSize, myMarkerSize ) ) );
623 curve->setColor( color );
624 curve->setLine( qwt2plotLine( typeLine ) );
625 curve->setMarker( qwt2plotMarker( typeMarker ) );
628 Qt::PenStyle ps = plot2qwtLine( curve->getLine() );
629 QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
630 myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
631 myPlot->setCurveSymbol( curveKey, QwtSymbol( ms,
632 QBrush( curve->getColor() ),
633 QPen( curve->getColor() ),
634 QSize( myMarkerSize, myMarkerSize ) ) );
636 if ( myCurveType == 0 )
637 myPlot->setCurveStyle( curveKey, QwtCurve::NoCurve );
638 else if ( myCurveType == 1 )
639 myPlot->setCurveStyle( curveKey, QwtCurve::Lines );
640 else if ( myCurveType == 2 )
641 myPlot->setCurveStyle( curveKey, QwtCurve::Spline );
642 myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
650 Adds curves into view
652 void Plot2d_ViewFrame::displayCurves( const curveList& curves, bool update )
654 myPlot->setUpdatesEnabled( false );
655 QPtrListIterator<Plot2d_Curve> it(curves);
656 Plot2d_Curve* aCurve;
657 while( (aCurve = it.current()) ) {
658 displayCurve( aCurve, false );
663 myPlot->setUpdatesEnabled( true );
671 void Plot2d_ViewFrame::eraseCurve( Plot2d_Curve* curve, bool update )
675 int curveKey = hasCurve( curve );
677 myPlot->removeCurve( curveKey );
678 myCurves.remove( curveKey );
688 void Plot2d_ViewFrame::eraseCurves( const curveList& curves, bool update )
690 QPtrListIterator<Plot2d_Curve> it(curves);
691 Plot2d_Curve* aCurve;
692 while( (aCurve = it.current()) ) {
693 eraseCurve( aCurve, false );
702 Updates curves attributes
704 void Plot2d_ViewFrame::updateCurve( Plot2d_Curve* curve, bool update )
708 int curveKey = hasCurve( curve );
710 if ( !curve->isAutoAssign() ) {
711 Qt::PenStyle ps = plot2qwtLine( curve->getLine() );
712 QwtSymbol::Style ms = plot2qwtMarker( curve->getMarker() );
713 myPlot->setCurvePen( curveKey, QPen( curve->getColor(), curve->getLineWidth(), ps ) );
714 myPlot->setCurveSymbol( curveKey, QwtSymbol( ms,
715 QBrush( curve->getColor() ),
716 QPen( curve->getColor() ),
717 QSize( myMarkerSize, myMarkerSize ) ) );
718 myPlot->setCurveData( curveKey, curve->horData(), curve->verData(), curve->nbPoints() );
720 myPlot->setCurveTitle( curveKey, curve->getVerTitle() );
721 myPlot->curve( curveKey )->setEnabled( true );
728 Returns curve key if is is displayed in the viewer and 0 otherwise
730 int Plot2d_ViewFrame::hasCurve( Plot2d_Curve* curve )
732 QIntDictIterator<Plot2d_Curve> it( myCurves );
733 for ( ; it.current(); ++it ) {
734 if ( it.current() == curve )
735 return it.currentKey();
741 Gets lsit of displayed curves
743 int Plot2d_ViewFrame::getCurves( QList<Plot2d_Curve>& clist )
746 clist.setAutoDelete( false );
747 QIntDictIterator<Plot2d_Curve> it( myCurves );
748 for ( ; it.current(); ++it ) {
749 clist.append( it.current() );
751 return clist.count();
755 Returns true if the curve is visible
757 bool Plot2d_ViewFrame::isVisible( Plot2d_Curve* curve )
760 int key = hasCurve( curve );
762 return myPlot->curve( key )->enabled();
770 void Plot2d_ViewFrame::updateLegend( const Plot2d_Prs* prs )
772 if ( !prs || prs->IsNull() )
774 curveList aCurves = prs->getCurves();
776 QPtrListIterator<Plot2d_Curve> it(aCurves);
777 Plot2d_Curve* aCurve;
778 while( (aCurve = it.current()) ) {
779 int curveKey = hasCurve( aCurve );
781 myPlot->setCurveTitle( curveKey, aCurve->getVerTitle() );
787 Fits the view to see all data
789 void Plot2d_ViewFrame::fitAll()
791 QwtDiMap xMap1 = myPlot->canvasMap( QwtPlot::xBottom );
793 myPlot->setAxisAutoScale( QwtPlot::yLeft );
794 myPlot->setAxisAutoScale( QwtPlot::xBottom );
798 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
799 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
801 myPlot->setAxisScale( QwtPlot::xBottom,
802 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
803 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() ) );
804 myPlot->setAxisScale( QwtPlot::yLeft,
805 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
806 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() ) );
809 myPlot->setAxisAutoScale( QwtPlot::yRight );
811 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
812 myPlot->setAxisScale( QwtPlot::yRight,
813 myPlot->invTransform( QwtPlot::yRight, yMap2.i1() ),
814 myPlot->invTransform( QwtPlot::yRight, yMap2.i2() ) );
820 Fits the view to rectangle area (pixels)
822 void Plot2d_ViewFrame::fitArea( const QRect& area )
824 QRect rect = area.normalize();
825 if ( rect.width() < MIN_RECT_SIZE ) {
826 rect.setWidth( MIN_RECT_SIZE );
827 rect.setLeft( rect.left() - MIN_RECT_SIZE/2 );
829 if ( rect.height() < MIN_RECT_SIZE ) {
830 rect.setHeight( MIN_RECT_SIZE );
831 rect.setTop( rect.top() - MIN_RECT_SIZE/2 );
833 myPlot->setAxisScale( QwtPlot::yLeft,
834 myPlot->invTransform( QwtPlot::yLeft, rect.top() ),
835 myPlot->invTransform( QwtPlot::yLeft, rect.bottom() ) );
837 myPlot->setAxisScale( QwtPlot::yRight,
838 myPlot->invTransform( QwtPlot::yRight, rect.top() ),
839 myPlot->invTransform( QwtPlot::yRight, rect.bottom() ) );
840 myPlot->setAxisScale( QwtPlot::xBottom,
841 myPlot->invTransform( QwtPlot::xBottom, rect.left() ),
842 myPlot->invTransform( QwtPlot::xBottom, rect.right() ) );
847 "Fit Data" command for TUI interface
849 void Plot2d_ViewFrame::fitData(const int mode,
850 const double xMin, const double xMax,
851 const double yMin, const double yMax,
852 double y2Min, double y2Max)
854 if ( mode == 0 || mode == 2 ) {
855 myPlot->setAxisScale( QwtPlot::yLeft, yMax, yMin );
857 myPlot->setAxisScale( QwtPlot::yRight, y2Max, y2Min );
859 if ( mode == 0 || mode == 1 )
860 myPlot->setAxisScale( QwtPlot::xBottom, xMin, xMax );
865 Gets current fit ranges for view frame
867 void Plot2d_ViewFrame::getFitRanges(double& xMin,double& xMax,
868 double& yMin, double& yMax,
869 double& y2Min, double& y2Max)
871 int ixMin = myPlot->canvasMap( QwtPlot::xBottom ).i1();
872 int ixMax = myPlot->canvasMap( QwtPlot::xBottom ).i2();
873 int iyMin = myPlot->canvasMap( QwtPlot::yLeft ).i1();
874 int iyMax = myPlot->canvasMap( QwtPlot::yLeft ).i2();
875 xMin = myPlot->invTransform(QwtPlot::xBottom, ixMin);
876 xMax = myPlot->invTransform(QwtPlot::xBottom, ixMax);
877 yMin = myPlot->invTransform(QwtPlot::yLeft, iyMin);
878 yMax = myPlot->invTransform(QwtPlot::yLeft, iyMax);
882 int iyMin = myPlot->canvasMap( QwtPlot::yRight ).i1();
883 int iyMax = myPlot->canvasMap( QwtPlot::yRight ).i2();
884 y2Min = myPlot->invTransform(QwtPlot::yRight, iyMin);
885 y2Max = myPlot->invTransform(QwtPlot::yRight, iyMax);
890 Tests if it is necessary to start operation on mouse action
892 int Plot2d_ViewFrame::testOperation( const QMouseEvent& me )
894 int btn = me.button() | me.state();
895 const int zoomBtn = ControlButton | LeftButton;
896 const int panBtn = ControlButton | MidButton;
897 const int fitBtn = ControlButton | RightButton;
903 QPixmap zoomPixmap (imageZoomCursor);
904 QCursor zoomCursor (zoomPixmap);
905 myPlot->canvas()->setCursor( zoomCursor );
909 myPlot->canvas()->setCursor( QCursor( Qt::SizeAllCursor ) );
912 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
920 "Settings" toolbar action slot
922 void Plot2d_ViewFrame::onSettings()
924 #ifdef TEST_AUTOASSIGN
925 typedef QMap<int,int> IList;
926 typedef QMap<QString,int> SList;
929 cols[ "red-min" ] = 1000;
930 cols[ "red-max" ] = -1;
931 cols[ "green-min" ] = 1000;
932 cols[ "green-max" ] = -1;
933 cols[ "blue-min" ] = 1000;
934 cols[ "blue-max" ] = -1;
935 for ( unsigned i = 0; i < 10000; i++ ) {
936 QwtSymbol::Style typeMarker;
938 Qt::PenStyle typeLine;
939 myPlot->getNextMarker( typeMarker, color, typeLine );
940 if ( mars.contains(typeMarker) )
941 mars[ typeMarker ] = mars[ typeMarker ]+1;
943 mars[ typeMarker ] = 0;
944 if ( lins.contains(typeLine) )
945 lins[ typeLine ] = lins[ typeLine ]+1;
947 lins[ typeLine ] = 0;
948 if ( cols[ "red-max" ] < color.red() )
949 cols[ "red-max" ] = color.red();
950 if ( cols[ "red-min" ] > color.red() )
951 cols[ "red-min" ] = color.red();
952 if ( cols[ "green-max" ] < color.green() )
953 cols[ "green-max" ] = color.green();
954 if ( cols[ "green-min" ] > color.green() )
955 cols[ "green-min" ] = color.green();
956 if ( cols[ "blue-max" ] < color.blue() )
957 cols[ "blue-max" ] = color.blue();
958 if ( cols[ "blue-min" ] > color.blue() )
959 cols[ "blue-min" ] = color.blue();
963 Plot2d_SetupViewDlg* dlg = new Plot2d_SetupViewDlg( this, true, mySecondY );
964 dlg->setMainTitle( myTitleEnabled, myTitle );
965 dlg->setXTitle( myXTitleEnabled, myXTitle );
966 dlg->setYTitle( myYTitleEnabled, myYTitle );
968 dlg->setY2Title( myY2TitleEnabled, myY2Title );
969 dlg->setCurveType( myCurveType );
970 dlg->setLegend( myShowLegend, myLegendPos );
971 dlg->setMarkerSize( myMarkerSize );
972 dlg->setBackgroundColor( myBackground );
973 dlg->setScaleMode(myXMode, myYMode);
975 dlg->setMajorGrid( myXGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::xBottom ),
976 myYGridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yLeft ),
977 myY2GridMajorEnabled, myPlot->axisMaxMajor( QwtPlot::yRight ) );
978 dlg->setMinorGrid( myXGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::xBottom ),
979 myYGridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yLeft ),
980 myY2GridMinorEnabled, myPlot->axisMaxMinor( QwtPlot::yRight ) );
981 if ( dlg->exec() == QDialog::Accepted ) {
982 // horizontal axis title
983 setTitle( dlg->isXTitleEnabled(), dlg->getXTitle(), XTitle, false );
984 // vertical left axis title
985 setTitle( dlg->isYTitleEnabled(), dlg->getYTitle(), YTitle, false );
986 if (mySecondY) // vertical right axis title
987 setTitle( dlg->isY2TitleEnabled(), dlg->getY2Title(), Y2Title, false );
990 setTitle( dlg->isMainTitleEnabled(), dlg->getMainTitle(), MainTitle, true );
992 if ( myCurveType != dlg->getCurveType() ) {
993 setCurveType( dlg->getCurveType(), false );
996 if ( myShowLegend != dlg->isLegendEnabled() ) {
997 showLegend( dlg->isLegendEnabled(), false );
999 if ( myLegendPos != dlg->getLegendPos() ) {
1000 setLegendPos( dlg->getLegendPos() );
1003 if ( myMarkerSize != dlg->getMarkerSize() ) {
1004 setMarkerSize( dlg->getMarkerSize(), false );
1007 if ( myBackground != dlg->getBackgroundColor() ) {
1008 setBackgroundColor( dlg->getBackgroundColor() );
1011 bool aXGridMajorEnabled, aXGridMinorEnabled, aYGridMajorEnabled, aYGridMinorEnabled,
1012 aY2GridMajorEnabled, aY2GridMinorEnabled;
1013 int aXGridMaxMajor, aXGridMaxMinor, aYGridMaxMajor, aYGridMaxMinor,
1014 aY2GridMaxMajor, aY2GridMaxMinor;
1015 dlg->getMajorGrid( aXGridMajorEnabled, aXGridMaxMajor, aYGridMajorEnabled, aYGridMaxMajor,
1016 aY2GridMajorEnabled, aY2GridMaxMajor);
1017 dlg->getMinorGrid( aXGridMinorEnabled, aXGridMaxMinor, aYGridMinorEnabled, aYGridMaxMinor,
1018 aY2GridMinorEnabled, aY2GridMaxMinor);
1019 setXGrid( aXGridMajorEnabled, aXGridMaxMajor, aXGridMinorEnabled, aXGridMaxMinor, false );
1020 setYGrid( aYGridMajorEnabled, aYGridMaxMajor, aYGridMinorEnabled, aYGridMaxMinor,
1021 aY2GridMajorEnabled, aY2GridMaxMajor, aY2GridMinorEnabled, aY2GridMaxMinor, false );
1022 if ( myXMode != dlg->getXScaleMode() ) {
1023 setHorScaleMode( dlg->getXScaleMode() );
1025 if ( myYMode != dlg->getYScaleMode() ) {
1026 setVerScaleMode( dlg->getYScaleMode() );
1030 // update preferences
1031 if ( dlg->isSetAsDefault() )
1038 "Fit Data" command slot
1040 void Plot2d_ViewFrame::onFitData()
1042 Plot2d_FitDataDlg* dlg = new Plot2d_FitDataDlg( this, mySecondY );
1043 double xMin,xMax,yMin,yMax,y2Min,y2Max;
1044 getFitRanges(xMin,xMax,yMin,yMax,y2Min,y2Max);
1046 dlg->setRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1047 if ( dlg->exec() == QDialog::Accepted ) {
1048 int mode = dlg->getRange( xMin, xMax, yMin, yMax, y2Min, y2Max );
1049 fitData(mode,xMin,xMax,yMin,yMax,y2Min,y2Max);
1055 Change background color
1057 void Plot2d_ViewFrame::onChangeBackground()
1059 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
1060 if ( selColor.isValid() ) {
1061 setBackgroundColor( selColor );
1068 void Plot2d_ViewFrame::setCurveType( int curveType, bool update )
1070 myCurveType = curveType;
1071 QArray<long> keys = myPlot->curveKeys();
1072 for ( int i = 0; i < (int)keys.count(); i++ ) {
1073 if ( myCurveType == 0 )
1074 myPlot->setCurveStyle( keys[i], QwtCurve::Dots );//QwtCurve::NoCurve
1075 else if ( myCurveType == 1 )
1076 myPlot->setCurveStyle( keys[i], QwtCurve::Lines );
1077 else if ( myCurveType == 2 )
1078 myPlot->setCurveStyle( keys[i], QwtCurve::Spline );
1082 emit vpCurveChanged();
1085 void Plot2d_ViewFrame::setCurveTitle( int curveKey, const QString& title )
1087 if(myPlot) myPlot->setCurveTitle(curveKey, title);
1093 void Plot2d_ViewFrame::showLegend( bool show, bool update )
1095 myShowLegend = show;
1096 myPlot->setAutoLegend( myShowLegend );
1097 myPlot->enableLegend( myShowLegend );
1103 Sets legend position : 0 - left, 1 - right, 2 - top, 3 - bottom
1105 void Plot2d_ViewFrame::setLegendPos( int pos )
1110 myPlot->setLegendPos( Qwt::Left );
1113 myPlot->setLegendPos( Qwt::Right );
1116 myPlot->setLegendPos( Qwt::Top );
1119 myPlot->setLegendPos( Qwt::Bottom );
1125 Sets new marker size
1127 void Plot2d_ViewFrame::setMarkerSize( const int size, bool update )
1129 if ( myMarkerSize != size )
1131 myMarkerSize = size;
1132 QArray<long> keys = myPlot->curveKeys();
1133 for ( int i = 0; i < (int)keys.count(); i++ )
1135 QwtPlotCurve* crv = myPlot->curve( keys[i] );
1138 QwtSymbol aSymbol = crv->symbol();
1139 aSymbol.setSize( myMarkerSize, myMarkerSize );
1140 myPlot->setCurveSymbol( keys[i], aSymbol );
1149 Sets background color
1151 void Plot2d_ViewFrame::setBackgroundColor( const QColor& color )
1153 myBackground = color;
1154 //myPlot->setCanvasBackground( myBackground );
1155 myPlot->canvas()->setPalette( myBackground );
1156 myPlot->setPalette( myBackground );
1157 QPalette aPal = myPlot->getLegend()->palette();
1158 for ( int i = 0; i < QPalette::NColorGroups; i++ ) {
1159 QPalette::ColorGroup cg = (QPalette::ColorGroup)i;
1160 aPal.setColor( cg, QColorGroup::Base, myBackground );
1161 aPal.setColor( cg, QColorGroup::Background, myBackground );
1163 myPlot->getLegend()->setPalette( aPal );
1167 Gets background color
1169 QColor Plot2d_ViewFrame::backgroundColor() const
1171 return myBackground;
1174 Sets hor.axis grid parameters
1176 void Plot2d_ViewFrame::setXGrid( bool xMajorEnabled, const int xMajorMax,
1177 bool xMinorEnabled, const int xMinorMax,
1180 myXGridMajorEnabled = xMajorEnabled;
1181 myXGridMinorEnabled = xMinorEnabled;
1182 myXGridMaxMajor = xMajorMax;
1183 myXGridMaxMinor = xMinorMax;
1184 myPlot->setAxisMaxMajor( QwtPlot::xBottom, myXGridMaxMajor );
1185 myPlot->setAxisMaxMinor( QwtPlot::xBottom, myXGridMaxMinor );
1186 myPlot->setGridXAxis(QwtPlot::xBottom);
1187 myPlot->enableGridX( myXGridMajorEnabled );
1188 myPlot->enableGridXMin( myXGridMinorEnabled );
1193 Sets ver.axis grid parameters
1195 void Plot2d_ViewFrame::setYGrid( bool yMajorEnabled, const int yMajorMax,
1196 bool yMinorEnabled, const int yMinorMax,
1197 bool y2MajorEnabled, const int y2MajorMax,
1198 bool y2MinorEnabled, const int y2MinorMax,
1201 myYGridMajorEnabled = yMajorEnabled;
1202 myYGridMinorEnabled = yMinorEnabled;
1203 myYGridMaxMajor = yMajorMax;
1204 myYGridMaxMinor = yMinorMax;
1207 myY2GridMajorEnabled = y2MajorEnabled;
1208 myY2GridMinorEnabled = y2MinorEnabled;
1209 myY2GridMaxMajor = y2MajorMax;
1210 myY2GridMaxMinor = y2MinorMax;
1212 myPlot->setAxisMaxMajor( QwtPlot::yLeft, myYGridMaxMajor );
1213 myPlot->setAxisMaxMinor( QwtPlot::yLeft, myYGridMaxMinor );
1216 myPlot->setAxisMaxMajor( QwtPlot::yRight, myY2GridMaxMajor );
1217 myPlot->setAxisMaxMinor( QwtPlot::yRight, myY2GridMaxMinor );
1220 myPlot->setGridYAxis(QwtPlot::yLeft);
1223 if (myYGridMajorEnabled) {
1224 myPlot->enableGridYMin(myYGridMinorEnabled);
1225 myPlot->enableGridY( myYGridMajorEnabled);
1227 else if (myY2GridMajorEnabled) {
1228 myPlot->setGridYAxis(QwtPlot::yRight);
1229 myPlot->enableGridYMin(myY2GridMinorEnabled);
1230 myPlot->enableGridY(myY2GridMajorEnabled);
1233 myPlot->enableGridYMin(false);
1234 myPlot->enableGridY(false);
1238 myPlot->enableGridY( myYGridMajorEnabled );
1239 myPlot->enableGridYMin( myYGridMinorEnabled );
1246 Sets title for some axis
1248 void Plot2d_ViewFrame::setTitle( bool enabled, const QString& title,
1249 ObjectType type, bool update )
1253 myTitleEnabled = enabled;
1255 myPlot->setTitle( myTitleEnabled ? myTitle : QString::null );
1258 myXTitleEnabled = enabled;
1260 myPlot->setAxisTitle( QwtPlot::xBottom, myXTitleEnabled ? myXTitle : QString::null );
1263 myYTitleEnabled = enabled;
1265 myPlot->setAxisTitle( QwtPlot::yLeft, myYTitleEnabled ? myYTitle : QString::null );
1268 myY2TitleEnabled = enabled;
1270 myPlot->setAxisTitle( QwtPlot::yRight, myY2TitleEnabled ? myY2Title : QString::null );
1277 Sets title for some axis
1279 QString Plot2d_ViewFrame::getTitle( ObjectType type ) const
1284 title = myTitle; break;
1286 title = myXTitle; break;
1288 title = myYTitle; break;
1290 title = myY2Title; break;
1295 Sets font for Plot2d object : title or axis
1297 void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update)
1301 myPlot->setTitleFont(font);
1304 myPlot->setAxisTitleFont(QwtPlot::xBottom, font); break;
1306 myPlot->setAxisTitleFont(QwtPlot::yLeft, font); break;
1308 myPlot->setAxisTitleFont(QwtPlot::yRight, font); break;
1310 myPlot->setAxisFont(QwtPlot::xBottom, font); break;
1312 myPlot->setAxisFont(QwtPlot::yLeft, font); break;
1314 myPlot->setAxisFont(QwtPlot::yRight, font); break;
1320 Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
1322 void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
1324 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
1325 // it crashes if switched to X/Y logarithmic mode, when one or more points have
1326 // non-positive X/Y coordinate
1327 if ( mode && !isXLogEnabled() ){
1328 SUIT_MessageBox::warn1(this, tr("WARNING"), tr("WRN_XLOG_NOT_ALLOWED"), tr("BUT_OK"));
1334 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, myXMode != 0 );
1338 emit vpModeHorChanged();
1341 Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
1343 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
1345 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
1346 // it crashes if switched to X/Y logarithmic mode, when one or more points have
1347 // non-positive X/Y coordinate
1348 if ( mode && !isYLogEnabled() ){
1349 SUIT_MessageBox::warn1(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"), tr("BUT_OK"));
1354 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, myYMode != 0 );
1356 myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, myYMode != 0 );
1360 emit vpModeVerChanged();
1364 Return, scale mode for horizontal axis
1366 bool Plot2d_ViewFrame::isModeHorLinear()
1368 return (myXMode == 0 ? true : false);
1372 Return, scale mode for vertical axis
1374 bool Plot2d_ViewFrame::isModeVerLinear()
1376 return (myYMode == 0 ? true : false);
1379 Slot, called when user presses mouse button
1381 void Plot2d_ViewFrame::plotMousePressed(const QMouseEvent& me )
1383 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1385 aParent->putInfo(getInfo(me.pos()));
1386 if ( myOperation == NoOpId )
1387 myOperation = testOperation( me );
1388 if ( myOperation != NoOpId ) {
1390 if ( myOperation == FitAreaId ) {
1391 myPlot->setOutlineStyle( Qwt::Rect );
1393 else if ( myOperation == GlPanId ) {
1394 myPlot->setAxisScale( QwtPlot::yLeft,
1395 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2,
1396 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2 );
1397 myPlot->setAxisScale( QwtPlot::xBottom,
1398 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2,
1399 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
1401 myPlot->setAxisScale( QwtPlot::yRight,
1402 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2,
1403 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2 );
1408 int btn = me.button() | me.state();
1409 if (btn == RightButton) {
1410 QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
1411 me.pos(), btn, me.state());
1412 // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
1413 parent()->eventFilter(this, aEvent);
1418 Slot, called when user moves mouse
1420 void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
1422 int dx = me.pos().x() - myPnt.x();
1423 int dy = me.pos().y() - myPnt.y();
1425 if ( myOperation != NoOpId) {
1426 if ( myOperation == ZoomId ) {
1427 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1428 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1430 myPlot->setAxisScale( QwtPlot::yLeft,
1431 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1432 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + dy ) );
1433 myPlot->setAxisScale( QwtPlot::xBottom,
1434 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1435 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - dx ) );
1437 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1438 myPlot->setAxisScale( QwtPlot::yRight,
1439 myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ),
1440 myPlot->invTransform( QwtPlot::yRight, y2Map.i2() + dy ) );
1445 else if ( myOperation == PanId ) {
1446 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1447 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1449 myPlot->setAxisScale( QwtPlot::yLeft,
1450 myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-dy ),
1451 myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-dy ) );
1452 myPlot->setAxisScale( QwtPlot::xBottom,
1453 myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-dx ),
1454 myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-dx ) );
1456 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1457 myPlot->setAxisScale( QwtPlot::yRight,
1458 myPlot->invTransform( QwtPlot::yRight, y2Map.i1()-dy ),
1459 myPlot->invTransform( QwtPlot::yRight, y2Map.i2()-dy ) );
1466 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1468 aParent->putInfo(getInfo(me.pos()));
1472 Slot, called when user releases mouse
1474 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
1476 if ( myOperation == NoOpId && me.button() == RightButton )
1478 QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
1479 me.pos(), me.globalPos(),
1481 emit contextMenuRequested( &aEvent );
1483 if ( myOperation == FitAreaId ) {
1484 QRect rect( myPnt, me.pos() );
1487 myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
1488 myPlot->setOutlineStyle( Qwt::Triangle );
1490 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1492 aParent->putInfo(tr("INF_READY"));
1493 myOperation = NoOpId;
1496 Slot, called when user wheeling mouse
1498 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
1500 double aDelta = event->delta();
1501 double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.;
1503 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1504 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1506 myPlot->setAxisScale( QwtPlot::yLeft,
1507 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1508 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() )*aScale );
1509 myPlot->setAxisScale( QwtPlot::xBottom,
1510 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1511 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() )*aScale );
1513 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1514 myPlot->setAxisScale( QwtPlot::yRight,
1515 myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ),
1516 myPlot->invTransform( QwtPlot::yRight, y2Map.i2() )*aScale );
1519 myPnt = event->pos();
1522 View operations : Pan view
1524 void Plot2d_ViewFrame::onViewPan()
1526 QCursor panCursor (Qt::SizeAllCursor);
1527 myPlot->canvas()->setCursor( panCursor );
1528 myOperation = PanId;
1529 qApp->installEventFilter( this );
1532 View operations : Zoom view
1534 void Plot2d_ViewFrame::onViewZoom()
1536 QPixmap zoomPixmap (imageZoomCursor);
1537 QCursor zoomCursor (zoomPixmap);
1538 myPlot->canvas()->setCursor( zoomCursor );
1539 myOperation = ZoomId;
1540 qApp->installEventFilter( this );
1543 View operations : Fot All
1545 void Plot2d_ViewFrame::onViewFitAll()
1550 View operations : Fit Area
1552 void Plot2d_ViewFrame::onViewFitArea()
1554 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1555 myOperation = FitAreaId;
1556 qApp->installEventFilter( this );
1559 View operations : Global panning
1561 void Plot2d_ViewFrame::onViewGlobalPan()
1563 QPixmap globalPanPixmap (imageCrossCursor);
1564 QCursor glPanCursor (globalPanPixmap);
1565 myPlot->canvas()->setCursor( glPanCursor );
1566 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1567 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1569 myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1571 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1572 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1574 myXDistance = xMap.d2() - xMap.d1();
1575 myYDistance = yMap.d2() - yMap.d1();
1578 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
1579 myYDistance2 = yMap2.d2() - yMap2.d1();
1582 myOperation = GlPanId;
1583 qApp->installEventFilter( this );
1587 Precaution for logarithmic X scale
1589 bool Plot2d_ViewFrame::isXLogEnabled() const
1591 bool allPositive = true;
1592 QIntDictIterator<Plot2d_Curve> it( myCurves );
1593 for ( ; allPositive && it.current(); ++it ) {
1594 allPositive = ( it.current()->getMinX() > 0. );
1600 Precaution for logarithmic Y scale
1602 bool Plot2d_ViewFrame::isYLogEnabled() const
1604 bool allPositive = true;
1605 QIntDictIterator<Plot2d_Curve> it( myCurves );
1606 for ( ; allPositive && it.current(); ++it ) {
1607 allPositive = ( it.current()->getMinY() > 0. );
1612 //=================================================================================
1613 // Plot2d_Plot2d implementation
1614 //=================================================================================
1618 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
1622 enableOutline( true );
1623 setOutlineStyle( Qwt::Triangle );
1624 setOutlinePen( green );
1626 setAutoLegend( false );
1627 setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
1628 enableLegend( false );
1630 enableGridX( false );
1631 enableGridXMin( false );
1632 enableGridY( false );
1633 enableGridYMin( false );
1634 // auto scaling by default
1635 setAxisAutoScale( QwtPlot::yLeft );
1636 setAxisAutoScale( QwtPlot::yRight );
1637 setAxisAutoScale( QwtPlot::xBottom );
1640 Recalculates and redraws Plot 2d view
1642 void Plot2d_Plot2d::replot()
1644 updateLayout(); // to fix bug(?) of Qwt - view is not updated when title is changed
1649 Checks if two colors are close to each other [ static ]
1650 uses COLOR_DISTANCE variable as max tolerance for comparing of colors
1652 const long COLOR_DISTANCE = 100;
1653 const int MAX_ATTEMPTS = 10;
1654 static bool closeColors( const QColor& color1, const QColor& color2 )
1656 long tol = abs( color2.red() - color1.red() ) +
1657 abs( color2.green() - color1.green() ) +
1658 abs( color2.blue() - color1.blue() );
1660 return ( tol <= COLOR_DISTANCE );
1663 Gets new unique marker for item if possible
1665 void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine )
1670 int aRed = (int)( 256.0 * rand() / RAND_MAX); // generate random color
1671 int aGreen = (int)( 256.0 * rand() / RAND_MAX); // ...
1672 int aBlue = (int)( 256.0 * rand() / RAND_MAX); // ...
1673 int aMarker = (int)( 9.0 * rand() / RAND_MAX) + 1; // 9 markers types ( not including empty )
1674 int aLine = (int)( 5.0 * rand() / RAND_MAX) + 1; // 5 line types ( not including empty )
1676 typeMarker = ( QwtSymbol::Style )aMarker;
1677 color = QColor( aRed, aGreen, aBlue );
1678 typeLine = ( Qt::PenStyle )aLine;
1681 if ( cnt == MAX_ATTEMPTS )
1684 bOk = !existMarker( typeMarker, color, typeLine );
1687 static int aMarker = -1;
1688 static int aColor = -1;
1689 static int aLine = -1;
1691 if ( myColors.isEmpty() ) {
1692 // creating colors list
1693 myColors.append( Qt::white );
1694 myColors.append( Qt::blue );
1695 myColors.append( Qt::gray );
1696 myColors.append( Qt::darkGreen );
1697 myColors.append( Qt::magenta );
1698 myColors.append( Qt::darkGray );
1699 myColors.append( Qt::red );
1700 myColors.append( Qt::darkBlue );
1701 myColors.append( Qt::darkYellow );
1702 myColors.append( Qt::cyan );
1703 myColors.append( Qt::darkRed );
1704 myColors.append( Qt::darkCyan );
1705 myColors.append( Qt::yellow );
1706 myColors.append( Qt::darkMagenta );
1707 myColors.append( Qt::green );
1708 myColors.append( Qt::black );
1711 int nbMarkers = 11; // QwtSymbol supports 11 marker types
1712 int nbLines = 6; // Qt supports 6 line types
1713 int nbColors = myColors.count(); // number of default colors supported
1715 aMarker = ( aMarker + 1 ) % nbMarkers;
1716 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1717 aColor = ( aColor + 1 ) % nbColors;
1718 aLine = ( aLine + 1 ) % nbLines;
1719 if ( aLine == Qt::NoPen ) aLine++;
1721 typeMarker = ( QwtSymbol::Style )aMarker;
1722 color = myColors[ aColor ];
1723 typeLine = ( Qt::PenStyle )aLine;
1724 if ( !existMarker( typeMarker, color, typeLine ) )
1728 for ( i = 0; i < nbMarkers; i++ ) {
1729 aMarker = ( aMarker + 1 ) % nbMarkers;
1730 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1731 for ( j = 0; j < nbColors; j++ ) {
1732 aColor = ( aColor + 1 ) % nbColors;
1733 for ( k = 0; k < nbLines; k++ ) {
1734 aLine = ( aLine + 1 ) % nbLines;
1735 if ( aLine == Qt::NoPen ) aLine++;
1736 if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
1737 typeMarker = ( QwtSymbol::Style )aMarker;
1738 color = myColors[ aColor ];
1739 typeLine = ( Qt::PenStyle )aLine;
1748 QSizePolicy Plot2d_Plot2d::sizePolicy() const
1750 return QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
1753 QSize Plot2d_Plot2d::sizeHint() const
1755 return QwtPlot::minimumSizeHint();
1759 return minimum size for qwt plot
1761 QSize Plot2d_Plot2d::minimumSizeHint() const
1763 return QSize( 0, 0 );
1764 // QSize aSize = QwtPlot::minimumSizeHint();
1765 // return QSize(aSize.width()*3/4, aSize.height());
1768 Checks if marker belongs to any enitity
1770 bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine )
1772 // getting all curves
1773 QArray<long> keys = curveKeys();
1776 if ( closeColors( color, backgroundColor() ) )
1778 for ( int i = 0; i < (int)keys.count(); i++ )
1780 QwtPlotCurve* crv = curve( keys[i] );
1782 QwtSymbol::Style aStyle = crv->symbol().style();
1783 QColor aColor = crv->pen().color();
1784 Qt::PenStyle aLine = crv->pen().style();
1785 // if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
1786 if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
1793 // TEMPORARY SOLUTION!!! TO BE IMPLEMENTED!!!
1794 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
1799 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
1804 myCurveType = vf->myCurveType;
1805 myShowLegend = vf->myShowLegend;
1806 myLegendPos = vf->myLegendPos;
1807 myMarkerSize = vf->myMarkerSize;
1808 myBackground = vf->myBackground;
1809 myTitle = vf->myTitle;
1810 myXTitle = vf->myXTitle;
1811 myYTitle = vf->myYTitle;
1812 myY2Title = vf->myY2Title;
1813 myTitleEnabled = vf->myTitleEnabled;
1814 myXTitleEnabled = vf->myXTitleEnabled;
1815 myYTitleEnabled = vf->myYTitleEnabled;
1816 myY2TitleEnabled = vf->myY2TitleEnabled;
1817 myXGridMajorEnabled = vf->myXGridMajorEnabled;
1818 myYGridMajorEnabled = vf->myYGridMajorEnabled;
1819 myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
1820 myXGridMinorEnabled = vf->myXGridMinorEnabled;
1821 myYGridMinorEnabled = vf->myYGridMinorEnabled;
1822 myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
1823 myXGridMaxMajor = vf->myXGridMaxMajor;
1824 myYGridMaxMajor = vf->myYGridMaxMajor;
1825 myY2GridMaxMajor = vf->myY2GridMaxMajor;
1826 myXGridMaxMinor = vf->myXGridMaxMinor;
1827 myYGridMaxMinor = vf->myYGridMaxMinor;
1828 myY2GridMaxMinor = vf->myY2GridMaxMinor;
1829 myXMode = vf->myXMode;
1830 myYMode = vf->myYMode;
1831 mySecondY = vf->mySecondY;
1835 Updates titles according to curves
1837 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
1838 void Plot2d_ViewFrame::updateTitles()
1840 QIntDictIterator<Plot2d_Curve> it( myCurves );
1841 QStringList aXTitles;
1842 QStringList aYTitles;
1843 QStringList aXUnits;
1844 QStringList aYUnits;
1845 QStringList aTables;
1847 while ( it.current() ) {
1848 // collect titles and units from all curves...
1849 QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
1850 QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
1851 QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
1852 QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
1854 aYTitles.append( yTitle );
1855 if ( aXTitles.find( xTitle ) == aXTitles.end() )
1856 aXTitles.append( xTitle );
1857 if ( aXUnits.find( xUnits ) == aXUnits.end() )
1858 aXUnits.append( xUnits );
1859 if ( aYUnits.find( yUnits ) == aYUnits.end() )
1860 aYUnits.append( yUnits );
1862 QString aName = it.current()->getTableTitle();
1863 if( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
1864 aTables.append( aName );
1869 // ... and update plot 2d view
1870 QString xUnits, yUnits;
1871 if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
1872 xUnits = BRACKETIZE( aXUnits[0] );
1873 if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
1874 yUnits = BRACKETIZE( aYUnits[0] );
1875 QString xTitle, yTitle;
1876 if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
1877 xTitle = aXTitles[0];
1878 if ( aYTitles.count() == 1 )
1879 yTitle = aYTitles[0];
1881 if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
1883 if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
1886 setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, true );
1887 setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true );
1888 setTitle( true, aTables.join("; "), MainTitle, true );
1891 bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
1900 QPaintDevice* pd = 0;
1903 QPrinter* pr = new QPrinter( QPrinter::HighResolution );
1904 pr->setPageSize( QPrinter::A4 );
1905 pr->setOutputToFile( true );
1906 pr->setOutputFileName( file );
1907 pr->setPrintProgram( "" );
1913 myPlot->print( *pd );
1922 QString Plot2d_ViewFrame::getVisualParameters()
1924 double xmin, xmax, ymin, ymax, y2min, y2max;
1925 getFitRanges( xmin, xmax, ymin, ymax, y2min, y2max );
1927 retStr.sprintf( "%d*%d*%d*%.12e*%.12e*%.12e*%.12e*%.12e*%.12e", myXMode,
1928 myYMode, mySecondY, xmin, xmax, ymin, ymax, y2min, y2max );
1932 void Plot2d_ViewFrame::setVisualParameters( const QString& parameters )
1934 QStringList paramsLst = QStringList::split( '*', parameters, true );
1935 if ( paramsLst.size() == 9 ) {
1936 double xmin, xmax, ymin, ymax, y2min, y2max;
1937 myXMode = paramsLst[0].toInt();
1938 myYMode = paramsLst[1].toInt();
1939 mySecondY = (bool)paramsLst[2].toInt();
1940 xmin = paramsLst[3].toDouble();
1941 xmax = paramsLst[4].toDouble();
1942 ymin = paramsLst[5].toDouble();
1943 ymax = paramsLst[6].toDouble();
1944 y2min = paramsLst[7].toDouble();
1945 y2max = paramsLst[8].toDouble();
1948 setTitle( myY2TitleEnabled, myY2Title, Y2Title, false );
1949 setHorScaleMode( myXMode, /*update=*/false );
1950 setVerScaleMode( myYMode, /*update=*/false );
1953 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
1954 myYDistance2 = yMap2.d2() - yMap2.d1();
1957 fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );
1958 fitData( 0, xmin, xmax, ymin, ymax, y2min, y2max );