当前位置: 首页 > article >正文

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;
        }
    });
}

在这里插入图片描述


http://www.kler.cn/a/567007.html

相关文章:

  • JeeWMS cgReportController.do 多个参数SQL注入漏洞(CVE-2024-57760)
  • Jeecg-Boot 开放接口开发实战:在 Jeecg-Boot 的jeecg-system-biz中添加一个controller 实现免鉴权数据接口
  • AcWing 农夫约翰的奶酪块
  • DeepSeek引爆AI浪潮:B站如何成为科技普惠的“新课堂”?
  • Linux Mem -- 关于AArch64 MTE功能的疑问
  • 大数据与金融科技:革新金融行业的动力引擎
  • CSS Selectors
  • unity学习56:旧版legacy和新版TMP文本输入框 InputField学习
  • STM32G431RBT6——(1)芯片命名规则
  • 每天一个Flutter开发小项目 (8) : 掌握Flutter网络请求 - 构建每日名言应用
  • Kafka重复消费问题和解决方式
  • Redis大key
  • 基于JAVA+Spring+mysql_快递管理系统源码+设计文档
  • C++20 Lambda表达式新特性:包扩展与初始化捕获的强强联合
  • WatchDog 看门狗
  • 22-接雨水
  • 什么是蓝绿发布?
  • vulfocus靶场漏洞学习——wordpress 垂直越权 (CVE=2021-21389)
  • DeepSeek 1.5B蒸馏模型的J6部署(Llama方式)
  • 【算法】图论 —— Floyd算法 python