当前位置:嗨网首页>书籍在线阅读

16-柱状图

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

9.3.3 柱状图

1.柱状图的绘制

MainWindow的构造函数里调用iniBarChart()函数对绘制柱状图进行初始化,单击图9-10的“BarChart”页面的“刷新柱状图”按钮,会调用buildBarChart()绘制柱状图。绘制的柱状图如图9-10所示,柱状图由3个数据集组成,分别是数学、语文和英语,平均分用折线序列显示。图表的横坐标是学生姓名,纵坐标是数值。

iniBarChart()函数的代码如下:

void MainWindow::iniBarChart()
{ //柱状图初始化
   QChart *chart = new QChart(); 
   chart->setTitle("Barchart演示");
   chart->setAnimationOptions(QChart::SeriesAnimations);
   ui->chartViewBar->setChart(chart); 
   ui->chartViewBar->setRenderHint(QPainter::Antialiasing);
}

在可视化设计界面时,放置了一个QGraphicsView组件,然后升级为QChartView,并命名为chartViewBar。在iniBarChart()函数的代码里,创建了一个QChart对象,然后设置为QChartView组件显示的图表。

buildBarChart()函数用于绘制柱状图和平均分折线图,代码如下:

void MainWindow::buildBarChart()
{ //构造柱状图
   QChart *chart =ui->chartViewBar->chart(); //获取ChartView关联的chart
   chart->removeAllSeries(); //删除所有序列
   chart->removeAxis(chart->axisX()); //删除坐标轴
   chart->removeAxis(chart->axisY()); //删除坐标轴
//创建三个QBarSet数据集,从数据模型的表头获取Name
   QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());
   QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());
   QBarSet *setEnglish= new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text());
   QLineSeries *Line = new QLineSeries(); //用于显示平均分
   Line ->setName(theModel->horizontalHeaderItem(colNoAverage)->text());
   QPen   pen;
   pen.setColor(Qt::red);
   pen.setWidth(2);
   Line ->setPen(pen);
   for(int i=0;i<theModel->rowCount();i++)
   {//从数据模型获取数据
     setMath->append(theModel->item(i,colNoMath)->text().toInt());
     setChinese->append(theModel->item(i,colNoChinese)->text().toInt()); 
     setEnglish->append(theModel->item(i,colNoEnglish)->text().toInt());
     Line->append(QPointF(i,theModel->item(i, colNoAverage)->text().toFloat()));
   }
//创建一个柱状图序列 QBarSeries, 并添加三个数据集
   QBarSeries *series = new QBarSeries();
   series->append(setMath);
   series->append(setChinese);
   series->append(setEnglish);
   chart->addSeries(series); //添加柱状图序列
   chart->addSeries(Line); //添加折线图序列
//用于横坐标的字符串列表,即学生姓名
   QStringList categories;
   for (int i=0;i<theModel->rowCount();i++)
      categories <<theModel->item(i,colNoName)->text();
//用于柱状图的横坐标轴
   QBarCategoryAxis *axisX = new QBarCategoryAxis();
   axisX->append(categories); //添加横坐标文字列表
   chart->setAxisX(axisX, series); //设置横坐标
   chart->setAxisX(axisX, Line);//设置横坐标
   axisX->setRange(categories.at(0), categories.at(categories.count()-1)); 
//数值型坐标作为纵坐标轴
   QValueAxis *axisY = new QValueAxis;
   axisY->setRange(0, 100);
   axisY->setTitleText("分数");
   axisY->setTickCount(6);
   axisY->setLabelFormat("%.0f"); //标签格式
   chart->setAxisY(axisY, series); 
   chart->setAxisY(axisY, Line);
   chart->legend()->setVisible(true); //显示图例
   chart->legend()->setAlignment(Qt::AlignBottom);  //图例显示在下方
}

代码里首先通过下面的一行语句获取chartViewBar关联的QChart组件,然后对Chart的操作就都可以使用此变量。

QChart *chart =ui->chartViewBar->chart();

获得chart之后,先删除chart原有的所有序列和坐标轴。

一个柱状图由多个数据集组成,在此创建了3个QBarSet数据集,分别对应数学、语文、英语3门课的分数。

柱状图的数据集类是QBarSet,创建对象时使用了数据模型的列标题作为数据集的名称,这个名称会显示在图例里。

显示平均分使用QLineSeries序列,即折线序列。

创建3个QBarSet数据集和折线序列后,遍历数据模型将数据添加到数据集或折线序列。QBarSet::append(const qreal value)只需添加一个数值,如:

setMath->append(theModel->item(i,colNoMath)->text().toInt()); //数学

QLineSeries::append(const QPointF &point)则是添加一个数据点。

