Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo

前言

  上一篇的demo使用隐藏js代码的方式,实现了一个饼图的基本交互方式,并预留了Qt模块对外的基础接口。
  本篇的demo实现了自动排序的柱状图,实现了一个自动排序柱状图的基本交互方式,即Qt调用js脚本操作html。
  本篇demo使用Qt定时器方式,实现数据定时刷新自增,并预留出了定时器间隔参数。
  像大数据网页常看的人口增长时间图,收入年度增长时间图等都是这一类。

 

Demo演示

  Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo

 

ECharts代码效果调试

  使用ECharts的在线调试器,先调试出大致预期的效果。

option = {   xAxis: {     max: 'dataMax'   },   yAxis: {     type: 'category',     data: ['特斯拉', '奔驰', '宝马', '理想', '蔚来'],     inverse: true,     animationDuration: 300,     animationDurationUpdate: 300,     max: 4   },   series: [     {       realtimeSort: true,       name: 'X',       type: 'bar',       data: [10,20,50,10,30],       label: {         show: true,         position: 'right',         valueAnimation: true       },       itemStyle: {             color: function(params) {               var colorList = ['#EE14FF', '#F092FF', '#FF61FE', '#A02F99', '#F00682'];  /* 注意1:需要分号 */               return colorList[params.dataIndex];    /* 注意2:需要dataIndex,获取序号 */          }       }     },   ],   graphic: {     elements: [    /* 时间标志 */       {         type: 'text',          right: 160,         bottom: 100,         style: {           text: '1970-01',           font: 'bolder 100px monospace',           fill: 'rgba(100, 100, 100, 0.25)'         },         z: 100       }     ]   },   legend: {     show: false,   },   animationDuration: 0,   animationDurationUpdate: 1000,   animationEasing: 'linear',   animationEasingUpdate: 'linear' }; 

  Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo

 

Qt封装动态ECharts

步骤一:静态html

  此系列的标准html文件,因为是标准的所以对文件名进行了调整,改为eChartWidget.html。

<!DOCTYPE html> <html>   <head>     <meta charset="utf-8" />     <title>ECharts</title>     <script src="./echarts.js"></script>   </head>   <body>     <style>         #main,         html,         body{             width: 100%;             height: 100%;             overflow: hidden;         }         #main {             width: 95%;             height: 95%;         }     </style>     <div id="main"></div>     <script type="text/javascript">         var myChart = echarts.init(document.getElementById('main'));         window.onresize = function() {             myChart.resize();         };     </script>   </body> </html> 

步骤二:初始化

