Qt学习之QtCharts绘图(饼图、曲线图、柱状图)

QtCharts

QtCharts是 Qt 框架的一个模块,用于创建和处理数据可视化图表。它提供了多种类型的图表和可视化工具,允许开发者在基于 Qt 的应用程序中轻松地展示数据。
图表类型

  • 折线图 (Line Chart):展示连续数据点之间的关系,适用于趋势和时间序列分析。
  • 柱状图 (Bar Chart):展示类别数据的分布,适合比较不同类别的数据值。
  • 饼图 (Pie Chart):展示部分与整体的关系,适合展示比例和百分比。
  • 散点图 (Scatter Chart):展示数据点的分布,适合分析数据集中的相关性。
  • 区域图 (Area Chart):类似于折线图,但区域图强调数据的累积变化。
  • 盒状图 (Box-and-Whisker Chart):展示数据的分布和变异性,常用于统计分析。

.pro文件中添加:QT += charts

头文件 #include <QtCharts>


饼图绘:

在ui界面上添加QChartView  命名为:pie_1

void MainWindow::show_pie_1()
{
    QList<QString>id;
    //饼状图
    QPieSeries pie_series1 = new QPieSeries(this);
    pie_series1->clear();
    pie_series1->setPieSize(0.8);  //设置饼图占矩形区的大小,1为最大值
    connect(pie_series1, SIGNAL(clicked(QPieSlice*)), this, SLOT(onPieSeriesClicked(QPieSlice*)));//饼图动画

    QList<qreal> list_data;
    QList<QString> list_name;
    //定义各扇形切片的颜色
//    static const QStringList list_pie_color = {"#6480D6","#A1DC85","#FFAD25","#FF7777","#84D1EF","#4CB383",""};

    //遍历数据库-获取数据
    QSqlQuery q_select(db);
    q_select.prepare("SELECT * FROM slice_v2 WHERE  TRIM(status)='11'");
    q_select.setForwardOnly(true);
    q_select.exec(); //运行数据库
    int i_max = q_select.size();

    float a=800;

    while(q_select.next()){
        list_data.append(q_select.value("bw_limit").toFloat()*10);
        id.append(q_select.value("slice_id").toString());
        list_name.append(q_select.value("slice_name").toString().trimmed());
        a=a-q_select.value("bw_limit").toFloat()*10;

    }
    q_select.finish();
    q_select.clear();

    list_data.append(a);
    list_name.append("空闲资源");
    id.append("NULL");

    //扇形
    qreal factor = 0.05; //默认值
    for (int i = 0; i < list_data.size(); i++)
    {
        QPieSlice* pie_slice= new QPieSlice(this);
        //pie_slice->setLabelVisible(true);
        pie_slice->setValue(list_data[i]);
//        QString str_percent = QString::number(list_data[i],'f', 1).append("%");
//        pie_slice->setLabel(str_percent);
        pie_slice->setLabelVisible(false);
//调整标签角度
        //占比10%以下切片的臂长
        if ( list_data[i] < 15) {
                    pie_slice->setLabelArmLengthFactor(factor);
                    factor += 0.15;  //参数视界面大小而定

                    //调整起始、结束角度. 目的是将数值较小的区域调整到右下角
        if (pie_series1->pieStartAngle() < 135) {
                        pie_series1->setPieStartAngle(135);
                        pie_series1->setPieEndAngle(360 + 135);}}

        if(list_name[i]=="空闲资源"){
            pie_slice->setColor("#C0C0C0");
            pie_slice->setLabelColor("#C0C0C0");
            pie_slice->setBorderColor("#C0C0C0");
        }
        if(id[i]=="1"){
            pie_slice->setColor("#FF6384");
            pie_slice->setLabelColor("#FF6384");
            pie_slice->setBorderColor("#FF6384");
        }
        //....
        pie_series1->append(pie_slice);
    }


    //图表视图
    QChart* chart = new QChart;
    chart->setTitle("带宽资源分配图(%)<br>\n\n\n\n总带宽:800M");
    //标题字体
    QFont font = qApp->font();
    font.setBold(true);
    font.setPointSize(16);
    chart->setTitleFont(font);
    
    //加入饼图
    chart->addSeries(pie_series1);
    chart->setAnimationOptions(QChart::SeriesAnimations);
    QList<QLegendMarker*> list_market=chart->legend()->markers(pie_series1);
    for (int i = 0; i < list_data.size(); i++)
    {
        QString label=list_name[i]+" "+"("+QString::number(list_data[i]/8,'f', 1).append("%")+QString(",%1M)").arg(list_data[i]);
        QString wrappedLabel = label.replace(QString(" "), QString("<br>")); // 将空格替换为换行符
        list_market[i]->setLabel(QString("<html>%1</html>").arg(wrappedLabel));

    }
    chart->setBackgroundRoundness(0); // 取消背景圆角效果

    chart->setMargins(QMargins(0, 10, 0, 0));
    chart->layout()->setContentsMargins(0, 0, 0, 0); // 取消绘图区域的边距

    //图例
    chart->legend()->setAlignment(Qt::AlignRight);
    chart->legend()->setBackgroundVisible(false);
    ui->pie_1->setChart(chart);  // 饼状图在chart上显示



}
柱状图:

