若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/127171413

红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)

Qt开发专栏:三方库开发技术

上一篇:《Qt+ECharts开发笔记(四):ECharts的饼图介绍、基础使用和Qt封装百分比图Demo》
下一篇:敬请期待…

前言

  上一篇的demo使用隐藏js代码的方式,实现了一个饼图的基本交互方式,并预留了Qt模块对外的基础接口。
  本篇的demo实现了自动排序的柱状图,实现了一个自动排序柱状图的基本交互方式,即Qt调用js脚本操作html。
  本篇demo使用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

步骤一:静态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 1filePath = QString("%1/%2").arg(_htmlDir).arg(_indexFileName);
#elsefilePath = "qrc:/barAutoSortEChartWidget/html/eChartWidget.html";
#endifLOG << "file exist:" << QFile::exists(filePath) << filePath;
#if 0// 打印html文件内容QFile file(_indexFilePath);file.open(QIODevice::ReadOnly);LOG << QString(file.readAll());file.close();
#endifconnect(_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::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_OBJECTpublic: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);
#endifinitControl();
}BarAutoSortEChartWidget::~BarAutoSortEChartWidget()
{delete ui;
}void BarAutoSortEChartWidget::initControl()
{_pWebEngineView = new QWebEngineView(this);_pWebEnginePage = new QWebEnginePage(this);_pWebChannel = new QWebChannel(this);QString filePath;
#if 1filePath = QString("%1/%2").arg(_htmlDir).arg(_indexFileName);
#elsefilePath = "qrc:/barAutoSortEChartWidget/html/eChartWidget.html";
#endifLOG << "file exist:" << QFile::exists(filePath) << filePath;
#if 0// 打印html文件内容QFile file(_indexFilePath);file.open(QIODevice::ReadOnly);LOG << QString(file.readAll());file.close();
#endifconnect(_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的js初始化代码在调试工具当中跑,如下图,web调试网页效果:
  

解决方法

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

上一篇:《Qt+ECharts开发笔记(四):ECharts的饼图介绍、基础使用和Qt封装百分比图Demo》
下一篇:敬请期待…

若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/127171413

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

  1. 开发笔记——vue echarts图表在切换页面大小时缩成一团

    开发笔记--vue echarts图表在切换页面大小时缩成一团 添加this.$nextTick() this.$nextTick(()=>{this.getjkechertsdata(); / ...

  2. Qt+QtWebApp开发笔记(一):QtWebApp介绍、下载和搭建基础封装http轻量级服务器Demo

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130631547 红胖子网络科技博文大全:开发技术集合( ...

  3. libzip开发笔记(一):libzip库介绍、编译和工程模板

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/111876926 长期持续带来更多项目与技术分 ...

  4. 【Visual C++】游戏开发笔记二十七 Direct3D 11入门级知识介绍

    游戏开发笔记二十七 Direct3D 11入门级知识介绍 作者:毛星云    邮箱: happylifemxy@163.com    期待着与志同道合的朋友们相互交流 上一节里我们介绍了在迈入Dire ...

  5. 微信小程序开发笔记 进阶篇⑤——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之前)

    文章目录 一.前言 二.前端代码wxml 三.前端代码js 四.后端java 五.程序流程 六.参考 一.前言 微信小程序开发笔记--导读 大部分微信小程序开发者都会有这样的需求:获取小程序用户的手机 ...

  6. 微信小程序开发笔记 进阶篇⑥——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之后)

    文章目录 一.前言 二.前端代码wxml 三.前端代码js 四.后端java 五.程序流程 六.参考 一.前言 微信小程序开发笔记--导读 大部分微信小程序开发者都会有这样的需求:获取小程序用户的手机 ...

  7. 树莓派开发笔记(五):GPIO引脚介绍和GPIO的输入输出使用(驱动LED灯、检测按键)

    若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...

  8. JNI开发笔记(五)--JNI语法总结

    JNI语法总结 引 前言 1. 传参类型为变量/变量指针 1.1 变量 1.2 变量指针 2. 传参类型为数组指针 3. 传参类型为结构体指针 引 JNI开发笔记(一)–Android Studio安 ...

  9. 【Vue ECharts开发】自定义echarts柱状图颜色渐变效果

    1. 效果演示 2. 示例代码 Vue 模板代码: <template><div><div id="main"></div>< ...

最新文章

  1. php发送指令,PHP发送AT指令实例代码
  2. BCI比赛数据集简介-BCI competition IV 2b
  3. 安装Ruby和Rails运行环境
  4. PyQt5 图形界面 - Qt Designer创建qrc资源文件引用图片资源实例演示,QTextBrower组件引用图片资源方法展示
  5. Go简单的Goroutine示例
  6. ext3分区修复linux,linux – 如何从损坏的ext3分区恢复数据?
  7. Echart在Openlayers的应用
  8. C++ 简单的语音合成(TTS,即文字转语音)类
  9. WPF 写一个提醒工具软件(完整项目)
  10. Ubuntu|ython3 :ImportError: cannot import name 'main'
  11. 如何成为一名好的研究生
  12. 在可见性变小的时代,如何修复网络问题?
  13. ASP.NET 控件与可访问
  14. 物流广告收入实现高速增长 国际投行看好京东转型潜力
  15. 图解设计模式-Visitor模式
  16. 计算机故障基本维修方法,11种打印机常见故障维修方法
  17. 解决java.lang.ClassCastException class java.lang.Integer cannot be cast to class java.lang.Long异常
  18. lisp 圆柱螺旋线_Visual LISP开发三维圆柱螺旋线程序
  19. python switch函数
  20. 【机械仿真】基于matlab GUI曲柄摇杆机构运动仿真【含Matlab源码 1608期】

热门文章

  1. [ 物联网篇 ] 14 - 联发科MTK8516 Yocto技巧
  2. 408计算机组成原理学习笔记——计算机系统概述
  3. Asp.net WebMatrix 学习笔记
  4. 毕业设计 单片机的手势识别系统 - 手势识别 单片机 物联网
  5. 生活多快乐:笑死爹的程序段子
  6. 面试官教你 ,如何应对秋招面试(不看后悔篇)!!!
  7. 4G+GPS天线+MQTT连接湖畔云,上传GPS信息
  8. 【转帖】暴雪CEO谈魔兽开发:研发团队要对项目有激情
  9. PowerBI实用技巧:案例四(实现复杂动态矩阵TOPN and Others 排名分类)
  10. Vin码/车架号OCr识别