九、图表使用

一、QCharts概述

Qt图表提供了:折线图、样条曲线图、面积图、散点图、条形图、饼图、方块胡须图、蜡烛图、极坐标图。

1、QChart介绍

Qt Charts基于Qt的QGraphics View架构,其核心组件是QChartView和QChart
  • QChartView是显示图标的视图,基类为QGraphicsView
  • QChart的基类是QGraphicsItem
QGraphicsItem
	QGraphicsObject
		QGraphicsWidget
			QChart

2、使用

(1)项目管理

在使用Qt Charts模块,必须在项目中配置
QT += charts

(2)类中使用QCharts

在类中使用QCharts,需要在头文件或者源文件分别添加:
#include 
// using namespace QtCharts;
QT_CHARTS_USE_NAMESPACE // 使用宏代替

3、实现程序

(1)创建项目,基于QMainWindow

(2)实现图表

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include 
QT_CHARTS_USE_NAMESPACE
#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 创建图标
    QChartView *chartView = new QChartView(this);
    QChart *chart = new QChart();
    chart->setTitle("简单函数曲线");
    chartView->setChart(chart);
    setCentralWidget(chartView);

    // 创建曲线序列
    QLineSeries *series0 = new QLineSeries;
    QLineSeries *series1 = new QLineSeries;
    series0->setName("Sin曲线");
    series1->setName("Cos曲线");
    chart->addSeries(series0);
    chart->addSeries(series1);

    qreal y0, y1, t = 0, intv = 0.1/*时间间隔*/;
    int cnt = 100;

    for (int i = 0; i < cnt; ++i)
    {
        y0 = qSin(t);
        series0->append(t, y0);
        y1 = qCos(t);
        series1->append(t, y1);
        t += intv;
    }

    //创建坐标轴
    QValueAxis *axisX = new QValueAxis;
    axisX->setRange(0, 10);
    chart->setAxisX(axisX, series0);
    chart->setAxisX(axisX, series1);

    QValueAxis *axisY = new QValueAxis;
    axisY->setRange(-1, 1);
    chart->setAxisY(axisY, series0);
    chart->setAxisY(axisY, series1);
}

MainWindow::~MainWindow()
{
    delete ui;
}

九、图表使用_第1张图片

二、QChart绘制折线图

1、类继承关系

(1)数据序列类

QAbractSeries
	QAreaSeries
	QBoxPlotSeries
	QAbstractBarSeries
		QBarSeries
		QHorizontalBarSeries
		QHorizontalStackedBarSeries
		QPercentBarSeries
		QStackedBarSeries
	QPieSeries
	QXYSeties
		QLineSeries
			QSplineSeries
		QScatterSeries

(2)坐标轴类

QAbstractAxis
	QValuesAxis
		QCategoryAxis
	QLogValueAxis
	QBarCategoryAxis
	QDataTimeAxis

2、实现程序

九、图表使用_第2张图片

(1)创建项目, 基于QMainwindow

(2)QScrollArea 滚动条

九、图表使用_第3张图片
九、图表使用_第4张图片

(3)添加组件

九、图表使用_第5张图片

(4)添设置画笔的UI和类

九、图表使用_第6张图片

#include "dialogpen.h"
#include "ui_dialogpen.h"

DialogPen::DialogPen(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogPen)
{
    ui->setupUi(this);

    ui->comboBoxLineType->clear();
    ui->comboBoxLineType->addItem("NoPen", 0);
    ui->comboBoxLineType->addItem("SolidLine", 1);
    ui->comboBoxLineType->addItem("DashLine", 2);
    ui->comboBoxLineType->addItem("DotLine", 3);
    ui->comboBoxLineType->addItem("DashDotLine", 4);
    ui->comboBoxLineType->addItem("DashDotDotLine", 5);
    ui->comboBoxLineType->addItem("CustomDashLine", 6);

    ui->comboBoxLineType->setCurrentIndex(1);
}

DialogPen::~DialogPen()
{
    delete ui;
}

QPen DialogPen::getPen()
{
    m_pen.setStyle(Qt::PenStyle(ui->comboBoxLineType->currentIndex()));
    m_pen.setWidth(ui->spinBoxLineWidth->value());
    QColor color = ui->btnLineColor->palette().color(QPalette::Button);
    m_pen.setColor(color);
    return m_pen;
}

QPen DialogPen::getPen(QPen initPen, bool &ok)
{
    QPen pen;
    DialogPen *dlg = new DialogPen;
    dlg->setPen(initPen);
    int ret = dlg->exec();

    if(ret == QDialog::Accepted)
    {
        pen = dlg->getPen();
        ok = true;
    }
    else
    {
        pen = initPen;
        ok = false;
    }

    delete dlg;
    return pen;
}

void DialogPen::setPen(const QPen &pen)
{
    m_pen = pen;
    ui->spinBoxLineWidth->setValue(pen.width());
    int nType = static_cast<int>(pen.style());
    ui->comboBoxLineType->setCurrentIndex(nType);
    ui->btnLineColor->setAutoFillBackground(true);

    QColor color = pen.color();
    QString str = QString::asprintf("background-color: rgb(%d,%d,%d)",
                                    color.red(), color.green(), color.blue());
    ui->btnLineColor->setStyleSheet(str);
}

