1
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
3
* Copyright (C) 1997 Josef Wilgen
4
* Copyright (C) 2002 Uwe Rathmann
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
*****************************************************************************/
12
#include <qbitarray.h>
13
#include "qwt_global.h"
14
#include "qwt_legend.h"
15
#include "qwt_legend_item.h"
17
#include "qwt_scale_map.h"
18
#include "qwt_double_rect.h"
20
#include "qwt_clipper.h"
21
#include "qwt_painter.h"
23
#include "qwt_plot_canvas.h"
24
#include "qwt_curve_fitter.h"
25
#include "qwt_symbol.h"
26
#include "qwt_plot_curve.h"
28
#if QT_VERSION >= 0x040000
31
#include <qpaintengine.h>
33
class QwtPlotCurvePaintHelper: public QObject
36
QwtPlotCurvePaintHelper(const QwtPlotCurve *curve, int from, int to):
43
virtual bool eventFilter(QObject *, QEvent *event)
45
if ( event->type() == QEvent::Paint )
47
_curve->draw(_from, _to);
53
const QwtPlotCurve *_curve;
58
#endif // QT_VERSION >= 0x040000
60
static int verifyRange(int size, int &i1, int &i2)
65
i1 = qwtLim(i1, 0, size-1);
66
i2 = qwtLim(i2, 0, size-1);
74
class QwtPlotCurve::PrivateData
77
class PixelMatrix: private QBitArray
80
PixelMatrix(const QRect& rect):
81
QBitArray(rect.width() * rect.height()),
87
inline bool testPixel(const QPoint& pos)
89
if ( !_rect.contains(pos) )
92
const int idx = _rect.width() * (pos.y() - _rect.y()) +
93
(pos.x() - _rect.x());
95
const bool marked = testBit(idx);
108
style(QwtPlotCurve::Lines),
113
symbol = new QwtSymbol();
114
pen = QPen(Qt::black);
115
curveFitter = new QwtSplineCurveFitter;
124
QwtPlotCurve::CurveType curveType;
125
QwtPlotCurve::CurveStyle style;
129
QwtCurveFitter *curveFitter;
139
QwtPlotCurve::QwtPlotCurve():
140
QwtPlotItem(QwtText())
147
\param title title of the curve
149
QwtPlotCurve::QwtPlotCurve(const QwtText &title):
157
\param title title of the curve
159
QwtPlotCurve::QwtPlotCurve(const QString &title):
160
QwtPlotItem(QwtText(title))
166
QwtPlotCurve::~QwtPlotCurve()
173
\brief Initialize data members
175
void QwtPlotCurve::init()
177
setItemAttribute(QwtPlotItem::Legend);
178
setItemAttribute(QwtPlotItem::AutoScale);
180
d_data = new PrivateData;
181
d_xy = new QwtPolygonFData(QwtArray<QwtDoublePoint>());
186
//! \return QwtPlotItem::Rtti_PlotCurve
187
int QwtPlotCurve::rtti() const
189
return QwtPlotItem::Rtti_PlotCurve;
193
\brief Specify an attribute how to draw the curve
195
The attributes can be used to modify the drawing algorithm.
197
The following attributes are defined:<dl>
198
<dt>PaintFiltered</dt>
199
<dd>Tries to reduce the data that has to be painted, by sorting out
200
duplicates, or paintings outside the visible area. Might have a
201
notable impact on curves with many close points.
202
Only a couple of very basic filtering algos are implemented.</dd>
203
<dt>ClipPolygons</dt>
204
<dd>Clip polygons before painting them. In situations, where points
205
are far outside the visible area this might be a great improvement
206
for the painting performance ( especially on Windows ).
209
The default is, that no paint attributes are enabled.
211
\param attribute Paint attribute
213
/sa testPaintAttribute()
215
void QwtPlotCurve::setPaintAttribute(PaintAttribute attribute, bool on)
218
d_data->paintAttributes |= attribute;
220
d_data->paintAttributes &= ~attribute;
224
\brief Return the current paint attributes
225
\sa setPaintAttribute
227
bool QwtPlotCurve::testPaintAttribute(PaintAttribute attribute) const
229
return (d_data->paintAttributes & attribute);
233
\brief Set the curve's drawing style
238
<dd>Don't draw a curve. Note: This doesn't affect the symbol. </dd>
240
<dd>Connect the points with straight lines. The lines might
241
be interpolated depending on the 'Fitted' option. Curve
242
fitting can be configured using setCurveFitter.</dd>
244
<dd>Draw vertical sticks from a baseline which is defined by setBaseline().</dd>
246
<dd>Connect the points with a step function. The step function
247
is drawn from the left to the right or vice versa,
248
depending on the 'Inverted' option.</dd>
250
<dd>Draw dots at the locations of the data points. Note:
251
This is different from a dotted line (see setPen()).</dd>
252
<dt>UserCurve ...</dt>
253
<dd>Styles >= UserCurve are reserved for derived
254
classes of QwtPlotCurve that overload drawCurve() with
255
additional application specific curve types.</dd>
259
void QwtPlotCurve::setStyle(CurveStyle style)
261
if ( style != d_data->style )
263
d_data->style = style;
269
\brief Return the current style
272
QwtPlotCurve::CurveStyle QwtPlotCurve::style() const
274
return d_data->style;
278
\brief Assign a symbol
282
void QwtPlotCurve::setSymbol(const QwtSymbol &symbol )
284
delete d_data->symbol;
285
d_data->symbol = symbol.clone();
290
\brief Return the current symbol
293
const QwtSymbol &QwtPlotCurve::symbol() const
295
return *d_data->symbol;
303
void QwtPlotCurve::setPen(const QPen &pen)
305
if ( pen != d_data->pen )
313
\brief Return the pen used to draw the lines
314
\sa setPen(), brush()
316
const QPen& QwtPlotCurve::pen() const
322
\brief Assign a brush.
323
In case of brush.style() != QBrush::NoBrush
324
and style() != QwtPlotCurve::Sticks
325
the area between the curve and the baseline will be filled.
326
In case !brush.color().isValid() the area will be filled by
327
pen.color(). The fill algorithm simply connects the first and the
328
last curve point to the baseline. So the curve data has to be sorted
329
(ascending or descending).
330
\param brush New brush
331
\sa brush(), setBaseline(), baseline()
333
void QwtPlotCurve::setBrush(const QBrush &brush)
335
if ( brush != d_data->brush )
337
d_data->brush = brush;
343
\brief Return the brush used to fill the area between lines and the baseline
344
\sa setBrush(), setBaseline(), baseline()
346
const QBrush& QwtPlotCurve::brush() const
348
return d_data->brush;
353
Set data by copying x- and y-values from specified memory blocks.
354
Contrary to setCurveRawData(), this function makes a 'deep copy' of
357
\param xData pointer to x values
358
\param yData pointer to y values
359
\param size size of xData and yData
363
void QwtPlotCurve::setData(const double *xData, const double *yData, int size)
366
d_xy = new QwtArrayData(xData, yData, size);
371
\brief Initialize data with x- and y-arrays (explicitly shared)
378
void QwtPlotCurve::setData(const QwtArray<double> &xData,
379
const QwtArray<double> &yData)
382
d_xy = new QwtArrayData(xData, yData);
387
Initialize data with an array of points (explicitly shared).
392
#if QT_VERSION < 0x040000
393
void QwtPlotCurve::setData(const QwtArray<QwtDoublePoint> &data)
395
void QwtPlotCurve::setData(const QPolygonF &data)
399
d_xy = new QwtPolygonFData(data);
404
Initialize data with a pointer to QwtData.
409
void QwtPlotCurve::setData(const QwtData &data)
417
\brief Initialize the data by pointing to memory blocks which are not managed
420
setRawData is provided for efficiency. It is important to keep the pointers
421
during the lifetime of the underlying QwtCPointerData class.
423
\param xData pointer to x data
424
\param yData pointer to y data
425
\param size size of x and y
427
\sa QwtCPointerData::setData.
429
void QwtPlotCurve::setRawData(const double *xData, const double *yData, int size)
432
d_xy = new QwtCPointerData(xData, yData, size);
437
Returns the bounding rectangle of the curve data. If there is
438
no bounding rect, like for empty data the rectangle is invalid.
439
\sa QwtData::boundingRect(), QwtDoubleRect::isValid()
442
QwtDoubleRect QwtPlotCurve::boundingRect() const
445
return QwtDoubleRect(1.0, 1.0, -2.0, -2.0); // invalid
447
return d_xy->boundingRect();
451
\brief Draw the complete curve
453
\param painter Painter
454
\param xMap Maps x-values into pixel coordinates.
455
\param yMap Maps y-values into pixel coordinates.
457
\sa drawCurve(), drawSymbols()
459
void QwtPlotCurve::draw(QPainter *painter,
460
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
463
draw(painter, xMap, yMap, 0, -1);
467
\brief Draw a set of points of a curve.
469
When observing an measurement while it is running, new points have to be
470
added to an existing curve. drawCurve can be used to display them avoiding
471
a complete redraw of the canvas.
473
Setting plot()->canvas()->setAttribute(Qt::WA_PaintOutsidePaintEvent, true);
474
will result in faster painting, if the paint engine of the canvas widget
475
supports this feature.
477
\param from Index of the first point to be painted
478
\param to Index of the last point to be painted. If to < 0 the
479
curve will be painted to its last point.
481
\sa drawCurve(), drawSymbols()
483
void QwtPlotCurve::draw(int from, int to) const
488
QwtPlotCanvas *canvas = plot()->canvas();
490
#if QT_VERSION >= 0x040000
491
if ( canvas->paintEngine()->type() == QPaintEngine::OpenGL )
494
OpenGL alway repaint the complete widget.
495
So for this operation OpenGL is one of the slowest
502
if ( !canvas->testAttribute(Qt::WA_WState_InPaintEvent) &&
503
!canvas->testAttribute(Qt::WA_PaintOutsidePaintEvent) )
506
We save curve and range in helper and call repaint.
507
The helper filters the Paint event, to repeat
508
the QwtPlotCurve::draw, but now from inside the paint
512
QwtPlotCurvePaintHelper helper(this, from, to);
513
canvas->installEventFilter(&helper);
515
const bool noSystemBackground =
516
canvas->testAttribute(Qt::WA_NoSystemBackground);
517
canvas->setAttribute(Qt::WA_NoSystemBackground, true);
519
canvas->setAttribute(Qt::WA_NoSystemBackground, noSystemBackground);
525
const QwtScaleMap xMap = plot()->canvasMap(xAxis());
526
const QwtScaleMap yMap = plot()->canvasMap(yAxis());
528
if ( canvas->testPaintAttribute(QwtPlotCanvas::PaintCached) &&
529
canvas->paintCache() && !canvas->paintCache()->isNull() )
531
QPainter cachePainter((QPixmap *)canvas->paintCache());
532
cachePainter.translate(-canvas->contentsRect().x(),
533
-canvas->contentsRect().y());
535
draw(&cachePainter, xMap, yMap, from, to);
538
QPainter painter(canvas);
540
painter.setClipping(true);
541
painter.setClipRect(canvas->contentsRect());
543
draw(&painter, xMap, yMap, from, to);
547
\brief Draw an interval of the curve
548
\param painter Painter
549
\param xMap maps x-values into pixel coordinates.
550
\param yMap maps y-values into pixel coordinates.
551
\param from index of the first point to be painted
552
\param to index of the last point to be painted. If to < 0 the
553
curve will be painted to its last point.
555
\sa drawCurve(), drawSymbols(),
557
void QwtPlotCurve::draw(QPainter *painter,
558
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
559
int from, int to) const
561
if ( !painter || dataSize() <= 0 )
567
if ( verifyRange(dataSize(), from, to) > 0 )
570
painter->setPen(d_data->pen);
573
Qt 4.0.0 is slow when drawing lines, but it's even
574
slower when the painter has a brush. So we don't
575
set the brush before we really need it.
578
drawCurve(painter, d_data->style, xMap, yMap, from, to);
581
if (d_data->symbol->style() != QwtSymbol::NoSymbol)
584
drawSymbols(painter, *d_data->symbol, xMap, yMap, from, to);
591
\brief Draw the line part (without symbols) of a curve interval.
592
\param painter Painter
593
\param style curve style, see QwtPlotCurve::CurveStyle
596
\param from index of the first point to be painted
597
\param to index of the last point to be painted
598
\sa draw(), drawDots(), drawLines(), drawSteps(), drawSticks()
601
void QwtPlotCurve::drawCurve(QPainter *painter, int style,
602
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
603
int from, int to) const
608
if ( testCurveAttribute(Fitted) )
610
// we always need the complete
615
drawLines(painter, xMap, yMap, from, to);
618
drawSticks(painter, xMap, yMap, from, to);
621
drawSteps(painter, xMap, yMap, from, to);
624
drawDots(painter, xMap, yMap, from, to);
635
If the CurveAttribute Fitted is enabled a QwtCurveFitter tries
636
to interpolate/smooth the curve, before it is painted.
638
\param painter Painter
641
\param from index of the first point to be painted
642
\param to index of the last point to be painted
644
\sa setCurveAttribute(), setCurveFitter(), draw(),
645
drawLines(), drawDots(), drawSteps(), drawSticks()
647
void QwtPlotCurve::drawLines(QPainter *painter,
648
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
649
int from, int to) const
651
int size = to - from + 1;
656
if ( ( d_data->attributes & Fitted ) && d_data->curveFitter )
658
// Transform x and y values to window coordinates
659
// to avoid a distinction between linear and
660
// logarithmic scales.
662
#if QT_VERSION < 0x040000
663
QwtArray<QwtDoublePoint> points(size);
665
QPolygonF points(size);
667
for (int i = from; i <= to; i++)
669
QwtDoublePoint &p = points[i];
670
p.setX( xMap.xTransform(x(i)) );
671
p.setY( yMap.xTransform(y(i)) );
674
points = d_data->curveFitter->fitCurve(points);
675
size = points.size();
680
// Round QwtDoublePoints to QPoints
681
// When Qwt support for Qt3 has been dropped (Qwt 6.x)
682
// we will use a doubles for painting and the following
683
// step will be obsolete.
685
polyline.resize(size);
687
const QwtDoublePoint *p = points.data();
688
QPoint *pl = polyline.data();
689
if ( d_data->paintAttributes & PaintFiltered )
692
QPoint pp(qRound(p[0].x()), qRound(p[0].y()));
696
for (int i = 1; i < size; i++)
698
const QPoint pi(qRound(p[i].x()), qRound(p[i].y()));
706
polyline.resize(count);
710
for ( int i = 0; i < size; i++ )
712
pl[i].setX( qRound(p[i].x()) );
713
pl[i].setY( qRound(p[i].y()) );
719
polyline.resize(size);
721
if ( d_data->paintAttributes & PaintFiltered )
723
QPoint pp( xMap.transform(x(from)), yMap.transform(y(from)) );
724
polyline.setPoint(0, pp);
727
for (int i = from + 1; i <= to; i++)
729
const QPoint pi(xMap.transform(x(i)), yMap.transform(y(i)));
732
polyline.setPoint(count, pi);
739
polyline.resize(count);
743
for (int i = from; i <= to; i++)
745
int xi = xMap.transform(x(i));
746
int yi = yMap.transform(y(i));
748
polyline.setPoint(i - from, xi, yi);
753
if ( d_data->paintAttributes & ClipPolygons )
754
polyline = QwtClipper::clipPolygon(painter->window(), polyline);
756
QwtPainter::drawPolyline(painter, polyline);
758
if ( d_data->brush.style() != Qt::NoBrush )
759
fillCurve(painter, xMap, yMap, polyline);
765
\param painter Painter
768
\param from index of the first point to be painted
769
\param to index of the last point to be painted
771
\sa draw(), drawCurve(), drawDots(), drawLines(), drawSteps()
773
void QwtPlotCurve::drawSticks(QPainter *painter,
774
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
775
int from, int to) const
777
int x0 = xMap.transform(d_data->reference);
778
int y0 = yMap.transform(d_data->reference);
780
for (int i = from; i <= to; i++)
782
const int xi = xMap.transform(x(i));
783
const int yi = yMap.transform(y(i));
785
if (d_data->curveType == Xfy)
786
QwtPainter::drawLine(painter, x0, yi, xi, yi);
788
QwtPainter::drawLine(painter, xi, y0, xi, yi);
795
\param painter Painter
798
\param from index of the first point to be painted
799
\param to index of the last point to be painted
801
\sa draw(), drawCurve(), drawSticks(), drawLines(), drawSteps()
803
void QwtPlotCurve::drawDots(QPainter *painter,
804
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
805
int from, int to) const
807
const QRect window = painter->window();
808
if ( window.isEmpty() )
811
const bool doFill = d_data->brush.style() != Qt::NoBrush;
815
polyline.resize(to - from + 1);
817
if ( to > from && d_data->paintAttributes & PaintFiltered )
821
QPoint pp( xMap.transform(x(from)), yMap.transform(y(from)) );
823
QwtPainter::drawPoint(painter, pp.x(), pp.y());
824
polyline.setPoint(0, pp);
827
for (int i = from + 1; i <= to; i++)
829
const QPoint pi(xMap.transform(x(i)), yMap.transform(y(i)));
832
QwtPainter::drawPoint(painter, pi.x(), pi.y());
834
polyline.setPoint(count, pi);
840
if ( int(polyline.size()) != count )
841
polyline.resize(count);
845
// if we don't need to fill, we can sort out
846
// duplicates independent from the order
848
PrivateData::PixelMatrix pixelMatrix(window);
850
for (int i = from; i <= to; i++)
852
const QPoint p( xMap.transform(x(i)),
853
yMap.transform(y(i)) );
855
if ( pixelMatrix.testPixel(p) )
856
QwtPainter::drawPoint(painter, p.x(), p.y());
862
for (int i = from; i <= to; i++)
864
const int xi = xMap.transform(x(i));
865
const int yi = yMap.transform(y(i));
866
QwtPainter::drawPoint(painter, xi, yi);
869
polyline.setPoint(i - from, xi, yi);
875
if ( d_data->paintAttributes & ClipPolygons )
876
polyline = QwtClipper::clipPolygon(painter->window(), polyline);
878
fillCurve(painter, xMap, yMap, polyline);
885
The direction of the steps depends on Inverted attribute.
887
\param painter Painter
890
\param from index of the first point to be painted
891
\param to index of the last point to be painted
893
\sa CurveAttribute, setCurveAttribute(),
894
draw(), drawCurve(), drawDots(), drawLines(), drawSticks()
896
void QwtPlotCurve::drawSteps(QPainter *painter,
897
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
898
int from, int to) const
900
QwtPolygon polyline(2 * (to - from) + 1);
902
bool inverted = d_data->curveType == Yfx;
903
if ( d_data->attributes & Inverted )
904
inverted = !inverted;
907
for (i = from, ip = 0; i <= to; i++, ip += 2)
909
const int xi = xMap.transform(x(i));
910
const int yi = yMap.transform(y(i));
915
polyline.setPoint(ip - 1, polyline[ip-2].x(), yi);
917
polyline.setPoint(ip - 1, xi, polyline[ip-2].y());
920
polyline.setPoint(ip, xi, yi);
923
if ( d_data->paintAttributes & ClipPolygons )
924
polyline = QwtClipper::clipPolygon(painter->window(), polyline);
926
QwtPainter::drawPolyline(painter, polyline);
928
if ( d_data->brush.style() != Qt::NoBrush )
929
fillCurve(painter, xMap, yMap, polyline);
934
\brief Specify an attribute for drawing the curve
936
The attributes can be used to modify the drawing style.
937
The following attributes are defined:<dl>
939
<dd>For Lines only. A QwtCurveFitter tries to
940
interpolate/smooth the curve, before it is painted.
941
Note that curve fitting requires temorary memory
942
for calculating coefficients and additional points.
943
If painting in Fitted mode is slow it might be better
944
to fit the points, before they are passed to QwtPlotCurve.
947
<dd>For Steps only. Draws a step function
948
from the right to the left.</dd></dl>
950
\param attribute Curve attribute
953
/sa testCurveAttribute(), setCurveFitter()
955
void QwtPlotCurve::setCurveAttribute(CurveAttribute attribute, bool on)
957
if ( bool(d_data->attributes & attribute) == on )
961
d_data->attributes |= attribute;
963
d_data->attributes &= ~attribute;
969
\return true, if attribute is enabled
970
\sa setCurveAttribute()
972
bool QwtPlotCurve::testCurveAttribute(CurveAttribute attribute) const
974
return d_data->attributes & attribute;
978
Assign the curve type
980
<dt>QwtPlotCurve::Yfx
981
<dd>Draws y as a function of x (the default). The
982
baseline is interpreted as a horizontal line
983
with y = baseline().</dd>
984
<dt>QwtPlotCurve::Xfy
985
<dd>Draws x as a function of y. The baseline is
986
interpreted as a vertical line with x = baseline().</dd>
988
The baseline is used for aligning the sticks, or
989
filling the curve with a brush.
993
void QwtPlotCurve::setCurveType(CurveType curveType)
995
if ( d_data->curveType != curveType )
997
d_data->curveType = curveType;
1003
Return the curve type
1006
QwtPlotCurve::CurveType QwtPlotCurve::curveType() const
1008
return d_data->curveType;
1011
void QwtPlotCurve::setCurveFitter(QwtCurveFitter *curveFitter)
1013
delete d_data->curveFitter;
1014
d_data->curveFitter = curveFitter;
1019
QwtCurveFitter *QwtPlotCurve::curveFitter() const
1021
return d_data->curveFitter;
1025
Fill the area between the curve and the baseline with
1028
\param painter Painter
1033
\sa setBrush(), setBaseline(), setCurveType()
1036
void QwtPlotCurve::fillCurve(QPainter *painter,
1037
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
1038
QwtPolygon &pa) const
1040
if ( d_data->brush.style() == Qt::NoBrush )
1043
closePolyline(xMap, yMap, pa);
1044
if ( pa.count() <= 2 ) // a line can't be filled
1047
QBrush b = d_data->brush;
1048
if ( !b.color().isValid() )
1049
b.setColor(d_data->pen.color());
1053
painter->setPen(QPen(Qt::NoPen));
1054
painter->setBrush(b);
1056
QwtPainter::drawPolygon(painter, pa);
1062
\brief Complete a polygon to be a closed polygon
1063
including the area between the original polygon
1067
\param pa Polygon to be completed
1070
void QwtPlotCurve::closePolyline(
1071
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
1072
QwtPolygon &pa) const
1074
const int sz = pa.size();
1080
if ( d_data->curveType == QwtPlotCurve::Xfy )
1083
xMap.transform(d_data->reference), pa.point(sz - 1).y());
1085
xMap.transform(d_data->reference), pa.point(0).y());
1090
pa.point(sz - 1).x(), yMap.transform(d_data->reference));
1091
pa.setPoint(pa.size() - 1,
1092
pa.point(0).x(), yMap.transform(d_data->reference));
1098
\param painter Painter
1099
\param symbol Curve symbol
1102
\param from index of the first point to be painted
1103
\param to index of the last point to be painted
1105
\sa setSymbol(), draw(), drawCurve()
1107
void QwtPlotCurve::drawSymbols(QPainter *painter, const QwtSymbol &symbol,
1108
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
1109
int from, int to) const
1111
painter->setBrush(symbol.brush());
1112
painter->setPen(symbol.pen());
1115
rect.setSize(QwtPainter::metricsMap().screenToLayout(symbol.size()));
1117
if ( to > from && d_data->paintAttributes & PaintFiltered )
1119
const QRect window = painter->window();
1120
if ( window.isEmpty() )
1123
PrivateData::PixelMatrix pixelMatrix(window);
1125
for (int i = from; i <= to; i++)
1127
const QPoint pi( xMap.transform(x(i)),
1128
yMap.transform(y(i)) );
1130
if ( pixelMatrix.testPixel(pi) )
1132
rect.moveCenter(pi);
1133
symbol.draw(painter, rect);
1139
for (int i = from; i <= to; i++)
1141
const int xi = xMap.transform(x(i));
1142
const int yi = yMap.transform(y(i));
1144
rect.moveCenter(QPoint(xi, yi));
1145
symbol.draw(painter, rect);
1151
\brief Set the value of the baseline
1153
The baseline is needed for filling the curve with a brush or
1154
the Sticks drawing style.
1155
The default value is 0.0. The interpretation
1156
of the baseline depends on the CurveType. With QwtPlotCurve::Yfx,
1157
the baseline is interpreted as a horizontal line at y = baseline(),
1158
with QwtPlotCurve::Yfy, it is interpreted as a vertical line at
1160
\param reference baseline
1161
\sa baseline(), setBrush(), setStyle(), setCurveType()
1163
void QwtPlotCurve::setBaseline(double reference)
1165
if ( d_data->reference != reference )
1167
d_data->reference = reference;
1173
Return the value of the baseline
1176
double QwtPlotCurve::baseline() const
1178
return d_data->reference;
1182
Return the size of the data arrays
1185
int QwtPlotCurve::dataSize() const
1187
return d_xy->size();
1190
int QwtPlotCurve::closestPoint(const QPoint &pos, double *dist) const
1192
if ( plot() == NULL || dataSize() <= 0 )
1195
const QwtScaleMap xMap = plot()->canvasMap(xAxis());
1196
const QwtScaleMap yMap = plot()->canvasMap(yAxis());
1199
double dmin = 1.0e10;
1201
for (int i=0; i < dataSize(); i++)
1203
const double cx = xMap.xTransform(x(i)) - pos.x();
1204
const double cy = yMap.xTransform(y(i)) - pos.y();
1206
const double f = qwtSqr(cx) + qwtSqr(cy);
1219
//! Update the widget that represents the curve on the legend
1220
void QwtPlotCurve::updateLegend(QwtLegend *legend) const
1225
QwtPlotItem::updateLegend(legend);
1227
QWidget *widget = legend->find(this);
1228
if ( !widget || !widget->inherits("QwtLegendItem") )
1231
QwtLegendItem *legendItem = (QwtLegendItem *)widget;
1233
#if QT_VERSION < 0x040000
1234
const bool doUpdate = legendItem->isUpdatesEnabled();
1236
const bool doUpdate = legendItem->updatesEnabled();
1238
legendItem->setUpdatesEnabled(false);
1240
const int policy = legend->displayPolicy();
1242
if (policy == QwtLegend::FixedIdentifier)
1244
int mode = legend->identifierMode();
1246
if (mode & QwtLegendItem::ShowLine)
1247
legendItem->setCurvePen(pen());
1249
if (mode & QwtLegendItem::ShowSymbol)
1250
legendItem->setSymbol(symbol());
1252
if (mode & QwtLegendItem::ShowText)
1253
legendItem->setText(title());
1255
legendItem->setText(QwtText());
1257
legendItem->setIdentifierMode(mode);
1259
else if (policy == QwtLegend::AutoIdentifier)
1263
if (QwtPlotCurve::NoCurve != style())
1265
legendItem->setCurvePen(pen());
1266
mode |= QwtLegendItem::ShowLine;
1268
if (QwtSymbol::NoSymbol != symbol().style())
1270
legendItem->setSymbol(symbol());
1271
mode |= QwtLegendItem::ShowSymbol;
1273
if ( !title().isEmpty() )
1275
legendItem->setText(title());
1276
mode |= QwtLegendItem::ShowText;
1280
legendItem->setText(QwtText());
1282
legendItem->setIdentifierMode(mode);
1285
legendItem->setUpdatesEnabled(doUpdate);
1286
legendItem->update();