Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo
若该文为原创文章,转载请注明原文出处
本文章博客地址: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相关推荐
- 开发笔记——vue echarts图表在切换页面大小时缩成一团
开发笔记--vue echarts图表在切换页面大小时缩成一团 添加this.$nextTick() this.$nextTick(()=>{this.getjkechertsdata(); / ...
- Qt+QtWebApp开发笔记(一):QtWebApp介绍、下载和搭建基础封装http轻量级服务器Demo
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130631547 红胖子网络科技博文大全:开发技术集合( ...
- libzip开发笔记(一):libzip库介绍、编译和工程模板
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/111876926 长期持续带来更多项目与技术分 ...
- 【Visual C++】游戏开发笔记二十七 Direct3D 11入门级知识介绍
游戏开发笔记二十七 Direct3D 11入门级知识介绍 作者:毛星云 邮箱: happylifemxy@163.com 期待着与志同道合的朋友们相互交流 上一节里我们介绍了在迈入Dire ...
- 微信小程序开发笔记 进阶篇⑤——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之前)
文章目录 一.前言 二.前端代码wxml 三.前端代码js 四.后端java 五.程序流程 六.参考 一.前言 微信小程序开发笔记--导读 大部分微信小程序开发者都会有这样的需求:获取小程序用户的手机 ...
- 微信小程序开发笔记 进阶篇⑥——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之后)
文章目录 一.前言 二.前端代码wxml 三.前端代码js 四.后端java 五.程序流程 六.参考 一.前言 微信小程序开发笔记--导读 大部分微信小程序开发者都会有这样的需求:获取小程序用户的手机 ...
- 树莓派开发笔记(五):GPIO引脚介绍和GPIO的输入输出使用(驱动LED灯、检测按键)
若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...
- JNI开发笔记(五)--JNI语法总结
JNI语法总结 引 前言 1. 传参类型为变量/变量指针 1.1 变量 1.2 变量指针 2. 传参类型为数组指针 3. 传参类型为结构体指针 引 JNI开发笔记(一)–Android Studio安 ...
- 【Vue ECharts开发】自定义echarts柱状图颜色渐变效果
1. 效果演示 2. 示例代码 Vue 模板代码: <template><div><div id="main"></div>< ...
最新文章
- php发送指令,PHP发送AT指令实例代码
- BCI比赛数据集简介-BCI competition IV 2b
- 安装Ruby和Rails运行环境
- PyQt5 图形界面 - Qt Designer创建qrc资源文件引用图片资源实例演示,QTextBrower组件引用图片资源方法展示
- Go简单的Goroutine示例
- ext3分区修复linux,linux – 如何从损坏的ext3分区恢复数据?
- Echart在Openlayers的应用
- C++ 简单的语音合成(TTS,即文字转语音)类
- WPF 写一个提醒工具软件(完整项目)
- Ubuntu|ython3 :ImportError: cannot import name 'main'
- 如何成为一名好的研究生
- 在可见性变小的时代,如何修复网络问题?
- ASP.NET 控件与可访问
- 物流广告收入实现高速增长 国际投行看好京东转型潜力
- 图解设计模式-Visitor模式
- 计算机故障基本维修方法,11种打印机常见故障维修方法
- 解决java.lang.ClassCastException class java.lang.Integer cannot be cast to class java.lang.Long异常
- lisp 圆柱螺旋线_Visual LISP开发三维圆柱螺旋线程序
- python switch函数
- 【机械仿真】基于matlab GUI曲柄摇杆机构运动仿真【含Matlab源码 1608期】