void BarAutoSortEChartWidget::initControl() {     _pWebEngineView = new QWebEngineView(this);     _pWebEnginePage = new QWebEnginePage(this);     _pWebChannel = new QWebChannel(this);     QString filePath; #if 1     filePath = QString("%1/%2").arg(_htmlDir).arg(_indexFileName); #else     filePath = "qrc:/barAutoSortEChartWidget/html/eChartWidget.html"; #endif     LOG << "file exist:" << QFile::exists(filePath) << filePath; #if 0     // 打印html文件内容     QFile file(_indexFilePath);     file.open(QIODevice::ReadOnly);     LOG << QString(file.readAll());     file.close(); #endif     connect(_pWebEnginePage, SIGNAL(loadFinished(bool)), this, SLOT(slot_loadFinished(bool)));     _pWebEnginePage->load(QUrl(filePath));     _pWebEnginePage->setWebChannel(_pWebChannel);     _pWebEngineView->setPage(_pWebEnginePage);      // 背景透明 //    _pWebEngineView->setStyleSheet("background-color: transparent");     _pWebEnginePage->setBackgroundColor(Qt::transparent); } 

步骤三:动态操作

  Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo

重置

void BarAutoSortEChartWidget::on_pushButton_reset_clicked() {     initJs(); } 

刷新

void BarAutoSortEChartWidget::on_pushButton_flush_clicked() {     QString jsStr =             "var empty = {};"             "myChart.setOption(empty, true);"             "myChart.setOption(option, true);";     runJsScript(jsStr); } 

开始统计(使用Qt代码)

  这里预留了定时器间隔。

void BarAutoSortEChartWidget::on_pushButton_start_clicked() {     if(_timerId == -1)     {         LOG << ui->lineEdit_interval->text().toInt();         _timerId = startTimer(ui->lineEdit_interval->text().toInt());         _dateTime.setSecsSinceEpoch(0);         QString jsStr = QString(                 "option.series[0].data[0] = 0;"                 "option.series[0].data[1] = 0;"                 "option.series[0].data[2] = 0;"                 "option.series[0].data[3] = 0;"                 "option.series[0].data[4] = 0;"                 "option.graphic.elements[0].style.text= '%1';"                 "myChart.setOption(option, true);"                 )                 .arg(_dateTime.toString("yyyy-MM"));         runJsScript(jsStr);          ui->pushButton_start->setText("停止统计");     }else{         if(_timerId != -1)         {             killTimer(_timerId);             _timerId = -1;         }         ui->pushButton_start->setText("开始统计");     } } void BarAutoSortEChartWidget::timerEvent(QTimerEvent *event) {     _dateTime = _dateTime.addMonths(1);     if(_dateTime >= QDateTime::currentDateTime())     {         if(_timerId != -1)         {             killTimer(_timerId);             _timerId = -1;         }     }     QString jsStr = QString(             "option.series[0].data[0] = option.series[0].data[0] + %1;"             "option.series[0].data[1] = option.series[0].data[1] + %2;"             "option.series[0].data[2] = option.series[0].data[2] + %3;"             "option.series[0].data[3] = option.series[0].data[3] + %4;"             "option.series[0].data[4] = option.series[0].data[4] + %5;"             "option.graphic.elements[0].style.text= '%6';"             "myChart.setOption(option, true);"             )             .arg(qrand()%100)             .arg(qrand()%100)             .arg(qrand()%100)             .arg(qrand()%100)             .arg(qrand()%100)             .arg(_dateTime.toString("yyyy-MM"));     runJsScript(jsStr); } 

清除数据

void BarAutoSortEChartWidget::on_pushButton_clear_clicked() {     _dateTime.setSecsSinceEpoch(0);     QString jsStr = QString(             "option.series[0].data[0] = 0;"             "option.series[0].data[1] = 0;"             "option.series[0].data[2] = 0;"             "option.series[0].data[3] = 0;"             "option.series[0].data[4] = 0;"             "option.graphic.elements[0].style.text= '%1';"             "myChart.setOption(option, true);"             )             .arg(_dateTime.toString("yyyy-MM"));     runJsScript(jsStr); } 

 

Demo源码

BarAutoSortEChartWidget.h

#ifndef BARAUTOSORTECHARTWIDGET_H #define BARAUTOSORTECHARTWIDGET_H  #include <QWidget> #include <QWebEngineView> #include <QWebEnginePage> #include <QWebChannel>  namespace Ui { class BarAutoSortEChartWidget; }  class BarAutoSortEChartWidget : public QWidget {     Q_OBJECT  public:     explicit BarAutoSortEChartWidget(QWidget *parent = 0);     ~BarAutoSortEChartWidget();  protected:     void initControl();  protected slots:     void slot_loadFinished(bool result);  protected:     void initJs();  protected:     void runJsScript(QString str);  protected:     void resizeEvent(QResizeEvent *event);     void timerEvent(QTimerEvent *event);  private slots:     void on_pushButton_clear_clicked();     void on_pushButton_flush_clicked();     void on_pushButton_start_clicked();     void on_pushButton_reset_clicked();   private:     Ui::BarAutoSortEChartWidget *ui;  private:     QWebEngineView *_pWebEngineView;            // 浏览器窗口     QWebEnginePage *_pWebEnginePage;            // 浏览器页面     QWebChannel *_pWebChannel;                  // 浏览器js交互      QString _htmlDir;                           // html文件夹路径     QString _indexFileName;                     // html文件      QString _initJsStr;                         // 第一次初始化的表格  private:     int _timerId;     QDateTime _dateTime; };  #endif // BARAUTOSORTECHARTWIDGET_H 

BarAutoSortEChartWidget.cpp

#include "BarAutoSortEChartWidget.h" #include "ui_BarAutoSortEChartWidget.h"  #include <QFile> #include <QMessageBox> #include <QTimer>  // QtCreator在msvc下设置编码也或有一些乱码,直接一刀切,避免繁琐的设置 //#define MSVC #ifdef MSVC #define QSTRING(s)  QString::fromLocal8Bit(s) #else #define QSTRING(s)  QString(s) #endif  #include <QDebug> #include <QDateTime> //#define LOG qDebug()<<__FILE__<<__LINE__ //#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__ //#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread() //#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd") #define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")  BarAutoSortEChartWidget::BarAutoSortEChartWidget(QWidget *parent) :     QWidget(parent),     ui(new Ui::BarAutoSortEChartWidget),     _pWebEngineView(0),     _pWebEnginePage(0),     _pWebChannel(0),     _htmlDir("D:/qtProject/echartsDemo/echartsDemo/modules/barAutoSortEChartWidget/html"),    // 使用了绝对路径,引到html文件夹     _indexFileName("eChartWidget.html"),     _timerId(-1) {     ui->setupUi(this);      QString version = "v1.0.0";     setWindowTitle(QString("基于Qt的ECharts条状图(自动排序)Demo %1(长沙红胖子).arg(version));      // 设置无边框,以及背景透明     // 背景透明,在界面构架时,若为本窗口为其他窗口提升为本窗口时,     // 则再qss会在主窗口第一级添加frame_all,防止其他窗口提升本窗口而冲掉qss设置 //    setWindowFlag(Qt::FramelessWindowHint); //    setAttribute(Qt::WA_TranslucentBackground, true);  #if 0     // 这是方法一:让滚动条不出来(通过大小),还有一个方法是在html设置body的overflow: hidden //    resize(600 + 20, 400 + 20); #endif      initControl(); }  BarAutoSortEChartWidget::~BarAutoSortEChartWidget() {     delete ui; }   void BarAutoSortEChartWidget::initControl() {     _pWebEngineView = new QWebEngineView(this);     _pWebEnginePage = new QWebEnginePage(this);     _pWebChannel = new QWebChannel(this);     QString filePath; #if 1     filePath = QString("%1/%2").arg(_htmlDir).arg(_indexFileName); #else     filePath = "qrc:/barAutoSortEChartWidget/html/eChartWidget.html"; #endif     LOG << "file exist:" << QFile::exists(filePath) << filePath; #if 0     // 打印html文件内容     QFile file(_indexFilePath);     file.open(QIODevice::ReadOnly);     LOG << QString(file.readAll());     file.close(); #endif     connect(_pWebEnginePage, SIGNAL(loadFinished(bool)), this, SLOT(slot_loadFinished(bool)));     _pWebEnginePage->load(QUrl(filePath));     _pWebEnginePage->setWebChannel(_pWebChannel);     _pWebEngineView->setPage(_pWebEnginePage);      // 背景透明 //    _pWebEngineView->setStyleSheet("background-color: transparent");     _pWebEnginePage->setBackgroundColor(Qt::transparent); }  void BarAutoSortEChartWidget::slot_loadFinished(bool result) {     if(result)     {         initJs();         // 因为使用布局,在没有完全构造之前,其大小是不可预期的,等构造完成后,布局的大小才会形成,此时再初始化一次         resizeEvent(0);     } }  void BarAutoSortEChartWidget::initJs() {     _initJsStr = QSTRING(             "option = {"             "  xAxis: {"             "    max: 'dataMax'"             "  },"             "  yAxis: {"             "    type: 'category',"             "    data: ['特斯拉', '奔驰', '宝马', '理想', '蔚来'],"             "    inverse: true,"             "    animationDuration: 300,"             "    animationDurationUpdate: 300,"             "    max: 4"             "  },"             "  series: ["             "    {"             "      realtimeSort: true,"             "      name: 'X',"             "      type: 'bar',"             "      data: [10,20,50,10,30],"             "      label: {"             "        show: true,"             "        position: 'right',"             "        valueAnimation: true"             "      },"             "      itemStyle: {"             "            color: function(params) {"             "              var colorList = ['#EE14FF', '#F092FF', '#FF61FE', '#A02F99', '#F00682'];  /* 注意1:需要分号 */"             "              return colorList[params.dataIndex];    /* 注意2:需要dataIndex,获取序号 */"             "         }"             "      }"             "    },"             "  ],"             "  graphic: {"             "    elements: [    /* 时间标志 */"             "      {"             "        type: 'text', "             "        right: 160,"             "        bottom: 100,"             "        style: {"             "          text: '1970-01',"             "          font: 'bolder 100px monospace',"             "          fill: 'rgba(100, 100, 100, 0.25)'"             "        },"             "        z: 100"             "      }"             "    ]"             "  },"             "  legend: {"             "    show: false,"             "  },"             "  animationDuration: 0,"             "  animationDurationUpdate: 1000,"             "  animationEasing: 'linear',"             "  animationEasingUpdate: 'linear'"             "};"             "myChart.setOption(option);");     runJsScript(_initJsStr); }  void BarAutoSortEChartWidget::runJsScript(QString str) {     if(_pWebEnginePage)     {         _pWebEnginePage->runJavaScript(str);     } }  void BarAutoSortEChartWidget::resizeEvent(QResizeEvent *event) {     if(_pWebEngineView)     {         _pWebEngineView->setGeometry(ui->label_echarts->geometry());         LOG << ui->label_echarts->geometry();     } }  void BarAutoSortEChartWidget::timerEvent(QTimerEvent *event) {     _dateTime = _dateTime.addMonths(1);     if(_dateTime >= QDateTime::currentDateTime())     {         if(_timerId != -1)         {             killTimer(_timerId);             _timerId = -1;         }     }     QString jsStr = QString(             "option.series[0].data[0] = option.series[0].data[0] + %1;"             "option.series[0].data[1] = option.series[0].data[1] + %2;"             "option.series[0].data[2] = option.series[0].data[2] + %3;"             "option.series[0].data[3] = option.series[0].data[3] + %4;"             "option.series[0].data[4] = option.series[0].data[4] + %5;"             "option.graphic.elements[0].style.text= '%6';"             "myChart.setOption(option, true);"             )             .arg(qrand()%100)             .arg(qrand()%100)             .arg(qrand()%100)             .arg(qrand()%100)             .arg(qrand()%100)             .arg(_dateTime.toString("yyyy-MM"));     runJsScript(jsStr); }  void BarAutoSortEChartWidget::on_pushButton_clear_clicked() {     _dateTime.setSecsSinceEpoch(0);     QString jsStr = QString(             "option.series[0].data[0] = 0;"             "option.series[0].data[1] = 0;"             "option.series[0].data[2] = 0;"             "option.series[0].data[3] = 0;"             "option.series[0].data[4] = 0;"             "option.graphic.elements[0].style.text= '%1';"             "myChart.setOption(option, true);"             )             .arg(_dateTime.toString("yyyy-MM"));     runJsScript(jsStr); }  void BarAutoSortEChartWidget::on_pushButton_flush_clicked() {     QString jsStr =             "var empty = {};"             "myChart.setOption(empty, true);"             "myChart.setOption(option, true);";     runJsScript(jsStr); }  void BarAutoSortEChartWidget::on_pushButton_start_clicked() {     if(_timerId == -1)     {         LOG << ui->lineEdit_interval->text().toInt();         _timerId = startTimer(ui->lineEdit_interval->text().toInt());         _dateTime.setSecsSinceEpoch(0);         QString jsStr = QString(                 "option.series[0].data[0] = 0;"                 "option.series[0].data[1] = 0;"                 "option.series[0].data[2] = 0;"                 "option.series[0].data[3] = 0;"                 "option.series[0].data[4] = 0;"                 "option.graphic.elements[0].style.text= '%1';"                 "myChart.setOption(option, true);"                 )                 .arg(_dateTime.toString("yyyy-MM"));         runJsScript(jsStr);          ui->pushButton_start->setText("停止统计");     }else{         if(_timerId != -1)         {             killTimer(_timerId);             _timerId = -1;         }         ui->pushButton_start->setText("开始统计");     } }  void BarAutoSortEChartWidget::on_pushButton_reset_clicked() {     initJs(); } 

 

工程模板v1.4.0

  Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo

 

入坑

入坑一:排序图问题无法自动排序

问题

  没有排序:
  Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo

原理

  这里之前我们已经遇见各种坑了,所以直接上调试工具,将Qt的js初始化代码在调试工具当中跑,如下图,web调试网页效果:
  Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo

解决方法

  自己调整序号,交换数据可以实现,但是无法实现上下条交换的动画了。

发表评论

相关文章

当前内容话题