前言
上一篇的demo使用隐藏js代码的方式,实现了一个饼图的基本交互方式,并预留了Qt模块对外的基础接口。
本篇的demo实现了自动排序的柱状图,实现了一个自动排序柱状图的基本交互方式,即Qt调用js脚本操作html。
本篇demo使用Qt定时器方式,实现数据定时刷新自增,并预留出了定时器间隔参数。
像大数据网页常看的人口增长时间图,收入年度增长时间图等都是这一类。
使用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' };
此系列的标准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); }
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); }
这里预留了定时器间隔。
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); }
#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
#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