一:先上效果图,横轴纵轴可以根据需求显示任意文本,每个样本点也可以显示成任意形状
二:横纵轴显示任意文本实现:
QwtPlot类提供如下函数,用于设置坐标轴文本显示。
void setAxisScaleDraw( int axisId, QwtScaleDraw * );
所以通过继承QwtScaleDraw类,重写下面的虚函数,按照自定义的规则返回文本。
virtual QwtText label(double v) const;
具体实现,将坐标轴的文本放到list里,挨个取值:
#pragma once
#include "qwt_scale_draw.h"
class CustomScakeDraw : public QwtScaleDraw
{
public:
//scale:文本标签数组 labelRotation:斜率
CustomScakeDraw(const QList& scale, double labelRotation = 0) : m_scale(scale)
{
setLabelRotation(labelRotation);
}
virtual QwtText label(double v) const
{
QString text;
int value = v;
if (value >= 0 && value < m_scale.size())
{
text = m_scale[value];
}
return text;
}
private:
QList m_scale;
};
使用示例:
//设置Y轴坐标
QList valueY{"A", "B", "C", "D", "E", "F", "G"};
ui->plot->setAxisScale(QwtPlot::yLeft, 0, valueY.size() - 1, 1); //从0开始,步长为1,若从负数开始,则要加个偏移量,可在CustomScakeDraw类中加
ui->plot->setAxisMaxMinor(QwtPlot::yLeft, 0); //取消小格
ui->plot->setAxisScaleDraw(QwtPlot::yLeft, new CustomScakeDraw(valueY));
三:同一条曲线显示多种形状样本点
QwtPlotCurve类提供了设置样本点形状的函数:void setSymbol( QwtSymbol* );,但是只支持同一条曲线所有样本点的形状都一致。若要在同一条曲线上根据样本点的值显示不同的形状,就需要继承QwtPlotCurve类。
实现:
1)增加接口:setSymbols
//CustomPlotCurve 继承于 QwtPlotCurve
void CustomPlotCurve::setSymbols(QVector symbols)
{
for (int i = 0; i < d_data->symbols.size(); i++)
{
QwtSymbol* temp = d_data->symbols[i];
delete temp;
d_data->symbols[i] = NULL;
}
d_data->symbols = symbols;
qwtUpdateLegendIconSize(this);
legendChanged();
itemChanged();
}
2)重载drawSeries
void CustomPlotCurve::drawSeries( QPainter* painter,
const QwtScaleMap& xMap, const QwtScaleMap& yMap,
const QRectF& canvasRect, int from, int to ) const
{
const size_t numSamples = dataSize();
if ( !painter || numSamples <= 0 )
{
return;
}
if ( to < 0 )
{
to = numSamples - 1;
}
if ( qwtVerifyRange( numSamples, from, to ) > 0 )
{
painter->save();
painter->setPen( d_data->pen );
drawCurve( painter, d_data->style, xMap, yMap, canvasRect, from, to );
painter->restore();
if(d_data->symbols.size() > 0)
{
for (int i = from; i <= to; i++)
{
if (i >= d_data->symbols.size())
{
break;
}
if (d_data->symbols[i]->style() != QwtSymbol::NoSymbol)
{
painter->save();
drawSymbols(painter, *d_data->symbols[i], xMap, yMap, canvasRect, i, i);
painter->restore();
}
}
}
else
{
if (d_data->symbol && ( d_data->symbol->style() != QwtSymbol::NoSymbol ))
{
painter->save();
drawSymbols( painter, *d_data->symbol, xMap, yMap, canvasRect, i, to );
painter->restore();
}
}
}
}
3)样本点画任意图形
QwtSymbol类提供了一些常用的图形,若不能满足需求,则需要自定义。
可用圈中的构造函数,先使用QPainterPath画好图,传给构造函数
4)使用示例
QVector& symbols;
for(int i = 0; i < 10; i++)
{
if(i % 2 == 0)
{
symbols << new QwtSymbol(QwtSymbol::Ellipse, QBrush(color), QPen(color, 1), QSize(diameter, diameter));
}
else
{
QPainterPath path;
//使用path画任意图形
.
.
.
symbols << new QwtSymbol(path, QBrush(Qt::white), QPen(Qt::blue, 1));
}
}
CustomPlotCurve* curve = new CustomPlotCurve;
//各种设置
.
.
.
curve->setSymbols(symbols); //添加样本点形状