#include 
void DialogPen::on_btnLineColor_clicked()
{
    QColor color = m_pen.color();
    color = QColorDialog::getColor(color);

    if(color.isValid())
    {
        QString str = QString::asprintf("background-color: rgb(%d,%d,%d)",
                                        color.red(), color.green(), color.blue());
        ui->btnLineColor->setStyleSheet(str);
    }
}

(5)初始化图表

void MainWindow::createChart()
{
    QChart*chart = new QChart();
    chart->setTitle("简单的曲线");
    ui->chartView->setChart(chart);
    ui->chartView->setRenderHint(QPainter::Antialiasing); // 抗锯齿

    QLineSeries *series0 = new QLineSeries;
    QLineSeries *series1 = new QLineSeries;

    series0->setName("Sin曲线");
    series1->setName("Cos曲线");
    curSeries = series0;

    QPen pen;
    pen.setStyle(Qt::DotLine);
    pen.setWidth(2);
    pen.setColor(Qt::red);
    series0->setPen(pen);

    pen.setStyle(Qt::SolidLine);
    pen.setColor(Qt::blue);
    series1->setPen(pen);

    chart->addSeries(series0);
    chart->addSeries(series1);

    QValueAxis *axisX = new QValueAxis;
    QValueAxis *axisY = new QValueAxis;
    curAxis = axisX;

    axisX->setRange(0, 10);
    axisX->setLabelFormat("%0.1f");
    axisX->setTickCount(11); // 大格间隔数
    axisX->setMinorTickCount(4); // 小格间隔数
    axisX->setTitleText("time(secs)");

    axisY->setRange(-1.2, 1.2);
    axisY->setTickCount(3); // 大格间隔数
    axisY->setMinorTickCount(4); // 小格间隔数
    axisY->setTitleText("value");

    chart->setAxisX(axisX, series0);
    chart->setAxisX(axisX, series1);
    chart->setAxisY(axisY, series0);
    chart->setAxisY(axisY, series1);
}```
### (6)绘制曲线

```bash
void MainWindow::prepareData()
{
    QLineSeries *series0 = (QLineSeries*)ui->chartView->chart()->series().at(0);
    QLineSeries *series1 = (QLineSeries*)ui->chartView->chart()->series().at(1);
    int cnt = 100;
    series0->clear();
    series1->clear();

    qsrand(QTime::currentTime().second());
    qreal t = 0, y0 = 0, y1 = 0, intv = 0.1;
    qreal rd;

    for (int i = 0; i < cnt; ++i)
    {
        rd = (qrand() % 10 - 5);
        y0 = qSin(t) + rd / 50;
        series0->append(t, y0);
        y1 = qCos(t) + rd / 50;
        series1->append(t, y1);
        t += intv;
    }
}

(6)实现组件功能

#include "mainwindow.h"

#include 
#include "ui_mainwindow.h"
#include "dialogpen.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    createChart();
    prepareData();
    updateFromChart();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::createChart()
{
    QChart*chart = new QChart();
    chart->setTitle("简单的曲线");
    ui->chartView->setChart(chart);
    ui->chartView->setRenderHint(QPainter::Antialiasing); // 抗锯齿

    QLineSeries *series0 = new QLineSeries;
    QLineSeries *series1 = new QLineSeries;

    series0->setName("Sin曲线");
    series1->setName("Cos曲线");
    curSeries = series0;

    QPen pen;
    pen.setStyle(Qt::DotLine);
    pen.setWidth(2);
    pen.setColor(Qt::red);
    series0->setPen(pen);

    pen.setStyle(Qt::SolidLine);
    pen.setColor(Qt::blue);
    series1->setPen(pen);

    chart->addSeries(series0);
    chart->addSeries(series1);

    QValueAxis *axisX = new QValueAxis;
    QValueAxis *axisY = new QValueAxis;
    curAxis = axisX;

    axisX->setRange(0, 10);
    axisX->setLabelFormat("%0.1f");
    axisX->setTickCount(11); // 大格间隔数
    axisX->setMinorTickCount(4); // 小格间隔数
    axisX->setTitleText("time(secs)");

    axisY->setRange(-1.2, 1.2);
    axisY->setTickCount(3); // 大格间隔数
    axisY->setMinorTickCount(4); // 小格间隔数
    axisY->setTitleText("value");

    chart->setAxisX(axisX, series0);
    chart->setAxisX(axisX, series1);
    chart->setAxisY(axisY, series0);
    chart->setAxisY(axisY, series1);
}

