Changeset 8127 in ntrip for trunk/BNC/qwt/qwt_plot_curve.cpp
- Timestamp:
- May 10, 2017, 3:20:54 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/BNC/qwt/qwt_plot_curve.cpp
r4271 r8127 9 9 10 10 #include "qwt_plot_curve.h" 11 #include "qwt_point_data.h" 11 12 #include "qwt_math.h" 12 13 #include "qwt_clipper.h" 13 14 #include "qwt_painter.h" 14 #include "qwt_legend.h"15 #include "qwt_legend_item.h"16 15 #include "qwt_scale_map.h" 17 16 #include "qwt_plot.h" 18 #include "qwt_plot_canvas.h"19 17 #include "qwt_curve_fitter.h" 20 18 #include "qwt_symbol.h" 19 #include "qwt_point_mapper.h" 21 20 #include <qpainter.h> 22 21 #include <qpixmap.h> … … 24 23 #include <qmath.h> 25 24 26 static int verifyRange( int size, int &i1, int &i2 ) 25 static void qwtUpdateLegendIconSize( QwtPlotCurve *curve ) 26 { 27 if ( curve->symbol() && 28 curve->testLegendAttribute( QwtPlotCurve::LegendShowSymbol ) ) 29 { 30 QSize sz = curve->symbol()->boundingRect().size(); 31 sz += QSize( 2, 2 ); // margin 32 33 if ( curve->testLegendAttribute( QwtPlotCurve::LegendShowLine ) ) 34 { 35 // Avoid, that the line is completely covered by the symbol 36 37 int w = qCeil( 1.5 * sz.width() ); 38 if ( w % 2 ) 39 w++; 40 41 sz.setWidth( qMax( 8, w ) ); 42 } 43 44 curve->setLegendIconSize( sz ); 45 } 46 } 47 48 static int qwtVerifyRange( int size, int &i1, int &i2 ) 27 49 { 28 50 if ( size < 1 ) … … 46 68 symbol( NULL ), 47 69 attributes( 0 ), 48 paintAttributes( QwtPlotCurve::ClipPolygons ), 70 paintAttributes( 71 QwtPlotCurve::ClipPolygons | QwtPlotCurve::FilterPoints ), 49 72 legendAttributes( 0 ) 50 73 { … … 79 102 */ 80 103 QwtPlotCurve::QwtPlotCurve( const QwtText &title ): 81 QwtPlotSeriesItem <QPointF>( title )104 QwtPlotSeriesItem( title ) 82 105 { 83 106 init(); … … 89 112 */ 90 113 QwtPlotCurve::QwtPlotCurve( const QString &title ): 91 QwtPlotSeriesItem <QPointF>( QwtText( title ) )114 QwtPlotSeriesItem( QwtText( title ) ) 92 115 { 93 116 init(); … … 107 130 108 131 d_data = new PrivateData; 109 d_series = new QwtPointSeriesData();132 setData( new QwtPointSeriesData() ); 110 133 111 134 setZ( 20.0 ); … … 134 157 135 158 /*! 136 \ brief Return the current paint attributes159 \return True, when attribute is enabled 137 160 \sa setPaintAttribute() 138 161 */ … … 143 166 144 167 /*! 145 Specify an attribute how to draw the legend i dentifier168 Specify an attribute how to draw the legend icon 146 169 147 170 \param attribute Attribute 148 171 \param on On/Off 149 /sa testLegendAttribute() 172 /sa testLegendAttribute(). legendIcon() 150 173 */ 151 174 void QwtPlotCurve::setLegendAttribute( LegendAttribute attribute, bool on ) 152 175 { 153 if ( on ) 154 d_data->legendAttributes |= attribute; 155 else 156 d_data->legendAttributes &= ~attribute; 157 } 158 159 /*! 160 \brief Return the current paint attributes 161 \sa setLegendAttribute() 176 if ( on != testLegendAttribute( attribute ) ) 177 { 178 if ( on ) 179 d_data->legendAttributes |= attribute; 180 else 181 d_data->legendAttributes &= ~attribute; 182 183 qwtUpdateLegendIconSize( this ); 184 legendChanged(); 185 } 186 } 187 188 /*! 189 \return True, when attribute is enabled 190 \sa setLegendAttribute() 162 191 */ 163 192 bool QwtPlotCurve::testLegendAttribute( LegendAttribute attribute ) const … … 177 206 { 178 207 d_data->style = style; 208 209 legendChanged(); 179 210 itemChanged(); 180 211 } … … 182 213 183 214 /*! 184 Return the current style185 215 \return Style of the curve 216 \sa setStyle() 186 217 */ 187 218 QwtPlotCurve::CurveStyle QwtPlotCurve::style() const … … 191 222 192 223 /*! 193 Assign a symbol 224 \brief Assign a symbol 225 226 The curve will take the ownership of the symbol, hence the previously 227 set symbol will be delete by setting a new one. If \p symbol is 228 \c NULL no symbol will be drawn. 194 229 195 230 \param symbol Symbol 196 231 \sa symbol() 197 232 */ 198 void QwtPlotCurve::setSymbol( constQwtSymbol *symbol )233 void QwtPlotCurve::setSymbol( QwtSymbol *symbol ) 199 234 { 200 235 if ( symbol != d_data->symbol ) … … 202 237 delete d_data->symbol; 203 238 d_data->symbol = symbol; 239 240 qwtUpdateLegendIconSize( this ); 241 242 legendChanged(); 204 243 itemChanged(); 205 244 } … … 216 255 217 256 /*! 257 Build and assign a pen 258 259 In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it 260 non cosmetic ( see QPen::isCosmetic() ). This method has been introduced 261 to hide this incompatibility. 262 263 \param color Pen color 264 \param width Pen width 265 \param style Pen style 266 267 \sa pen(), brush() 268 */ 269 void QwtPlotCurve::setPen( const QColor &color, qreal width, Qt::PenStyle style ) 270 { 271 setPen( QPen( color, width, style ) ); 272 } 273 274 /*! 218 275 Assign a pen 219 276 … … 226 283 { 227 284 d_data->pen = pen; 285 286 legendChanged(); 228 287 itemChanged(); 229 288 } … … 259 318 { 260 319 d_data->brush = brush; 320 321 legendChanged(); 261 322 itemChanged(); 262 323 } … … 278 339 \param xMap Maps x-values into pixel coordinates. 279 340 \param yMap Maps y-values into pixel coordinates. 280 \param canvasRect Contents rect of the canvas341 \param canvasRect Contents rectangle of the canvas 281 342 \param from Index of the first point to be painted 282 343 \param to Index of the last point to be painted. If to < 0 the … … 289 350 const QRectF &canvasRect, int from, int to ) const 290 351 { 291 if ( !painter || dataSize() <= 0 ) 352 const size_t numSamples = dataSize(); 353 354 if ( !painter || numSamples <= 0 ) 292 355 return; 293 356 294 357 if ( to < 0 ) 295 to = dataSize()- 1;296 297 if ( verifyRange( dataSize(), from, to ) > 0 )358 to = numSamples - 1; 359 360 if ( qwtVerifyRange( numSamples, from, to ) > 0 ) 298 361 { 299 362 painter->save(); … … 326 389 \param xMap x map 327 390 \param yMap y map 328 \param canvasRect Contents rect of the canvas391 \param canvasRect Contents rectangle of the canvas 329 392 \param from index of the first point to be painted 330 393 \param to index of the last point to be painted … … 371 434 \param xMap x map 372 435 \param yMap y map 373 \param canvasRect Contents rect of the canvas436 \param canvasRect Contents rectangle of the canvas 374 437 \param from index of the first point to be painted 375 438 \param to index of the last point to be painted … … 382 445 const QRectF &canvasRect, int from, int to ) const 383 446 { 384 int size = to - from + 1; 385 if ( size <= 0 ) 447 if ( from > to ) 386 448 return; 387 449 388 450 const bool doAlign = QwtPainter::roundingAlignment( painter ); 389 390 QPolygonF polyline( size ); 391 392 QPointF *points = polyline.data(); 393 for ( int i = from; i <= to; i++ ) 394 { 395 const QPointF sample = d_series->sample( i ); 396 397 double x = xMap.transform( sample.x() ); 398 double y = yMap.transform( sample.y() ); 399 if ( doAlign ) 400 { 401 x = qRound( x ); 402 y = qRound( y ); 403 } 404 405 points[i - from].rx() = x; 406 points[i - from].ry() = y; 407 } 408 409 if ( ( d_data->attributes & Fitted ) && d_data->curveFitter ) 410 polyline = d_data->curveFitter->fitCurve( polyline ); 411 451 const bool doFit = ( d_data->attributes & Fitted ) && d_data->curveFitter; 452 const bool doFill = ( d_data->brush.style() != Qt::NoBrush ) 453 && ( d_data->brush.color().alpha() > 0 ); 454 455 QRectF clipRect; 412 456 if ( d_data->paintAttributes & ClipPolygons ) 413 457 { 414 458 qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF()); 415 const QPolygonF clipped = QwtClipper::clipPolygonF( 416 canvasRect.adjusted(-pw, -pw, pw, pw), polyline, false ); 417 418 QwtPainter::drawPolyline( painter, clipped ); 459 clipRect = canvasRect.adjusted(-pw, -pw, pw, pw); 460 } 461 462 bool doIntegers = false; 463 464 #if QT_VERSION < 0x040800 465 466 // For Qt <= 4.7 the raster paint engine is significantly faster 467 // for rendering QPolygon than for QPolygonF. So let's 468 // see if we can use it. 469 470 if ( painter->paintEngine()->type() == QPaintEngine::Raster ) 471 { 472 // In case of filling or fitting performance doesn't count 473 // because both operations are much more expensive 474 // then drawing the polyline itself 475 476 if ( !doFit && !doFill ) 477 doIntegers = true; 478 } 479 #endif 480 481 const bool noDuplicates = d_data->paintAttributes & FilterPoints; 482 483 QwtPointMapper mapper; 484 mapper.setFlag( QwtPointMapper::RoundPoints, doAlign ); 485 mapper.setFlag( QwtPointMapper::WeedOutPoints, noDuplicates ); 486 mapper.setBoundingRect( canvasRect ); 487 488 if ( doIntegers ) 489 { 490 QPolygon polyline = mapper.toPolygon( 491 xMap, yMap, data(), from, to ); 492 493 if ( d_data->paintAttributes & ClipPolygons ) 494 { 495 polyline = QwtClipper::clipPolygon( 496 clipRect.toAlignedRect(), polyline, false ); 497 } 498 499 QwtPainter::drawPolyline( painter, polyline ); 419 500 } 420 501 else 421 502 { 422 QwtPainter::drawPolyline( painter, polyline ); 423 } 424 425 if ( d_data->brush.style() != Qt::NoBrush ) 426 fillCurve( painter, xMap, yMap, canvasRect, polyline ); 503 QPolygonF polyline = mapper.toPolygonF( xMap, yMap, data(), from, to ); 504 505 if ( doFit ) 506 polyline = d_data->curveFitter->fitCurve( polyline ); 507 508 if ( doFill ) 509 { 510 if ( painter->pen().style() != Qt::NoPen ) 511 { 512 // here we are wasting memory for the filled copy, 513 // do polygon clipping twice etc .. TODO 514 515 QPolygonF filled = polyline; 516 fillCurve( painter, xMap, yMap, canvasRect, filled ); 517 filled.clear(); 518 519 if ( d_data->paintAttributes & ClipPolygons ) 520 { 521 polyline = QwtClipper::clipPolygonF( 522 clipRect, polyline, false ); 523 } 524 525 QwtPainter::drawPolyline( painter, polyline ); 526 } 527 else 528 { 529 fillCurve( painter, xMap, yMap, canvasRect, polyline ); 530 } 531 } 532 else 533 { 534 if ( d_data->paintAttributes & ClipPolygons ) 535 { 536 polyline = QwtClipper::clipPolygonF( 537 clipRect, polyline, false ); 538 } 539 540 QwtPainter::drawPolyline( painter, polyline ); 541 } 542 } 427 543 } 428 544 … … 433 549 \param xMap x map 434 550 \param yMap y map 435 \param canvasRect Contents rect of the canvas551 \param canvasRect Contents rectangle of the canvas 436 552 \param from index of the first point to be painted 437 553 \param to index of the last point to be painted … … 458 574 const Qt::Orientation o = orientation(); 459 575 576 const QwtSeriesData<QPointF> *series = data(); 577 460 578 for ( int i = from; i <= to; i++ ) 461 579 { 462 const QPointF sample = d_series->sample( i );580 const QPointF sample = series->sample( i ); 463 581 double xi = xMap.transform( sample.x() ); 464 582 double yi = yMap.transform( sample.y() ); … … 484 602 \param xMap x map 485 603 \param yMap y map 486 \param canvasRect Contents rect of the canvas604 \param canvasRect Contents rectangle of the canvas 487 605 \param from index of the first point to be painted 488 606 \param to index of the last point to be painted … … 494 612 const QRectF &canvasRect, int from, int to ) const 495 613 { 496 const bool doFill = d_data->brush.style() != Qt::NoBrush; 614 const QColor color = painter->pen().color(); 615 616 if ( painter->pen().style() == Qt::NoPen || color.alpha() == 0 ) 617 { 618 return; 619 } 620 621 const bool doFill = ( d_data->brush.style() != Qt::NoBrush ) 622 && ( d_data->brush.color().alpha() > 0 ); 497 623 const bool doAlign = QwtPainter::roundingAlignment( painter ); 498 624 499 QPolygonF polyline; 625 QwtPointMapper mapper; 626 mapper.setBoundingRect( canvasRect ); 627 mapper.setFlag( QwtPointMapper::RoundPoints, doAlign ); 628 629 if ( d_data->paintAttributes & FilterPoints ) 630 { 631 if ( ( color.alpha() == 255 ) 632 && !( painter->renderHints() & QPainter::Antialiasing ) ) 633 { 634 mapper.setFlag( QwtPointMapper::WeedOutPoints, true ); 635 } 636 } 637 500 638 if ( doFill ) 501 polyline.resize( to - from + 1 ); 502 503 QPointF *points = polyline.data(); 504 505 for ( int i = from; i <= to; i++ ) 506 { 507 const QPointF sample = d_series->sample( i ); 508 double xi = xMap.transform( sample.x() ); 509 double yi = yMap.transform( sample.y() ); 639 { 640 mapper.setFlag( QwtPointMapper::WeedOutPoints, false ); 641 642 QPolygonF points = mapper.toPointsF( 643 xMap, yMap, data(), from, to ); 644 645 QwtPainter::drawPoints( painter, points ); 646 fillCurve( painter, xMap, yMap, canvasRect, points ); 647 } 648 else if ( d_data->paintAttributes & ImageBuffer ) 649 { 650 const QImage image = mapper.toImage( xMap, yMap, 651 data(), from, to, d_data->pen, 652 painter->testRenderHint( QPainter::Antialiasing ), 653 renderThreadCount() ); 654 655 painter->drawImage( canvasRect.toAlignedRect(), image ); 656 } 657 else if ( d_data->paintAttributes & MinimizeMemory ) 658 { 659 const QwtSeriesData<QPointF> *series = data(); 660 661 for ( int i = from; i <= to; i++ ) 662 { 663 const QPointF sample = series->sample( i ); 664 665 double xi = xMap.transform( sample.x() ); 666 double yi = yMap.transform( sample.y() ); 667 668 if ( doAlign ) 669 { 670 xi = qRound( xi ); 671 yi = qRound( yi ); 672 } 673 674 QwtPainter::drawPoint( painter, QPointF( xi, yi ) ); 675 } 676 } 677 else 678 { 510 679 if ( doAlign ) 511 680 { 512 xi = qRound( xi ); 513 yi = qRound( yi ); 514 } 515 516 QwtPainter::drawPoint( painter, QPointF( xi, yi ) ); 517 518 if ( doFill ) 519 { 520 points[i - from].rx() = xi; 521 points[i - from].ry() = yi; 522 } 523 } 524 525 if ( doFill ) 526 fillCurve( painter, xMap, yMap, canvasRect, polyline ); 681 const QPolygon points = mapper.toPoints( 682 xMap, yMap, data(), from, to ); 683 684 QwtPainter::drawPoints( painter, points ); 685 } 686 else 687 { 688 const QPolygonF points = mapper.toPointsF( 689 xMap, yMap, data(), from, to ); 690 691 QwtPainter::drawPoints( painter, points ); 692 } 693 } 527 694 } 528 695 … … 535 702 \param xMap x map 536 703 \param yMap y map 537 \param canvasRect Contents rect of the canvas704 \param canvasRect Contents rectangle of the canvas 538 705 \param from index of the first point to be painted 539 706 \param to index of the last point to be painted … … 555 722 inverted = !inverted; 556 723 724 const QwtSeriesData<QPointF> *series = data(); 725 557 726 int i, ip; 558 727 for ( i = from, ip = 0; i <= to; i++, ip += 2 ) 559 728 { 560 const QPointF sample = d_series->sample( i );729 const QPointF sample = series->sample( i ); 561 730 double xi = xMap.transform( sample.x() ); 562 731 double yi = yMap.transform( sample.y() ); … … 590 759 if ( d_data->paintAttributes & ClipPolygons ) 591 760 { 761 qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF()); 762 const QRectF clipRect = canvasRect.adjusted(-pw, -pw, pw, pw); 763 592 764 const QPolygonF clipped = QwtClipper::clipPolygonF( 593 c anvasRect, polygon, false );765 clipRect, polygon, false ); 594 766 595 767 QwtPainter::drawPolyline( painter, clipped ); … … 678 850 \param xMap x map 679 851 \param yMap y map 680 \param canvasRect Contents rect of the canvas852 \param canvasRect Contents rectangle of the canvas 681 853 \param polygon Polygon - will be modified ! 682 854 … … 733 905 if ( orientation() == Qt::Vertical ) 734 906 { 735 if ( yMap.transformation()->type() == QwtScaleTransformation::Log10 ) 736 { 737 if ( baseline < QwtScaleMap::LogMin ) 738 baseline = QwtScaleMap::LogMin; 739 } 907 if ( yMap.transformation() ) 908 baseline = yMap.transformation()->bounded( baseline ); 740 909 741 910 double refY = yMap.transform( baseline ); … … 748 917 else 749 918 { 750 if ( xMap.transformation()->type() == QwtScaleTransformation::Log10 ) 751 { 752 if ( baseline < QwtScaleMap::LogMin ) 753 baseline = QwtScaleMap::LogMin; 754 } 919 if ( xMap.transformation() ) 920 baseline = xMap.transformation()->bounded( baseline ); 755 921 756 922 double refX = xMap.transform( baseline ); … … 770 936 \param xMap x map 771 937 \param yMap y map 772 \param canvasRect Contents rect of the canvas938 \param canvasRect Contents rectangle of the canvas 773 939 \param from Index of the first point to be painted 774 940 \param to Index of the last point to be painted … … 780 946 const QRectF &canvasRect, int from, int to ) const 781 947 { 782 const bool doAlign = QwtPainter::roundingAlignment( painter ); 783 784 bool usePixmap = testPaintAttribute( CacheSymbols ); 785 if ( usePixmap && !doAlign ) 786 { 787 // Don't use the pixmap, when the paint device 788 // could generate scalable vectors 789 790 usePixmap = false; 791 } 792 793 if ( usePixmap ) 794 { 795 QPixmap pm( symbol.boundingSize() ); 796 pm.fill( Qt::transparent ); 797 798 const double pw2 = 0.5 * pm.width(); 799 const double ph2 = 0.5 * pm.height(); 800 801 QPainter p( &pm ); 802 p.setRenderHints( painter->renderHints() ); 803 symbol.drawSymbol( &p, QPointF( pw2, ph2 ) ); 804 p.end(); 805 806 for ( int i = from; i <= to; i++ ) 807 { 808 const QPointF sample = d_series->sample( i ); 809 810 double xi = xMap.transform( sample.x() ); 811 double yi = yMap.transform( sample.y() ); 812 if ( doAlign ) 813 { 814 xi = qRound( xi ); 815 yi = qRound( yi ); 816 } 817 818 if ( canvasRect.contains( xi, yi ) ) 819 { 820 const int left = qCeil( xi ) - pw2; 821 const int top = qCeil( yi ) - ph2; 822 823 painter->drawPixmap( left, top, pm ); 824 } 825 } 826 } 827 else 828 { 829 const int chunkSize = 500; 830 831 for ( int i = from; i <= to; i += chunkSize ) 832 { 833 const int n = qMin( chunkSize, to - i + 1 ); 834 835 QPolygonF points; 836 for ( int j = 0; j < n; j++ ) 837 { 838 const QPointF sample = d_series->sample( i + j ); 839 840 const double xi = xMap.transform( sample.x() ); 841 const double yi = yMap.transform( sample.y() ); 842 843 if ( canvasRect.contains( xi, yi ) ) 844 points += QPointF( xi, yi ); 845 } 846 847 if ( points.size() > 0 ) 848 symbol.drawSymbols( painter, points ); 849 } 948 QwtPointMapper mapper; 949 mapper.setFlag( QwtPointMapper::RoundPoints, 950 QwtPainter::roundingAlignment( painter ) ); 951 mapper.setFlag( QwtPointMapper::WeedOutPoints, 952 testPaintAttribute( QwtPlotCurve::FilterPoints ) ); 953 mapper.setBoundingRect( canvasRect ); 954 955 const int chunkSize = 500; 956 957 for ( int i = from; i <= to; i += chunkSize ) 958 { 959 const int n = qMin( chunkSize, to - i + 1 ); 960 961 const QPolygonF points = mapper.toPointsF( xMap, yMap, 962 data(), i, i + n - 1 ); 963 964 if ( points.size() > 0 ) 965 symbol.drawSymbols( painter, points ); 850 966 } 851 967 } … … 856 972 The baseline is needed for filling the curve with a brush or 857 973 the Sticks drawing style. 858 The interpretation of the baseline depends on the CurveType. 859 With QwtPlotCurve::Yfx, the baseline is interpreted as a horizontal line 860 at y = baseline(), with QwtPlotCurve::Yfy, it is interpreted as a vertical 974 975 The interpretation of the baseline depends on the orientation(). 976 With Qt::Horizontal, the baseline is interpreted as a horizontal line 977 at y = baseline(), with Qt::Vertical, it is interpreted as a vertical 861 978 line at x = baseline(). 862 979 … … 864 981 865 982 \param value Value of the baseline 866 \sa baseline(), setBrush(), setStyle(), setStyle()983 \sa baseline(), setBrush(), setStyle(), QwtPlotAbstractSeriesItem::orientation() 867 984 */ 868 985 void QwtPlotCurve::setBaseline( double value ) … … 889 1006 \param pos Position, where to look for the closest curve point 890 1007 \param dist If dist != NULL, closestPoint() returns the distance between 891 the position and the clos test curve point1008 the position and the closest curve point 892 1009 \return Index of the closest curve point, or -1 if none can be found 893 1010 ( f.e when the curve has no points ) … … 897 1014 int QwtPlotCurve::closestPoint( const QPoint &pos, double *dist ) const 898 1015 { 899 if ( plot() == NULL || dataSize() <= 0 ) 1016 const size_t numSamples = dataSize(); 1017 1018 if ( plot() == NULL || numSamples <= 0 ) 900 1019 return -1; 1020 1021 const QwtSeriesData<QPointF> *series = data(); 901 1022 902 1023 const QwtScaleMap xMap = plot()->canvasMap( xAxis() ); … … 906 1027 double dmin = 1.0e10; 907 1028 908 for ( uint i = 0; i < dataSize(); i++ )909 { 910 const QPointF sample = d_series->sample( i );1029 for ( uint i = 0; i < numSamples; i++ ) 1030 { 1031 const QPointF sample = series->sample( i ); 911 1032 912 1033 const double cx = xMap.transform( sample.x() ) - pos.x(); … … 927 1048 928 1049 /*! 929 \brief Update the widget that represents the item on the legend 930 931 \param legend Legend 932 \sa drawLegendIdentifier(), legendItem(), QwtPlotItem::Legend 933 */ 934 void QwtPlotCurve::updateLegend( QwtLegend *legend ) const 935 { 936 if ( legend && testItemAttribute( QwtPlotItem::Legend ) 937 && ( d_data->legendAttributes & QwtPlotCurve::LegendShowSymbol ) 938 && d_data->symbol 939 && d_data->symbol->style() != QwtSymbol::NoSymbol ) 940 { 941 QWidget *lgdItem = legend->find( this ); 942 if ( lgdItem == NULL ) 943 { 944 lgdItem = legendItem(); 945 if ( lgdItem ) 946 legend->insert( this, lgdItem ); 947 } 948 949 QwtLegendItem *l = qobject_cast<QwtLegendItem *>( lgdItem ); 950 if ( l ) 951 { 952 QSize sz = d_data->symbol->boundingSize(); 953 sz += QSize( 2, 2 ); // margin 954 955 if ( d_data->legendAttributes & QwtPlotCurve::LegendShowLine ) 1050 \return Icon representing the curve on the legend 1051 1052 \param index Index of the legend entry 1053 ( ignored as there is only one ) 1054 \param size Icon size 1055 1056 \sa QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData() 1057 */ 1058 QwtGraphic QwtPlotCurve::legendIcon( int index, 1059 const QSizeF &size ) const 1060 { 1061 Q_UNUSED( index ); 1062 1063 if ( size.isEmpty() ) 1064 return QwtGraphic(); 1065 1066 QwtGraphic graphic; 1067 graphic.setDefaultSize( size ); 1068 graphic.setRenderHint( QwtGraphic::RenderPensUnscaled, true ); 1069 1070 QPainter painter( &graphic ); 1071 painter.setRenderHint( QPainter::Antialiasing, 1072 testRenderHint( QwtPlotItem::RenderAntialiased ) ); 1073 1074 if ( d_data->legendAttributes == 0 || 1075 d_data->legendAttributes & QwtPlotCurve::LegendShowBrush ) 1076 { 1077 QBrush brush = d_data->brush; 1078 1079 if ( brush.style() == Qt::NoBrush && 1080 d_data->legendAttributes == 0 ) 1081 { 1082 if ( style() != QwtPlotCurve::NoCurve ) 956 1083 { 957 // Avoid, that the line is completely covered by the symbol 958 959 int w = qCeil( 1.5 * sz.width() ); 960 if ( w % 2 ) 961 w++; 962 963 sz.setWidth( qMax( 8, w ) ); 1084 brush = QBrush( pen().color() ); 964 1085 } 965 966 l->setIdentifierSize( sz );967 }968 }969 970 QwtPlotItem::updateLegend( legend );971 }972 973 /*!974 \brief Draw the identifier representing the curve on the legend975 976 \param painter Painter977 \param rect Bounding rectangle for the identifier978 979 \sa setLegendAttribute(), QwtPlotItem::Legend980 */981 void QwtPlotCurve::drawLegendIdentifier(982 QPainter *painter, const QRectF &rect ) const983 {984 if ( rect.isEmpty() )985 return;986 987 const int dim = qMin( rect.width(), rect.height() );988 989 QSize size( dim, dim );990 991 QRectF r( 0, 0, size.width(), size.height() );992 r.moveCenter( rect.center() );993 994 if ( d_data->legendAttributes == 0 )995 {996 QBrush brush = d_data->brush;997 if ( brush.style() == Qt::NoBrush )998 {999 if ( style() != QwtPlotCurve::NoCurve )1000 brush = QBrush( pen().color() );1001 1086 else if ( d_data->symbol && 1002 1087 ( d_data->symbol->style() != QwtSymbol::NoSymbol ) ) … … 1005 1090 } 1006 1091 } 1092 1007 1093 if ( brush.style() != Qt::NoBrush ) 1008 painter->fillRect( r, brush ); 1009 } 1010 if ( d_data->legendAttributes & QwtPlotCurve::LegendShowBrush ) 1011 { 1012 if ( d_data->brush.style() != Qt::NoBrush ) 1013 painter->fillRect( r, d_data->brush ); 1014 } 1094 { 1095 QRectF r( 0, 0, size.width(), size.height() ); 1096 painter.fillRect( r, brush ); 1097 } 1098 } 1099 1015 1100 if ( d_data->legendAttributes & QwtPlotCurve::LegendShowLine ) 1016 1101 { 1017 1102 if ( pen() != Qt::NoPen ) 1018 1103 { 1019 painter->setPen( pen() ); 1020 QwtPainter::drawLine( painter, rect.left(), rect.center().y(), 1021 rect.right() - 1.0, rect.center().y() ); 1022 } 1023 } 1104 QPen pn = pen(); 1105 pn.setCapStyle( Qt::FlatCap ); 1106 1107 painter.setPen( pn ); 1108 1109 const double y = 0.5 * size.height(); 1110 QwtPainter::drawLine( &painter, 0.0, y, size.width(), y ); 1111 } 1112 } 1113 1024 1114 if ( d_data->legendAttributes & QwtPlotCurve::LegendShowSymbol ) 1025 1115 { 1026 if ( d_data->symbol && 1027 ( d_data->symbol->style() != QwtSymbol::NoSymbol ) ) 1028 { 1029 QSize symbolSize = d_data->symbol->boundingSize(); 1030 symbolSize -= QSize( 2, 2 ); 1031 1032 // scale the symbol size down if it doesn't fit into rect. 1033 1034 double xRatio = 1.0; 1035 if ( rect.width() < symbolSize.width() ) 1036 xRatio = rect.width() / symbolSize.width(); 1037 double yRatio = 1.0; 1038 if ( rect.height() < symbolSize.height() ) 1039 yRatio = rect.height() / symbolSize.height(); 1040 1041 const double ratio = qMin( xRatio, yRatio ); 1042 1043 painter->save(); 1044 painter->scale( ratio, ratio ); 1045 1046 d_data->symbol->drawSymbol( painter, rect.center() / ratio ); 1047 1048 painter->restore(); 1049 } 1050 } 1051 } 1052 1053 /*! 1054 Initialize data with an array of points (explicitly shared). 1116 if ( d_data->symbol ) 1117 { 1118 QRectF r( 0, 0, size.width(), size.height() ); 1119 d_data->symbol->drawSymbol( &painter, r ); 1120 } 1121 } 1122 1123 return graphic; 1124 } 1125 1126 /*! 1127 Initialize data with an array of points. 1055 1128 1056 1129 \param samples Vector of points 1130 \note QVector is implicitly shared 1131 \note QPolygonF is derived from QVector<QPointF> 1057 1132 */ 1058 1133 void QwtPlotCurve::setSamples( const QVector<QPointF> &samples ) 1059 1134 { 1060 delete d_series; 1061 d_series = new QwtPointSeriesData( samples ); 1062 itemChanged(); 1135 setData( new QwtPointSeriesData( samples ) ); 1136 } 1137 1138 /*! 1139 Assign a series of points 1140 1141 setSamples() is just a wrapper for setData() without any additional 1142 value - beside that it is easier to find for the developer. 1143 1144 \param data Data 1145 \warning The item takes ownership of the data object, deleting 1146 it when its not used anymore. 1147 */ 1148 void QwtPlotCurve::setSamples( QwtSeriesData<QPointF> *data ) 1149 { 1150 setData( data ); 1063 1151 } 1064 1152 … … 1082 1170 const double *xData, const double *yData, int size ) 1083 1171 { 1084 delete d_series; 1085 d_series = new QwtCPointerData( xData, yData, size ); 1086 itemChanged(); 1172 setData( new QwtCPointerData( xData, yData, size ) ); 1087 1173 } 1088 1174 … … 1101 1187 const double *xData, const double *yData, int size ) 1102 1188 { 1103 delete d_series; 1104 d_series = new QwtPointArrayData( xData, yData, size ); 1105 itemChanged(); 1189 setData( new QwtPointArrayData( xData, yData, size ) ); 1106 1190 } 1107 1191 … … 1117 1201 const QVector<double> &yData ) 1118 1202 { 1119 delete d_series; 1120 d_series = new QwtPointArrayData( xData, yData ); 1121 itemChanged(); 1122 } 1203 setData( new QwtPointArrayData( xData, yData ) ); 1204 } 1205 1123 1206 #endif // !QWT_NO_COMPAT 1124 1207
Note:
See TracChangeset
for help on using the changeset viewer.