React多个echarts图表在一个页面的使用

news2024/10/2 10:33:56

前景

  • 很多情况下图标都是一个,我们大概率会像下面代码一样的做法

    • 大概流程就是获取到数据后执行初始化,因为先初始化后异步请求再设置state里面的数据回导致无法正常显示echarts(除非再次调用setOption)
    • 下面就记录下自己解决过程
    • 源码
      • https://github.com/superBiuBiuMan/react-class-test

根据ID获取DOM进行初始化

import React, { Component } from 'react';
import * as echarts from 'echarts';
import axios from 'axios';

class TestEcharts extends Component {
  constructor(props) {
    super(props);
    this.state = {
      testData: '测试数据',
      list1: [],
    };
  }
  componentDidMount() {
    this.initEchartsData();
  }
  // 请求并初始化echarts数据
  initEchartsData() {
    axios.get('https://api.oick.cn/api/lishi').then((res) => {
      console.log(res);
      //处理数据
      this.setState(
        {
          list1: res.data.result.map((item) => Math.round(Math.random() * 100)),
        },
      );
      // 初始化echarts
      const myChart = echarts.init(document.getElementById('myChart'));
      myChart.setOption({
        xAxis: {
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        },
        yAxis: {
          type: 'value',
        },
        series: [
          {
            data: this.state.list1,
            type: 'line',
          },
        ],
      });
    });
  }


  render() {
    return (
      <div>
        <div id="myChart" style={{ width: '400px', height: '400px' }}></div>
        <div>{this.state.testData}</div>
      </div>
    );
  }
}

export default TestEcharts;

根据ref获取DOM进行初始化

import React, { Component,createRef  } from 'react';
import * as echarts from 'echarts';
import axios from 'axios';

class TestEcharts extends Component {
  constructor(props) {
    super(props);
    this.state = {
      testData: '测试数据',
      list1: [],
    };
    this.echart1 = createRef();
  }
  componentDidMount() {
    this.initEchartsData();
  }
  // 请求并初始化echarts数据
  initEchartsData() {
    axios.get('https://api.oick.cn/api/lishi').then((res) => {
      console.log(res);
      //处理数据
      this.setState(
        {
          list1: res.data.result.map((item) => Math.round(Math.random() * 100)),
        },
      );
      // 初始化echarts
      // const myChart = echarts.init(document.getElementById('myChart'));
      console.log(this.echart1.current);
      const myChart = echarts.init(this.echart1.current);
      myChart.setOption({
        xAxis: {
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        },
        yAxis: {
          type: 'value',
        },
        series: [
          {
            data: this.state.list1,
            type: 'line',
          },
        ],
      });
    });
  }

  
  render() {
    return (
      <div>
         {/* id="myChart" */}
        <div ref={this.echart1} style={{ width: '400px', height: '400px' }}></div>
        <div>{this.state.testData}</div>
      </div>
    );
  }
}

export default TestEcharts;

如果有1个页面有多个echart图标怎么解决呢?

方式1-一个图表就是一个组件

数据获取到后再setOption

  • 主index.jsx
import React, { Component } from 'react'
import ShowData from "./component/showData/index";
export default class index extends Component {
  render() {
    return (
      <div>
        <div>显示多个图表</div>
        <div style={{ display:'flex' }}>
          <ShowData/>
          <ShowData/>
          <ShowData/>
          <ShowData/>
        </div>
      </div>
    )
  }
}

  • 图表ShowData.jsx
import React, { Component, createRef } from 'react';
import * as echarts from 'echarts';
import axios from 'axios';
export default class index extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
    };
    this.echartDOM = createRef();
  }
  // 请求数据
  initData() {
    axios.get('https://api.oick.cn/api/lishi').then((res) => {
      console.log(res);
      //处理数据
      this.setState({
        data: res.data.result.map((item) => Math.round(Math.random() * 100)),
      },() => {
        this.initEchartsData();
      });
    });
  }
  //初始化echart图表
  initEchartsData(){
    const myChart = echarts.init(this.echartDOM.current);
    myChart.setOption({
      xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
      },
      yAxis: {
        type: 'value',
      },
      series: [
        {
          data: this.state.data,
          type: 'line',
        },
      ],
    });
  }
  componentDidMount() {
    this.initData(); //初始化数据
  }
  render() {
    return (
      <div
        ref={this.echartDOM}
        style={{ width: '400px', height: '400px' }}
      ></div>
    );
  }
}

先setOption后再更新

  • 通过createRef获取DOM再保存echarts实例方式
  • 主index.jsx
