上一篇的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 = "qrc:/barAutoSortEChartWidget/html/eChartWidget.html";