为3个QBarSet数据集添加完数据后,创建一个QBarSeries序列,并将3个数据集添加到这个QBarSeries序列,即:

QBarSeries *series = new QBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);

所以,虽然是有3个数据集,但是只有一个柱状图序列。然后将QBarSeries序列和QLineSeries序列添加到图表。

添加完序列后要创建坐标轴。横坐标是QBarCategoryAxis类的坐标,是每个学生的姓名;纵坐标是QValueAxis类型坐标,是数值型坐标,为其设置范围和刻度等属性后,设置为两个序列的Y轴坐标。

2.柱状图相关的主要类

从以上创建柱状图的程序可以看出,与柱状图相关的主要类包括以下3个。

  • QBarSet:用于创建柱状图的数据集。
  • QBarSeries:柱状图序列,一个柱状图序列一般包含多个QBarSet数据集。
  • QBarCategoryAxis:柱状图分类坐标,以文字标签形式表示的坐标。

QBarSet是直接从QObject继承而来的类,其主要的函数功能见表9-6(仅列出函数的返回数据类型,省略了输入参数)。

表9-6 QBarSet类的主要函数功能

| 分组 | 函数 | 功能描述 | | :----- | :----- | :----- | :----- | :----- | | 标签 | void setLabel() | 设置数据集的标签,用于图例显示的文字 | | void setLabelBrush() | 设置标签的画刷 | | void setLabelColor() | 设置标签的文字颜色 | | void setLabelFont() | 设置标签的字体 | | 数据棒 | void setBorderColor() | 设置数据集的棒图的边框颜色 | | void setBrush() | 设置数据集的棒图的画刷 | | void setColor() | 设置数据集的棒图填充颜色 | | void setPen() | 设置数据集的棒图的边框画笔 | | 数据点 | void append() | 添加一个数据到数据集 | | void insert() | 在某个位置插入一个数据到数据集 | | void remove() | 从某个位置开始删除一定数量的数据 | | void replace() | 替换某个位置的数据 | | qreal at() | 返回某个位置的数据 | | int count() | 返回数据的个数 | | qreal sum() | 返回数据集内所有数据的和 |

QBarSeries是绘制柱状图序列的类,从QAbstractBarSeries类继承而来。QBarSeries类主要实现对QBarSet数据集的操作,一个柱状图序列可以有多个数据集。QBarSeries类的主要函数功能见表9-7(包括从QAbstractBarSeries继承的函数,仅列出函数的返回数据类型,省略了输入参数)。

表9-7 QBarSeries类的主要函数功能

| 分组 | 函数 | 功能描述 | | :----- | :----- | :----- | :----- | :----- | | 外观 | void setBarWidth() | 设置数据棒的宽度 | | void setLabelsVisible() | 设置数据棒的标签可见性 | | void setLabelsFormat() | 设置数据棒的标签的格式,只支持一种:@value | | void setLabelsPosition() | 数据棒标签的位置,可在数据棒的中间、顶端、底端、外部 | | void setLabelsAngle() | 设置标签的角度 | | 数据集 | bool append() | 添加一个QBarSet数据集到序列 | | bool insert() | 在某个位置插入一个QBarSet数据集到序列 | | bool remove() | 移除一个数据集,解除所属关系,并删除数据集对象 | | bool take() | 移除出一个数据集,但是不删除数据集对象 | | void clear() | 清除全部数据集,并删除数据集对象 | | QList<QBarSet *> barSets() | 返回数据集对象的列表 | | int count() | 返回数据集的个数 |

柱状图的横坐标一般是文字表示的类别,所以用于柱状图的横坐标类是QBarCategoryAxis,表9-8是QBarCategoryAxis的主要函数的功能(仅列出函数的返回数据类型,省略了输入参数)。

表9-8 QBarCategoryAxis主要函数功能

| 分组 | 函数 | 功能描述 | | :----- | :----- | :----- | :----- | :----- | | 坐标内容 | void append() | 添加一个类别(category)到坐标轴 | | void insert() | 在某个位置插入一个类别到坐标轴 | | void replace() | 替换某个类别 | | void remove() | 移除某个类别 | | void clear() | 删除所有类别 | | QString at() | 返回某个索引位置的类别文字 | | int count() | 返回类别的个数 | | void setCategories() | 设置一个QStringList字符串列表作为坐标轴的类别文字,删除原来所有类别文字 | | 坐标范围 | void setMin() | 设置坐标轴最小值 | | void setMax() | 设置坐标轴最大值 | | void setRange() | 设置坐标轴范围 |

QBarCategoryAxis坐标轴的内容是一系列文字表示的类别,所以,其函数基本都是针对字符串的操作。