import React, { Component } from 'react'
import ShowData from "./component/showData/index";
import ShowData2 from "./component/showData/index2";
export default class index extends Component {
  render() {
    return (
      <div>
        <div>显示多个图表</div>
        <div style={{ display:'flex' }}>
          <ShowData2/>
          <ShowData2/>
          <ShowData2/>
          <ShowData2/>
        </div>
      </div>
    )
  }
}

  • 图表ShowData2.jsx
import React, { Component, createRef } from 'react';
import * as echarts from 'echarts';
import axios from 'axios';
export default class index extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      myEchart: '',
    };
    this.echartDOM = createRef();
  }
  // 请求数据
  initData() {
    axios.get('https://api.oick.cn/api/lishi').then((res) => {
      console.log(res);
      //处理数据
      this.setState({
        data: res.data.result.map((item) => Math.round(Math.random() * 100)),
      },() => {
        this.state.myEchart.setOption({
          xAxis: {
            type: 'category',
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
          },
          yAxis: {
            type: 'value',
          },
          series: [
            {
              data: this.state.data,
              type: 'line',
            },
          ],
        });
      });
    });
  }
  //初始化echart图表
  initEchartsData(){
    const myEchart = echarts.init(this.echartDOM.current);
    this.setState({
      myEchart,
    })
    myEchart.setOption({
      xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
      },
      yAxis: {
        type: 'value',
      },
      series: [
        {
          data: this.state.data,
          type: 'line',
        },
      ],
    });
  }
  componentDidMount() {
    this.initData(); //初始化数据
    this.initEchartsData();//初始化数据
  }
  render() {
    return (
      <div
        ref={this.echartDOM}
        style={{ width: '400px', height: '400px' }}
      ></div>
    );
  }
}

方式2-都写在一个jsx\tsx文件中

  • 比较难的地方在于怎么获取到这么多个的DOM再进行统一的初始化,并且还可能后续不同操作需要更新不同的DOM
  • 这里只是数组简单的存储,你也可以通过Map来进行存储

  • 点击更新

  • 主index.jsx
import React, { Component } from 'react'
import ShowData from "./component/showData/index";
import ShowData2 from "./component/showData/index2";
import ShowData3 from "./component/showData/index3";
export default class index extends Component {
  render() {
    return (
      <div>
        <div>显示多个图表</div>
        {/* 方式1 */}
        <h1>方式1</h1>
        <div style={{ display:'flex' }}>
          {/* <ShowData2/>
          <ShowData2/>
          <ShowData2/>
          <ShowData2/> */}
        </div>
        {/* 方式2 */}
        <h1>方式2</h1>
        <div >
          <ShowData3/>
        </div>
      </div>
    )
  }
}

  • 图表ShowData.jsx
import React, { Component, createRef } from 'react';
import * as echarts from 'echarts';
import axios from 'axios';
export default class index3 extends Component {
  constructor(props) {
    super(props);
    this.state = {
      myEchartList: [], //实例化echart列表
      data1: [],
      data2: [],
      data3: [],
      data4: [],
    };
    this.allRef = []; //存储所有的ref
  }
  componentDidMount() {
    this.setState({
      //实例化echart
      myEchartList: this.allRef.map((item) => echarts.init(item)),
    });
    //获取数据A
    this.initDataA();
    //获取数据B
    this.initDataB();
  }
  initDataA = () => {
    axios.get('https://api.oick.cn/api/lishi').then((res) => {
      console.log(res,'来自initDataA');
      let data1 = res.data.result.map(() => Math.round(Math.random() * 100));
      let data2 = res.data.result.map(() => Math.round(Math.random() * 100));
      //处理数据
      this.setState({
        data1,
        data2,
      });
      this.state.myEchartList[0].setOption({
        xAxis: {
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        },
        yAxis: {
          type: 'value',
        },
        series: [
          {
            data:data1,
            type: 'line',
          },
        ],
      });
      this.state.myEchartList[1].setOption({
        xAxis: {
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        },
        yAxis: {
          type: 'value',
        },
        series: [
          {
            data:data2,
            type: 'line',
          },
        ],
      });
    });
  };
  initDataB = () => {
    axios.get('https://api.oick.cn/api/lishi').then((res) => {
      console.log(res,'来自initDataB');
      let data3 = res.data.result.map(() => Math.round(Math.random() * 100));
      let data4 = res.data.result.map(() => Math.round(Math.random() * 100));
      //处理数据
      this.setState({
        data3,
        data4,
      });
      this.state.myEchartList[2].setOption({
        xAxis: {
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        },
        yAxis: {
          type: 'value',
        },
        series: [
          {
            data:data3,
            type: 'line',
          },
        ],
      });
      this.state.myEchartList[3].setOption({
        xAxis: {
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        },
        yAxis: {
          type: 'value',
        },
        series: [
          {
            data:data4,
            type: 'line',
          },
        ],
      });
    });
  };
  handleUpdate = () => {
    this.initDataA();
  };
  render() {
    return (
      <>
        <button onClick={this.handleUpdate}>点击我更新2个图表数据</button>
        <div
          style={{ display: 'flex' }}
        >
          <div
            ref={(node) => {
              this.allRef.push(node);
            }}
            style={{ width: '401px', height: '400px' }}
          ></div>
          <div
            ref={(node) => {
              this.allRef.push(node);
            }}
            style={{ width: '402px', height: '400px' }}
          ></div>
          <div
            ref={(node) => {
              this.allRef.push(node);
            }}
            style={{ width: '403px', height: '400px' }}
          ></div>
          <div
            ref={(node) => {
              this.allRef.push(node);
            }}
            style={{ width: '404px', height: '400px' }}
          ></div>
        </div>
      </>
    );
  }
}