#include 
void MainWindow::prepareData()
{
    QLineSeries *series0 = (QLineSeries*)ui->chartView->chart()->series().at(0);
    QLineSeries *series1 = (QLineSeries*)ui->chartView->chart()->series().at(1);
    int cnt = 100;
    series0->clear();
    series1->clear();

    qsrand(QTime::currentTime().second());
    qreal t = 0, y0 = 0, y1 = 0, intv = 0.1;
    qreal rd;

    for (int i = 0; i < cnt; ++i)
    {
        rd = (qrand() % 10 - 5);
        y0 = qSin(t) + rd / 50;
        series0->append(t, y0);
        y1 = qCos(t) + rd / 50;
        series1->append(t, y1);
        t += intv;
    }
}

void MainWindow::updateFromChart()
{
    QChart *chart = ui->chartView->chart();
    ui->lineEditTitle->setText(chart->title());

    QMargins mg = chart->margins();
    ui->spinBoxUp->setValue(mg.top());
    ui->spinBoxDown->setValue(mg.bottom());
    ui->spinBoxLeft->setValue(mg.left());
    ui->spinBoxRight->setValue(mg.right());


}

void MainWindow::on_actZoomIn_triggered()
{
    ui->chartView->chart()->zoom(1.2);
}

void MainWindow::on_actZoomOut_triggered()
{
    ui->chartView->chart()->zoom(0.8);
}

void MainWindow::on_actDraw_triggered()
{
    prepareData();
}

void MainWindow::on_actZoomReset_triggered()
{
    ui->chartView->chart()->zoomReset();
}

void MainWindow::on_btnLinePen_clicked()
{
    QPen pen = curSeries->pen();
    bool ok = false;
    pen = DialogPen::getPen(pen, ok);

    if(ok)
    {
        curSeries->setPen(pen);
    }
}

void MainWindow::on_btnSetTitle_clicked()
{
    QString strTitle =  ui->lineEditTitle->text();
    QChart *chart = ui->chartView->chart();
    chart->setTitle(strTitle);
}

void MainWindow::on_btnSetTitleFont_clicked()
{
    QFont font = ui->chartView->chart()->titleFont();
    bool ok;
    font = QFontDialog::getFont(&ok, font);

    if(ok)
    {
        ui->chartView->chart()->setTitleFont(font);
    }
}

void MainWindow::on_rbtnUp_clicked()
{
    ui->chartView->chart()->legend()->setAlignment(Qt::AlignTop);
}

void MainWindow::on_rbtnDown_clicked()
{
    ui->chartView->chart()->legend()->setAlignment(Qt::AlignBottom);
}

void MainWindow::on_rbtnLeft_clicked()
{
    ui->chartView->chart()->legend()->setAlignment(Qt::AlignLeft);
}

void MainWindow::on_rbtnRight_clicked()
{
    ui->chartView->chart()->legend()->setAlignment(Qt::AlignRight);
}

void MainWindow::on_checkBoxName_clicked(bool checked)
{
    ui->chartView->chart()->legend()->setVisible(checked);
}

void MainWindow::on_checkBoxBack_clicked(bool checked)
{
    ui->chartView->chart()->legend()->setBackgroundVisible(checked);
}

void MainWindow::on_btnNameFont_clicked()
{
    QFont font = ui->chartView->chart()->legend()->font();
    bool ok;
    font = QFontDialog::getFont(&ok, font);

    if(ok)
    {
        ui->chartView->chart()->legend()->setFont(font);
    }
}

void MainWindow::on_btnNameColor_clicked()
{
    QColor color = ui->chartView->chart()->legend()->labelColor();
    color = QColorDialog::getColor(color);

    if(color.isValid())
    {
        ui->chartView->chart()->legend()->setLabelColor(    color);
    }
}

void MainWindow::on_btnSetMargin_clicked()
{
    QMargins mg;
    mg.setTop(ui->spinBoxUp->value());
    mg.setBottom(ui->spinBoxDown->value());
    mg.setLeft(ui->spinBoxLeft->value());
    mg.setRight(ui->spinBoxRight->value());
    ui->chartView->chart()->setMargins(mg);
}

void MainWindow::on_comboBoxAction_currentIndexChanged(int index)
{
    ui->chartView->chart()->setAnimationOptions((QChart::AnimationOptions)index);
}

void MainWindow::on_comboBoxTheme_currentIndexChanged(int index)
{
    ui->chartView->chart()->setTheme((QChart::ChartTheme)index);
}

void MainWindow::on_rbtnSeriesSin_clicked()
{
    if( ui->rbtnSeriesSin->isChecked())
    {
        curSeries = (QLineSeries*)ui->chartView->chart()->series().at(0);
    }
    else
    {
        curSeries = (QLineSeries*)ui->chartView->chart()->series().at(1);
    }

    ui->lineEditLine->setText(curSeries->name());
    ui->checkBoxSeries->setChecked(curSeries->isVisible());
    ui->checkBoxDataPoint->setChecked(curSeries->pointsVisible());
    ui->horizontalSlider->setValue(curSeries->opacity() * 10); // 0-1 => 0-10
    ui->checkBoxPointTip->setChecked(curSeries->pointLabelsVisible());
}

