📄 qwt_plot_curve.cpp
字号:
}
}
else
{
for (int i = from; i <= to; i++)
{
const int xi = xMap.transform(x(i));
const int yi = yMap.transform(y(i));
QwtPainter::drawPoint(painter, xi, yi);
if ( doFill )
polyline.setPoint(i - from, xi, yi);
}
}
if ( doFill )
{
if ( d_data->paintAttributes & ClipPolygons )
{
const QwtRect r = painter->window();
polyline = r.clip(polyline);
}
fillCurve(painter, xMap, yMap, polyline);
}
}
/*!
Draw step function
The direction of the steps depends on Inverted attribute.
\param painter Painter
\param xMap x map
\param yMap y map
\param from index of the first point to be painted
\param to index of the last point to be painted
\sa CurveAttribute, setCurveAttribute(),
draw(), drawCurve(), drawDots(), drawLines(), drawSticks()
*/
void QwtPlotCurve::drawSteps(QPainter *painter,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
int from, int to) const
{
QwtPolygon polyline(2 * (to - from) + 1);
bool inverted = d_data->attributes & Yfx;
if ( d_data->attributes & Inverted )
inverted = !inverted;
int i,ip;
for (i = from, ip = 0; i <= to; i++, ip += 2)
{
const int xi = xMap.transform(x(i));
const int yi = yMap.transform(y(i));
if ( ip > 0 )
{
if (inverted)
polyline.setPoint(ip - 1, polyline[ip-2].x(), yi);
else
polyline.setPoint(ip - 1, xi, polyline[ip-2].y());
}
polyline.setPoint(ip, xi, yi);
}
if ( d_data->paintAttributes & ClipPolygons )
{
const QwtRect r = painter->window();
polyline = r.clip(polyline);
}
QwtPainter::drawPolyline(painter, polyline);
if ( d_data->brush.style() != Qt::NoBrush )
fillCurve(painter, xMap, yMap, polyline);
}
/*!
\brief Specify an attribute for drawing the curve
The attributes can be used to modify the drawing style.
The following attributes are defined:<dl>
<dt>Fitted</dt>
<dd>For Lines only. A QwtCurveFitter tries to
interpolate/smooth the curve, before it is painted.
Note that curve fitting requires temorary memory
for calculating coefficients and additional points.
If painting in Fitted mode is slow it might be better
to fit the points, before they are passed to QwtPlotCurve.
</dd>
<dt>Inverted</dt>
<dd>For Steps only. Draws a step function
from the right to the left.</dd></dl>
\param attribute Curve attribute
\param on On/Off
/sa testCurveAttribute(), setCurveFitter()
*/
void QwtPlotCurve::setCurveAttribute(CurveAttribute attribute, bool on)
{
if ( bool(d_data->attributes & attribute) == on )
return;
if ( on )
d_data->attributes |= attribute;
else
d_data->attributes &= ~attribute;
itemChanged();
}
/*!
Return the current curve attributes
\sa setCurveAttribute()
*/
bool QwtPlotCurve::testCurveAttribute(CurveAttribute attribute) const
{
return d_data->attributes & attribute;
}
/*!
Assign the curve type
<dt>QwtPlotCurve::Yfx
<dd>Draws y as a function of x (the default). The
baseline is interpreted as a horizontal line
with y = baseline().</dd>
<dt>QwtPlotCurve::Xfy
<dd>Draws x as a function of y. The baseline is
interpreted as a vertical line with x = baseline().</dd>
The baseline is used for aligning the sticks, or
filling the curve with a brush.
\sa curveType()
*/
void QwtPlotCurve::setCurveType(CurveType curveType)
{
if ( d_data->curveType != curveType )
{
d_data->curveType = curveType;
itemChanged();
}
}
/*!
Return the curve type
\sa setCurveType()
*/
QwtPlotCurve::CurveType QwtPlotCurve::curveType() const
{
return d_data->curveType;
}
void QwtPlotCurve::setCurveFitter(QwtCurveFitter *curveFitter)
{
delete d_data->curveFitter;
d_data->curveFitter = curveFitter;
itemChanged();
}
QwtCurveFitter *QwtPlotCurve::curveFitter() const
{
return d_data->curveFitter;
}
/*!
Fill the area between the curve and the baseline with
the curve brush
\param painter Painter
\param xMap x map
\param yMap y map
\param pa Polygon
\sa setBrush(), setBaseline(), setCurveType()
*/
void QwtPlotCurve::fillCurve(QPainter *painter,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
QwtPolygon &pa) const
{
if ( d_data->brush.style() == Qt::NoBrush )
return;
closePolyline(xMap, yMap, pa);
if ( pa.count() <= 2 ) // a line can't be filled
return;
QBrush b = d_data->brush;
if ( !b.color().isValid() )
b.setColor(d_data->pen.color());
painter->save();
painter->setPen(QPen(Qt::NoPen));
painter->setBrush(b);
QwtPainter::drawPolygon(painter, pa);
painter->restore();
}
/*!
\brief Complete a polygon to be a closed polygon
including the area between the original polygon
and the baseline.
\param xMap X map
\param yMap Y map
\param pa Polygon to be completed
*/
void QwtPlotCurve::closePolyline(
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
QwtPolygon &pa) const
{
const int sz = pa.size();
if ( sz < 2 )
return;
pa.resize(sz + 2);
if ( d_data->attributes & QwtPlotCurve::Xfy )
{
pa.setPoint(sz,
xMap.transform(d_data->reference), pa.point(sz - 1).y());
pa.setPoint(sz + 1,
xMap.transform(d_data->reference), pa.point(0).y());
}
else
{
pa.setPoint(sz,
pa.point(sz - 1).x(), yMap.transform(d_data->reference));
pa.setPoint(pa.size() - 1,
pa.point(0).x(), yMap.transform(d_data->reference));
}
}
/*!
\brief Draw symbols
\param painter Painter
\param symbol Curve symbol
\param xMap x map
\param yMap y map
\param from index of the first point to be painted
\param to index of the last point to be painted
\sa setSymbol(), draw(), drawCurve()
*/
void QwtPlotCurve::drawSymbols(QPainter *painter, const QwtSymbol &symbol,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
int from, int to) const
{
painter->setBrush(symbol.brush());
painter->setPen(symbol.pen());
QRect rect;
rect.setSize(QwtPainter::metricsMap().screenToLayout(symbol.size()));
if ( to > from && d_data->paintAttributes & PaintFiltered )
{
const QRect window = painter->window();
if ( window.isEmpty() )
return;
PrivateData::PixelMatrix pixelMatrix(window);
for (int i = from; i <= to; i++)
{
const QPoint pi( xMap.transform(x(i)),
yMap.transform(y(i)) );
if ( pixelMatrix.testPixel(pi) )
{
rect.moveCenter(pi);
symbol.draw(painter, rect);
}
}
}
else
{
for (int i = from; i <= to; i++)
{
const int xi = xMap.transform(x(i));
const int yi = yMap.transform(y(i));
rect.moveCenter(QPoint(xi, yi));
symbol.draw(painter, rect);
}
}
}
/*!
\brief Set the value of the baseline
The baseline is needed for filling the curve with a brush or
the Sticks drawing style.
The default value is 0.0. The interpretation
of the baseline depends on the CurveType. With QwtPlotCurve::Yfx,
the baseline is interpreted as a horizontal line at y = baseline(),
with QwtPlotCurve::Yfy, it is interpreted as a vertical line at
x = baseline().
\param reference baseline
\sa baseline(), setBrush(), setStyle(), setCurveType()
*/
void QwtPlotCurve::setBaseline(double reference)
{
if ( d_data->reference != reference )
{
d_data->reference = reference;
itemChanged();
}
}
/*!
Return the value of the baseline
\sa setBaseline
*/
double QwtPlotCurve::baseline() const
{
return d_data->reference;
}
/*!
Return the size of the data arrays
\sa setData()
*/
int QwtPlotCurve::dataSize() const
{
return d_xy->size();
}
int QwtPlotCurve::closestPoint(const QPoint &pos, double *dist) const
{
if ( plot() == NULL || dataSize() <= 0 )
return -1;
const QwtScaleMap xMap = plot()->canvasMap(xAxis());
const QwtScaleMap yMap = plot()->canvasMap(yAxis());
int index = -1;
double dmin = 1.0e10;
for (int i=0; i < dataSize(); i++)
{
const double cx = xMap.xTransform(x(i)) - pos.x();
const double cy = yMap.xTransform(y(i)) - pos.y();
const double f = qwtSqr(cx) + qwtSqr(cy);
if (f < dmin)
{
index = i;
dmin = f;
}
}
if ( dist )
*dist = sqrt(dmin);
return index;
}
void QwtPlotCurve::updateLegend(QwtLegend *legend) const
{
if ( !legend )
return;
QwtPlotItem::updateLegend(legend);
QWidget *widget = legend->find(this);
if ( !widget || !widget->inherits("QwtLegendItem") )
return;
QwtLegendItem *legendItem = (QwtLegendItem *)widget;
#if QT_VERSION < 0x040000
const bool doUpdate = legendItem->isUpdatesEnabled();
#else
const bool doUpdate = legendItem->updatesEnabled();
#endif
legendItem->setUpdatesEnabled(false);
const int policy = legend->displayPolicy();
if (policy == QwtLegend::FixedIdentifier)
{
int mode = legend->identifierMode();
if (mode & QwtLegendItem::ShowLine)
legendItem->setCurvePen(pen());
if (mode & QwtLegendItem::ShowSymbol)
legendItem->setSymbol(symbol());
if (mode & QwtLegendItem::ShowText)
legendItem->setText(title());
else
legendItem->setText(QwtText());
legendItem->setIdentifierMode(mode);
}
else if (policy == QwtLegend::AutoIdentifier)
{
int mode = 0;
if (QwtPlotCurve::NoCurve != style())
{
legendItem->setCurvePen(pen());
mode |= QwtLegendItem::ShowLine;
}
if (QwtSymbol::NoSymbol != symbol().style())
{
legendItem->setSymbol(symbol());
mode |= QwtLegendItem::ShowSymbol;
}
if ( !title().isEmpty() )
{
legendItem->setText(title());
mode |= QwtLegendItem::ShowText;
}
else
{
legendItem->setText(QwtText());
}
legendItem->setIdentifierMode(mode);
}
legendItem->setUpdatesEnabled(doUpdate);
legendItem->update();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -