Qwt绘制柱形图
该示例包含以下功能:
1.使用qwt绘制柱形图
2.绘制横向、纵向柱形图
3.柱形图上显示柱子值
程序如下:
新建一个Qt Application项目,命名为QwtBarEg,Base class选择Qwidget,
然后添加一个Widget部件,
然后添加一个Qt5Class类,命名为MyBarChart,Base class为QwtPlot,Constructor signature选择Qwidget *parent。
然后定义一个C++头文件defineclass.h
mybarchart头文件内容如下:
#ifndef MYBARCHART_H
#define MYBARCHART_H
#include "QWT\qwt_plot.h"
#include "QWT\qwt_plot_multi_barchart.h"
#include "defineclass.h"
class MyBarChart : public QwtPlot
{
Q_OBJECT
public:
MyBarChart(QWidget *parent=NULL);
~MyBarChart();
public:
GJHPlotMultiBarChart *multiBarChart;
void InitBarChat(int Oritention, QVector< QVector<double> > series, QStringList m_list);
void setOrientation(int orientation, QStringList m_list);
};
#endif // MYBARCHART_H
mybarchart源文件内容如下:
#include "mybarchart.h"
#include "QWT\qwt_plot_canvas.h"
#include "QWT\qwt_plot_multi_barchart.h"
#include "QWT\qwt_column_symbol.h"
#include "QWT\qwt_legend.h"
#include "QWT\qwt_scale_draw.h"
#include "QWT\qwt_plot_layout.h"
//自定义一个bar类型继承自QwtPlot
MyBarChart::MyBarChart(QWidget *parent)
: QwtPlot(parent)
{
setAutoFillBackground(true);
setPalette(Qt::white); //设置部件背景色
canvas()->setPalette(Qt::darkCyan); //设置绘图区域背景色
setTitle("Bar Chart");
multiBarChart = new GJHPlotMultiBarChart();
multiBarChart->setLayoutPolicy(QwtPlotMultiBarChart::AutoAdjustSamples);
multiBarChart->setSpacing(20); //每组之间的间隔
multiBarChart->setMargin(0);
multiBarChart->attach(this);
insertLegend(new QwtLegend());
setAutoReplot(true);
}
MyBarChart::~MyBarChart()
{
}
//参数1相当于二维数组,表示每组每个柱子的值;参数2每组柱子标签
void MyBarChart::InitBarChat(int Oritention, QVector< QVector<double> > series, QStringList m_list)
{
const int numBars = sizeof(colors) / sizeof(colors[0]);
//图例名称和大小
QList<QwtText> titles;
for (int i = 0; i < numBars; i++)
{
QString title("Bar %1");
titles += title.arg(i);
}
multiBarChart->setBarTitles(titles);
multiBarChart->setLegendIconSize(QSize(10, 14));
//图例样式
for (int i = 0; i < numBars; i++)
{
QwtColumnSymbol *symbol = new QwtColumnSymbol(QwtColumnSymbol::Box);
symbol->setLineWidth(2);
symbol->setFrameStyle(QwtColumnSymbol::Raised);
symbol->setPalette(QPalette(colors[i]));
multiBarChart->setSymbol(i, symbol);
}
//设置每组柱子的值
multiBarChart->m_barValue.clear();
multiBarChart->m_barValue = series; //柱状图上方显示的值
multiBarChart->setSamples(series);
setOrientation(Oritention, m_list);
}
void MyBarChart::setOrientation(int orientation, QStringList m_list)
{
QwtPlot::Axis axis1, axis2;
if (orientation == 0)
{
axis1 = QwtPlot::xBottom;
axis2 = QwtPlot::yLeft;
multiBarChart->setOrientation(Qt::Vertical);
}
else
{
axis1 = QwtPlot::yLeft;
axis2 = QwtPlot::xBottom;
multiBarChart->setOrientation(Qt::Horizontal);
}
QStringList d_distros = m_list;
setAxisScale(axis1, 0, multiBarChart->dataSize() - 1, 1.0);
setAxisAutoScale(axis2);
setAxisScaleDraw(axis1, new DistroScaleDraw((Qt::Orientation)orientation, d_distros));
setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignCenter | Qt::AlignBottom);
//绘制刻度线
QwtScaleDraw *scaleDraw1 = axisScaleDraw(axis1);
scaleDraw1->enableComponent(QwtScaleDraw::Backbone, false); //刻度基线
scaleDraw1->enableComponent(QwtScaleDraw::Ticks, false); //刻度线
QwtScaleDraw *scaleDraw2 = axisScaleDraw(axis2);
scaleDraw2->enableComponent(QwtScaleDraw::Backbone, true);
scaleDraw2->enableComponent(QwtScaleDraw::Ticks, true);
//为指定的轴线设置排列画布到轴线比例尺
plotLayout()->setAlignCanvasToScale(axis1, true);
plotLayout()->setAlignCanvasToScale(axis2, false);
plotLayout()->setCanvasMargin(0);
replot();
}
defindeclass.h头文件内容如下:
#include "QWT\qwt_plot_canvas.h"
#include "QWT\qwt_plot_multi_barchart.h"
#include "QWT\qwt_column_symbol.h"
#include "QWT\qwt_legend.h"
#include "QWT\qwt_scale_draw.h"
#include "QWT\qwt_plot_layout.h"
//设置柱形图的颜色
static const char *colors[] = { "DarkOrchid", "SteelBlue", "Gold" };
//设置柱形图的X轴刻度
class DistroScaleDraw : public QwtScaleDraw
{
public:
DistroScaleDraw(Qt::Orientation orientation, const QStringList &labels)
: d_labels(labels)
{
//设置间距、中间刻度、主刻度
setTickLength(QwtScaleDiv::MinorTick, 0);
setTickLength(QwtScaleDiv::MediumTick, 0);
setTickLength(QwtScaleDiv::MajorTick, 2);
//设置旋转角度、对齐方式
setLabelRotation(0);
setLabelAlignment(Qt::AlignLeft | Qt::AlignVCenter);
}
//The value is converted to a plain text using QLocale::system().toString(value).
//This method is often overloaded by applications to have individual labels.
virtual QwtText label(double value) const
{
QString text;
int val = value;
if (val >= 0 && val < d_labels.size())
{
text = d_labels[val];
}
return text; //只能显示英文
}
以下方法可以显示中文
//virtual QwtText label(double value) const
//{
// //QT默认编码为unicode,不能显示中文,使用formLocal8Bit函数可以实现本地字符集GB到unicode的转换
// //从而处理中文乱码问题
// return QString::fromLocal8Bit(" ");
//}
//
此处是绘制X轴刻度
//virtual void drawLabel(QPainter *painter, double val) const
//{
// QFont font(QStringLiteral("宋体"), 12, 0);
// QRectF rect = this->labelRect(font, val);
// QString text("");
// int index = qRound(val);
// if (index >= 0 && index < d_labels.size())
// text = d_labels[index];
// QFontMetrics fm(font);
// int width = fm.width(text);
// //获取左边的坐标
// int x = (rect.width() - width) / 2;
// QPointF point = this->labelPosition(val);
// int left = point.x() - rect.width() / 2 + x;
// painter->drawText(QRect(left, point.y(), rect.width()-x , rect.height()), Qt::AlignLeft, text);
//}
private:
QStringList d_labels;
};
//绘制柱子及柱形图的柱子的值
class ColumnSymbol : public QwtColumnSymbol
{
public:
ColumnSymbol(int hit, QColor color) : QwtColumnSymbol()
{
d_hit = hit;
d_color = color;
}
//绘制柱形图,代码画矩形,添加标签
virtual void draw(QPainter *p, const QwtColumnRect &rect) const
{
QRectF rect2 = rect.toRect();
p->setBrush(d_color);
p->setPen(d_color);
p->drawRect(rect.toRect());
QColor tempColor = QColor("black");
p->setPen(tempColor);
int top = rect2.top();
int height = rect2.height();
Qt::Alignment alignment;
alignment = Qt::AlignTop | Qt::AlignHCenter;
p->drawText(QRect(rect2.left() + 1, top, rect2.width() + 2, height), alignment, QString::number(d_hit));
}
private:
int d_hit;
QColor d_color;
};
//每组多个柱形图
class GJHPlotMultiBarChart :public QwtPlotMultiBarChart
{
public:
GJHPlotMultiBarChart(const QString &title = QString::null) : QwtPlotMultiBarChart()
{
}
QVector< QVector<double> > m_barValue; //存储多组
QwtColumnSymbol* specialSymbol(int sampleIndex, int valueIndex) const
{
ColumnSymbol *pSymbol = new ColumnSymbol(m_barValue[sampleIndex][valueIndex], colors[valueIndex]);
return pSymbol;
}
};
然后利用上面的类绘制柱形图
在qwtbareg.h中添加#include "mybarchart.h"头文件,然后添加类对象和函数
MyBarChart *myBarChart;
void Init(QString xlabel, QString ylabel);
void PrepareData();
在qwtbareg.cpp中添加上述函数的定义
void QwtBarEg::Init(QString xlabel, QString ylabel)
{
//初始化类对象
myBarChart = new MyBarChart();
//添加坐标轴的标题
myBarChart->setAxisTitle(QwtPlot::xBottom, xlabel);
myBarChart->setAxisTitle(QwtPlot::yLeft, ylabel);
//设置布局
QHBoxLayout *layout = new QHBoxLayout();
layout->setMargin(0);
layout->setContentsMargins(QMargins(0, 0, 0, 0));
layout->addWidget(myBarChart);
ui.widget->setLayout(layout);
}
//产生数据
void QwtBarEg::PrepareData()
{
QVector< QVector<double> > values;
QStringList strList;
int oritention = 1; //1:绘制横向柱形图;0:绘制纵向柱形图
qsrand(QTime::currentTime().second()); //随机数种子
for (int i = 0; i < 5; i++)
{
QVector<double> val;
for (int j = 0; j < 3; j++)
{
double randomData = 20 + (qrand() % 30); //随机数
val += randomData;
}
values += val; //添加每组的多个值
strList += QString("Group %1").arg(i); //每组柱形图的标签
}
myBarChart->InitBarChat(oritention, values, strList);
}