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

news/2024/7/15 18:09:40 标签: react.js, echarts, javascript

前景

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

    • 大概流程就是获取到数据后执行初始化,因为先初始化后异步请求再设置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中

  • 参考文章

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

http://www.niftyadmin.cn/n/5403274.html

相关文章

Matlab偏微分方程拟合 | 源码分享 | 视频教程

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《复杂函数拟合案例分享》本专栏旨在提供 1.以案例的形式讲解各类复杂函数拟合的程序实现方法&#xff0c;并提供所有案例完整源码&#xff1b;2.…

OpenHarmony中SystemAbility的实现方法

简介 在系统服务管理子系统中safwk组件定义OpenHarmony中SystemAbility的实现方法&#xff0c;并提供启动、注册等接口实现。 系统架构 图 1 系统服务框架图 目录 /foundation/systemabilitymgr │── safwk # 组件目录 │ ├── bundle.json # 组件…

神经网络之万能定理python-pytorch实现,可以拟合任意曲线

神经网络之万能定理python-pytorch实现&#xff0c;可以拟合任意曲线 博主&#xff0c;这几天一直在做这个曲线拟合的实验&#xff0c;讲道理&#xff0c;网上可能也有很多这方面的资料&#xff0c;但是博主其实试了很多&#xff0c;效果只能对一般的曲线还行&#xff0c;稍微…

启动pyspark时:/usr/local/spark/bin/pyspark: 行 45: python: 未找到命令

一、问题描述 二、解决办法 创建 Python 符号链接&#xff1a; 确保系统中有正确的 Python 符号链接指向要使用的 Python 版本&#xff1a; sudo ln -s /usr/bin/python3 /usr/bin/python 这将创建一个 python 的符号链接&#xff0c;指向系统中的 Python 3 版本。这样 pysp…

图论 - Trie树(字符串统计、最大异或对)

文章目录 前言Part 1&#xff1a;Trie字符串统计1.题目描述输入格式输出格式数据范围输入样例输出样例 2.算法 Part 2&#xff1a;最大异或对1.题目描述输入格式输出格式数据范围输入样例输出样例 2.算法 前言 本篇博客将介绍Trie树的常见应用&#xff0c;包括&#xff1a;Trie…

Unity 游戏设计模式:单例模式

本文由 简悦 SimpRead 转码&#xff0c; 原文地址 mp.weixin.qq.com 单例模式 在 C# 游戏设计中&#xff0c;单例模式是一种常见的设计模式&#xff0c;它的主要目的是确保一个类只有一个实例&#xff0c;并提供一个全局访问点。单例模式在游戏开发中具有以下几个作用&#xf…

点云从入门到精通技术详解100篇-基于点云网络和 PSO 优化算法的手势估计

目录 前言 国内外研究现状 2 基于改进型 YOLO 框架的手部区域实时检测模型 2.1 YOLO 算法简介</

图论 - 最小生成树(Prime、Kruskal)

文章目录 前言Part 1&#xff1a;Prim算法求最小生成树1.题目描述输入格式输出格式数据范围输入样例输出样例 2.算法 Part 2&#xff1a;Kruskal算法求最小生成树1.题目描述输入格式输出格式数据范围输入样例输出样例 2.算法 前言 本篇博客介绍两种求最小生成树的方法&#xff…