总结

  • 可以了解下setOption的其他用法https://www.jb51.net/article/269766.htm

  • 也可以使用在react中

    • echarts-for-react: https://www.npmjs.com/package/echarts-for-react
  • 参考文章

    • https://blog.csdn.net/A15029296293/article/details/130500081

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1484535.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《秦时明月》IP新高度:与陕西历史博物馆共同书写文化传承新篇章!

在IP产业风起云涌的今天&#xff0c;如何以创意和匠心为传统文化注入新的活力&#xff0c;成为了摆在每一位文化工作者面前的重要课题。近日&#xff0c;《秦时明月》作为一部深受观众喜爱的国产动画IP&#xff0c;在迎来其十七周年之际&#xff0c;联手陕西历史博物馆&#xf…

线性dp:P2679 子串

1.P2679 子串 传送门https://www.luogu.com.cn/problem/P2679这道题是公共子串问题的变种&#xff0c;但是我第一时间确实没想到转移方程&#xff08;写少了&#xff09; 一开始看了题解也没太看懂&#xff0c;直到自己模拟一遍&#xff08;模拟数据便于理解原理&#xff09;…

#WEB前端(HTML属性)

1.实验&#xff1a;a,img 2.IDE&#xff1a;VSCODE 3.记录&#xff1a; a: href插入超链接 默认情况下在本窗口打开链接, target可以设置打开的窗口,parent在父窗口打开&#xff0c;blank新开串口打开,top在顶层串口打开,self为默认在本窗口打开 img: 插入图片 可以插…

持续集成(CICD)- Git版本管理工具,Gitee线上仓库

文章目录 一、学习目标:二、什么是Git工具三 、Git环境搭建(windows系统)四、Gitee设置(私钥和公钥绑定)五、Git结合Gittee进行基本设置(重要)六、在Gitee上新建仓库私有仓库(非空仓库)七、Git拉取线上仓库代码,提交代码(重要)八、Git解决版本冲突问题(重要)场景一…

LeetCode 刷题 [C++] 第45题.跳跃游戏 II