void MainWindow::on_rbtnSeriesCos_clicked()
{
    if( ui->rbtnSeriesSin->isChecked())
    {
        curSeries = (QLineSeries*)ui->chartView->chart()->series().at(0);
    }
    else
    {
        curSeries = (QLineSeries*)ui->chartView->chart()->series().at(1);
    }

    ui->lineEditLine->setText(curSeries->name());
    ui->checkBoxSeries->setChecked(curSeries->isVisible());
    ui->checkBoxDataPoint->setChecked(curSeries->pointsVisible());
    ui->horizontalSlider->setValue(curSeries->opacity() * 10); // 0-1 => 0-10
    ui->checkBoxPointTip->setChecked(curSeries->pointLabelsVisible());
}

void MainWindow::on_btnLineName_clicked()
{
    curSeries->setName(ui->lineEditLine->text());
}

void MainWindow::on_checkBoxSeries_clicked(bool checked)
{
    curSeries->setVisible(checked);
}

void MainWindow::on_checkBoxDataPoint_clicked(bool checked)
{
    curSeries->setPointLabelsVisible(checked);
}

void MainWindow::on_btnLineColor_clicked()
{
    QColor color = curSeries->color();
    color = QColorDialog::getColor(color);

    if(color.isValid())
    {
        curSeries->setColor(color);
    }
}

void MainWindow::on_horizontalSlider_valueChanged(int value)
{
    curSeries->setOpacity(value / 10.0);
}

void MainWindow::on_checkBoxPointTip_clicked(bool checked)
{
    curSeries->setPointLabelsVisible(checked);
}

void MainWindow::on_btnPointTipColor_clicked()
{
    QColor color = curSeries->pointLabelsColor();
    color = QColorDialog::getColor(color);

    if(color.isValid())
    {
        curSeries->setPointLabelsColor(color);
    }
}

void MainWindow::on_btnPointTipFont_clicked()
{
    QFont font = curSeries->pointLabelsFont();
    bool ok;
    font = QFontDialog::getFont(&ok, font);

    if(ok)
    {
        curSeries->setPointLabelsFont(font);
    }
}

void MainWindow::on_rbtnDisplayX_clicked()
{
    if(ui->rbtnDisplayX->isChecked())
    {
        curSeries->setPointLabelsFormat("@yPoint");
    }
    else
    {
        curSeries->setPointLabelsFormat("(@xPoint,@yPoint)");
    }
}

void MainWindow::on_rbtnDisplayXY_clicked()
{
    if(ui->rbtnDisplayX->isChecked())
    {
        curSeries->setPointLabelsFormat("@yPoint");
    }
    else
    {
        curSeries->setPointLabelsFormat("(@xPoint,@yPoint)");
    }
}

void MainWindow::on_rbtnSetX_clicked()
{
    QList<QAbstractAxis*> axes;

    if(ui->rbtnSetX->isChecked())
    {
        axes = ui->chartView->chart()->axes(Qt::Horizontal);
    }
    else
    {
        axes = ui->chartView->chart()->axes(Qt::Vertical);
    }

    curAxis = (QValueAxis*)axes[0];

    ui->doubleSpinBoxMin->setValue(curAxis->min());
    ui->doubleSpinBoxMax->setValue(curAxis->max());

    ui->lineEditAxisTitle->setText(curAxis->titleText());
    ui->checkBoxAxisTitleIsVisibe->setChecked(curAxis->isTitleVisible());

    ui->lineEditFormat->setText(curAxis->labelFormat());
    ui->checkBoxAxisTitleIsVisibe->setChecked(curAxis->labelsVisible());

    ui->checkBoxIsGridLineVisible->setChecked(curAxis->isGridLineVisible());
    ui->checkBoxisLineVisible->setChecked(curAxis->isLineVisible());

    ui->spinBoxTick->setValue(curAxis->tickCount());
    ui->checkBoxisLineVisible->setChecked(curAxis->isLineVisible());

    ui->spinBoxMinorTick->setValue(curAxis->minorTickCount());
    ui->checkBoxIsMinorGirdLineVisible->setChecked(curAxis->isMinorGridLineVisible());
}

void MainWindow::on_rbtnSetY_clicked()
{
    QList<QAbstractAxis*> axes;

    if(ui->rbtnSetX->isChecked())
    {
        axes = ui->chartView->chart()->axes(Qt::Horizontal);
    }
    else
    {
        axes = ui->chartView->chart()->axes(Qt::Vertical);
    }

    curAxis = (QValueAxis*)axes[0];

    ui->doubleSpinBoxMin->setValue(curAxis->min());
    ui->doubleSpinBoxMax->setValue(curAxis->max());

    ui->lineEditAxisTitle->setText(curAxis->titleText());
    ui->checkBoxAxisTitleIsVisibe->setChecked(curAxis->isTitleVisible());

    ui->lineEditFormat->setText(curAxis->labelFormat());
    ui->checkBoxAxisTitleIsVisibe->setChecked(curAxis->labelsVisible());

    ui->checkBoxIsGridLineVisible->setChecked(curAxis->isGridLineVisible());
    ui->checkBoxisLineVisible->setChecked(curAxis->isLineVisible());

    ui->spinBoxTick->setValue(curAxis->tickCount());
    ui->checkBoxisLineVisible->setChecked(curAxis->isLineVisible());

    ui->spinBoxMinorTick->setValue(curAxis->minorTickCount());
    ui->checkBoxIsMinorGirdLineVisible->setChecked(curAxis->isMinorGridLineVisible());
}

