1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
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, or (at your option) any later version.
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/ or email : webmaster.salome@opencascade.com
21 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
28 #include <qwt_plot_curve.h>
31 const int MAX_ATTEMPTS = 10; // max attempts
33 // color tolerance (used to compare color values)
34 const long COLOR_DISTANCE = 100;
41 Plot2d_Point::Plot2d_Point()
42 : x( 0. ), y( 0. ), deviationPtr(0)
49 Plot2d_Point::Plot2d_Point( double theX, double theY, const QString& theText )
50 : x( theX ), y( theY ), text( theText ), deviationPtr(0)
57 Plot2d_Point::~Plot2d_Point() {
62 Free memory allocated for the deviation data.
64 void Plot2d_Point::clearDeviation() {
71 Return true in case if deviation data is assigned to the point.
73 bool Plot2d_Point::hasDeviation() const {
74 return !(deviationPtr == 0);
78 Assign deviation data to the point.
80 void Plot2d_Point::setDeviation(double min, double max) {
82 deviationPtr = new double[2];
83 deviationPtr[0] = min;deviationPtr[1] = max;
87 Return true in case if deviation data is assigned to the point
88 and store deviation data in the input parameters.
90 bool Plot2d_Point::deviation(double& min, double& max) const {
92 min = deviationPtr[0];
93 max = deviationPtr[1];
99 Return minimal deviation value.
101 bool Plot2d_Point::minDeviation(double& min) const {
103 min = deviationPtr[0];
112 Return minimal deviation value.
114 bool Plot2d_Point::maxDeviation(double& max) const {
116 max = deviationPtr[1];
127 \brief Convert Plot2d marker type to Qwt marker type.
128 \param m Plot2d marker type
129 \return Qwt marker type
131 QwtSymbol::Style Plot2d::plot2qwtMarker( Plot2d::MarkerType m )
133 QwtSymbol::Style ms = QwtSymbol::NoSymbol;
136 ms = QwtSymbol::Ellipse; break;
137 case Plot2d::Rectangle:
138 ms = QwtSymbol::Rect; break;
139 case Plot2d::Diamond:
140 ms = QwtSymbol::Diamond; break;
141 case Plot2d::DTriangle:
142 ms = QwtSymbol::DTriangle; break;
143 case Plot2d::UTriangle:
144 ms = QwtSymbol::UTriangle; break;
145 case Plot2d::LTriangle:
146 ms = QwtSymbol::LTriangle; break;
147 case Plot2d::RTriangle:
148 ms = QwtSymbol::RTriangle; break;
150 ms = QwtSymbol::Cross; break;
152 ms = QwtSymbol::XCross; break;
155 ms = QwtSymbol::NoSymbol; break;
161 \brief Convert Qwt marker type to Plot2d marker type.
162 \param m Qwt marker type
163 \return Plot2d marker type
165 Plot2d::MarkerType Plot2d::qwt2plotMarker( QwtSymbol::Style m )
167 Plot2d::MarkerType ms = Plot2d::None;
169 case QwtSymbol::Ellipse:
170 ms = Plot2d::Circle; break;
171 case QwtSymbol::Rect:
172 ms = Plot2d::Rectangle; break;
173 case QwtSymbol::Diamond:
174 ms = Plot2d::Diamond; break;
175 case QwtSymbol::DTriangle:
176 ms = Plot2d::DTriangle; break;
177 case QwtSymbol::UTriangle:
178 ms = Plot2d::UTriangle; break;
179 case QwtSymbol::RTriangle:
180 ms = Plot2d::RTriangle; break;
181 case QwtSymbol::LTriangle:
182 ms = Plot2d::LTriangle; break;
183 case QwtSymbol::Cross:
184 ms = Plot2d::Cross; break;
185 case QwtSymbol::XCross:
186 ms = Plot2d::XCross; break;
187 case QwtSymbol::NoSymbol:
189 ms = Plot2d::None; break;
195 \brief Convert Plot2d line type to Qt/Qwt line type.
196 \param p Plot2d line type
197 \return Qt/Qwt line type
199 Qt::PenStyle Plot2d::plot2qwtLine( Plot2d::LineType p )
201 Qt::PenStyle ps = Qt::NoPen;
204 ps = Qt::SolidLine; break;
206 ps = Qt::DashLine; break;
208 ps = Qt::DotLine; break;
209 case Plot2d::DashDot:
210 ps = Qt::DashDotLine; break;
211 case Plot2d::DashDotDot:
212 ps = Qt::DashDotDotLine; break;
215 ps = Qt::NoPen; break;
221 \brief Convert Qt/Qwt line type to Plot2d line type.
222 \param p Qt/Qwt line type
223 \return Plot2d line type
225 Plot2d::LineType Plot2d::qwt2plotLine( Qt::PenStyle p )
227 Plot2d::LineType ps = Plot2d::NoPen;
230 ps = Plot2d::Solid; break;
232 ps = Plot2d::Dash; break;
234 ps = Plot2d::Dot; break;
235 case Qt::DashDotLine:
236 ps = Plot2d::DashDot; break;
237 case Qt::DashDotDotLine:
238 ps = Plot2d::DashDotDot; break;
241 ps = Plot2d::NoPen; break;
248 \param painter painter
249 \param p1 starting point
250 \param p2 ending point
251 \param type line type
252 \param color line color
253 \param width line width
255 void Plot2d::drawLine( QPainter* painter, const QPoint& p1, const QPoint& p2,
256 Qt::PenStyle type, const QColor& color, int width )
260 pen.setColor( color );
261 pen.setWidth( width );
262 painter->setPen( pen );
263 painter->drawLine( p1, p2 );
269 \param painter painter
270 \param p1 starting point
271 \param p2 ending point
272 \param type line type
273 \param color line color
274 \param width line width
276 void Plot2d::drawLine( QPainter* painter, const QPoint& p1, const QPoint& p2,
277 Plot2d::LineType type, const QColor& color, int width )
279 drawLine( painter, p1, p2, plot2qwtLine( type ), color, width );
284 \param painter painter
285 \param x1 X coordinate of the starting point
286 \param y1 Y coordinate of the starting point
287 \param x2 X coordinate of the ending point
288 \param y2 Y coordinate of the ending point
289 \param type line type
290 \param color line color
291 \param width line width
293 void Plot2d::drawLine( QPainter* painter, int x1, int y1, int x2, int y2,
294 Qt::PenStyle type, const QColor& color, int width )
296 drawLine( painter, QPoint( x1, y1 ), QPoint( x2, y2 ), type, color, width );
301 \param painter painter
302 \param x1 X coordinate of the starting point
303 \param y1 Y coordinate of the starting point
304 \param x2 X coordinate of the ending point
305 \param y2 Y coordinate of the ending point
306 \param type line type
307 \param color line color
308 \param width line width
310 void Plot2d::drawLine( QPainter* painter, int x1, int y1, int x2, int y2,
311 Plot2d::LineType type, const QColor& color, int width )
313 drawLine( painter, QPoint( x1, y1 ), QPoint( x2, y2 ),
314 plot2qwtLine( type), color, width );
319 \param painter painter
320 \param p central point
321 \param r marker rectangle
322 \param type marker type
323 \param color marker color
325 void Plot2d::drawMarker( QPainter* painter, const QPoint& p, const QRect& r,
326 QwtSymbol::Style type, const QColor& color )
329 painter->setPen( color );
330 painter->setBrush( color );
334 const int w2 = ar.width() / 2;
335 const int h2 = ar.height() / 2;
338 case QwtSymbol::Ellipse:
339 painter->drawEllipse( ar );
341 case QwtSymbol::Rect:
342 painter->drawRect( ar );
343 painter->fillRect( ar, QBrush( color ) );
345 case QwtSymbol::Diamond:
348 polygon << QPoint( ar.x() + w2, ar.y() );
349 polygon << QPoint( ar.right(), ar.y() + h2 );
350 polygon << QPoint( ar.x() + w2, ar.bottom() );
351 polygon << QPoint( ar.x(), ar.y() + h2 );
352 painter->drawPolygon( polygon );
355 case QwtSymbol::Cross:
356 painter->drawLine( ar.left() + w2, ar.top(), ar.left() + w2, ar.bottom() );
357 painter->drawLine( ar.left(), ar.top() + h2, ar.right(), ar.top() + h2 );
359 case QwtSymbol::XCross:
360 painter->drawLine( ar.left(), ar.top(), ar.right(), ar.bottom() );
361 painter->drawLine( ar.left(), ar.bottom(), ar.right(), ar.top() );
363 case QwtSymbol::UTriangle:
366 polygon << QPoint( ar.left() + w2, ar.top() );
367 polygon << QPoint( ar.right(), ar.bottom() );
368 polygon << QPoint( ar.left(), ar.bottom() );
369 painter->drawPolygon( polygon );
372 case QwtSymbol::DTriangle:
375 polygon << QPoint( ar.left() + w2, ar.bottom() );
376 polygon << QPoint( ar.right(), ar.top() );
377 polygon << QPoint( ar.left(), ar.top() );
378 painter->drawPolygon( polygon );
381 case QwtSymbol::RTriangle:
384 polygon << QPoint( ar.left(), ar.top() );
385 polygon << QPoint( ar.right(), ar.top() + h2 );
386 polygon << QPoint( ar.left(), ar.bottom() );
387 painter->drawPolygon( polygon );
390 case QwtSymbol::LTriangle:
393 polygon << QPoint( ar.left(), ar.top() + h2 );
394 polygon << QPoint( ar.right(), ar.top() );
395 polygon << QPoint( ar.right(), ar.bottom() );
396 painter->drawPolygon( polygon );
407 \param painter painter
408 \param p central point
409 \param r marker rectangle
410 \param type marker type
411 \param color marker color
413 void Plot2d::drawMarker( QPainter* painter, const QPoint& p, const QRect& r,
414 Plot2d::MarkerType type, const QColor& color )
416 drawMarker( painter, p, r, plot2qwtMarker( type ), color );
421 \param painter painter
422 \param x X coordinate of the central point
423 \param y Y coordinate of the central point
424 \param w marker rectangle width
425 \param h marker rectangle height
426 \param type marker type
427 \param color marker color
429 void Plot2d::drawMarker( QPainter* painter, int x, int y, int w, int h,
430 QwtSymbol::Style type, const QColor& color )
432 drawMarker( painter, QPoint( x, y ), QRect( 0, 0, w, h ), type, color );
437 \param painter painter
438 \param x X coordinate of the central point
439 \param y Y coordinate of the central point
440 \param w marker rectangle width
441 \param h marker rectangle height
442 \param type marker type
443 \param color marker color
445 void Plot2d::drawMarker( QPainter* painter, int x, int y, int w, int h,
446 Plot2d::MarkerType type, const QColor& color )
448 drawMarker( painter, QPoint( x, y ), QRect( 0, 0, w, h ), plot2qwtMarker( type ), color );
453 \brief Create icon pixmap according to the marker type.
454 \param size icon size
455 \param type marker type
456 \param color icon color
459 QPixmap Plot2d::markerIcon(const QSize &size, const QColor& color, Plot2d::MarkerType type )
463 px.fill( QColor( 255, 255, 255, 0 ) );
465 Plot2d::drawMarker( &p, size.width()/2, size.height()/2, MSIZE, MSIZE, type, color );
471 \brief Create icon pixmap according to the line type.
472 \param size icon size
473 \param type line type
474 \param color icon color
477 QPixmap Plot2d::lineIcon( const QSize& size, const QColor& color, Plot2d::LineType type )
481 px.fill( QColor( 255, 255, 255, 0 ) );
483 drawLine( &p, 5, size.height()/2, size.width()-5, size.height()/2, type,
489 Gets new unique marker for item if possible
491 void Plot2d::getNextMarker( const int rtti, const QwtPlot* thePlot, QwtSymbol::Style& typeMarker,
492 QColor& color, Qt::PenStyle& typeLine )
497 int aRed = (int)( 256.0 * rand() / RAND_MAX ); // generate random color
498 int aGreen = (int)( 256.0 * rand() / RAND_MAX ); // ...
499 int aBlue = (int)( 256.0 * rand() / RAND_MAX ); // ...
500 int aMarker = (int)( 9.0 * rand() / RAND_MAX ) + 1;// 9 markers types( not including empty )
501 int aLine = (int)( 5.0 * rand() / RAND_MAX ) + 1;// 5 line types ( not including empty )
503 typeMarker = ( QwtSymbol::Style )aMarker;
504 color = QColor( aRed, aGreen, aBlue );
505 typeLine = ( Qt::PenStyle )aLine;
507 bOk = ( ++cnt == MAX_ATTEMPTS ) || !existMarker( rtti, thePlot, typeMarker, color, typeLine );
512 Checks if marker belongs to any enitity
514 bool Plot2d::existMarker( const int rtti, const QwtPlot* thePlot, const QwtSymbol::Style typeMarker,
515 const QColor& color, const Qt::PenStyle typeLine )
519 QColor bgColor = thePlot->palette().color( QPalette::Background );
520 if ( closeColors( color, bgColor ) ) {
524 QwtPlotItemList anItems = thePlot->itemList();
525 QwtPlotItemIterator anIt = anItems.begin(), aLast = anItems.end();
527 for ( ; anIt != aLast && !ok; anIt++ ) {
529 if ( anItem && anItem->rtti() == rtti ) {
530 QwtPlotCurve* crv = dynamic_cast<QwtPlotCurve*>( anItem );
532 QwtSymbol::Style aStyle = crv->symbol().style();
533 QColor aColor = crv->pen().color();
534 Qt::PenStyle aLine = crv->pen().style();
535 ok = closeColors( aColor, color ) && aStyle == typeMarker && aLine == typeLine;
544 Checks if two colors are close to each other
545 uses COLOR_DISTANCE variable as max tolerance for comparing of colors
548 bool Plot2d::closeColors( const QColor& color1,
549 const QColor& color2,
553 qAbs( color2.red() - color1.red() ) +
554 qAbs( color2.green() - color1.green() ) +
555 qAbs( color2.blue() - color1.blue() ) -
556 ( distance < 0 ? COLOR_DISTANCE : distance );