文章目录
- 上一篇成功是EChart随着Qt窗口变化而变化,本篇将开始正式介绍柱状图介绍、基础使用,并将其封装一层Qt。 本篇的demo实现了隐藏js代码的方式,实现了一个条形图的基本交互方式,即Qt调用js脚本操作html。 <br>
- <br>
- ECharts提供的纯JS代码编辑开发调试工具,可编辑js,并且查看运行效果: https://echarts.apache.org/examples/zh/editor.html 开发过程中对于属性的查询和调试ECharts也提供了配置帮助。 官方配置手册:https://echarts.apache.org/zh/option.html <br>
- 随便找一个预期目标: <br>
- 使用EChart调试工具开发,先调试出基础框架。 这里贴出的全部代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>ECharts</title> <!-- 引入刚刚下载的 ECharts 文件 --> <!--<script src="echarts.js"></script>--> <script src="./echarts.js"></script> <!--<script src="D:/qtProject/echartsDemo/echartsDemo/modules/barEChartWidget/html/echarts.js"></script>--> <!--<script src="echarts.min.js"></script>--> <!--<script src="./echarts.min.js"></script>--> <!--<script src="./html/echarts.min.js"></script>--> <!--<script src="D:/qtProject/echartsDemo/echartsDemo/modules/barEChartWidget/html/echarts.min.js"></script>--> </head> <body> <!--设置body跟随查u哪个口,main填充body--> <style> #main, html, body{ width: 100%; height: 100%; overflow: hidden; } #main { width: 100%; height: 100%; } </style> <div id="main"></div> <script type="text/javascript"> // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main')); // 窗口高度变化设置 window.onresize = function() { myChart.resize(); }; // 指定图表的配置项和数据 var option = { title: { text: 'ECharts 入门示例' }, tooltip: {}, legend: { data: ['销量'] }, xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, series: [ { name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); function initJs() { var myChart = echarts.init(document.getElementById('main')); var option; option = { tooltip: { trigger: 'axis' }, grid: { left: '3%', right: '4%', bottom: '50', containLabel: true }, legend: { orient: 'horizontal', x: 'center', y: 'bottom', itemGap: 100 }, xAxis: { type: 'value' }, yAxis: { type: 'category', data: ['项目1', '项目2', '项目3'] }, series: [ { name: '变量1', type: 'bar', stack: 'totla', label: { show: true }, data: [11, 12, 13] }, { name: '子项目1', type: 'bar', stack: 'totla', label: { show: true }, data: [24, 20, 21] }, { name: '变量3', type: 'bar', stack: 'totla', label: { show: true }, data: [95, 87, 55] } ] }; }; initJs(); </script> </body> </html> <br>
- 动态方式,最初目的是为了动态实现数据的js操作,在开发过程中发现动态方式还能隐藏echarts代码,使echarts代码不被抓取,最后决定全部改为动态加载方式。
- <!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>
- 新增了loadFinished信号槽关联。 void BarEChartWidget::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:/barEChartWidget/html/barEChartWidget.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 BarEChartWidget::slot_loadFinished(bool result) { if(result) { initJs(); } } void BarEChartWidget::initJs() { _initJsStr = QSTRING( "var option;" "option = {" " tooltip: {" " trigger: 'axis'" " }," " grid: {" " left: '10'," " right: '10'," " top: '10'," " bottom: 30," " containLabel: true" " }," " legend: {" " orient: 'horizontal'," " x: 'center'," " y: 'bottom'," " itemGap: 20" " }," " xAxis: {" " type: 'value'" " }," " yAxis: {" " type: 'category'," " data: ['项目1', '项目2', '项目3']" " }," " series: [" " {" " name: '变量1'," " type: 'bar'," " stack: 'totla'," " label: {" " show: true" " }," " data: [11, 12, 13]" " }," " {" " name: '变量2'," " type: 'bar'," " stack: 'totla'," " label: {" " show: true" " }," " data: [24, 20, 21]" " }," " {" " name: '变量3'," " type: 'bar'," " stack: 'totla'," " label: {" " show: true" " }," " data: [95, 87, 55]" " }" " ]" "};" "myChart.setOption(option);"); runJsScript(_initJsStr); } void BarEChartWidget::runJsScript(QString str) { if(_pWebEnginePage) { _pWebEnginePage->runJavaScript(str); } }
-
- void BarEChartWidget::on_pushButton_reset_clicked() { initJs(); }
- void BarEChartWidget::on_pushButton_flush_clicked() { QString jsStr = "var empty = {};" "myChart.setOption(empty, true);" "myChart.setOption(option, true);"; runJsScript(jsStr); }
- void BarEChartWidget::on_pushButton_clear_clicked() { QString jsStr = "option.series[0].data = [];" "option.series[1].data = [];" "option.series[2].data = [];" "myChart.setOption(option, true);"; runJsScript(jsStr); }
- void BarEChartWidget::on_pushButton_createRandom_clicked() { QString jsStr = "var min = 0;" "var max = 100;" "for(var i = 0; i < option.series.length; i++)" "{" " for(var j = 0; j < option.yAxis.data.length; j++)" " {" " option.series[i].data[j] = Math.floor(Math.random() * (max - min)) + min;" " }" "}" "myChart.setOption(option, true);"; runJsScript(jsStr); } 后续用会将数据进行Qt的一份缓存数据,由Qt的数据去生成ecahrts的js脚本。 <br>
- 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> 在代码中使用js初始化echarts: BarECartWidget.h #ifndef BARECHARTWIDGET_H #define BARECHARTWIDGET_H #include <QWidget> #include <QWebEngineView> #include <QWebEnginePage> #include <QWebChannel> namespace Ui { class BarEChartWidget; } class BarEChartWidget : public QWidget { Q_OBJECT public: explicit BarEChartWidget(QWidget *parent = 0); ~BarEChartWidget(); protected: void initControl(); protected slots: void slot_loadFinished(bool result); protected: void initJs(); protected: void runJsScript(QString str); protected: void resizeEvent(QResizeEvent *event); private slots: void on_pushButton_clear_clicked(); void on_pushButton_flush_clicked(); void on_pushButton_createRandom_clicked(); void on_pushButton_reset_clicked(); private: Ui::BarEChartWidget *ui; private: QWebEngineView *_pWebEngineView; // 浏览器窗口 QWebEnginePage *_pWebEnginePage; // 浏览器页面 QWebChannel *_pWebChannel; // 浏览器js交互 QString _htmlDir; // html文件夹路径 QString _indexFileName; // html文件 QString _initJsStr; // 第一次初始化的表格 }; #endif // BARECHARTWIDGET_H BarEChartWidget.cpp #include "BarEChartWidget.h" #include "ui_BarEChartWidget.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") BarEChartWidget::BarEChartWidget(QWidget *parent) : QWidget(parent), ui(new Ui::BarEChartWidget), _pWebEngineView(0), _pWebEnginePage(0), _pWebChannel(0), _htmlDir("D:/qtProject/echartsDemo/echartsDemo/modules/barEChartWidget/html"), // 使用了绝对路径,引到html文件夹 _indexFileName("barEChartWidget.html") { ui->setupUi(this); QString version = "v1.0.0"; setWindowTitle(QString("基于Qt的ECharts条状图Demo %1(长沙红胖子 QQ:21497936 WX:15173255813 blog:hpzwl.blog.csdn.net").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(); } BarEChartWidget::~BarEChartWidget() { delete ui; } void BarEChartWidget::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:/barEChartWidget/html/barEChartWidget.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 BarEChartWidget::slot_loadFinished(bool result) { if(result) { initJs(); } } void BarEChartWidget::initJs() { _initJsStr = QSTRING( "var option;" "option = {" " tooltip: {" " trigger: 'axis'" " }," " grid: {" " left: '10'," " right: '10'," " top: '10'," " bottom: 30," " containLabel: true" " }," " legend: {" " orient: 'horizontal'," " x: 'center'," " y: 'bottom'," " itemGap: 20" " }," " xAxis: {" " type: 'value'" " }," " yAxis: {" " type: 'category'," " data: ['项目1', '项目2', '项目3']" " }," " series: [" " {" " name: '变量1'," " type: 'bar'," " stack: 'totla'," " label: {" " show: true" " }," " data: [11, 12, 13]" " }," " {" " name: '变量2'," " type: 'bar'," " stack: 'totla'," " label: {" " show: true" " }," " data: [24, 20, 21]" " }," " {" " name: '变量3'," " type: 'bar'," " stack: 'totla'," " label: {" " show: true" " }," " data: [95, 87, 55]" " }" " ]" "};" "myChart.setOption(option);"); runJsScript(_initJsStr); } void BarEChartWidget::runJsScript(QString str) { if(_pWebEnginePage) { _pWebEnginePage->runJavaScript(str); } } void BarEChartWidget::resizeEvent(QResizeEvent *event) { if(_pWebEngineView) { _pWebEngineView->setGeometry(ui->label_echarts->geometry()); } } void BarEChartWidget::on_pushButton_clear_clicked() { QString jsStr = "option.series[0].data = [];" "option.series[1].data = [];" "option.series[2].data = [];" "myChart.setOption(option, true);"; runJsScript(jsStr); } void BarEChartWidget::on_pushButton_flush_clicked() { QString jsStr = "var empty = {};" "myChart.setOption(empty, true);" "myChart.setOption(option, true);"; runJsScript(jsStr); } void BarEChartWidget::on_pushButton_createRandom_clicked() { QString jsStr = "var min = 0;" "var max = 100;" "for(var i = 0; i < option.series.length; i++)" "{" " for(var j = 0; j < option.yAxis.data.length; j++)" " {" " option.series[i].data[j] = Math.floor(Math.random() * (max - min)) + min;" " }" "}" "myChart.setOption(option, true);"; runJsScript(jsStr); } void BarEChartWidget::on_pushButton_reset_clicked() { initJs(); } <br>
- <br>
- 条形图将会根据实际需求持续升级版本,下一篇会继续折线图的基础封装。
上一篇成功是EChart随着Qt窗口变化而变化,本篇将开始正式介绍柱状图介绍、基础使用,并将其封装一层Qt。 本篇的demo实现了隐藏js代码的方式,实现了一个条形图的基本交互方式,即Qt调用js脚本操作html。,<br>,
,<br>, ECharts提供的纯JS代码编辑开发调试工具,可编辑js,并且查看运行效果:
https://echarts.apache.org/examples/zh/editor.html
开发过程中对于属性的查询和调试ECharts也提供了配置帮助。 官方配置手册:
https://echarts.apache.org/zh/option.html
,<br>, 随便找一个预期目标:
,<br>, 使用EChart调试工具开发,先调试出基础框架。 这里贴出的全部代码:,<br>, 动态方式,最初目的是为了动态实现数据的js操作,在开发过程中发现动态方式还能
隐藏echarts代码,使echarts代码不被抓取,最后决定全部改为动态加载方式。, 新增了loadFinished信号槽关联。, 后续用会将数据进行Qt的一份缓存数据,由Qt的数据去生成ecahrts的js脚本。,<br>,html文件, 在代码中使用js初始化echarts:
BarECartWidget.h,BarEChartWidget.cpp,<br>, 通过qt代码跑js调用函数失败。
,
, 先要等页面加载完成后才能调用定义的函数。, 发现是调用成功了,原来只定义也会报这个错误。
由此可以看出,在qt中去初始化需要等待页面加载完成才行。, 少数中文乱码,加空格等都无法解决。
, 最终解决了,尝试了QTextCodec等各种都不行,最终:
,<br>,
,<br>, 条形图将会根据实际需求持续升级版本,下一篇会继续折线图的基础封装。,BarEChartWidget.cpp,
上一篇成功是EChart随着Qt窗口变化而变化,本篇将开始正式介绍柱状图介绍、基础使用,并将其封装一层Qt。 本篇的demo实现了隐藏js代码的方式,实现了一个条形图的基本交互方式,即Qt调用js脚本操作html。
<br>

