QT:Echart-折线图
折线图展示
下载echarts.min.js文件
参考:QT:Qt与ECharts
下载HTML文件
工程代码
#include "widget.h"
#include "ui_widget.h"
#include <QApplication> // 包含 QApplication 头文件
#include <QWebEngineView> // 包含 QWebEngineView 头文件,假设 ui->widget 是 QWebEngineView 类型
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QString exe_path = qApp->applicationDirPath();
// 假设 line-simple.html 文件在可执行文件所在目录下
QString _klinePath = exe_path + "/line-simple.html";
qDebug() << _klinePath;
// 确保 ui->widget 是 QWebEngineView 类型
QWebEngineView *webView = qobject_cast<QWebEngineView*>(ui->widget);
if (webView) {
webView->setUrl(QUrl::fromLocalFile(_klinePath));
} else {
qDebug() << "ui->widget is not a QWebEngineView.";
}
}
Widget::~Widget()
{
delete ui;
}
HTML文件调整
注意HTML文件当中的echarts.min.js文件路径
<!-- <script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
-->
<script src="echarts.min.js"></script>
下载后的HTML文件
<!--
此示例下载自 https://echarts.apache.org/examples/zh/editor.html?c=line-simple
-->
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<head>
<meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0">
<div id="container" style="height: 100%"></div>
<!-- <script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
-->
<script src="echarts.min.js"></script>
<!-- Uncomment this line if you want to dataTool extension
<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5/dist/extension/dataTool.min.js"></script>
-->
<!-- Uncomment this line if you want to use gl extension
<script type="text/javascript" src="https://echarts.apache.org/zh/js/vendors/echarts-gl@2/dist/echarts-gl.min.js"></script>
-->
<!-- Uncomment this line if you want to echarts-stat extension
<script type="text/javascript" src="https://echarts.apache.org/zh/js/vendors/echarts-stat@latest/dist/ecStat.min.js"></script>
-->
<!-- Uncomment this line if you want to echarts-graph-modularity extension
<script type="text/javascript" src="https://echarts.apache.org/zh/js/vendors/echarts-graph-modularity/dist/echarts-graph-modularity.min.js"></script>
-->
<!-- Uncomment this line if you want to use map
<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@4.9.0/map/js/world.js"></script>
-->
<!-- Uncomment these two lines if you want to use bmap extension
<script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=YOUR_API_KEY"></script>
<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5/dist/extension/bmap.min.js"></script>
-->
<script type="text/javascript">
var dom = document.getElementById('container');
var myChart = echarts.init(dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
var option;
option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
}
]
};
if (option && typeof option === 'object') {
myChart.setOption(option);
}
window.addEventListener('resize', myChart.resize);
</script>
</body>
</html>
鼠标控制HTML文件
<!--
此示例下载自 https://echarts.apache.org/examples/zh/editor.html?c=line-simple
-->
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<head>
<meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0">
<div id="container" style="height: 100%"></div>
<!-- <script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
-->
<script src="echarts.min.js"></script>
<!-- Uncomment this line if you want to dataTool extension
<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5/dist/extension/dataTool.min.js"></script>
-->
<!-- Uncomment this line if you want to use gl extension
<script type="text/javascript" src="https://echarts.apache.org/zh/js/vendors/echarts-gl@2/dist/echarts-gl.min.js"></script>
-->
<!-- Uncomment this line if you want to echarts-stat extension
<script type="text/javascript" src="https://echarts.apache.org/zh/js/vendors/echarts-stat@latest/dist/ecStat.min.js"></script>
-->
<!-- Uncomment this line if you want to echarts-graph-modularity extension
<script type="text/javascript" src="https://echarts.apache.org/zh/js/vendors/echarts-graph-modularity/dist/echarts-graph-modularity.min.js"></script>
-->
<!-- Uncomment this line if you want to use map
<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@4.9.0/map/js/world.js"></script>
-->
<!-- Uncomment these two lines if you want to use bmap extension
<script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=YOUR_API_KEY"></script>
<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5/dist/extension/bmap.min.js"></script>
-->
<script type="text/javascript">
var dom = document.getElementById('container');
var myChart = echarts.init(dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
var data = [150, 230, 224, 218, 135, 147, 260]; // 提取数据到变量,方便后续修改
var option;
option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: data, // 使用提取的变量
type: 'line'
}
]
};
// 标记是否正在拖动
var isDragging = false;
var currentIndex = -1;
// 鼠标按下事件
myChart.getZr().on('mousedown', function (params) {
var pointInPixel = [params.offsetX, params.offsetY];
var series = myChart.getOption().series[0];
for (var i = 0; i < series.data.length; i++) {
var point = myChart.convertToPixel('grid', [i, series.data[i]]);
var dx = pointInPixel[0] - point[0];
var dy = pointInPixel[1] - point[1];
if (dx * dx + dy * dy < 25) { // 假设点的半径为5
isDragging = true;
currentIndex = i;
break;
}
}
});
// 鼠标移动事件
myChart.getZr().on('mousemove', function (params) {
if (isDragging) {
var newY = myChart.convertFromPixel('grid', [params.offsetX, params.offsetY])[1];
data[currentIndex] = newY; // 更新数据
option.series[0].data = data; // 更新 option 中的数据
myChart.setOption(option); // 重新设置图表选项,更新图表
}
});
// 鼠标释放事件
myChart.getZr().on('mouseup', function () {
isDragging = false;
currentIndex = -1;
});
if (option && typeof option === 'object') {
myChart.setOption(option);
}
window.addEventListener('resize', myChart.resize);
</script>
</body>
</html>
html 文件的基础上实现鼠标移动图表上的点,可以按照以下步骤添加相应的 JavaScript 代码来实现交互功能。主要思路是通过监听鼠标事件(按下、移动、松开),判断鼠标是否在点的范围内,若在则允许拖动点并更新图表数据。
添加控件可修改图像内容
使用 Qt Designer 创建一个主窗口,添加一个 QLineEdit 和一个 QWebEngineView
修改HTML 文件
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<head>
<meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0">
<div id="container" style="height: 100%"></div>
<script src="echarts.min.js"></script>
<script type="text/javascript">
var dom = document.getElementById('container');
var myChart = echarts.init(dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
// 定义更新线条颜色的函数,并添加简单的颜色值验证
function changeLineColor(color) {
// 简单的颜色值验证,这里只检查十六进制颜色码格式
if (/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color)) {
var option = myChart.getOption();
option.series[0].color = color;
myChart.setOption(option);
} else {
console.warn('Invalid color value. Please use a valid color code (e.g., #RRGGBB or #RGB).');
}
}
var option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
}
]
};
if (option && typeof option === 'object') {
myChart.setOption(option);
}
window.addEventListener('resize', myChart.resize);
</script>
</body>
</html>
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QWebEngineView>
#include <QLineEdit>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_lineEdit_textChanged(const QString &arg1);
private:
Ui::Widget *ui;
QWebEngineView *webView;
QLineEdit *lineEdit;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QApplication> // 包含 QApplication 头文件
#include <QWebEngineView> // 包含 QWebEngineView 头文件,假设 ui->widget 是 QWebEngineView 类型
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// webView = ui->webEngineView;
lineEdit = ui->lineEdit;
QString exe_path = qApp->applicationDirPath();
// 假设 line-simple.html 文件在可执行文件所在目录下
QString _klinePath = exe_path + "/line-simple.html";
qDebug() << _klinePath;
// 确保 ui->widget 是 QWebEngineView 类型
webView = qobject_cast<QWebEngineView*>(ui->widget);
if (webView) {
webView->setUrl(QUrl::fromLocalFile(_klinePath));
} else {
qDebug() << "ui->widget is not a QWebEngineView.";
}
// 连接输入框文本变化信号到槽函数
connect(lineEdit, &QLineEdit::textChanged, this, &Widget::on_lineEdit_textChanged);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_lineEdit_textChanged(const QString &arg1)
{
// 构建 JavaScript 代码,调用 HTML 中的函数更新线条颜色
QString jsCode = QString("changeLineColor('%1');").arg(arg1);
webView->page()->runJavaScript(jsCode);
qDebug() << "Input text:" << arg1;
}
main.c
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
修改折现图,更新控件参数
在 UI 设计中添加一个 QLabel 控件。
TML代码
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<head>
<meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0">
<div id="container" style="height: 100%"></div>
<script src="echarts.min.js"></script>
<script type="text/javascript">
var dom = document.getElementById('container');
var myChart = echarts.init(dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
// 存储原始数据
var originalData = [150, 230, 224, 218, 135, 147, 260];
var data = originalData.slice(); // 复制原始数据
function changeLineColor(color) {
var option = myChart.getOption();
option.series[0].color = color;
myChart.setOption(option);
}
function getData() {
try {
var option = myChart.getOption();
return option.series[0].data;
} catch (error) {
// 将错误信息作为字符串返回
return "Error in getData: " + error.message;
}
}
// 标记是否正在拖动
var isDragging = false;
var currentIndex = -1;
// 鼠标按下事件
myChart.getZr().on('mousedown', function (params) {
var pointInPixel = [params.offsetX, params.offsetY];
var series = myChart.getOption().series[0];
for (var i = 0; i < series.data.length; i++) {
var point = myChart.convertToPixel('grid', [i, series.data[i]]);
var dx = pointInPixel[0] - point[0];
var dy = pointInPixel[1] - point[1];
if (dx * dx + dy * dy < 25) { // 假设点的半径为5
isDragging = true;
currentIndex = i;
break;
}
}
});
// 鼠标移动事件
myChart.getZr().on('mousemove', function (params) {
if (isDragging) {
var newY = myChart.convertFromPixel('grid', [params.offsetX, params.offsetY])[1];
data[currentIndex] = newY;
var option = myChart.getOption();
option.series[0].data = data;
myChart.setOption(option);
}
});
// 鼠标释放事件
myChart.getZr().on('mouseup', function () {
isDragging = false;
currentIndex = -1;
});
var option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: data,
type: 'line'
}
]
};
if (option && typeof option === 'object') {
myChart.setOption(option);
}
window.addEventListener('resize', myChart.resize);
</script>
</body>
</html>
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QWebEngineView>
#include <QLineEdit>
#include <QLabel>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_lineEdit_textChanged(const QString &arg1);
void updateMaxValueLabel();
private:
Ui::Widget *ui;
QWebEngineView *webView;
QLineEdit *lineEdit;
QLabel *maxValueLabel; // 添加 QLabel 成员变量
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QApplication> // 包含 QApplication 头文件
#include <QWebEngineView> // 包含 QWebEngineView 头文件,假设 ui->widget 是 QWebEngineView 类型
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
lineEdit = ui->lineEdit;
maxValueLabel = ui->label;
QString exe_path = qApp->applicationDirPath();
// 假设 line-simple.html 文件在可执行文件所在目录下
QString _klinePath = exe_path + "/line-simple.html";
qDebug() << _klinePath;
// 确保 ui->widget 是 QWebEngineView 类型
webView = qobject_cast<QWebEngineView*>(ui->widget);
if (webView) {
webView->setUrl(QUrl::fromLocalFile(_klinePath));
} else {
qDebug() << "ui->widget is not a QWebEngineView.";
}
// 连接输入框文本变化信号到槽函数
connect(lineEdit, &QLineEdit::textChanged, this, &Widget::on_lineEdit_textChanged);
// updateMaxValueLabel();
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_lineEdit_textChanged(const QString &arg1)
{
// 构建 JavaScript 代码,调用 HTML 中的函数更新线条颜色
QString jsCode = QString("changeLineColor('%1');").arg(arg1);
webView->page()->runJavaScript(jsCode);
qDebug() << "Input text:" << arg1;
// 输入框文本变化时也更新最大值标签
updateMaxValueLabel();
}
void Widget::updateMaxValueLabel()
{
QString jsCode = "getData();";
webView->page()->runJavaScript(jsCode, [this](const QVariant &result) {
if(result.isNull())
{
qDebug() << "JavaScript execution result:isNull";
}
// 检查结果的类型是否符合预期且不为空
if (result.type() == QVariant::List &&!result.isNull()) {
if (result.canConvert<QVariantList>()) {
QVariantList dataList = result.toList();
int maxValue = 0;
for (const QVariant &value : dataList) {
if (value.canConvert<int>()) {
int currentValue = value.toInt();
l if (currentValue > maxValue) {
maxValue = currentValue;
}
}
}
maxValueLabel->setText(QString("Max Value: %1").arg(maxValue));
qDebug() << "Max Value:" << maxValue;
} else {
maxValueLabel->setText("Max Value: N/A");
qDebug() << "Result cannot be converted to QVariantList:" << result;
}
} else {
maxValueLabel->setText("Max Value: N/A");
qDebug() << "JavaScript execution result is invalid:" << result;
}
});
}