Qwt User's Guide 6.3.0
Loading...
Searching...
No Matches
qwt_plot_curve.cpp
1/******************************************************************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10#include "qwt_plot_curve.h"
11#include "qwt_point_data.h"
12#include "qwt_math.h"
13#include "qwt_clipper.h"
14#include "qwt_painter.h"
15#include "qwt_scale_map.h"
16#include "qwt_plot.h"
17#include "qwt_spline_curve_fitter.h"
18#include "qwt_symbol.h"
19#include "qwt_point_mapper.h"
20#include "qwt_text.h"
21#include "qwt_graphic.h"
22
23#include <qpainter.h>
24#include <qpainterpath.h>
25#include <qnumeric.h>
26
27#include <climits>
28
29static inline QRectF qwtIntersectedClipRect( const QRectF& rect, QPainter* painter )
30{
31 QRectF clipRect = rect;
32 if ( painter->hasClipping() )
33 clipRect &= painter->clipBoundingRect();
34
35 return clipRect;
36}
37
38static void qwtUpdateLegendIconSize( QwtPlotCurve* curve )
39{
40 if ( curve->symbol() &&
42 {
43 QSize sz = curve->symbol()->boundingRect().size();
44 sz += QSize( 2, 2 ); // margin
45
47 {
48 // Avoid, that the line is completely covered by the symbol
49
50 int w = qwtCeil( 1.5 * sz.width() );
51 if ( w % 2 )
52 w++;
53
54 sz.setWidth( qMax( 8, w ) );
55 }
56
57 curve->setLegendIconSize( sz );
58 }
59}
60
61static int qwtVerifyRange( int size, int& i1, int& i2 )
62{
63 if ( size < 1 )
64 return 0;
65
66 i1 = qBound( 0, i1, size - 1 );
67 i2 = qBound( 0, i2, size - 1 );
68
69 if ( i1 > i2 )
70 qSwap( i1, i2 );
71
72 return ( i2 - i1 + 1 );
73}
74
75class QwtPlotCurve::PrivateData
76{
77 public:
78 PrivateData()
79 : style( QwtPlotCurve::Lines )
80 , baseline( 0.0 )
81 , symbol( NULL )
82 , pen( Qt::black )
83 , paintAttributes( QwtPlotCurve::ClipPolygons | QwtPlotCurve::FilterPoints )
84 {
85 curveFitter = new QwtSplineCurveFitter;
86 }
87
88 ~PrivateData()
89 {
90 delete symbol;
91 delete curveFitter;
92 }
93
95 double baseline;
96
97 const QwtSymbol* symbol;
98 QwtCurveFitter* curveFitter;
99
100 QPen pen;
101 QBrush brush;
102
104 QwtPlotCurve::PaintAttributes paintAttributes;
105
106 QwtPlotCurve::LegendAttributes legendAttributes;
107};
108
114 : QwtPlotSeriesItem( title )
115{
116 init();
117}
118
123QwtPlotCurve::QwtPlotCurve( const QString& title )
124 : QwtPlotSeriesItem( QwtText( title ) )
125{
126 init();
127}
128
131{
132 delete m_data;
133}
134
137{
140
141 m_data = new PrivateData;
143
144 setZ( 20.0 );
145}
146
149{
151}
152
161{
162 if ( on )
163 m_data->paintAttributes |= attribute;
164 else
165 m_data->paintAttributes &= ~attribute;
166}
167
173{
174 return ( m_data->paintAttributes & attribute );
175}
176
185{
186 if ( on != testLegendAttribute( attribute ) )
187 {
188 if ( on )
189 m_data->legendAttributes |= attribute;
190 else
191 m_data->legendAttributes &= ~attribute;
192
193 qwtUpdateLegendIconSize( this );
195 }
196}
197
203{
204 return ( m_data->legendAttributes & attribute );
205}
206
214{
215 if ( attributes != m_data->legendAttributes )
216 {
217 m_data->legendAttributes = attributes;
218
219 qwtUpdateLegendIconSize( this );
221 }
222}
223
229{
230 return m_data->legendAttributes;
231}
232
240{
241 if ( style != m_data->style )
242 {
243 m_data->style = style;
244
246 itemChanged();
247 }
248}
249
255{
256 return m_data->style;
257}
258
270{
271 if ( symbol != m_data->symbol )
272 {
273 delete m_data->symbol;
274 m_data->symbol = symbol;
275
276 qwtUpdateLegendIconSize( this );
277
279 itemChanged();
280 }
281}
282
288{
289 return m_data->symbol;
290}
291
305void QwtPlotCurve::setPen( const QColor& color, qreal width, Qt::PenStyle style )
306{
307 setPen( QPen( color, width, style ) );
308}
309
316void QwtPlotCurve::setPen( const QPen& pen )
317{
318 if ( pen != m_data->pen )
319 {
320 m_data->pen = pen;
321
323 itemChanged();
324 }
325}
326
331const QPen& QwtPlotCurve::pen() const
332{
333 return m_data->pen;
334}
335
351void QwtPlotCurve::setBrush( const QBrush& brush )
352{
353 if ( brush != m_data->brush )
354 {
355 m_data->brush = brush;
356
358 itemChanged();
359 }
360}
361
366const QBrush& QwtPlotCurve::brush() const
367{
368 return m_data->brush;
369}
370
384void QwtPlotCurve::drawSeries( QPainter* painter,
385 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
386 const QRectF& canvasRect, int from, int to ) const
387{
388 const size_t numSamples = dataSize();
389
390 if ( !painter || numSamples <= 0 )
391 return;
392
393 if ( to < 0 )
394 to = numSamples - 1;
395
396 if ( qwtVerifyRange( numSamples, from, to ) > 0 )
397 {
398 painter->save();
399 painter->setPen( m_data->pen );
400
401 /*
402 Qt 4.0.0 is slow when drawing lines, but it's even
403 slower when the painter has a brush. So we don't
404 set the brush before we really need it.
405 */
406
407 drawCurve( painter, m_data->style, xMap, yMap, canvasRect, from, to );
408 painter->restore();
409
410 if ( m_data->symbol &&
411 ( m_data->symbol->style() != QwtSymbol::NoSymbol ) )
412 {
413 painter->save();
414 drawSymbols( painter, *m_data->symbol,
415 xMap, yMap, canvasRect, from, to );
416 painter->restore();
417 }
418 }
419}
420
432void QwtPlotCurve::drawCurve( QPainter* painter, int style,
433 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
434 const QRectF& canvasRect, int from, int to ) const
435{
436 switch ( style )
437 {
438 case Lines:
439 if ( testCurveAttribute( Fitted ) )
440 {
441 // we always need the complete
442 // curve for fitting
443 from = 0;
444 to = dataSize() - 1;
445 }
446 drawLines( painter, xMap, yMap, canvasRect, from, to );
447 break;
448 case Sticks:
449 drawSticks( painter, xMap, yMap, canvasRect, from, to );
450 break;
451 case Steps:
452 drawSteps( painter, xMap, yMap, canvasRect, from, to );
453 break;
454 case Dots:
455 drawDots( painter, xMap, yMap, canvasRect, from, to );
456 break;
457 case NoCurve:
458 default:
459 break;
460 }
461}
462
479void QwtPlotCurve::drawLines( QPainter* painter,
480 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
481 const QRectF& canvasRect, int from, int to ) const
482{
483 if ( from > to )
484 return;
485
486 const bool doFit = ( m_data->attributes & Fitted ) && m_data->curveFitter;
487 const bool doAlign = !doFit && QwtPainter::roundingAlignment( painter );
488 const bool doFill = ( m_data->brush.style() != Qt::NoBrush )
489 && ( m_data->brush.color().alpha() > 0 );
490
491 QRectF clipRect;
492 if ( m_data->paintAttributes & ClipPolygons )
493 {
494 clipRect = qwtIntersectedClipRect( canvasRect, painter );
495
496 const qreal pw = QwtPainter::effectivePenWidth( painter->pen() );
497 clipRect = clipRect.adjusted(-pw, -pw, pw, pw);
498 }
499
500 QwtPointMapper mapper;
501
502 if ( doAlign )
503 {
504 mapper.setFlag( QwtPointMapper::RoundPoints, true );
507 }
508
512
513 mapper.setBoundingRect( canvasRect );
514
515 QPolygonF polyline = mapper.toPolygonF( xMap, yMap, data(), from, to );
516
517 if ( doFill )
518 {
519 if ( doFit )
520 {
521 // it might be better to extend and draw the curvePath, but for
522 // the moment we keep an implementation, where we translate the
523 // path back to a polyline.
524
525 polyline = m_data->curveFitter->fitCurve( polyline );
526 }
527
528 if ( painter->pen().style() != Qt::NoPen )
529 {
530 // here we are wasting memory for the filled copy,
531 // do polygon clipping twice etc .. TODO
532
533 QPolygonF filled = polyline;
534 fillCurve( painter, xMap, yMap, canvasRect, filled );
535 filled.clear();
536
537 if ( m_data->paintAttributes & ClipPolygons )
538 QwtClipper::clipPolygonF( clipRect, polyline, false );
539
540 QwtPainter::drawPolyline( painter, polyline );
541 }
542 else
543 {
544 fillCurve( painter, xMap, yMap, canvasRect, polyline );
545 }
546 }
547 else
548 {
550 {
551 QwtClipper::clipPolygonF( clipRect, polyline, false );
552 }
553
554 if ( doFit )
555 {
556 if ( m_data->curveFitter->mode() == QwtCurveFitter::Path )
557 {
558 const QPainterPath curvePath =
559 m_data->curveFitter->fitCurvePath( polyline );
560
561 painter->drawPath( curvePath );
562 }
563 else
564 {
565 polyline = m_data->curveFitter->fitCurve( polyline );
566 QwtPainter::drawPolyline( painter, polyline );
567 }
568 }
569 else
570 {
571 QwtPainter::drawPolyline( painter, polyline );
572 }
573 }
574}
575
588void QwtPlotCurve::drawSticks( QPainter* painter,
589 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
590 const QRectF& canvasRect, int from, int to ) const
591{
592 Q_UNUSED( canvasRect )
593
594 painter->save();
595 painter->setRenderHint( QPainter::Antialiasing, false );
596
597 const bool doAlign = QwtPainter::roundingAlignment( painter );
598
599 double x0 = xMap.transform( m_data->baseline );
600 double y0 = yMap.transform( m_data->baseline );
601 if ( doAlign )
602 {
603 x0 = qRound( x0 );
604 y0 = qRound( y0 );
605 }
606
607 const Qt::Orientation o = orientation();
608
609 const QwtSeriesData< QPointF >* series = data();
610
611 for ( int i = from; i <= to; i++ )
612 {
613 const QPointF sample = series->sample( i );
614 double xi = xMap.transform( sample.x() );
615 double yi = yMap.transform( sample.y() );
616 if ( doAlign )
617 {
618 xi = qRound( xi );
619 yi = qRound( yi );
620 }
621
622 if ( o == Qt::Horizontal )
623 QwtPainter::drawLine( painter, x0, yi, xi, yi );
624 else
625 QwtPainter::drawLine( painter, xi, y0, xi, yi );
626 }
627
628 painter->restore();
629}
630
643void QwtPlotCurve::drawDots( QPainter* painter,
644 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
645 const QRectF& canvasRect, int from, int to ) const
646{
647 const QColor color = painter->pen().color();
648
649 if ( painter->pen().style() == Qt::NoPen || color.alpha() == 0 )
650 {
651 return;
652 }
653
654 const bool doFill = ( m_data->brush.style() != Qt::NoBrush )
655 && ( m_data->brush.color().alpha() > 0 );
656 const bool doAlign = QwtPainter::roundingAlignment( painter );
657
658 QwtPointMapper mapper;
659 mapper.setBoundingRect( canvasRect );
660 mapper.setFlag( QwtPointMapper::RoundPoints, doAlign );
661
662 if ( m_data->paintAttributes & FilterPoints )
663 {
664 if ( ( color.alpha() == 255 )
665 && !( painter->renderHints() & QPainter::Antialiasing ) )
666 {
668 }
669 }
670
671 if ( doFill )
672 {
673 mapper.setFlag( QwtPointMapper::WeedOutPoints, false );
674
675 QPolygonF points = mapper.toPolygonF(
676 xMap, yMap, data(), from, to );
677
678 QwtPainter::drawPoints( painter, points );
679 fillCurve( painter, xMap, yMap, canvasRect, points );
680 }
681 else if ( m_data->paintAttributes & ImageBuffer )
682 {
683 const QImage image = mapper.toImage( xMap, yMap,
684 data(), from, to, m_data->pen,
685 painter->testRenderHint( QPainter::Antialiasing ),
687
688 painter->drawImage( canvasRect.toAlignedRect(), image );
689 }
690 else if ( m_data->paintAttributes & MinimizeMemory )
691 {
692 const QwtSeriesData< QPointF >* series = data();
693
694 for ( int i = from; i <= to; i++ )
695 {
696 const QPointF sample = series->sample( i );
697
698 double xi = xMap.transform( sample.x() );
699 double yi = yMap.transform( sample.y() );
700
701 if ( doAlign )
702 {
703 xi = qRound( xi );
704 yi = qRound( yi );
705 }
706
707 QwtPainter::drawPoint( painter, QPointF( xi, yi ) );
708 }
709 }
710 else
711 {
712 if ( doAlign )
713 {
714 const QPolygon points = mapper.toPoints(
715 xMap, yMap, data(), from, to );
716
717 QwtPainter::drawPoints( painter, points );
718 }
719 else
720 {
721 const QPolygonF points = mapper.toPointsF(
722 xMap, yMap, data(), from, to );
723
724 QwtPainter::drawPoints( painter, points );
725 }
726 }
727}
728
744void QwtPlotCurve::drawSteps( QPainter* painter,
745 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
746 const QRectF& canvasRect, int from, int to ) const
747{
748 const bool doAlign = QwtPainter::roundingAlignment( painter );
749
750 QPolygonF polygon( 2 * ( to - from ) + 1 );
751 QPointF* points = polygon.data();
752
753 bool inverted = orientation() == Qt::Vertical;
754 if ( m_data->attributes & Inverted )
755 inverted = !inverted;
756
757 const QwtSeriesData< QPointF >* series = data();
758
759 int i, ip;
760 for ( i = from, ip = 0; i <= to; i++, ip += 2 )
761 {
762 const QPointF sample = series->sample( i );
763 double xi = xMap.transform( sample.x() );
764 double yi = yMap.transform( sample.y() );
765 if ( doAlign )
766 {
767 xi = qRound( xi );
768 yi = qRound( yi );
769 }
770
771 if ( ip > 0 )
772 {
773 const QPointF& p0 = points[ip - 2];
774 QPointF& p = points[ip - 1];
775
776 if ( inverted )
777 {
778 p.rx() = p0.x();
779 p.ry() = yi;
780 }
781 else
782 {
783 p.rx() = xi;
784 p.ry() = p0.y();
785 }
786 }
787
788 points[ip].rx() = xi;
789 points[ip].ry() = yi;
790 }
791
792 if ( m_data->paintAttributes & ClipPolygons )
793 {
794 QRectF clipRect = qwtIntersectedClipRect( canvasRect, painter );
795
796 const qreal pw = QwtPainter::effectivePenWidth( painter->pen() );
797 clipRect = clipRect.adjusted(-pw, -pw, pw, pw);
798
799 const QPolygonF clipped = QwtClipper::clippedPolygonF(
800 clipRect, polygon, false );
801
802 QwtPainter::drawPolyline( painter, clipped );
803 }
804 else
805 {
806 QwtPainter::drawPolyline( painter, polygon );
807 }
808
809 if ( m_data->brush.style() != Qt::NoBrush )
810 fillCurve( painter, xMap, yMap, canvasRect, polygon );
811}
812
813
823{
824 if ( bool( m_data->attributes & attribute ) == on )
825 return;
826
827 if ( on )
828 m_data->attributes |= attribute;
829 else
830 m_data->attributes &= ~attribute;
831
832 itemChanged();
833}
834
840{
841 return m_data->attributes & attribute;
842}
843
862{
863 delete m_data->curveFitter;
864 m_data->curveFitter = curveFitter;
865
866 itemChanged();
867}
868
876{
877 return m_data->curveFitter;
878}
879
892void QwtPlotCurve::fillCurve( QPainter* painter,
893 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
894 const QRectF& canvasRect, QPolygonF& polygon ) const
895{
896 if ( m_data->brush.style() == Qt::NoBrush )
897 return;
898
899 closePolyline( painter, xMap, yMap, polygon );
900 if ( polygon.count() <= 2 ) // a line can't be filled
901 return;
902
903 QBrush brush = m_data->brush;
904 if ( !brush.color().isValid() )
905 brush.setColor( m_data->pen.color() );
906
907 if ( m_data->paintAttributes & ClipPolygons )
908 {
909 const QRectF clipRect = qwtIntersectedClipRect( canvasRect, painter );
910 QwtClipper::clipPolygonF( clipRect, polygon, true );
911 }
912
913 painter->save();
914
915 painter->setPen( Qt::NoPen );
916 painter->setBrush( brush );
917
918 QwtPainter::drawPolygon( painter, polygon );
919
920 painter->restore();
921}
922
932void QwtPlotCurve::closePolyline( QPainter* painter,
933 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
934 QPolygonF& polygon ) const
935{
936 if ( polygon.size() < 2 )
937 return;
938
939 const bool doAlign = QwtPainter::roundingAlignment( painter );
940
941 double baseline = m_data->baseline;
942
943 if ( orientation() == Qt::Vertical )
944 {
945 if ( yMap.transformation() )
947
948 double refY = yMap.transform( baseline );
949 if ( doAlign && qAbs( refY ) < std::numeric_limits< int >::max() )
950 refY = qRound( refY );
951
952 polygon += QPointF( polygon.last().x(), refY );
953 polygon += QPointF( polygon.first().x(), refY );
954 }
955 else
956 {
957 if ( xMap.transformation() )
959
960 double refX = xMap.transform( baseline );
961 if ( doAlign && qAbs( refX ) < std::numeric_limits< int >::max() )
962 refX = qRound( refX );
963
964 polygon += QPointF( refX, polygon.last().y() );
965 polygon += QPointF( refX, polygon.first().y() );
966 }
967}
968
982void QwtPlotCurve::drawSymbols( QPainter* painter, const QwtSymbol& symbol,
983 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
984 const QRectF& canvasRect, int from, int to ) const
985{
986 QwtPointMapper mapper;
991
992 const QRectF clipRect = qwtIntersectedClipRect( canvasRect, painter );
993 mapper.setBoundingRect( clipRect );
994
995 const int chunkSize = 500;
996
997 for ( int i = from; i <= to; i += chunkSize )
998 {
999 const int n = qMin( chunkSize, to - i + 1 );
1000
1001 const QPolygonF points = mapper.toPointsF( xMap, yMap,
1002 data(), i, i + n - 1 );
1003
1004 if ( points.size() > 0 )
1005 symbol.drawSymbols( painter, points );
1006 }
1007}
1008
1025void QwtPlotCurve::setBaseline( double value )
1026{
1027 if ( m_data->baseline != value )
1028 {
1029 m_data->baseline = value;
1030 itemChanged();
1031 }
1032}
1033
1039{
1040 return m_data->baseline;
1041}
1042
1054int QwtPlotCurve::closestPoint( const QPointF& pos, double* dist ) const
1055{
1056 const QwtPlot* plot = this->plot();
1057
1058 if ( ( plot == NULL ) || !plot->isAxisValid( xAxis() ) || !plot->isAxisValid( yAxis() ) )
1059 return -1;
1060
1061 const size_t numSamples = dataSize();
1062 if ( numSamples <= 0 )
1063 return -1;
1064
1065 const QwtSeriesData< QPointF >* series = data();
1066
1067 const QwtScaleMap xMap = plot->canvasMap( xAxis() );
1068 const QwtScaleMap yMap = plot->canvasMap( yAxis() );
1069
1070 int index = -1;
1071 double dmin = 1.0e10;
1072
1073 for ( uint i = 0; i < numSamples; i++ )
1074 {
1075 const QPointF sample = series->sample( i );
1076
1077 const double cx = xMap.transform( sample.x() ) - pos.x();
1078 const double cy = yMap.transform( sample.y() ) - pos.y();
1079
1080 const double f = qwtSqr( cx ) + qwtSqr( cy );
1081 if ( f < dmin )
1082 {
1083 index = i;
1084 dmin = f;
1085 }
1086 }
1087 if ( dist )
1088 *dist = std::sqrt( dmin );
1089
1090 return index;
1091}
1092
1108int QwtPlotCurve::adjacentPoint( Qt::Orientation orientation, qreal value ) const
1109{
1110 const QwtSeriesData< QPointF >* data = this->data();
1111 if ( data == NULL )
1112 return -1;
1113
1114 if ( orientation == Qt::Horizontal )
1115 {
1116 struct compareX
1117 {
1118 inline bool operator()( const double x, const QPointF& pos ) const
1119 {
1120 return ( x < pos.x() );
1121 }
1122 };
1123
1124 return qwtUpperSampleIndex< QPointF >( *data, value, compareX() );
1125 }
1126 else
1127 {
1128 struct compareY
1129 {
1130 inline bool operator()( const double y, const QPointF& pos ) const
1131 {
1132 return ( y < pos.y() );
1133 }
1134 };
1135
1136 return qwtUpperSampleIndex< QPointF >( *data, value, compareY() );
1137 }
1138
1139 return -1;
1140}
1141
1158qreal QwtPlotCurve::interpolatedValueAt( Qt::Orientation orientation, double value ) const
1159{
1160 const QRectF br = boundingRect();
1161 if ( br.width() <= 0.0 )
1162 return qQNaN();
1163
1164 double v;
1165
1166 if ( orientation == Qt::Horizontal )
1167 {
1168 if ( value < br.left() || value > br.right() )
1169 return qQNaN();
1170
1171 const int index = adjacentPoint( orientation, value );
1172
1173 if ( index == -1 )
1174 {
1175 const QPointF last = sample( dataSize() - 1 );
1176
1177 if ( value != last.x() )
1178 return qQNaN();
1179
1180 v = last.y();
1181 }
1182 else
1183 {
1184 const QLineF line( sample( index - 1 ), sample( index ) );
1185 v = line.pointAt( ( value - line.p1().x() ) / line.dx() ).y();
1186 }
1187 }
1188 else
1189 {
1190 if ( value < br.top() || value > br.bottom() )
1191 return qQNaN();
1192
1193 const int index = adjacentPoint( orientation, value );
1194
1195 if ( index == -1 )
1196 {
1197 const QPointF last = sample( dataSize() - 1 );
1198
1199 if ( value != last.y() )
1200 return qQNaN();
1201
1202 v = last.x();
1203 }
1204 else
1205 {
1206 const QLineF line( sample( index - 1 ), sample( index ) );
1207 v = line.pointAt( ( value - line.p1().y() ) / line.dy() ).x();
1208 }
1209 }
1210
1211 return v;
1212}
1213
1223QwtGraphic QwtPlotCurve::legendIcon( int index, const QSizeF& size ) const
1224{
1225 Q_UNUSED( index );
1226
1227 if ( size.isEmpty() )
1228 return QwtGraphic();
1229
1230 QwtGraphic graphic;
1231 graphic.setDefaultSize( size );
1233
1234 QPainter painter( &graphic );
1235 painter.setRenderHint( QPainter::Antialiasing,
1237
1238 if ( m_data->legendAttributes == 0 ||
1239 m_data->legendAttributes & QwtPlotCurve::LegendShowBrush )
1240 {
1241 QBrush brush = m_data->brush;
1242
1243 if ( brush.style() == Qt::NoBrush &&
1244 m_data->legendAttributes == 0 )
1245 {
1246 if ( style() != QwtPlotCurve::NoCurve )
1247 {
1248 brush = QBrush( pen().color() );
1249 }
1250 else if ( m_data->symbol &&
1251 ( m_data->symbol->style() != QwtSymbol::NoSymbol ) )
1252 {
1253 brush = QBrush( m_data->symbol->pen().color() );
1254 }
1255 }
1256
1257 if ( brush.style() != Qt::NoBrush )
1258 {
1259 QRectF r( 0, 0, size.width(), size.height() );
1260 painter.fillRect( r, brush );
1261 }
1262 }
1263
1264 if ( m_data->legendAttributes & QwtPlotCurve::LegendShowLine )
1265 {
1266 if ( pen() != Qt::NoPen )
1267 {
1268 QPen pn = pen();
1269 pn.setCapStyle( Qt::FlatCap );
1270
1271 painter.setPen( pn );
1272
1273 const double y = 0.5 * size.height();
1274 QwtPainter::drawLine( &painter, 0.0, y, size.width(), y );
1275 }
1276 }
1277
1278 if ( m_data->legendAttributes & QwtPlotCurve::LegendShowSymbol )
1279 {
1280 if ( m_data->symbol )
1281 {
1282 QRectF r( 0, 0, size.width(), size.height() );
1283 m_data->symbol->drawSymbol( &painter, r );
1284 }
1285 }
1286
1287 return graphic;
1288}
1289
1304
1313{
1314 setData( new QwtPointSeriesData( samples ) );
1315}
1316
1332 const double* xData, const double* yData, int size )
1333{
1334 setData( new QwtCPointerData< double >( xData, yData, size ) );
1335}
1336
1352 const float* xData, const float* yData, int size )
1353{
1354 setData( new QwtCPointerData< float >( xData, yData, size ) );
1355}
1356
1373void QwtPlotCurve::setRawSamples( const double* yData, int size )
1374{
1375 setData( new QwtCPointerValueData< double >( yData, size ) );
1376}
1377
1394void QwtPlotCurve::setRawSamples( const float* yData, int size )
1395{
1396 setData( new QwtCPointerValueData< float >( yData, size ) );
1397}
1398
1411 const double* xData, const double* yData, int size )
1412{
1413 setData( new QwtPointArrayData< double >( xData, yData, size ) );
1414}
1415
1428 const float* xData, const float* yData, int size )
1429{
1430 setData( new QwtPointArrayData< float >( xData, yData, size ) );
1431}
1432
1442 const QVector< double >& yData )
1443{
1444 setData( new QwtPointArrayData< double >( xData, yData ) );
1445}
1446
1456 const QVector< float >& yData )
1457{
1458 setData( new QwtPointArrayData< float >( xData, yData ) );
1459}
1460
1472void QwtPlotCurve::setSamples( const double* yData, int size )
1473{
1474 setData( new QwtValuePointData< double >( yData, size ) );
1475}
1476
1488void QwtPlotCurve::setSamples( const float* yData, int size )
1489{
1490 setData( new QwtValuePointData< float >( yData, size ) );
1491}
1492
1504{
1505 setData( new QwtValuePointData< double >( yData ) );
1506}
1507
1519{
1520 setData( new QwtValuePointData< float >( yData ) );
1521}
Template class for data, that is organized as QVector.
Data class containing two pointers to memory blocks of T.
Data class containing a pointer to memory of y coordinates.
Abstract base class for a curve fitter.
virtual QPainterPath fitCurvePath(const QPolygonF &polygon) const =0
virtual QPolygonF fitCurve(const QPolygonF &polygon) const =0
A paint device for scalable graphics.
Definition qwt_graphic.h:76
@ RenderPensUnscaled
Definition qwt_graphic.h:96
void setRenderHint(RenderHint, bool on=true)
void setDefaultSize(const QSizeF &)
Set a default size.
static void drawPoints(QPainter *, const QPolygon &)
Wrapper for QPainter::drawPoints()
static void drawPolygon(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolygon()
static void drawPolyline(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolyline()
static qreal effectivePenWidth(const QPen &)
static void drawPoint(QPainter *, const QPoint &)
Wrapper for QPainter::drawPoint()
static bool roundingAlignment()
static void drawLine(QPainter *, qreal x1, qreal y1, qreal x2, qreal y2)
Wrapper for QPainter::drawLine()
A plot item, that represents a series of points.
qreal interpolatedValueAt(Qt::Orientation, double) const
void setLegendAttribute(LegendAttribute, bool on=true)
virtual void drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const override
void setLegendAttributes(LegendAttributes)
void closePolyline(QPainter *, const QwtScaleMap &, const QwtScaleMap &, QPolygonF &) const
Complete a polygon to be a closed polygon including the area between the original polygon and the bas...
LegendAttributes legendAttributes() const
virtual void drawCurve(QPainter *, int style, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
Draw the line part (without symbols) of a curve interval.
QFlags< LegendAttribute > LegendAttributes
virtual void fillCurve(QPainter *, const QwtScaleMap &, const QwtScaleMap &, const QRectF &canvasRect, QPolygonF &) const
void setStyle(CurveStyle style)
CurveStyle style() const
void setSymbol(QwtSymbol *)
Assign a symbol.
virtual int closestPoint(const QPointF &pos, double *dist=NULL) const
virtual void drawDots(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
QwtPlotCurve(const QString &title=QString())
virtual void drawSticks(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
virtual void drawSymbols(QPainter *, const QwtSymbol &, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
virtual int adjacentPoint(Qt::Orientation orientation, qreal value) const
bool testLegendAttribute(LegendAttribute) const
bool testCurveAttribute(CurveAttribute) const
void setCurveAttribute(CurveAttribute, bool on=true)
void init()
Initialize internal members.
void setPaintAttribute(PaintAttribute, bool on=true)
bool testPaintAttribute(PaintAttribute) const
virtual QwtGraphic legendIcon(int index, const QSizeF &) const override
virtual void drawLines(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
Draw lines.
virtual ~QwtPlotCurve()
Destructor.
void setSamples(const double *xData, const double *yData, int size)
const QPen & pen() const
void setCurveFitter(QwtCurveFitter *)
const QBrush & brush() const
void setBaseline(double)
Set the value of the baseline.
void setBrush(const QBrush &)
Assign a brush.
const QwtSymbol * symbol() const
QFlags< PaintAttribute > PaintAttributes
void setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
QwtCurveFitter * curveFitter() const
QFlags< CurveAttribute > CurveAttributes
double baseline() const
virtual void drawSteps(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
virtual int rtti() const override
void setRawSamples(const double *xData, const double *yData, int size)
Initialize the data by pointing to memory blocks which are not managed by QwtPlotCurve.
A 2-D plotting widget.
Definition qwt_plot.h:79
bool isAxisValid(QwtAxisId) const
virtual QwtScaleMap canvasMap(QwtAxisId) const
Definition qwt_plot.cpp:800
QwtAxisId yAxis() const
Return yAxis.
void setLegendIconSize(const QSize &)
virtual void legendChanged()
void setZ(double z)
Set the z value.
void setItemAttribute(ItemAttribute, bool on=true)
QwtPlot * plot() const
Return attached plot.
QwtAxisId xAxis() const
Return xAxis.
@ Rtti_PlotCurve
For QwtPlotCurve.
@ RenderAntialiased
Enable antialiasing.
bool testRenderHint(RenderHint) const
virtual void itemChanged()
@ Legend
The item is represented on the legend.
uint renderThreadCount() const
Base class for plot items representing a series of samples.
Qt::Orientation orientation() const
virtual QRectF boundingRect() const override
Interface for iterating over two QVector<T> objects.
A helper class for translating a series of points.
void setBoundingRect(const QRectF &)
QPolygonF toPolygonF(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
Translate a series of points into a QPolygonF.
QImage toImage(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to, const QPen &, bool antialiased, uint numThreads) const
Translate a series into a QImage.
QPolygonF toPointsF(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
Translate a series into a QPolygonF.
void setFlag(TransformationFlag, bool on=true)
@ RoundPoints
Round points to integer values.
QPolygon toPoints(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
Translate a series of points into a QPolygon.
A scale map.
double transform(double s) const
const QwtTransform * transformation() const
Get the transformation.
virtual T sample(size_t i) const =0
QPointF sample(int index) const
virtual size_t dataSize() const override
QwtSeriesData< QPointF > * data()
void setData(QwtSeriesData< QPointF > *series)
A curve fitter using a spline interpolation.
A class for drawing symbols.
Definition qwt_symbol.h:32
Style style() const
void drawSymbol(QPainter *, const QRectF &) const
Draw the symbol into a rectangle.
virtual QRect boundingRect() const
void drawSymbols(QPainter *, const QPolygonF &) const
Draw symbols at the specified points.
Definition qwt_symbol.h:251
@ NoSymbol
No Style. The symbol cannot be drawn.
Definition qwt_symbol.h:41
const QPen & pen() const
A class representing a text.
Definition qwt_text.h:52
virtual double bounded(double value) const
Interface for iterating over a QVector<T>.
QWT_EXPORT QPolygonF clippedPolygonF(const QRectF &, const QPolygonF &, bool closePolygon=false)
QWT_EXPORT void clipPolygonF(const QRectF &, QPolygonF &, bool closePolygon=false)