在ui界面上添加QChartView  命名为:chartView_UE

void MainWindow::show_UE()
{
    QBarSeries series = new QBarSeries(this);

    //遍历数据库
    QSqlQuery q_select(db);
    q_select.prepare("SELECT * FROM slice_v2 WHERE  TRIM(status)='11'");
    q_select.setForwardOnly(true);
    q_select.exec(); //运行数据库

    //柱状

    int row=0;
    while (q_select.next()){
        int num=q_select.value("num_ue").toInt();
        QString id=q_select.value("slice_id").toString();
        QBarSet *set = new QBarSet(q_select.value("slice_name").toString(),this);
        *set << num;  //向柱状切片i添加用户数量

        if(id=="1"){
            set->setLabelColor("#FF6384");
            set->setColor("#FF6384");

        }
        if(id=="2"){
            set->setLabelColor("#CC66FF");
            set->setColor("#CC66FF");

        series->append(set);
        row++;
         }

    q_select.finish();
    q_select.clear();


    QChart *chart = new QChart();//创建图表
    chart->addSeries(series);//序列添加到图表
    chart->setTitle("切片支持接入终端数量(个)");//设置图表标题
//    chart->setAnimationOptions(QChart::SeriesAnimations);//序列动态
    QValueAxis *axisY = new QValueAxis(); //y轴
    axisY->setGridLineVisible(true);
    axisY->setTickCount(6); // 设置刻度数为 6

    axisY->setRange(0, 10);
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);
    series->setLabelsPosition(QAbstractBarSeries::LabelsOutsideEnd);//用户数量显示在柱形图外部上端
    series->setLabelsVisible(true);
    series->setBarWidth(0.2);
    chart->legend()->setVisible(true);
    chart->legend()->setAlignment(Qt::AlignBottom);
    ui->chartView_UE->setChart(chart);//图表添加到场景
    ui->chartView_UE->setRenderHint(QPainter::Antialiasing);
}
折线图:

在ui界面上添加QChartView  命名为:chartView_delay