<br>
ECharts提供的纯JS代码编辑开发调试工具,可编辑js,并且查看运行效果: https://echarts.apache.org/examples/zh/editor.html
开发过程中对于属性的查询和调试ECharts也提供了配置帮助。 官方配置手册:https://echarts.apache.org/zh/option.html 
<br>
随便找一个预期目标: 
<br>
使用EChart调试工具开发,先调试出基础框架。 这里贴出的全部代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>ECharts</title>
<!-- 引入刚刚下载的 ECharts 文件 -->
<!--<script src="echarts.js"></script>-->
<script src="./echarts.js"></script>
<!--<script src="D:/qtProject/echartsDemo/echartsDemo/modules/barEChartWidget/html/echarts.js"></script>-->
<!--<script src="echarts.min.js"></script>-->
<!--<script src="./echarts.min.js"></script>-->
<!--<script src="./html/echarts.min.js"></script>-->
<!--<script src="D:/qtProject/echartsDemo/echartsDemo/modules/barEChartWidget/html/echarts.min.js"></script>-->
</head>
<body>
<!--设置body跟随查u哪个口,main填充body-->
<style>
#main,
html,
body{
width: 100%;
height: 100%;
overflow: hidden;
}
#main {
width: 100%;
height: 100%;
}
</style>
<div id="main"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 窗口高度变化设置
window.onresize = function() {
myChart.resize();
};
// 指定图表的配置项和数据
var option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
function initJs() {
var myChart = echarts.init(document.getElementById('main'));
var option;
option = {
tooltip: {
trigger: 'axis'
},
grid: {
left: '3%',
right: '4%',
bottom: '50',
containLabel: true
},
legend: {
orient: 'horizontal',
x: 'center',
y: 'bottom',
itemGap: 100
},
xAxis: {
type: 'value'
},
yAxis: {
type: 'category',
data: ['项目1', '项目2', '项目3']
},
series: [
{
name: '变量1',
type: 'bar',
stack: 'totla',
label: {
show: true
},
data: [11, 12, 13]
},
{
name: '子项目1',
type: 'bar',
stack: 'totla',
label: {
show: true
},
data: [24, 20, 21]
},
{
name: '变量3',
type: 'bar',
stack: 'totla',
label: {
show: true
},
data: [95, 87, 55]
}
]
};
};
initJs();
</script>
</body>
</html>
<br>
动态方式,最初目的是为了动态实现数据的js操作,在开发过程中发现动态方式还能隐藏echarts代码,使echarts代码不被抓取,最后决定全部改为动态加载方式。
<!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>
<!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>
新增了loadFinished信号槽关联。
void BarEChartWidget::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:/barEChartWidget/html/barEChartWidget.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 BarEChartWidget::slot_loadFinished(bool result)
{
if(result)
{
initJs();
}
}
void BarEChartWidget::initJs()
{
_initJsStr = QSTRING(
"var option;"
"option = {"
" tooltip: {"
" trigger: 'axis'"
" },"
" grid: {"
" left: '10',"
" right: '10',"
" top: '10',"
" bottom: 30,"
" containLabel: true"
" },"
" legend: {"
" orient: 'horizontal',"
" x: 'center',"
" y: 'bottom',"
" itemGap: 20"
" },"
" xAxis: {"
" type: 'value'"
" },"
" yAxis: {"
" type: 'category',"
" data: ['项目1', '项目2', '项目3']"
" },"
" series: ["
" {"
" name: '变量1',"
" type: 'bar',"
" stack: 'totla',"
" label: {"
" show: true"
" },"
" data: [11, 12, 13]"
" },"
" {"
" name: '变量2',"
" type: 'bar',"
" stack: 'totla',"
" label: {"
" show: true"
" },"
" data: [24, 20, 21]"
" },"
" {"
" name: '变量3',"
" type: 'bar',"
" stack: 'totla',"
" label: {"
" show: true"
" },"
" data: [95, 87, 55]"
" }"
" ]"
"};"
"myChart.setOption(option);");
runJsScript(_initJsStr);
}
void BarEChartWidget::runJsScript(QString str)
{
if(_pWebEnginePage)
{
_pWebEnginePage->runJavaScript(str);
}
}
void BarEChartWidget::slot_loadFinished(bool result)
{
if(result)
{
initJs();
}
}
void BarEChartWidget::initJs()
{
_initJsStr = QSTRING(
"var option;"
"option = {"
" tooltip: {"
" trigger: 'axis'"
" },"
" grid: {"
" left: '10',"
" right: '10',"
" top: '10',"
" bottom: 30,"
" containLabel: true"
" },"
" legend: {"
" orient: 'horizontal',"
" x: 'center',"
" y: 'bottom',"
" itemGap: 20"
" },"
" xAxis: {"
" type: 'value'"
" },"
" yAxis: {"
" type: 'category',"
" data: ['项目1', '项目2', '项目3']"
" },"
" series: ["
" {"
" name: '变量1',"
" type: 'bar',"
" stack: 'totla',"
" label: {"
" show: true"
" },"
" data: [11, 12, 13]"
" },"
" {"
" name: '变量2',"
" type: 'bar',"
" stack: 'totla',"
" label: {"
" show: true"
" },"
" data: [24, 20, 21]"
" },"
" {"
" name: '变量3',"
" type: 'bar',"
" stack: 'totla',"
" label: {"
" show: true"
" },"
" data: [95, 87, 55]"
" }"
" ]"
"};"
"myChart.setOption(option);");
runJsScript(_initJsStr);
}
void BarEChartWidget::runJsScript(QString str)
{
if(_pWebEnginePage)
{
_pWebEnginePage->runJavaScript(str);
}
}
void BarEChartWidget::on_pushButton_reset_clicked()
{
initJs();
}
void BarEChartWidget::on_pushButton_reset_clicked()
{
initJs();
}
void BarEChartWidget::on_pushButton_flush_clicked()
{
QString jsStr =
"var empty = {};"
"myChart.setOption(empty, true);"
"myChart.setOption(option, true);";
runJsScript(jsStr);
}
void BarEChartWidget::on_pushButton_flush_clicked()
{
QString jsStr =
"var empty = {};"
"myChart.setOption(empty, true);"
"myChart.setOption(option, true);";
runJsScript(jsStr);
}
void BarEChartWidget::on_pushButton_clear_clicked()
{
QString jsStr =
"option.series[0].data = [];"
"option.series[1].data = [];"
"option.series[2].data = [];"
"myChart.setOption(option, true);";
runJsScript(jsStr);
}
void BarEChartWidget::on_pushButton_clear_clicked()
{
QString jsStr =
"option.series[0].data = [];"
"option.series[1].data = [];"
"option.series[2].data = [];"
"myChart.setOption(option, true);";
runJsScript(jsStr);
}
void BarEChartWidget::on_pushButton_createRandom_clicked()
{
QString jsStr =
"var min = 0;"
"var max = 100;"
"for(var i = 0; i < option.series.length; i++)"
"{"
" for(var j = 0; j < option.yAxis.data.length; j++)"
" {"
" option.series[i].data[j] = Math.floor(Math.random() * (max - min)) + min;"
" }"
"}"
"myChart.setOption(option, true);";
runJsScript(jsStr);
}
void BarEChartWidget::on_pushButton_createRandom_clicked()
{
QString jsStr =
"var min = 0;"
"var max = 100;"
"for(var i = 0; i < option.series.length; i++)"
"{"
" for(var j = 0; j < option.yAxis.data.length; j++)"
" {"
" option.series[i].data[j] = Math.floor(Math.random() * (max - min)) + min;"
" }"
"}"
"myChart.setOption(option, true);";
runJsScript(jsStr);
}
后续用会将数据进行Qt的一份缓存数据,由Qt的数据去生成ecahrts的js脚本。
<br>
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>
在代码中使用js初始化echarts: BarECartWidget.h
#ifndef BARECHARTWIDGET_H
#define BARECHARTWIDGET_H
#include <QWidget>
#include <QWebEngineView>
#include <QWebEnginePage>
#include <QWebChannel>
namespace Ui {
class BarEChartWidget;
}
class BarEChartWidget : public QWidget
{
Q_OBJECT
public:
explicit BarEChartWidget(QWidget *parent = 0);
~BarEChartWidget();
protected:
void initControl();
protected slots:
void slot_loadFinished(bool result);
protected:
void initJs();
protected:
void runJsScript(QString str);
protected:
void resizeEvent(QResizeEvent *event);
private slots:
void on_pushButton_clear_clicked();
void on_pushButton_flush_clicked();
void on_pushButton_createRandom_clicked();
void on_pushButton_reset_clicked();
private:
Ui::BarEChartWidget *ui;
private:
QWebEngineView *_pWebEngineView; // 浏览器窗口
QWebEnginePage *_pWebEnginePage; // 浏览器页面
QWebChannel *_pWebChannel; // 浏览器js交互
QString _htmlDir; // html文件夹路径
QString _indexFileName; // html文件
QString _initJsStr; // 第一次初始化的表格
};
#endif // BARECHARTWIDGET_H
BarEChartWidget.cpp
#include "BarEChartWidget.h"
#include "ui_BarEChartWidget.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")
BarEChartWidget::BarEChartWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::BarEChartWidget),
_pWebEngineView(0),
_pWebEnginePage(0),
_pWebChannel(0),
_htmlDir("D:/qtProject/echartsDemo/echartsDemo/modules/barEChartWidget/html"), // 使用了绝对路径,引到html文件夹
_indexFileName("barEChartWidget.html")
{
ui->setupUi(this);
QString version = "v1.0.0";
setWindowTitle(QString("基于Qt的ECharts条状图Demo %1(长沙红胖子 QQ:21497936 WX:15173255813 blog:hpzwl.blog.csdn.net").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();
}
BarEChartWidget::~BarEChartWidget()
{
delete ui;
}
void BarEChartWidget::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:/barEChartWidget/html/barEChartWidget.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 BarEChartWidget::slot_loadFinished(bool result)
{
if(result)
{
initJs();
}
}
void BarEChartWidget::initJs()
{
_initJsStr = QSTRING(
"var option;"
"option = {"
" tooltip: {"
" trigger: 'axis'"
" },"
" grid: {"
" left: '10',"
" right: '10',"
" top: '10',"
" bottom: 30,"
" containLabel: true"
" },"
" legend: {"
" orient: 'horizontal',"
" x: 'center',"
" y: 'bottom',"
" itemGap: 20"
" },"
" xAxis: {"
" type: 'value'"
" },"
" yAxis: {"
" type: 'category',"
" data: ['项目1', '项目2', '项目3']"
" },"
" series: ["
" {"
" name: '变量1',"
" type: 'bar',"
" stack: 'totla',"
" label: {"
" show: true"
" },"
" data: [11, 12, 13]"
" },"
" {"
" name: '变量2',"
" type: 'bar',"
" stack: 'totla',"
" label: {"
" show: true"
" },"
" data: [24, 20, 21]"
" },"
" {"
" name: '变量3',"
" type: 'bar',"
" stack: 'totla',"
" label: {"
" show: true"
" },"
" data: [95, 87, 55]"
" }"
" ]"
"};"
"myChart.setOption(option);");
runJsScript(_initJsStr);
}
void BarEChartWidget::runJsScript(QString str)
{
if(_pWebEnginePage)
{
_pWebEnginePage->runJavaScript(str);
}
}
void BarEChartWidget::resizeEvent(QResizeEvent *event)
{
if(_pWebEngineView)
{
_pWebEngineView->setGeometry(ui->label_echarts->geometry());
}
}
void BarEChartWidget::on_pushButton_clear_clicked()
{
QString jsStr =
"option.series[0].data = [];"
"option.series[1].data = [];"
"option.series[2].data = [];"
"myChart.setOption(option, true);";
runJsScript(jsStr);
}
void BarEChartWidget::on_pushButton_flush_clicked()
{
QString jsStr =
"var empty = {};"
"myChart.setOption(empty, true);"
"myChart.setOption(option, true);";
runJsScript(jsStr);
}
void BarEChartWidget::on_pushButton_createRandom_clicked()
{
QString jsStr =
"var min = 0;"
"var max = 100;"
"for(var i = 0; i < option.series.length; i++)"
"{"
" for(var j = 0; j < option.yAxis.data.length; j++)"
" {"
" option.series[i].data[j] = Math.floor(Math.random() * (max - min)) + min;"
" }"
"}"
"myChart.setOption(option, true);";
runJsScript(jsStr);
}
void BarEChartWidget::on_pushButton_reset_clicked()
{
initJs();
}
<br>
通过qt代码跑js调用函数失败。 

先要等页面加载完成后才能调用定义的函数。
发现是调用成功了,原来只定义也会报这个错误。
由此可以看出,在qt中去初始化需要等待页面加载完成才行。
少数中文乱码,加空格等都无法解决。 
最终解决了,尝试了QTextCodec等各种都不行,最终:

<br>

<br>
条形图将会根据实际需求持续升级版本,下一篇会继续折线图的基础封装。