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 )
596 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
597 // it crashes if switched to X/Y logarithmic mode, when one or more points have
598 // non-positive X/Y coordinate
599 if ( myXMode && curve->getMinX() <= 0. )
600 setHorScaleMode( 0, false );
601 if ( myYMode && curve->getMinY() <= 0. )
602 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"));
1333 if ( myXMode == 0 ) // linear
1334 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1336 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, true );
1340 emit vpModeHorChanged();
1343 Sets scale mode for vertical axis: 0 - linear, 1 - logarithmic
1345 void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
1347 // san -- Protection against QwtCurve bug in Qwt 0.4.x:
1348 // it crashes if switched to X/Y logarithmic mode, when one or more points have
1349 // non-positive X/Y coordinate
1350 if ( mode && !isYLogEnabled() ){
1351 SUIT_MessageBox::warn1(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"), tr("BUT_OK"));
1356 if ( myYMode == 0 ) { // linear
1357 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1359 myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1361 else { // logarithmic
1362 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, true );
1364 myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, true );
1368 emit vpModeVerChanged();
1372 Return, scale mode for horizontal axis
1374 bool Plot2d_ViewFrame::isModeHorLinear()
1376 return (myXMode == 0 ? true : false);
1380 Return, scale mode for vertical axis
1382 bool Plot2d_ViewFrame::isModeVerLinear()
1384 return (myYMode == 0 ? true : false);
1387 Slot, called when user presses mouse button
1389 void Plot2d_ViewFrame::plotMousePressed(const QMouseEvent& me )
1391 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1393 aParent->putInfo(getInfo(me.pos()));
1394 if ( myOperation == NoOpId )
1395 myOperation = testOperation( me );
1396 if ( myOperation != NoOpId ) {
1398 if ( myOperation == FitAreaId ) {
1399 myPlot->setOutlineStyle( Qwt::Rect );
1401 else if ( myOperation == GlPanId ) {
1402 myPlot->setAxisScale( QwtPlot::yLeft,
1403 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) + myYDistance/2,
1404 myPlot->invTransform( QwtPlot::yLeft, myPnt.y() ) - myYDistance/2 );
1405 myPlot->setAxisScale( QwtPlot::xBottom,
1406 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) - myXDistance/2,
1407 myPlot->invTransform( QwtPlot::xBottom, myPnt.x() ) + myXDistance/2 );
1409 myPlot->setAxisScale( QwtPlot::yRight,
1410 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) + myYDistance2/2,
1411 myPlot->invTransform( QwtPlot::yRight, myPnt.y() ) - myYDistance2/2 );
1416 int btn = me.button() | me.state();
1417 if (btn == RightButton) {
1418 QMouseEvent* aEvent = new QMouseEvent(QEvent::MouseButtonPress,
1419 me.pos(), btn, me.state());
1420 // QMouseEvent 'me' has the 'MouseButtonDblClick' type. In this case we create new event 'aEvent'.
1421 parent()->eventFilter(this, aEvent);
1426 Slot, called when user moves mouse
1428 void Plot2d_ViewFrame::plotMouseMoved( const QMouseEvent& me )
1430 int dx = me.pos().x() - myPnt.x();
1431 int dy = me.pos().y() - myPnt.y();
1433 if ( myOperation != NoOpId) {
1434 if ( myOperation == ZoomId ) {
1435 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1436 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1438 myPlot->setAxisScale( QwtPlot::yLeft,
1439 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1440 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() + dy ) );
1441 myPlot->setAxisScale( QwtPlot::xBottom,
1442 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1443 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() - dx ) );
1445 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1446 myPlot->setAxisScale( QwtPlot::yRight,
1447 myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ),
1448 myPlot->invTransform( QwtPlot::yRight, y2Map.i2() + dy ) );
1453 else if ( myOperation == PanId ) {
1454 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1455 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1457 myPlot->setAxisScale( QwtPlot::yLeft,
1458 myPlot->invTransform( QwtPlot::yLeft, yMap.i1()-dy ),
1459 myPlot->invTransform( QwtPlot::yLeft, yMap.i2()-dy ) );
1460 myPlot->setAxisScale( QwtPlot::xBottom,
1461 myPlot->invTransform( QwtPlot::xBottom, xMap.i1()-dx ),
1462 myPlot->invTransform( QwtPlot::xBottom, xMap.i2()-dx ) );
1464 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1465 myPlot->setAxisScale( QwtPlot::yRight,
1466 myPlot->invTransform( QwtPlot::yRight, y2Map.i1()-dy ),
1467 myPlot->invTransform( QwtPlot::yRight, y2Map.i2()-dy ) );
1474 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1476 aParent->putInfo(getInfo(me.pos()));
1480 Slot, called when user releases mouse
1482 void Plot2d_ViewFrame::plotMouseReleased( const QMouseEvent& me )
1484 if ( myOperation == NoOpId && me.button() == RightButton )
1486 QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
1487 me.pos(), me.globalPos(),
1489 emit contextMenuRequested( &aEvent );
1491 if ( myOperation == FitAreaId ) {
1492 QRect rect( myPnt, me.pos() );
1495 myPlot->canvas()->setCursor( QCursor( Qt::CrossCursor ) );
1496 myPlot->setOutlineStyle( Qwt::Triangle );
1498 Plot2d_ViewWindow* aParent = dynamic_cast<Plot2d_ViewWindow*>(parent());
1500 aParent->putInfo(tr("INF_READY"));
1501 myOperation = NoOpId;
1504 Slot, called when user wheeling mouse
1506 void Plot2d_ViewFrame::wheelEvent(QWheelEvent* event)
1508 double aDelta = event->delta();
1509 double aScale = (aDelta < 0) ? 100./(-aDelta) : aDelta/100.;
1511 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1512 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1514 myPlot->setAxisScale( QwtPlot::yLeft,
1515 myPlot->invTransform( QwtPlot::yLeft, yMap.i1() ),
1516 myPlot->invTransform( QwtPlot::yLeft, yMap.i2() )*aScale );
1517 myPlot->setAxisScale( QwtPlot::xBottom,
1518 myPlot->invTransform( QwtPlot::xBottom, xMap.i1() ),
1519 myPlot->invTransform( QwtPlot::xBottom, xMap.i2() )*aScale );
1521 QwtDiMap y2Map = myPlot->canvasMap( QwtPlot::yRight );
1522 myPlot->setAxisScale( QwtPlot::yRight,
1523 myPlot->invTransform( QwtPlot::yRight, y2Map.i1() ),
1524 myPlot->invTransform( QwtPlot::yRight, y2Map.i2() )*aScale );
1527 myPnt = event->pos();
1530 View operations : Pan view
1532 void Plot2d_ViewFrame::onViewPan()
1534 QCursor panCursor (Qt::SizeAllCursor);
1535 myPlot->canvas()->setCursor( panCursor );
1536 myOperation = PanId;
1537 qApp->installEventFilter( this );
1540 View operations : Zoom view
1542 void Plot2d_ViewFrame::onViewZoom()
1544 QPixmap zoomPixmap (imageZoomCursor);
1545 QCursor zoomCursor (zoomPixmap);
1546 myPlot->canvas()->setCursor( zoomCursor );
1547 myOperation = ZoomId;
1548 qApp->installEventFilter( this );
1551 View operations : Fot All
1553 void Plot2d_ViewFrame::onViewFitAll()
1558 View operations : Fit Area
1560 void Plot2d_ViewFrame::onViewFitArea()
1562 myPlot->canvas()->setCursor( QCursor( Qt::PointingHandCursor ) );
1563 myOperation = FitAreaId;
1564 qApp->installEventFilter( this );
1567 View operations : Global panning
1569 void Plot2d_ViewFrame::onViewGlobalPan()
1571 QPixmap globalPanPixmap (imageCrossCursor);
1572 QCursor glPanCursor (globalPanPixmap);
1573 myPlot->canvas()->setCursor( glPanCursor );
1574 myPlot->changeAxisOptions( QwtPlot::xBottom, QwtAutoScale::Logarithmic, false );
1575 myPlot->changeAxisOptions( QwtPlot::yLeft, QwtAutoScale::Logarithmic, false );
1577 myPlot->changeAxisOptions( QwtPlot::yRight, QwtAutoScale::Logarithmic, false );
1579 QwtDiMap xMap = myPlot->canvasMap( QwtPlot::xBottom );
1580 QwtDiMap yMap = myPlot->canvasMap( QwtPlot::yLeft );
1582 myXDistance = xMap.d2() - xMap.d1();
1583 myYDistance = yMap.d2() - yMap.d1();
1586 QwtDiMap yMap2 = myPlot->canvasMap( QwtPlot::yRight );
1587 myYDistance2 = yMap2.d2() - yMap2.d1();
1590 myOperation = GlPanId;
1591 qApp->installEventFilter( this );
1595 Precaution for logarithmic X scale
1597 bool Plot2d_ViewFrame::isXLogEnabled() const
1599 bool allPositive = true;
1600 QIntDictIterator<Plot2d_Curve> it( myCurves );
1601 for ( ; allPositive && it.current(); ++it ) {
1602 allPositive = ( it.current()->getMinX() > 0. );
1608 Precaution for logarithmic Y scale
1610 bool Plot2d_ViewFrame::isYLogEnabled() const
1612 bool allPositive = true;
1613 QIntDictIterator<Plot2d_Curve> it( myCurves );
1614 for ( ; allPositive && it.current(); ++it ) {
1615 allPositive = ( it.current()->getMinY() > 0. );
1620 //=================================================================================
1621 // Plot2d_Plot2d implementation
1622 //=================================================================================
1626 Plot2d_Plot2d::Plot2d_Plot2d( QWidget* parent )
1630 enableOutline( true );
1631 setOutlineStyle( Qwt::Triangle );
1632 setOutlinePen( green );
1634 setAutoLegend( false );
1635 setLegendFrameStyle( QFrame::Box | QFrame::Sunken );
1636 enableLegend( false );
1638 enableGridX( false );
1639 enableGridXMin( false );
1640 enableGridY( false );
1641 enableGridYMin( false );
1642 // auto scaling by default
1643 setAxisAutoScale( QwtPlot::yLeft );
1644 setAxisAutoScale( QwtPlot::yRight );
1645 setAxisAutoScale( QwtPlot::xBottom );
1648 Recalculates and redraws Plot 2d view
1650 void Plot2d_Plot2d::replot()
1652 updateLayout(); // to fix bug(?) of Qwt - view is not updated when title is changed
1657 Checks if two colors are close to each other [ static ]
1658 uses COLOR_DISTANCE variable as max tolerance for comparing of colors
1660 const long COLOR_DISTANCE = 100;
1661 const int MAX_ATTEMPTS = 10;
1662 static bool closeColors( const QColor& color1, const QColor& color2 )
1664 long tol = abs( color2.red() - color1.red() ) +
1665 abs( color2.green() - color1.green() ) +
1666 abs( color2.blue() - color1.blue() );
1668 return ( tol <= COLOR_DISTANCE );
1671 Gets new unique marker for item if possible
1673 void Plot2d_Plot2d::getNextMarker( QwtSymbol::Style& typeMarker, QColor& color, Qt::PenStyle& typeLine )
1678 int aRed = (int)( 256.0 * rand() / RAND_MAX); // generate random color
1679 int aGreen = (int)( 256.0 * rand() / RAND_MAX); // ...
1680 int aBlue = (int)( 256.0 * rand() / RAND_MAX); // ...
1681 int aMarker = (int)( 9.0 * rand() / RAND_MAX) + 1; // 9 markers types ( not including empty )
1682 int aLine = (int)( 5.0 * rand() / RAND_MAX) + 1; // 5 line types ( not including empty )
1684 typeMarker = ( QwtSymbol::Style )aMarker;
1685 color = QColor( aRed, aGreen, aBlue );
1686 typeLine = ( Qt::PenStyle )aLine;
1689 if ( cnt == MAX_ATTEMPTS )
1692 bOk = !existMarker( typeMarker, color, typeLine );
1695 static int aMarker = -1;
1696 static int aColor = -1;
1697 static int aLine = -1;
1699 if ( myColors.isEmpty() ) {
1700 // creating colors list
1701 myColors.append( Qt::white );
1702 myColors.append( Qt::blue );
1703 myColors.append( Qt::gray );
1704 myColors.append( Qt::darkGreen );
1705 myColors.append( Qt::magenta );
1706 myColors.append( Qt::darkGray );
1707 myColors.append( Qt::red );
1708 myColors.append( Qt::darkBlue );
1709 myColors.append( Qt::darkYellow );
1710 myColors.append( Qt::cyan );
1711 myColors.append( Qt::darkRed );
1712 myColors.append( Qt::darkCyan );
1713 myColors.append( Qt::yellow );
1714 myColors.append( Qt::darkMagenta );
1715 myColors.append( Qt::green );
1716 myColors.append( Qt::black );
1719 int nbMarkers = 11; // QwtSymbol supports 11 marker types
1720 int nbLines = 6; // Qt supports 6 line types
1721 int nbColors = myColors.count(); // number of default colors supported
1723 aMarker = ( aMarker + 1 ) % nbMarkers;
1724 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1725 aColor = ( aColor + 1 ) % nbColors;
1726 aLine = ( aLine + 1 ) % nbLines;
1727 if ( aLine == Qt::NoPen ) aLine++;
1729 typeMarker = ( QwtSymbol::Style )aMarker;
1730 color = myColors[ aColor ];
1731 typeLine = ( Qt::PenStyle )aLine;
1732 if ( !existMarker( typeMarker, color, typeLine ) )
1736 for ( i = 0; i < nbMarkers; i++ ) {
1737 aMarker = ( aMarker + 1 ) % nbMarkers;
1738 if ( aMarker == QwtSymbol::None || aMarker == QwtSymbol::Triangle ) aMarker++;
1739 for ( j = 0; j < nbColors; j++ ) {
1740 aColor = ( aColor + 1 ) % nbColors;
1741 for ( k = 0; k < nbLines; k++ ) {
1742 aLine = ( aLine + 1 ) % nbLines;
1743 if ( aLine == Qt::NoPen ) aLine++;
1744 if ( !existMarker( ( QwtSymbol::Style )aMarker, aColor, ( Qt::PenStyle )aLine ) ) {
1745 typeMarker = ( QwtSymbol::Style )aMarker;
1746 color = myColors[ aColor ];
1747 typeLine = ( Qt::PenStyle )aLine;
1756 QSizePolicy Plot2d_Plot2d::sizePolicy() const
1758 return QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
1761 QSize Plot2d_Plot2d::sizeHint() const
1763 return QwtPlot::minimumSizeHint();
1767 return minimum size for qwt plot
1769 QSize Plot2d_Plot2d::minimumSizeHint() const
1771 return QSize( 0, 0 );
1772 // QSize aSize = QwtPlot::minimumSizeHint();
1773 // return QSize(aSize.width()*3/4, aSize.height());
1776 Checks if marker belongs to any enitity
1778 bool Plot2d_Plot2d::existMarker( const QwtSymbol::Style typeMarker, const QColor& color, const Qt::PenStyle typeLine )
1780 // getting all curves
1781 QArray<long> keys = curveKeys();
1784 if ( closeColors( color, backgroundColor() ) )
1786 for ( int i = 0; i < (int)keys.count(); i++ )
1788 QwtPlotCurve* crv = curve( keys[i] );
1790 QwtSymbol::Style aStyle = crv->symbol().style();
1791 QColor aColor = crv->pen().color();
1792 Qt::PenStyle aLine = crv->pen().style();
1793 // if ( aStyle == typeMarker && aColor == color && aLine == typeLine )
1794 if ( aStyle == typeMarker && closeColors( aColor,color ) && aLine == typeLine )
1801 // TEMPORARY SOLUTION!!! TO BE IMPLEMENTED!!!
1802 Plot2d_Prs* Plot2d_ViewFrame::CreatePrs( const char* /*entry*/ )
1807 void Plot2d_ViewFrame::copyPreferences( Plot2d_ViewFrame* vf )
1812 myCurveType = vf->myCurveType;
1813 myShowLegend = vf->myShowLegend;
1814 myLegendPos = vf->myLegendPos;
1815 myMarkerSize = vf->myMarkerSize;
1816 myBackground = vf->myBackground;
1817 myTitle = vf->myTitle;
1818 myXTitle = vf->myXTitle;
1819 myYTitle = vf->myYTitle;
1820 myY2Title = vf->myY2Title;
1821 myTitleEnabled = vf->myTitleEnabled;
1822 myXTitleEnabled = vf->myXTitleEnabled;
1823 myYTitleEnabled = vf->myYTitleEnabled;
1824 myY2TitleEnabled = vf->myY2TitleEnabled;
1825 myXGridMajorEnabled = vf->myXGridMajorEnabled;
1826 myYGridMajorEnabled = vf->myYGridMajorEnabled;
1827 myY2GridMajorEnabled = vf->myY2GridMajorEnabled;
1828 myXGridMinorEnabled = vf->myXGridMinorEnabled;
1829 myYGridMinorEnabled = vf->myYGridMinorEnabled;
1830 myY2GridMinorEnabled = vf->myY2GridMinorEnabled;
1831 myXGridMaxMajor = vf->myXGridMaxMajor;
1832 myYGridMaxMajor = vf->myYGridMaxMajor;
1833 myY2GridMaxMajor = vf->myY2GridMaxMajor;
1834 myXGridMaxMinor = vf->myXGridMaxMinor;
1835 myYGridMaxMinor = vf->myYGridMaxMinor;
1836 myY2GridMaxMinor = vf->myY2GridMaxMinor;
1837 myXMode = vf->myXMode;
1838 myYMode = vf->myYMode;
1839 mySecondY = vf->mySecondY;
1843 Updates titles according to curves
1845 #define BRACKETIZE(x) QString( "[ " ) + x + QString( " ]" )
1846 void Plot2d_ViewFrame::updateTitles()
1848 QIntDictIterator<Plot2d_Curve> it( myCurves );
1849 QStringList aXTitles;
1850 QStringList aYTitles;
1851 QStringList aXUnits;
1852 QStringList aYUnits;
1853 QStringList aTables;
1855 while ( it.current() ) {
1856 // collect titles and units from all curves...
1857 QString xTitle = it.current()->getHorTitle().stripWhiteSpace();
1858 QString yTitle = it.current()->getVerTitle().stripWhiteSpace();
1859 QString xUnits = it.current()->getHorUnits().stripWhiteSpace();
1860 QString yUnits = it.current()->getVerUnits().stripWhiteSpace();
1862 aYTitles.append( yTitle );
1863 if ( aXTitles.find( xTitle ) == aXTitles.end() )
1864 aXTitles.append( xTitle );
1865 if ( aXUnits.find( xUnits ) == aXUnits.end() )
1866 aXUnits.append( xUnits );
1867 if ( aYUnits.find( yUnits ) == aYUnits.end() )
1868 aYUnits.append( yUnits );
1870 QString aName = it.current()->getTableTitle();
1871 if( !aName.isEmpty() && aTables.find( aName ) == aTables.end() )
1872 aTables.append( aName );
1877 // ... and update plot 2d view
1878 QString xUnits, yUnits;
1879 if ( aXUnits.count() == 1 && !aXUnits[0].isEmpty() )
1880 xUnits = BRACKETIZE( aXUnits[0] );
1881 if ( aYUnits.count() == 1 && !aYUnits[0].isEmpty())
1882 yUnits = BRACKETIZE( aYUnits[0] );
1883 QString xTitle, yTitle;
1884 if ( aXTitles.count() == 1 && aXUnits.count() == 1 )
1885 xTitle = aXTitles[0];
1886 if ( aYTitles.count() == 1 )
1887 yTitle = aYTitles[0];
1889 if ( !xTitle.isEmpty() && !xUnits.isEmpty() )
1891 if ( !yTitle.isEmpty() && !yUnits.isEmpty() )
1894 setTitle( myXTitleEnabled, xTitle + xUnits, XTitle, true );
1895 setTitle( myYTitleEnabled, yTitle + yUnits, YTitle, true );
1896 setTitle( true, aTables.join("; "), MainTitle, true );
1899 bool Plot2d_ViewFrame::print( const QString& file, const QString& format ) const
1908 QPaintDevice* pd = 0;
1911 QPrinter* pr = new QPrinter( QPrinter::HighResolution );
1912 pr->setPageSize( QPrinter::A4 );
1913 pr->setOutputToFile( true );
1914 pr->setOutputFileName( file );
1915 pr->setPrintProgram( "" );
1921 myPlot->print( *pd );