00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <qpainter.h>
00011 #include <qpixmap.h>
00012 #include <qbitarray.h>
00013 #include "qwt_global.h"
00014 #include "qwt_legend.h"
00015 #include "qwt_legend_item.h"
00016 #include "qwt_data.h"
00017 #include "qwt_rect.h"
00018 #include "qwt_scale_map.h"
00019 #include "qwt_double_rect.h"
00020 #include "qwt_math.h"
00021 #include "qwt_painter.h"
00022 #include "qwt_plot.h"
00023 #include "qwt_plot_canvas.h"
00024 #include "qwt_curve_fitter.h"
00025 #include "qwt_symbol.h"
00026 #include "qwt_plot_curve.h"
00027
00028 #if QT_VERSION >= 0x040000
00029
00030 #include <qevent.h>
00031
00032 class QwtPlotCurvePaintHelper: public QObject
00033 {
00034 public:
00035 QwtPlotCurvePaintHelper(const QwtPlotCurve *curve, int from, int to):
00036 _curve(curve),
00037 _from(from),
00038 _to(to)
00039 {
00040 }
00041
00042 virtual bool eventFilter(QObject *, QEvent *event)
00043 {
00044 if ( event->type() == QEvent::Paint )
00045 {
00046 _curve->draw(_from, _to);
00047 return true;
00048 }
00049 return false;
00050 }
00051 private:
00052 const QwtPlotCurve *_curve;
00053 int _from;
00054 int _to;
00055 };
00056
00057 #endif // QT_VERSION >= 0x040000
00058
00059 static int verifyRange(int size, int &i1, int &i2)
00060 {
00061 if (size < 1)
00062 return 0;
00063
00064 i1 = qwtLim(i1, 0, size-1);
00065 i2 = qwtLim(i2, 0, size-1);
00066
00067 if ( i1 > i2 )
00068 qSwap(i1, i2);
00069
00070 return (i2 - i1 + 1);
00071 }
00072
00073 class QwtPlotCurve::PrivateData
00074 {
00075 public:
00076 class PixelMatrix: private QBitArray
00077 {
00078 public:
00079 PixelMatrix(const QRect& rect):
00080 QBitArray(rect.width() * rect.height()),
00081 _rect(rect)
00082 {
00083 fill(false);
00084 }
00085
00086 inline bool testPixel(const QPoint& pos)
00087 {
00088 if ( !_rect.contains(pos) )
00089 return false;
00090
00091 const int idx = _rect.width() * (pos.y() - _rect.y()) +
00092 (pos.x() - _rect.x());
00093
00094 const bool marked = testBit(idx);
00095 if ( !marked )
00096 setBit(idx, true);
00097
00098 return !marked;
00099 }
00100
00101 private:
00102 QRect _rect;
00103 };
00104
00105 PrivateData():
00106 curveType(Yfx),
00107 style(QwtPlotCurve::Lines),
00108 reference(0.0),
00109 attributes(0),
00110 paintAttributes(0)
00111 {
00112 pen = QPen(Qt::black, 0);
00113 curveFitter = new QwtSplineCurveFitter;
00114 }
00115
00116 ~PrivateData()
00117 {
00118 delete curveFitter;
00119 }
00120
00121 QwtPlotCurve::CurveType curveType;
00122 QwtPlotCurve::CurveStyle style;
00123 double reference;
00124
00125 QwtSymbol sym;
00126 QwtCurveFitter *curveFitter;
00127
00128 QPen pen;
00129 QBrush brush;
00130
00131 int attributes;
00132 int paintAttributes;
00133 };
00134
00138 QwtPlotCurve::QwtPlotCurve():
00139 QwtPlotItem(QwtText())
00140 {
00141 init();
00142 }
00143
00148 QwtPlotCurve::QwtPlotCurve(const QwtText &title):
00149 QwtPlotItem(title)
00150 {
00151 init();
00152 }
00153
00158 QwtPlotCurve::QwtPlotCurve(const QString &title):
00159 QwtPlotItem(QwtText(title))
00160 {
00161 init();
00162 }
00163
00165 QwtPlotCurve::~QwtPlotCurve()
00166 {
00167 delete d_xy;
00168 delete d_data;
00169 }
00170
00174 void QwtPlotCurve::init()
00175 {
00176 setItemAttribute(QwtPlotItem::Legend);
00177 setItemAttribute(QwtPlotItem::AutoScale);
00178
00179 d_data = new PrivateData;
00180 d_xy = new QwtPolygonFData(QwtArray<QwtDoublePoint>());
00181
00182 setZ(20.0);
00183 }
00184
00185 int QwtPlotCurve::rtti() const
00186 {
00187 return QwtPlotItem::Rtti_PlotCurve;
00188 }
00189
00211 void QwtPlotCurve::setPaintAttribute(PaintAttribute attribute, bool on)
00212 {
00213 if ( on )
00214 d_data->paintAttributes |= attribute;
00215 else
00216 d_data->paintAttributes &= ~attribute;
00217 }
00218
00223 bool QwtPlotCurve::testPaintAttribute(PaintAttribute attribute) const
00224 {
00225 return (d_data->paintAttributes & attribute);
00226 }
00227
00255 void QwtPlotCurve::setStyle(CurveStyle style)
00256 {
00257 if ( style != d_data->style )
00258 {
00259 d_data->style = style;
00260 itemChanged();
00261 }
00262 }
00263
00268 QwtPlotCurve::CurveStyle QwtPlotCurve::style() const
00269 {
00270 return d_data->style;
00271 }
00272
00278 void QwtPlotCurve::setSymbol(const QwtSymbol &s )
00279 {
00280 d_data->sym = s;
00281 itemChanged();
00282 }
00283
00288 const QwtSymbol &QwtPlotCurve::symbol() const
00289 {
00290 return d_data->sym;
00291 }
00292
00298 void QwtPlotCurve::setPen(const QPen &p)
00299 {
00300 if ( p != d_data->pen )
00301 {
00302 d_data->pen = p;
00303 itemChanged();
00304 }
00305 }
00306
00311 const QPen& QwtPlotCurve::pen() const
00312 {
00313 return d_data->pen;
00314 }
00315
00328 void QwtPlotCurve::setBrush(const QBrush &brush)
00329 {
00330 if ( brush != d_data->brush )
00331 {
00332 d_data->brush = brush;
00333 itemChanged();
00334 }
00335 }
00336
00341 const QBrush& QwtPlotCurve::brush() const
00342 {
00343 return d_data->brush;
00344 }
00345
00346
00358 void QwtPlotCurve::setData(const double *xData, const double *yData, int size)
00359 {
00360 delete d_xy;
00361 d_xy = new QwtArrayData(xData, yData, size);
00362 itemChanged();
00363 }
00364
00373 void QwtPlotCurve::setData(const QwtArray<double> &xData,
00374 const QwtArray<double> &yData)
00375 {
00376 delete d_xy;
00377 d_xy = new QwtArrayData(xData, yData);
00378 itemChanged();
00379 }
00380
00387 #if QT_VERSION < 0x040000
00388 void QwtPlotCurve::setData(const QwtArray<QwtDoublePoint> &data)
00389 #else
00390 void QwtPlotCurve::setData(const QPolygonF &data)
00391 #endif
00392 {
00393 delete d_xy;
00394 d_xy = new QwtPolygonFData(data);
00395 itemChanged();
00396 }
00397
00404 void QwtPlotCurve::setData(const QwtData &data)
00405 {
00406 delete d_xy;
00407 d_xy = data.copy();
00408 itemChanged();
00409 }
00410
00424 void QwtPlotCurve::setRawData(const double *xData, const double *yData, int size)
00425 {
00426 delete d_xy;
00427 d_xy = new QwtCPointerData(xData, yData, size);
00428 itemChanged();
00429 }
00430
00437 QwtDoubleRect QwtPlotCurve::boundingRect() const
00438 {
00439 if ( d_xy == NULL )
00440 return QwtDoubleRect(1.0, 1.0, -2.0, -2.0);
00441
00442 return d_xy->boundingRect();
00443 }
00444
00454 void QwtPlotCurve::draw(QPainter *painter,
00455 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00456 const QRect &) const
00457 {
00458 draw(painter, xMap, yMap, 0, -1);
00459 }
00460
00478 void QwtPlotCurve::draw(int from, int to) const
00479 {
00480 if ( !plot() )
00481 return;
00482
00483 QwtPlotCanvas *canvas = plot()->canvas();
00484
00485 #if QT_VERSION >= 0x040000
00486 if ( !canvas->testAttribute(Qt::WA_WState_InPaintEvent) &&
00487 !canvas->testAttribute(Qt::WA_PaintOutsidePaintEvent) )
00488 {
00489
00490
00491
00492
00493
00494
00495
00496 QwtPlotCurvePaintHelper helper(this, from, to);
00497 canvas->installEventFilter(&helper);
00498
00499 const bool noSystemBackground =
00500 canvas->testAttribute(Qt::WA_NoSystemBackground);
00501 canvas->setAttribute(Qt::WA_NoSystemBackground, true);
00502 canvas->repaint();
00503 canvas->setAttribute(Qt::WA_NoSystemBackground, noSystemBackground);
00504
00505 return;
00506 }
00507 #endif
00508
00509 const QwtScaleMap xMap = plot()->canvasMap(xAxis());
00510 const QwtScaleMap yMap = plot()->canvasMap(yAxis());
00511
00512 if ( canvas->testPaintAttribute(QwtPlotCanvas::PaintCached) &&
00513 canvas->paintCache() && !canvas->paintCache()->isNull() )
00514 {
00515 QPainter cachePainter((QPixmap *)canvas->paintCache());
00516 cachePainter.translate(-canvas->contentsRect().x(),
00517 -canvas->contentsRect().y());
00518
00519 draw(&cachePainter, xMap, yMap, from, to);
00520 }
00521
00522 QPainter painter(canvas);
00523
00524 painter.setClipping(true);
00525 painter.setClipRect(canvas->contentsRect());
00526
00527 draw(&painter, xMap, yMap, from, to);
00528 }
00529
00541 void QwtPlotCurve::draw(QPainter *painter,
00542 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00543 int from, int to) const
00544 {
00545 if ( !painter || dataSize() <= 0 )
00546 return;
00547
00548 if (to < 0)
00549 to = dataSize() - 1;
00550
00551 if ( verifyRange(dataSize(), from, to) > 0 )
00552 {
00553 painter->save();
00554 painter->setPen(d_data->pen);
00555
00556
00557
00558
00559
00560
00561
00562 drawCurve(painter, d_data->style, xMap, yMap, from, to);
00563 painter->restore();
00564
00565 if (d_data->sym.style() != QwtSymbol::NoSymbol)
00566 {
00567 painter->save();
00568 drawSymbols(painter, d_data->sym, xMap, yMap, from, to);
00569 painter->restore();
00570 }
00571 }
00572 }
00573
00585 void QwtPlotCurve::drawCurve(QPainter *painter, int style,
00586 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00587 int from, int to) const
00588 {
00589 switch (style)
00590 {
00591 case Lines:
00592 if ( testCurveAttribute(Fitted) )
00593 {
00594
00595
00596 from = 0;
00597 to = dataSize() - 1;
00598 }
00599 drawLines(painter, xMap, yMap, from, to);
00600 break;
00601 case Sticks:
00602 drawSticks(painter, xMap, yMap, from, to);
00603 break;
00604 case Steps:
00605 drawSteps(painter, xMap, yMap, from, to);
00606 break;
00607 case Dots:
00608 drawDots(painter, xMap, yMap, from, to);
00609 break;
00610 case NoCurve:
00611 default:
00612 break;
00613 }
00614 }
00615
00631 void QwtPlotCurve::drawLines(QPainter *painter,
00632 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00633 int from, int to) const
00634 {
00635 int size = to - from + 1;
00636 if ( size <= 0 )
00637 return;
00638
00639 QwtPolygon polyline;
00640 if ( ( d_data->attributes & Fitted ) && d_data->curveFitter )
00641 {
00642
00643
00644
00645
00646 #if QT_VERSION < 0x040000
00647 QwtArray<QwtDoublePoint> points(size);
00648 #else
00649 QPolygonF points(size);
00650 #endif
00651 for (int i = from; i <= to; i++)
00652 {
00653 QwtDoublePoint &p = points[i];
00654 p.setX( xMap.xTransform(x(i)) );
00655 p.setY( yMap.xTransform(y(i)) );
00656 }
00657
00658 points = d_data->curveFitter->fitCurve(points);
00659 size = points.size();
00660
00661 if ( size == 0 )
00662 return;
00663
00664
00665
00666
00667
00668
00669 polyline.resize(size);
00670
00671 const QwtDoublePoint *p = points.data();
00672 QPoint *pl = polyline.data();
00673 if ( d_data->paintAttributes & PaintFiltered )
00674 {
00675
00676 QPoint pp(qRound(p[0].x()), qRound(p[0].y()));
00677 pl[0] = pp;
00678
00679 int count = 1;
00680 for (int i = 1; i < size; i++)
00681 {
00682 const QPoint pi(qRound(p[i].x()), qRound(p[i].y()));
00683 if ( pi != pp )
00684 {
00685 pl[count++] = pi;
00686 pp = pi;
00687 }
00688 }
00689 if ( count != size )
00690 polyline.resize(count);
00691 }
00692 else
00693 {
00694 for ( int i = 0; i < size; i++ )
00695 {
00696 pl[i].setX( qRound(p[i].x()) );
00697 pl[i].setY( qRound(p[i].y()) );
00698 }
00699 }
00700 }
00701 else
00702 {
00703 polyline.resize(size);
00704
00705 if ( d_data->paintAttributes & PaintFiltered )
00706 {
00707 QPoint pp( xMap.transform(x(from)), yMap.transform(y(from)) );
00708 polyline.setPoint(0, pp);
00709
00710 int count = 1;
00711 for (int i = from + 1; i <= to; i++)
00712 {
00713 const QPoint pi(xMap.transform(x(i)), yMap.transform(y(i)));
00714 if ( pi != pp )
00715 {
00716 polyline.setPoint(count, pi);
00717 count++;
00718
00719 pp = pi;
00720 }
00721 }
00722 if ( count != size )
00723 polyline.resize(count);
00724 }
00725 else
00726 {
00727 for (int i = from; i <= to; i++)
00728 {
00729 int xi = xMap.transform(x(i));
00730 int yi = yMap.transform(y(i));
00731
00732 polyline.setPoint(i - from, xi, yi);
00733 }
00734 }
00735 }
00736
00737 if ( d_data->paintAttributes & ClipPolygons )
00738 {
00739 QwtRect r = painter->window();
00740 polyline = r.clip(polyline);
00741 }
00742
00743 QwtPainter::drawPolyline(painter, polyline);
00744
00745 if ( d_data->brush.style() != Qt::NoBrush )
00746 fillCurve(painter, xMap, yMap, polyline);
00747 }
00748
00760 void QwtPlotCurve::drawSticks(QPainter *painter,
00761 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00762 int from, int to) const
00763 {
00764 int x0 = xMap.transform(d_data->reference);
00765 int y0 = yMap.transform(d_data->reference);
00766
00767 for (int i = from; i <= to; i++)
00768 {
00769 const int xi = xMap.transform(x(i));
00770 const int yi = yMap.transform(y(i));
00771
00772 if (d_data->curveType == Xfy)
00773 QwtPainter::drawLine(painter, x0, yi, xi, yi);
00774 else
00775 QwtPainter::drawLine(painter, xi, y0, xi, yi);
00776 }
00777 }
00778
00790 void QwtPlotCurve::drawDots(QPainter *painter,
00791 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00792 int from, int to) const
00793 {
00794 const QRect window = painter->window();
00795 if ( window.isEmpty() )
00796 return;
00797
00798 const bool doFill = d_data->brush.style() != Qt::NoBrush;
00799
00800 QwtPolygon polyline;
00801 if ( doFill )
00802 polyline.resize(to - from + 1);
00803
00804 if ( to > from && d_data->paintAttributes & PaintFiltered )
00805 {
00806 if ( doFill )
00807 {
00808 QPoint pp( xMap.transform(x(from)), yMap.transform(y(from)) );
00809
00810 QwtPainter::drawPoint(painter, pp.x(), pp.y());
00811 polyline.setPoint(0, pp);
00812
00813 int count = 1;
00814 for (int i = from + 1; i <= to; i++)
00815 {
00816 const QPoint pi(xMap.transform(x(i)), yMap.transform(y(i)));
00817 if ( pi != pp )
00818 {
00819 QwtPainter::drawPoint(painter, pi.x(), pi.y());
00820
00821 polyline.setPoint(count, pi);
00822 count++;
00823
00824 pp = pi;
00825 }
00826 }
00827 if ( int(polyline.size()) != count )
00828 polyline.resize(count);
00829 }
00830 else
00831 {
00832
00833
00834
00835 PrivateData::PixelMatrix pixelMatrix(window);
00836
00837 for (int i = from; i <= to; i++)
00838 {
00839 const QPoint p( xMap.transform(x(i)),
00840 yMap.transform(y(i)) );
00841
00842 if ( pixelMatrix.testPixel(p) )
00843 QwtPainter::drawPoint(painter, p.x(), p.y());
00844 }
00845 }
00846 }
00847 else
00848 {
00849 for (int i = from; i <= to; i++)
00850 {
00851 const int xi = xMap.transform(x(i));
00852 const int yi = yMap.transform(y(i));
00853 QwtPainter::drawPoint(painter, xi, yi);
00854
00855 if ( doFill )
00856 polyline.setPoint(i - from, xi, yi);
00857 }
00858 }
00859
00860 if ( doFill )
00861 {
00862 if ( d_data->paintAttributes & ClipPolygons )
00863 {
00864 const QwtRect r = painter->window();
00865 polyline = r.clip(polyline);
00866 }
00867
00868 fillCurve(painter, xMap, yMap, polyline);
00869 }
00870 }
00871
00886 void QwtPlotCurve::drawSteps(QPainter *painter,
00887 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00888 int from, int to) const
00889 {
00890 QwtPolygon polyline(2 * (to - from) + 1);
00891
00892 bool inverted = d_data->curveType == Yfx;
00893 if ( d_data->attributes & Inverted )
00894 inverted = !inverted;
00895
00896 int i,ip;
00897 for (i = from, ip = 0; i <= to; i++, ip += 2)
00898 {
00899 const int xi = xMap.transform(x(i));
00900 const int yi = yMap.transform(y(i));
00901
00902 if ( ip > 0 )
00903 {
00904 if (inverted)
00905 polyline.setPoint(ip - 1, polyline[ip-2].x(), yi);
00906 else
00907 polyline.setPoint(ip - 1, xi, polyline[ip-2].y());
00908 }
00909
00910 polyline.setPoint(ip, xi, yi);
00911 }
00912
00913 if ( d_data->paintAttributes & ClipPolygons )
00914 {
00915 const QwtRect r = painter->window();
00916 polyline = r.clip(polyline);
00917 }
00918
00919 QwtPainter::drawPolyline(painter, polyline);
00920
00921 if ( d_data->brush.style() != Qt::NoBrush )
00922 fillCurve(painter, xMap, yMap, polyline);
00923 }
00924
00925
00948 void QwtPlotCurve::setCurveAttribute(CurveAttribute attribute, bool on)
00949 {
00950 if ( bool(d_data->attributes & attribute) == on )
00951 return;
00952
00953 if ( on )
00954 d_data->attributes |= attribute;
00955 else
00956 d_data->attributes &= ~attribute;
00957
00958 itemChanged();
00959 }
00960
00965 bool QwtPlotCurve::testCurveAttribute(CurveAttribute attribute) const
00966 {
00967 return d_data->attributes & attribute;
00968 }
00969
00986 void QwtPlotCurve::setCurveType(CurveType curveType)
00987 {
00988 if ( d_data->curveType != curveType )
00989 {
00990 d_data->curveType = curveType;
00991 itemChanged();
00992 }
00993 }
00994
00999 QwtPlotCurve::CurveType QwtPlotCurve::curveType() const
01000 {
01001 return d_data->curveType;
01002 }
01003
01004 void QwtPlotCurve::setCurveFitter(QwtCurveFitter *curveFitter)
01005 {
01006 delete d_data->curveFitter;
01007 d_data->curveFitter = curveFitter;
01008
01009 itemChanged();
01010 }
01011
01012 QwtCurveFitter *QwtPlotCurve::curveFitter() const
01013 {
01014 return d_data->curveFitter;
01015 }
01016
01029 void QwtPlotCurve::fillCurve(QPainter *painter,
01030 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
01031 QwtPolygon &pa) const
01032 {
01033 if ( d_data->brush.style() == Qt::NoBrush )
01034 return;
01035
01036 closePolyline(xMap, yMap, pa);
01037 if ( pa.count() <= 2 )
01038 return;
01039
01040 QBrush b = d_data->brush;
01041 if ( !b.color().isValid() )
01042 b.setColor(d_data->pen.color());
01043
01044 painter->save();
01045
01046 painter->setPen(QPen(Qt::NoPen));
01047 painter->setBrush(b);
01048
01049 QwtPainter::drawPolygon(painter, pa);
01050
01051 painter->restore();
01052 }
01053
01063 void QwtPlotCurve::closePolyline(
01064 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
01065 QwtPolygon &pa) const
01066 {
01067 const int sz = pa.size();
01068 if ( sz < 2 )
01069 return;
01070
01071 pa.resize(sz + 2);
01072
01073 if ( d_data->curveType == QwtPlotCurve::Xfy )
01074 {
01075 pa.setPoint(sz,
01076 xMap.transform(d_data->reference), pa.point(sz - 1).y());
01077 pa.setPoint(sz + 1,
01078 xMap.transform(d_data->reference), pa.point(0).y());
01079 }
01080 else
01081 {
01082 pa.setPoint(sz,
01083 pa.point(sz - 1).x(), yMap.transform(d_data->reference));
01084 pa.setPoint(pa.size() - 1,
01085 pa.point(0).x(), yMap.transform(d_data->reference));
01086 }
01087 }
01088
01100 void QwtPlotCurve::drawSymbols(QPainter *painter, const QwtSymbol &symbol,
01101 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
01102 int from, int to) const
01103 {
01104 painter->setBrush(symbol.brush());
01105 painter->setPen(symbol.pen());
01106
01107 QRect rect;
01108 rect.setSize(QwtPainter::metricsMap().screenToLayout(symbol.size()));
01109
01110 if ( to > from && d_data->paintAttributes & PaintFiltered )
01111 {
01112 const QRect window = painter->window();
01113 if ( window.isEmpty() )
01114 return;
01115
01116 PrivateData::PixelMatrix pixelMatrix(window);
01117
01118 for (int i = from; i <= to; i++)
01119 {
01120 const QPoint pi( xMap.transform(x(i)),
01121 yMap.transform(y(i)) );
01122
01123 if ( pixelMatrix.testPixel(pi) )
01124 {
01125 rect.moveCenter(pi);
01126 symbol.draw(painter, rect);
01127 }
01128 }
01129 }
01130 else
01131 {
01132 for (int i = from; i <= to; i++)
01133 {
01134 const int xi = xMap.transform(x(i));
01135 const int yi = yMap.transform(y(i));
01136
01137 rect.moveCenter(QPoint(xi, yi));
01138 symbol.draw(painter, rect);
01139 }
01140 }
01141 }
01142
01156 void QwtPlotCurve::setBaseline(double reference)
01157 {
01158 if ( d_data->reference != reference )
01159 {
01160 d_data->reference = reference;
01161 itemChanged();
01162 }
01163 }
01164
01169 double QwtPlotCurve::baseline() const
01170 {
01171 return d_data->reference;
01172 }
01173
01178 int QwtPlotCurve::dataSize() const
01179 {
01180 return d_xy->size();
01181 }
01182
01183 int QwtPlotCurve::closestPoint(const QPoint &pos, double *dist) const
01184 {
01185 if ( plot() == NULL || dataSize() <= 0 )
01186 return -1;
01187
01188 const QwtScaleMap xMap = plot()->canvasMap(xAxis());
01189 const QwtScaleMap yMap = plot()->canvasMap(yAxis());
01190
01191 int index = -1;
01192 double dmin = 1.0e10;
01193
01194 for (int i=0; i < dataSize(); i++)
01195 {
01196 const double cx = xMap.xTransform(x(i)) - pos.x();
01197 const double cy = yMap.xTransform(y(i)) - pos.y();
01198
01199 const double f = qwtSqr(cx) + qwtSqr(cy);
01200 if (f < dmin)
01201 {
01202 index = i;
01203 dmin = f;
01204 }
01205 }
01206 if ( dist )
01207 *dist = sqrt(dmin);
01208
01209 return index;
01210 }
01211
01212 void QwtPlotCurve::updateLegend(QwtLegend *legend) const
01213 {
01214 if ( !legend )
01215 return;
01216
01217 QwtPlotItem::updateLegend(legend);
01218
01219 QWidget *widget = legend->find(this);
01220 if ( !widget || !widget->inherits("QwtLegendItem") )
01221 return;
01222
01223 QwtLegendItem *legendItem = (QwtLegendItem *)widget;
01224
01225 #if QT_VERSION < 0x040000
01226 const bool doUpdate = legendItem->isUpdatesEnabled();
01227 #else
01228 const bool doUpdate = legendItem->updatesEnabled();
01229 #endif
01230 legendItem->setUpdatesEnabled(false);
01231
01232 const int policy = legend->displayPolicy();
01233
01234 if (policy == QwtLegend::FixedIdentifier)
01235 {
01236 int mode = legend->identifierMode();
01237
01238 if (mode & QwtLegendItem::ShowLine)
01239 legendItem->setCurvePen(pen());
01240
01241 if (mode & QwtLegendItem::ShowSymbol)
01242 legendItem->setSymbol(symbol());
01243
01244 if (mode & QwtLegendItem::ShowText)
01245 legendItem->setText(title());
01246 else
01247 legendItem->setText(QwtText());
01248
01249 legendItem->setIdentifierMode(mode);
01250 }
01251 else if (policy == QwtLegend::AutoIdentifier)
01252 {
01253 int mode = 0;
01254
01255 if (QwtPlotCurve::NoCurve != style())
01256 {
01257 legendItem->setCurvePen(pen());
01258 mode |= QwtLegendItem::ShowLine;
01259 }
01260 if (QwtSymbol::NoSymbol != symbol().style())
01261 {
01262 legendItem->setSymbol(symbol());
01263 mode |= QwtLegendItem::ShowSymbol;
01264 }
01265 if ( !title().isEmpty() )
01266 {
01267 legendItem->setText(title());
01268 mode |= QwtLegendItem::ShowText;
01269 }
01270 else
01271 {
01272 legendItem->setText(QwtText());
01273 }
01274 legendItem->setIdentifierMode(mode);
01275 }
01276
01277 legendItem->setUpdatesEnabled(doUpdate);
01278 legendItem->update();
01279 }