题目描述 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i]i j < n 返回到达 nums[n …

YOLOv9独家原创改进|增加SPD-Conv无卷积步长或池化:用于低分辨率图像和小物体的新 CNN 模块

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、文章摘要 卷积神经网络(CNNs)在计算即使觉任务中如图像分类和目标检测等取得了显著的成功。然而&#xff0c;当图像分辨率较低或物体较小时&…

每日一题 — 复写零

1089. 复写零 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 首先找到最后一个复写的数&#xff1a; 双指针算法&#xff1a; 1、先判断 cur 位置上的值 2、然后决定 dest 移动一步还是两步 3、然后判断 dest 是否到终点了 4、最后 cur 处理越界的情况 arr[n-1] …

Javaweb之SpringBootWeb案例之自动配置的原理分析的详细解析

3.2.3 原理分析 3.2.3.1 源码跟踪 前面我们讲解了在项目当中引入第三方依赖之后&#xff0c;如何加载第三方依赖中定义好的bean对象以及配置类&#xff0c;从而完成自动配置操作。那下面我们通过源码跟踪的形式来剖析下SpringBoot底层到底是如何完成自动配置的。 源码跟踪技巧…

QPaint绘制自定义仪表盘组件03

网上视频抄的&#xff0c;用来自己看一下&#xff0c;看完就删掉 ui mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QDebug> #include <QtMath> #include <QDialog> #include <QPainter> #include …

嵌入式中汇编语言的基本实现

大家好&#xff0c;今天给大家分享&#xff0c;GNU汇编的语法。 第一&#xff1a;汇编简介 GNU 汇编语法适用于所有的架构&#xff0c;并不是 ARM 独享的&#xff0c;GNU 汇编由一系列的语句组成&#xff0c; 每行一条语句&#xff0c;每条语句有三个可选部分&#xff0c;如下…

java List.forEach 引发的生产投诉

代码运行时直接抛异常报错&#xff0c;这个算是不幸中的万幸&#xff0c;至少可以及时发现并去解决代码运行不报错&#xff0c;但是业务逻辑莫名其妙的出现各种奇怪问题&#xff0c;这种就比较悲剧了&#xff0c;因为这个问题稍不留神的话&#xff0c;可能就会给后续业务埋下隐…

【C语言】熟悉文件顺序读写函数

前言 本篇详细介绍了 文件顺序读写常用函数&#xff0c;快来看看吧~ 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 前言 ​编辑 文件顺序读写函数 fgetc函数 示例 fputc函数 逐个字符写入 写入26个字母 文…

数学建模函数插值与拟合

1.脑图 2.介绍 我们自己找到的函数&#xff0c;在已知点处的函数值和要求的函数在这些点处的函数值相等&#xff0c;这个函数 就叫做未知函数的插值函数&#xff1b; 多项式函数构成的插值函数的集合叫做函数类&#xff1b; 3.拉格朗日插值法 基函数的求法和插值函数的构造…

使用QEMU搭建U-Boot+LinuxKernel+busybox+NFS嵌入式开发环境

目录 0.课程大纲1.为什么要使用QEMU学习嵌入式QEMU简介使用QEMU可以做哪些事情?当前嵌入式行业现状如何适应这种变化使用QEMU学习嵌入式有哪些好处?驱动开发技能为什么要学习Linux 2.搭建嵌入式开发基本环境2.1.安装u-boot-tools2.2.安装交叉编译工具什么是ABI和EABI 3.QEMU安…

MySQL:开始深入其数据(一)DML

在上一章初识MySQL了解了如何定义数据库和数据表&#xff08;DDL&#xff09;&#xff0c;接下来我们开始开始深入其数据,对其数据进行访问&#xff08;DAL&#xff09;、查询DQL&#xff08;&#xff09;和操作(DML)等。 通过DML语句操作管理数据库数据 DML (数据操作语言) …

第17章-文件传输协议

1. 概述 2. FTP协议 2.1 定义 2.2 端口 2.3 数据传输方式 2.4 文件传输模式 3. TFTP协议 3.1 定义&#xff1a; 4. 常用命令 1. 概述 场景&#xff1a;远端主机和本地服务器 2. FTP协议 2.1 定义 FTP(File Transfer Protocol)&#xff1a;文件传输协议&#xff1b;…

DataX及Datax-web杂记

&#x1f47d;个人博客&#xff1a;https://everspring.github.io/ &#x1f47d;公众号&#xff1a;爱历史的IT男 一. DataX调试 DataX之前调试不是很方便&#xff0c;要打包后才能调试。23年7月后一位叫"FuYouJ "的开源者提交了datax-example模块&#xff0c;就方…

GO-接口

1. 接口 在Go语言中接口&#xff08;interface&#xff09;是一种类型&#xff0c;一种抽象的类型。 interface是一组method的集合&#xff0c;接口做的事情就像是定义一个协议&#xff08;规则&#xff09;&#xff0c;只要一台机器有洗衣服和甩干的功能&#xff0c;我就称它…

13. Springboot集成Protobuf

目录 1、前言 2、Protobuf简介 2.1、核心思想 2.2、Protobuf是如何工作的&#xff1f; 2.3、如何使用 Protoc 生成代码&#xff1f; 3、Springboot集成 3.1、引入依赖 3.2、定义Proto文件 3.3、Protobuf生成Java代码 3.4、配置Protobuf的序列化和反序列化 3.5、定义…

事件循环相关知识

事件循环 浏览器的进程模型 何为进程 程序运行需要有专属的内存空间&#xff0c;可以吧这块内存空间简单的理解为进程 每个应用至少有一个进程&#xff0c;进程之间相互独立&#xff0c;即使要通信也需要双方同意 何为线程 有了进程就可以运行代码 运行代码的人称为线程 一…