//设置坐标轴和图表
void MainWindow::init_delay() //视频时延chartview图配置
{
    QList <QString> str;
    QList <QString> id;

    QSqlQuery q_select(db);
    q_select.prepare("SELECT * FROM slice_v2 WHERE  TRIM(status)='11'");
    q_select.setForwardOnly(true);
    q_select.exec(); //运行数据库

    //-------------建横纵坐标轴并设置显示范围------------//
    axisX1 = new QDateTimeAxis();
    axisY1 = new QValueAxis();
    axisX1->setTitleText("时间(s)");
    axisY1->setTitleText("时延(ms)");
    axisX1->setFormat("hh:mm:ss");
    axisX1->setMin(QDateTime::fromMSecsSinceEpoch(QDateTime::currentDateTime().toMSecsSinceEpoch()));
    axisX1->setMax(QDateTime::fromMSecsSinceEpoch(QDateTime::currentDateTime().toMSecsSinceEpoch()+600000));
    axisY1->setMin(0);
    AXIS_MAX_X1=QDateTime::fromMSecsSinceEpoch(QDateTime::currentDateTime().toMSecsSinceEpoch()+600000);
    axisY1->setMax(AXIS_MAX_Y1);
    delay_lineseries.clear();
    chart1 = new QChart();                                        // 创建图表对象
    chart1->addAxis(axisY1, Qt::AlignLeft);                      // 将Y轴添加到图表上
    chart1->addAxis(axisX1, Qt::AlignBottom);                    // 将X轴添加到图表上
    for(int i=0;i<Max_slice_num;i++){//根据切片定义6条曲线
        delay_lineseries.append(new QLineSeries());
    }
    for(int i=0;i<Max_slice_num;i++){
        delay_lineseries[i]->setVisible(false);                         // 设置数据点可见
        chart1->addSeries(delay_lineseries[i]);                              // 将曲线对象添加到图表上
        delay_lineseries[i]->attachAxis(axisX1);                             // 曲线对象关联上X轴,此步骤必须在chart->addSeries之后
        delay_lineseries[i]->attachAxis(axisY1);
    }
    chart1->setAnimationOptions(QChart::SeriesAnimations);        // 动画:能使曲线绘制显示的更平滑,过渡效果更好看
    ui->chartView_delay->setChart(chart1);                           // 将图表对象设置到graphicsView上进行显示
    ui->chartView_delay->setRenderHint(QPainter::Antialiasing);       // 设置渲染:抗锯齿,如果不设置那么曲线就显得不
}


//更新曲线数据和数据坐标

void MainWindow::show_delay(QList<QString>list_id,QList<float>list_delay,QList<QString>list_name) //显示视频时延数据和折线图
{
    for(int i=0;i<delay_lineseries.size();i++){
           if(QDateTime::fromMSecsSinceEpoch(QDateTime::currentDateTime().toMSecsSinceEpoch()) > AXIS_MAX_X1){
             chart1->axes(Qt::Horizontal).back()->setRange(QDateTime::fromMSecsSinceEpoch(QDateTime::currentDateTime().toMSecsSinceEpoch()-Max_time*1000),QDateTime::fromMSecsSinceEpoch(QDateTime::currentDateTime().toMSecsSinceEpoch()));    // 更新X轴范围
             }

           // 检查数据点数量是否超过600
           if (delay_lineseries[i]->count() > Max_time) {
               // 计算需要移除的数据点数量
               int removeCount = delay_lineseries[i]->count() - Max_time;
               // 移除之前的数据点
               delay_lineseries[i]->removePoints(0, removeCount);
           }
         }

    for(int i=0;i<Max_slice_num;i++){
        delay_lineseries[i]->setVisible(false); }
        for(int i=0;i<Max_slice_num;i++){
          if(list_id[i]!="0"){
            delay_lineseries[i]->setVisible(true);
            delay_lineseries[i]->setColor(list_color[i]);
            delay_lineseries[i]->setUseOpenGL(true);                                   //缓解数据过大时的卡顿
            delay_lineseries[i]->setName(list_name[i]);
            delay_lineseries[i]->append(QDateTime::currentDateTime().toMSecsSinceEpoch(), list_delay[i]);
           }
        }

        for(int i=0;i<Max_slice_num;i++){
            if(list_id[i]=="0")
                delay_lineseries[i]->clear();
             }



}


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值