void MainWindow::on_checkBoxIsVisible_clicked(bool checked)
{
    curAxis->setVisible(checked);
}

void MainWindow::on_btnSetAxisRange_clicked()
{
    curAxis->setRange(ui->doubleSpinBoxMin->value(), ui->doubleSpinBoxMax->value());
}

void MainWindow::on_btnSetAxisTitle_clicked()
{
    curAxis->setTitleText(ui->lineEditAxisTitle->text());
}

void MainWindow::on_checkBoxAxisTitleIsVisibe_clicked(bool checked)
{
    curAxis->setTitleVisible(checked);
}

void MainWindow::on_btnAxisTitleFont_clicked()
{
    QFont font = curAxis->titleFont();
    bool ok;
    font = QFontDialog::getFont(&ok, font);

    if(ok)
    {
        curAxis->setTitleFont(font);
    }
}

void MainWindow::on_btnSetFormat_clicked()
{
    curAxis->setLabelFormat(ui->lineEditFormat->text());
}

void MainWindow::on_btnSetColor_clicked()
{
    QColor color = curAxis->labelsColor();
    color = QColorDialog::getColor(color);

    if(color.isValid())
    {
        curAxis->setLabelsColor(color);
    }
}

void MainWindow::on_btnSetFont_clicked()
{
    QFont font = curAxis->labelsFont();
    bool ok;
    font = QFontDialog::getFont(&ok, font);

    if(ok)
    {
        curAxis->setLabelsFont(font);
    }
}

void MainWindow::on_checkBoxlabelVisible_clicked(bool checked)
{
    curAxis->setLabelsVisible(checked);
}

void MainWindow::on_checkBoxIsGridLineVisible_clicked(bool checked)
{
    curAxis->setLineVisible(checked);
}

void MainWindow::on_btnGridLineColor_clicked()
{
    QColor color = curAxis->gridLineColor();
    color = QColorDialog::getColor(color);

    if(color.isValid())
    {
        curAxis->setGridLineColor(color);
    }
}

void MainWindow::on_btnGridLinePen_clicked()
{
    QPen pen = curAxis->gridLinePen();
    bool ok = false;
    pen = DialogPen::getPen(pen, ok);

    if(ok)
    {
        curAxis->setGridLinePen(pen);
    }
}

void MainWindow::on_checkBoxIsMinorGirdLineVisible_clicked(bool checked)
{
    curAxis->setMinorGridLineVisible(checked);
}

void MainWindow::on_btnMinorGridLineColor_clicked()
{
    QColor color = curAxis->minorGridLineColor();
    color = QColorDialog::getColor(color);

    if(color.isValid())
    {
        curAxis->setMinorGridLineColor(color);
    }
}

void MainWindow::on_btnMinorGirdLinePen_clicked()
{
    QPen pen = curAxis->minorGridLinePen();
    bool ok = false;
    pen = DialogPen::getPen(pen, ok);

    if(ok)
    {
        curAxis->setMinorGridLinePen(pen);
    }
}

void MainWindow::on_spinBoxMinorTick_valueChanged(int arg1)
{
    curAxis->setMinorTickCount(arg1);
}

void MainWindow::on_btnLinePen_2_clicked()
{
    QPen pen = curAxis->linePen();
    bool ok = false;
    pen = DialogPen::getPen(pen, ok);

    if(ok)
    {
        curAxis->setLinePen(pen);
    }
}

void MainWindow::on_spinBoxTick_valueChanged(int arg1)
{
    curAxis->setTickCount(arg1);
}

void MainWindow::on_btnLinePenColor_clicked()
{
    QColor color = curAxis->linePenColor();
    color = QColorDialog::getColor(color);

    if(color.isValid())
    {
        curAxis->setLinePenColor(color);
    }
}

三、QChart常见图表绘制

1、图表与类

(1)柱状图

  • QBarSet:数据集
  • QBarSeries:一个序列可以包含多个QBarSet
  • QBarCategoryAxis:横坐标轴
  • QValueAxis:纵坐标轴

(2)饼状图

  • QPieSeries:数据序列
  • QPieSlice:饼图扇区

(3)堆叠柱状图

  • QBarSet:数据集
  • QStackedBarSeries:一个序列可以有多个QBarSet
  • QBarCategoryAxis:横坐标
  • QValueAxis:纵坐标轴

(4)百分比柱状图

  • QBarSet:数据集
  • QPercentageBarSeries:一个序列可以有多个QBarSet
  • QBarCategoryAxis:横坐标
  • QValueAxis:纵坐标轴

(5)散点图和光滑曲线

  • QSplineSeries、QLineSeries:散点和平滑线
  • QValueAxis:坐标轴。

