最近做个小界面,之前有用过qchart虽然比qwt好用一点,但是bug还是有那么些,总体还行吧。当前想实现的功能就是讲数据以柱状图的形式实现,并且在柱状图的顶部显示每个柱状图的数据,同时提供Tooltip功能。那么就开始说说如何创建吧。
1、首先定义实现qchart对象
m_char=new QChart();
m_char->setAnimationOptions(QChart::SeriesAnimations);//动画显示
2、接下来,定义实现 QBarSeries对象,记住一定要在构造函数中加m_char,这个对象实际上理解为就是你X轴S1,1、3号线的集合,
m_series=new QBarSeries(m_char);
3、然后就是建立XY轴了,
m_typeAxis = new QBarCategoryAxis();
//m_typeAxis->append(categories);
m_char->createDefaultAxes();//创建默认的左侧的坐标轴(根据 QBarSet 设置的值)
m_char->setAcceptTouchEvents(true);
m_char->setAxisX(m_typeAxis, m_series);//设置坐标轴
m_typeAxisY = new QValueAxis;
m_typeAxisY->setRange(0, 40);
// m_typeAxisY->setTickCount(10); //设置多少格
//m_typeAxisY->setMinorTickCount(5); //设置每格小刻度线的数目
m_char->setAxisY(m_typeAxisY, m_series);
4、生成 QChartView对象,将m_char加入其中;
m_mybarView=new QChartView(m_char);
m_mybarView->setRenderHint(QPainter::Antialiasing);
5、将m_mybarView这个对象加入到你得布局当中即可。
m_barview=new MyBarView(bvp);
ui->barChartView->addWidget(m_barview->m_mybarView);
6、如果你要tooltip功能,你需要使用这样的信号与槽,
connect(m_series, SIGNAL(hovered(bool, int, QBarSet*)), this, SLOT(sltTooltip(bool, int, QBarSet*)));
void MyBarView::sltTooltip(bool status, int index, QBarSet *barset)
{
if (m_tooltip == 0)
m_tooltip = new ChartTip(m_char);
if (status) {
int yindex=m_barSetList.indexOf(barset);
double indexbarset=m_barSetList.indexOf(barset)-1;//m_categories是x轴坐标
indexbarset=indexbarset/6;
QBarSet *set=m_barSetList.at(yindex);
QString yname=set->label();
m_tooltip->setText("from:"+m_categories.at(index)+"\n to :"+yname+QString("\n人数: %2 ").arg(barset->at(index)));
QPointF point(index+indexbarset, barset->at(index));
qDebug()<<"index:"<<indexbarset<<index<< " "<<barset->at(index);
m_tooltip->setAnchor(point);
m_tooltip->setZValue(11);
m_tooltip->updateGeometry();
m_tooltip->show();
}
else {
m_tooltip->hide();
}
}
7、当然最重要还是如何将数据显示在柱状图的顶部了,其中最为重要的就是当你添加完数据后一定要使用
m_series->setLabelsPosition(QAbstractBarSeries::LabelsInsideEnd); // 设置数据系列标签的位置于数据柱内测上方
m_series->setLabelsVisible(true); // 设置显示数据系列标签
这两个操作。不然无法实现效果。
void MyBarView::addBar(QStringList CategoryNm,QVector<QVector<int> > setValList)
{
for(int i=0;i<CategoryNm.size();i++)
{
for(int j=0;j<setValList[i].size();j++)
{
m_barSetList[i]->append(setValList[i][j]);
}
m_series->append( m_barSetList[i]);
}
m_series->setLabelsPosition(QAbstractBarSeries::LabelsInsideEnd); // 设置数据系列标签的位置于数据柱内测上方
m_series->setLabelsVisible(true); // 设置显示数据系列标签
m_categories =CategoryNm;//m_categories是x轴坐标
m_typeAxis->append(m_categories);//
}
下面贴出了代码和实例图,
头文件
#ifndef MYBARVIEW_H
#define MYBARVIEW_H
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QLegend>
#include <QtCharts/QBarCategoryAxis>
#include"charttip.h"
#include"common.h"
class QGraphicsScene;
QT_CHARTS_BEGIN_NAMESPACE
class QChart;
QT_CHARTS_END_NAMESPACE
class Callout;
QT_CHARTS_USE_NAMESPACE
class MyBarView: public QGraphicsView
{
Q_OBJECT
public:
MyBarView(BarViewParam *bvp, QWidget *parent = 0);
void addBar(QStringList CategoryNm, QVector<QVector<int> > setValList);
public:
ChartTip* m_tooltip;
QChartView *m_mybarView;
QStringList m_categories;
QBarSeries *m_series;
QChart *m_char;
QVector<QBarSet*> m_barSetList;
QBarCategoryAxis *m_typeAxis;
QValueAxis* m_typeAxisY;
private:
public slots:
void sltTooltip(bool status, int index, QBarSet *barset);
void tooltip(QPointF point, bool state);
};
#endif // MYBARVIEW_H
.cpp文件
#include "mybarview.h"
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QLegend>
#include <QtCharts/QBarCategoryAxis>
#include"charttip.h"
#include"qobject.h"
MyBarView::MyBarView(BarViewParam *bvp,QWidget *parent)
: QGraphicsView(new QGraphicsScene, parent)
{
m_tooltip=0;
m_char=new QChart();
m_char->setAnimationOptions(QChart::SeriesAnimations);
m_series=new QBarSeries(m_char);
m_series->setLabelsVisible(true);
m_series->setLabelsPosition(QAbstractBarSeries::LabelsOutsideEnd);
for(int i=0;i<bvp->m_setsNameList.size();i++)
{
QBarSet *set0= new QBarSet(bvp->m_setsNameList[i]);
m_barSetList.append(set0);
//m_series->append(set0);
}
connect(m_series, SIGNAL(hovered(bool, int, QBarSet*)), this, SLOT(sltTooltip(bool, int, QBarSet*)));
//connect(m_series, SIGNAL(hovered(QPointF, bool)), this, SLOT(tooltip(QPointF,bool)));
m_char->addSeries(m_series);
m_char->setTitle(bvp->m_title);
QStringList categories;
for(int i=0;i<bvp->m_categorieNameList.size();i++)
{
categories.append(bvp->m_categorieNameList[i]);
}
//categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
m_typeAxis = new QBarCategoryAxis();
//m_typeAxis->append(categories);
m_char->createDefaultAxes();//创建默认的左侧的坐标轴(根据 QBarSet 设置的值)
m_char->setAcceptTouchEvents(true);
m_char->setAxisX(m_typeAxis, m_series);//设置坐标轴
m_typeAxisY = new QValueAxis;
m_typeAxisY->setRange(0, 40);
// m_typeAxisY->setTickCount(10); //设置多少格
//m_typeAxisY->setMinorTickCount(5); //设置每格小刻度线的数目
m_char->setAxisY(m_typeAxisY, m_series);
m_char->legend()->setVisible(true); //设置图例为显示状态
m_char->legend()->setAlignment(Qt::AlignBottom);//设置图例的显示位置在底部
//m_myBarView->setAcceptTouchEvents(true);
m_mybarView=new QChartView(m_char);
m_mybarView->setRenderHint(QPainter::Antialiasing);
}
void MyBarView::addBar(QStringList CategoryNm,QVector<QVector<int> > setValList)
{
for(int i=0;i<CategoryNm.size();i++)
{
for(int j=0;j<setValList[i].size();j++)
{
m_barSetList[i]->append(setValList[i][j]);
}
m_series->append( m_barSetList[i]);
}
m_series->setLabelsPosition(QAbstractBarSeries::LabelsInsideEnd); // 设置数据系列标签的位置于数据柱内测上方
m_series->setLabelsVisible(true); // 设置显示数据系列标签
m_categories =CategoryNm;//m_categories是x轴坐标
m_typeAxis->append(m_categories);//
}
void MyBarView::sltTooltip(bool status, int index, QBarSet *barset)
{
if (m_tooltip == 0)
m_tooltip = new ChartTip(m_char);
if (status) {
int yindex=m_barSetList.indexOf(barset);
double indexbarset=m_barSetList.indexOf(barset)-1;//m_categories是x轴坐标
indexbarset=indexbarset/6;
QBarSet *set=m_barSetList.at(yindex);
QString yname=set->label();
m_tooltip->setText("from:"+m_categories.at(index)+"\n to :"+yname+QString("\n人数: %2 ").arg(barset->at(index)));
QPointF point(index+indexbarset, barset->at(index));
qDebug()<<"index:"<<indexbarset<<index<< " "<<barset->at(index);
m_tooltip->setAnchor(point);
m_tooltip->setZValue(11);
m_tooltip->updateGeometry();
m_tooltip->show();
}
else {
m_tooltip->hide();
}
}
void MyBarView::tooltip(QPointF point, bool state)
{
if (m_tooltip == 0)
m_tooltip = new ChartTip(m_char);
if (state) {
QString str;
str = QString("%1").arg(point.x());
qDebug() <<str;
str.replace(QString("E+12"), QString(""));
str.replace(QString("."), QString(""));
//qDebug() <<str;
int val=str.toInt();
m_tooltip->setText(QString("时间: %1 \n人数: %2 ").arg(val).arg(qRound(point.y())));
m_tooltip->setAnchor(point);
m_tooltip->setZValue(11);
m_tooltip->updateGeometry();
m_tooltip->show();
} else {
m_tooltip->hide();
}
}