2、实现程序

九、图表使用_第7张图片

(1)创建项目,基于QMainWindows

(2)添加图表资源文件,添加工具栏

(3)添加组件

九、图表使用_第8张图片

(4)柱状图

九、图表使用_第9张图片

void MainWindow::initBarChart()
{
    QChart *chart = new QChart;
    chart->setTitle("BarChart演示");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    ui->cvChartBar->setChart(chart);
    ui->cvChartBar->setRenderHint(QPainter::Antialiasing);
}

void MainWindow::buildBarChart()
{
    QChart *chart = ui->cvChartBar->chart();
    chart->removeAllSeries();

    if(chart->axisX() != nullptr)
    {
        chart->removeAxis(chart->axisX());
    }

    if(chart->axisY() != nullptr)
    {
        chart->removeAxis(chart->axisY());
    }

    // 数据集
    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 *lineAverage = new QLineSeries;
    lineAverage->setName(theModel->horizontalHeaderItem(colNoAverage)->text());
    QPen pen;
    pen.setColor(Qt::red);
    pen.setWidth(2);
    lineAverage->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());
        lineAverage->append(QPointF(i, theModel->item(i, colNoAverage)->text().toFloat()));
    }

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

    chart->addSeries(series);
    chart->addSeries(lineAverage);
    chart->legend()->setAlignment(Qt::AlignBottom);

    QStringList category;

    for (int i = 0; i < theModel->rowCount(); ++i)
    {
        category << theModel->item(i, colNoName)->text();
    }

    QBarCategoryAxis *axisX = new QBarCategoryAxis;
    axisX->setCategories(category);
    chart->setAxisX(axisX, series);
    chart->setAxisX(axisX, lineAverage);

    QValueAxis *axisY = new QValueAxis;
    axisY->setRange(0, 100);
    axisY->setTitleText("分数");
    chart->setAxisY(axisY, series);
    chart->setAxisY(axisY, lineAverage);
}

(5)饼状图

九、图表使用_第10张图片

void MainWindow::initPieChart()
{
    QChart *chart = new QChart;
    chart->setTitle("PieChart演示");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    ui->cvPieChart->setChart(chart);
    ui->cvPieChart->setRenderHint(QPainter::Antialiasing);
}

void MainWindow::buildPieChart()
{
    QChart *chart = ui->cvPieChart->chart();
    chart->removeAllSeries();

    if(chart->axisX() != nullptr)
    {
        chart->removeAxis(chart->axisX());
    }

    if(chart->axisY() != nullptr)
    {
        chart->removeAxis(chart->axisY());
    }

    QPieSeries *series = new QPieSeries;
    series->setHoleSize(ui->dSpinBoxHoleSize->value());
    series->setPieSize(ui->dSpinBoxPieSize->value());

    int colNo = ui->comboBoxScore->currentIndex() + colNoMath;

    for (int i = 0; i < 5; ++i)
    {
        QTreeWidgetItem *item = ui->treeWidget->topLevelItem(i);
        series->append(item->text(0), item->text(colNo).toFloat());
    }

    QPieSlice *slice;

    for (int i = 0; i < 5; ++i)
    {
        slice = series->slices().at(i);
        slice->setLabel(slice->label() + QString::asprintf("%.0f人, %.2f%%",
                        slice->value(), slice->percentage()));
        connect(slice, SIGNAL(hovered(bool)),
                this, SLOT(on_SliceHigtLight(bool)));
    }

    series->setLabelsVisible(true);
    chart->setTitle("PieChart --" + ui->comboBoxScore->currentText());
    chart->addSeries(series);
    chart->legend()->setAlignment(Qt::AlignRight);
}

void MainWindow::on_SliceHigtLight(bool show)
{
    // 鼠标到饼图扇区,弹出动画
    QPieSlice *slice = (QPieSlice*)sender();
    slice->setExploded(show);
}

void MainWindow::on_dSpinBoxHoleSize_valueChanged(double arg1)
{
    QPieSeries* series = (QPieSeries*) ui->cvPieChart->chart()->series().at(0);
    series->setHoleSize(arg1);
}

void MainWindow::on_dSpinBoxPieSize_valueChanged(double arg1)
{
    QPieSeries* series = (QPieSeries*) ui->cvPieChart->chart()->series().at(0);
    series->setPieSize(arg1);
}

void MainWindow::on_comboBoxTheme_currentIndexChanged(int index)
{
    ui->cvPieChart->chart()->setTheme(QChart::ChartTheme(index));
}

(6)堆叠柱状图

九、图表使用_第11张图片

void MainWindow::initStackedBar()
{
    QChart *chart = new QChart;
    chart->setTitle("StackedBar演示");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    ui->cvStackedBar->setChart(chart);
    ui->cvStackedBar->setRenderHint(QPainter::Antialiasing);
}

void MainWindow::buildStackedBar()
{
    QChart *chart = ui->cvStackedBar->chart();
    chart->removeAllSeries();

    if(chart->axisX() != nullptr)
    {
        chart->removeAxis(chart->axisX());
    }

    if(chart->axisY() != nullptr)
    {
        chart->removeAxis(chart->axisY());
    }

    // 数据集
    QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());
    QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());
    QBarSet *setEnglish = new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text());

    QStringList categories;

    for (int i = 0; i < theModel->rowCount(); ++i)
    {
        categories << theModel->item(i, colNoName)->text();

        setMath->append(theModel->item(i, colNoMath)->text().toFloat());
        setChinese->append(theModel->item(i, colNoChinese)->text().toFloat());
        setEnglish->append(theModel->item(i, colNoEnglish)->text().toFloat());
    }

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

    chart->addSeries(series);

    QBarCategoryAxis *axisX = new QBarCategoryAxis;
    axisX->append(categories);
    chart->setAxisX(axisX, series);

    QValueAxis *axisY = new QValueAxis;
    axisY->setRange(0, 300);
    axisY->setTitleText("总分");
    chart->setAxisY(axisY, series);
}

(7)百分比柱状图

九、图表使用_第12张图片

void MainWindow::initPercentBar()
{
    QChart *chart = new QChart;
    chart->setTitle("PercentBar演示");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    ui->cvPercentBar->setChart(chart);
    ui->cvPercentBar->setRenderHint(QPainter::Antialiasing);
}

void MainWindow::buildPercentBar()
{
    QChart *chart = ui->cvPercentBar->chart();
    chart->removeAllSeries();

    if(chart->axisX() != nullptr)
    {
        chart->removeAxis(chart->axisX());
    }

    if(chart->axisY() != nullptr)
    {
        chart->removeAxis(chart->axisY());
    }

    // 数据集
    QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(colNoMath)->text());
    QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(colNoChinese)->text());
    QBarSet *setEnglish = new QBarSet(theModel->horizontalHeaderItem(colNoEnglish)->text());

    QStringList categories;

    for (int i = 0; i < 5; ++i)
    {
        categories << ui->treeWidget->topLevelItem(i)->text(colNoName);

        setMath->append(ui->treeWidget->topLevelItem(i)->text(colNoMath).toFloat());
        setChinese->append(ui->treeWidget->topLevelItem(i)->text(colNoChinese).toFloat());
        setEnglish->append(ui->treeWidget->topLevelItem(i)->text(colNoEnglish).toFloat());
    }

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

    chart->addSeries(series);

    QBarCategoryAxis *axisX = new QBarCategoryAxis;
    axisX->append(categories);
    chart->setAxisX(axisX, series);

    QValueAxis *axisY = new QValueAxis;
    axisY->setRange(0, 100);
    axisY->setTitleText("分数百分比");
    chart->setAxisY(axisY, series);
}

(8)散点曲线图

九、图表使用_第13张图片

void MainWindow::initScatterChart()
{
    QChart *chart = new QChart;
    chart->setTitle("ScatterChart演示");
    chart->setAnimationOptions(QChart::SeriesAnimations);
    ui->cvScatterChart->setChart(chart);
    ui->cvScatterChart->setRenderHint(QPainter::Antialiasing);
}

void MainWindow::buildScatterChart()
{
    QChart *chart = ui->cvScatterChart->chart();
    chart->removeAllSeries();

    if(chart->axisX() != nullptr)
    {
        chart->removeAxis(chart->axisX());
    }

    if(chart->axisY() != nullptr)
    {
        chart->removeAxis(chart->axisY());
    }

    QSplineSeries *seriesLine = new QSplineSeries;
    seriesLine->setName("spline");

    QPen pen;
    pen.setWidth(2);
    pen.setColor(Qt::red);
    seriesLine->setPen(pen);

    QScatterSeries *series0 = new QScatterSeries;
    series0->setName("散点");
    series0->setMarkerShape(QScatterSeries::MarkerShapeCircle); // 圆形
    series0->setBorderColor(Qt::black);
    series0->setBrush(QBrush(Qt::blue));
    series0->setMarkerSize(12);

    for (int i = 0; i < 10; ++i)
    {
        int x = qrand() % 20;
        int y = qrand() % 20;
        series0->append(x, y);
        seriesLine->append(x, y);
    }

    chart->addSeries(seriesLine);
    chart->addSeries(series0);

    chart->createDefaultAxes();
    chart->axisX()->setTitleText("X轴");
    chart->axisX()->setRange(-5, 25);
    chart->axisY()->setTitleText("Y轴");
    chart->axisY()->setRange(-5, 25);
}

四、图表其他操作

图表特定鼠标事件操作需要使用继承类实现事件的处理

1、实现程序

九、图表使用_第14张图片

(1)创建项目,基于QMainWindow

(2)添加资源文件与图标

(3)添加QChartView派生类

#include "axbchartview.h"

AXBChartView::AXBChartView(QWidget *parent) : QChartView(parent)
{
    setMouseTracking(true); //
    setDragMode(QGraphicsView::RubberBandDrag); // 框选区域
}

void AXBChartView::keyPressEvent(QKeyEvent *event)
{
    switch (event->key())
    {
    case Qt::Key_Plus:
    {
        chart()->zoom(1.2);
    }
    break;

    case Qt::Key_Minus:
    {
        chart()->zoom(0.8);
    }
    break;

    case Qt::Key_Left:
    {
        chart()->scroll(10, 0);
    }
    break;

    case Qt::Key_Right:
    {
        chart()->scroll(-10, 0);
    }
    break;

    case Qt::Key_Up:
    {
        chart()->scroll(0, -10);
    }
    break;

    case Qt::Key_Down:
    {
        chart()->scroll(0, 10);
    }
    break;

    case Qt::Key_PageUp:
    {
        chart()->scroll(0, -50);
    }
    break;

    case Qt::Key_PageDown:
    {
        chart()->scroll(0, 50);
    }
    break;

    case Qt::Key_Home:
    {
        chart()->zoomReset();
    }
    break;

    default:
        QGraphicsView::keyPressEvent(event);
        break;
    }
}

void AXBChartView::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        beginPoint = event->pos();
    }

    QChartView::mousePressEvent(event);
}

void AXBChartView::mouseMoveEvent(QMouseEvent *event)
{
    QPoint point = event->pos();
    emit mouseMovePoint(point);
    QChartView::mouseMoveEvent(event);
}

void AXBChartView::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        endPoint = event->pos();
        QRectF rectF;
        rectF.setTopLeft(beginPoint);
        rectF.setBottomRight(endPoint);
        if(rectF.width() > 10 || rectF.height() > 10)
        {
            chart()->zoomIn(rectF);
        }
    }
    else if(event->button() == Qt::RightButton)
    {
        chart()->zoomReset();
    }

    QChartView::mouseReleaseEvent(event);
}

(4)实现功能

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "axbchartview.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setCentralWidget(ui->chartView);

    labXYValue = new QLabel("坐标X: Y: ");
    labXYValue->setMinimumWidth(200);
    ui->statusBar->addWidget(labXYValue);

    createChart();
    prepareData();

    connect(ui->chartView, SIGNAL(mouseMovePoint(QPoint)),
            this, SLOT(on_mouseMovePoint(QPoint)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::createChart()
{
    QChart *chart = new QChart;
    chart->setTitle("曲线");
    ui->chartView->setChart(chart);
    ui->chartView->setRenderHint(QPainter::Antialiasing);

    QLineSeries *series0 = new QLineSeries;
    QLineSeries *series1 = new QLineSeries;
    series0->setName("Sin曲线");
    series1->setName("Cos曲线");

    QPen pen;
    pen.setStyle(Qt::DotLine);
    pen.setColor(Qt::green);
    pen.setWidth(2);
    series0->setPen(pen);
    pen.setColor(Qt::red);
    series1->setPen(pen);

    chart->addSeries(series0);
    chart->addSeries(series1);
    chart->createDefaultAxes();
    chart->axisX()->setRange(0, 10);
    chart->axisY()->setRange(-1.5, 1.5);

    foreach (auto marker, ui->chartView->chart()->legend()->markers())
    {
        connect(marker, SIGNAL(clicked()),
                this, SLOT(on_legendMarkerClicked()));
    }
}

void MainWindow::prepareData()
{
    // 准备数据
    QLineSeries *series0 = (QLineSeries *)ui->chartView->chart()->series().at(0);
    QLineSeries *series1 = (QLineSeries *)ui->chartView->chart()->series().at(1);

    qsrand(QTime::currentTime().second());

    for (int i = 0; i < 100; ++i)
    {
        qreal dValue;
        dValue = qSin(i * 0.1) + (qrand() % 10 - 5) / 10.0;
        series0->append(i * 0.1, dValue);
        dValue = qCos(i * 0.1) + (qrand() % 10 - 5) / 10.0;
        series1->append(i * 0.1, dValue);
    }
}

void MainWindow::on_mouseMovePoint(QPoint point)
{
    QPointF pt = ui->chartView->chart()->mapToValue(point);
    labXYValue->setText(QString::asprintf("坐标X: %.2f Y: %.2f",
                                          pt.x(), pt.y()));
}

void MainWindow::on_legendMarkerClicked()
{
    QLegendMarker *marker = (QLegendMarker*)sender();
    marker->series()->setVisible(!marker->series()->isVisible());
    marker->setVisible(true);
    int alpha = 255;

    if(!marker->series()->isVisible())
    {
        alpha = 120;
    }

    QBrush brush = marker->labelBrush();
    QColor color = brush.color();
    color.setAlpha(alpha);
    brush.setColor(color);
    marker->setLabelBrush(brush);
}

void MainWindow::on_actZoomIn_triggered()
{
    ui->chartView->chart()->zoom(1.2);
}

void MainWindow::on_actZoomOut_triggered()
{
    ui->chartView->chart()->zoom(0.8);
}

void MainWindow::on_actZoomReset_triggered()
{
    ui->chartView->chart()->zoomReset();
}

你可能感兴趣的:(QT,qt)