【前端可视化】如何在React中优雅的使用ECharts🍉 您所在的位置:网站首页 r3nzskin怎么用 【前端可视化】如何在React中优雅的使用ECharts🍉

【前端可视化】如何在React中优雅的使用ECharts🍉

#【前端可视化】如何在React中优雅的使用ECharts🍉| 来源: 网络整理| 查看: 265

前言

这片文章由最近公司的一个可视化项目有感而发,随着前端的飞速发展,近年来数据可视化越来越火,有些公司的业务跟地图、位置、大数据等脱离不开关系,所以数据可视化甚至成了单独的一门前端行业,比如在杭州地区的前端可视化职位不但有一定的需求量且高薪,

截屏2021-08-25 下午10.57.37.png

至今为止,已经有很多的可视化框架供我们选择,比如D3、ECharts、Leaflet....等等。

本文使用的可视化框架为ECharts。

看完本文你可以学到什么? 如何搭建react+ts+echarts项目 typescript基础使用 eCharts如何在react中更安全高效的使用 eCharts的使用 eCharts图表尺寸自适应 启蒙可视化项目思想

本文的源码地址:github.com/Gexle-Tuy/e…

项目准备

技术栈为:React+TypeScript+ECharts。既然提到优雅那肯定跟TS逃离不开关系,毕竟强大的类型系统能给我的🐶💩代码保驾护航,什么?我不会TS,我不看了,别急,本文不做过于复杂的类型检查,只在组件状态(state)、属性(props)上做基本使用,不会TS也能看的懂,废话不多说,咱们开始吧。

使用的为react官方脚手架create-react-app,但是默认启动的为正常的js项目,如果想加上typescript类型检查,我们可以去它的仓库地址查看使用语法。在github上找到facebook/create-react-app。找到目录packages/cra-template-typescript。 在README中就可以看见启动命令create-react-app my-app --template typescript。 image

项目搭建完成之后看看src下的index文件的后缀名是否为tsx而不是jsx,为tsx就说明ts项目搭建成功了,就可以开始咱们的高雅之旅了~

初探

前面瞎吧啦半天完全跟我们本文的主角ECharts没有关系呀,伞兵作者?别急,这就开始,首先安装ECharts。

npm i echarts 复制代码

安装好之后该干什么?当然是来个官方的入门例子感受一下了啦,打开官网->快速入手->绘制一个简单的图表。

可以看到,每一个图表都需要一个DOM当作容器,在React中我们可以用ref来获取到DOM实例。

image

发现平时正常写的ref竟然报错了,这就是强大的ts发挥了作用,我们把鼠标放上去可以发现提示框有一大堆东西。

不能将类型“RefObject”分配给类型“LegacyRef | undefined”。 不能将类型“RefObject”分配给类型“RefObject”。 不能将类型“unknown”分配给类型“HTMLDivElement”。 ..... 复制代码

可以根据它的提示来解决这个问题,将ref加上类型检查,本文不对ts做过多介绍,只使用简单的基础类型检查,我们直接给它加上一个:any。

eChartsRef:any= React.createRef(); 复制代码

这样报错就消失了,可以理解为any类型就是没有类型检查,跟普通的js一样没有区别。真正的重点不在这里,所以就直接使用any,其实应该按照它的提示加上真正的类型检查RefObject。

拿到实例之后,直接copy官方的配置项例子过来看看效果。

import React, { PureComponent } from "react"; import * as eCharts from "echarts"; export default class App extends PureComponent { eChartsRef: any = React.createRef(); componentDidMount() { const myChart = eCharts.init(this.eChartsRef.current); let option = { title: { text: "ECharts 入门示例", }, tooltip: {}, legend: { data: ["销量"], }, xAxis: { data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"], }, yAxis: {}, series: [ { name: "销量", type: "bar", data: [5, 20, 36, 10, 10, 20], }, ], }; myChart.setOption(option); } render() { return ; } } 复制代码

gif

当图标的动态效果呈现在你眼前的时候是不是心动了,原来可视化这么简单,到这里你就会了最基本的使用了。

接下来就开始本文的重点!如何在react里封装图表组件动态渲染并自适应移动端。

正文

首先确定项目中我们要用到的图表,这里我选了四个最基本且常用的图表(折线图、趋势图、饼状图、柱状图)。

所有的图表都由无状态组件写(函数组件、Hooks),因为它们只负责拿到数据并渲染。并无自己维护的状态。

接下来就是封装图表组件,这里就不把四个表的代码都贴出来了,只拿一个折线图举例子。可以把拉下源码看下其他的图。

折线图:src/components/LineChart

import React, { useEffect, useRef } from 'react'; import { IProps } from "./type"; import * as echarts from "echarts"; const Index: React.FC = (props) => { const chartRef:any = useRef(); //拿到DOM容器 // 每当props改变的时候就会实时重新渲染 useEffect(()=>{ const chart = echarts.init(chartRef.current); //echart初始化容器 let option = { //配置项(数据都来自于props) title: { text: props.title ? props.title : "暂无数据", }, xAxis: { type: 'category', data: props.xData, }, yAxis: { type: 'value' }, series: [{ data: props.seriesData, type: 'line' }] }; chart.setOption(option); }, [props]); return } export default Index; 复制代码

同文件下新建一个type.ts,将要约束的props类型检查单独抽离出去,当然也可以直接写在index.tsx文件里面,看个人喜好。 type.ts

// 给props添加类型检查 export interface IProps { title: string, //图表的标题(为string类型) xData: string[], //图表x轴数据的数组(数字里面每一项都为string类型) seriesData: number[], //跟x轴每个坐标点对应的数据(数字里面每一项都为number类型) } 复制代码

根据每张图表对应的配置项,选出你想要动态配置的属性,就可以写成props作为属性传递过来。(比如,一个项目里需要用到很多张折线图,但是每个图表的线条颜色是不一样的,就可以把color写成一个props作为属性值传递进来。)

封装好之后,我们在App.tsx中引入使用一下。

App.tsx

import React, { PureComponent } from "react"; import LineChart from "./components/LineChart/Index"; import "./App.css"; export default class App extends PureComponent { eChartsRef: any = React.createRef(); state = { lineChartData: { //折线图模拟数据 xData: [ "2021/08/13", "2021/08/14", "2021/08/15", "2021/08/16", "2021/08/17", "2021/08/18", ], seriesData: [22, 19, 88, 66, 5, 90], }, }; componentDidMount() {} render() { return ( {/* 折线图 */} ); } } 复制代码

如果使用LineChart组件的时候少传了任何一个属性,或者说属性传递的类型不对,那么就会直接报错,将报错扼杀在开发阶段,而不是运行代码阶段,而且还有一个好处就是,加上类型检查后会有强大的智能提示,普通的js项目写一个组件根本就不会提示你需要传递某些属性。

忘记传递某个属性 image

传递的类型不符合类型检查 image

效果如下:

gif

这样一个基本的图表组件就完成了,但是都是我们模拟的数据,在真实的开发中数据都是来自于后端返回给我们,而且格式还不是我们想要的,那时候就需要我们自己处理下数据包装成需要的数据格式再传递。

这样封装成函数组件还有一个好处就是每当props改变的时候就会进行重新渲染。比如我在componentDidMount中开启一个定时器定时添加数据来模拟实时数据。

componentDidMount() { setInterval(() => { this.setState({ lineChartData: { xData: [...this.state.lineChartData.xData, "2000/01/01"], seriesData: [...this.state.lineChartData.seriesData, Math.floor(Math.random() * 100)], } }) }, 1500 ); } 复制代码

gif

这样就可以实现展示实时数据了,比如每秒的pv、uv数等等。我们把四个图表组件全部封装好之后的效果是这样的。

gif

前三个图表的数据都来自实时数据模拟,最后一张饼状图直接在组件中写死数据了,有兴趣的小伙伴可以拉下源码自行把它实现成实时的,可以看option中的配置哪些需要配置的,单独抽离出来写在type.ts文件中。

移动端适配

啥?echarts没做移动端适配?当然不是,echarts的官网中就介绍了移动端的相关优化:echarts.apache.org/zh/feature.… 当然也有跨平台使用。

gif

好像是那么回事,但感觉好像少了些什么,好像没有根据屏幕尺寸大小变化而自动发生调整尺寸。每次都要刷新一下也就是重新进入页面。

别着急,在它的API文档中,有这么一个方法,echarts创建的实例也就是通过echarts.init()之后的对象会有一个resize的方法。

我们可以监听窗口的变化,只要窗口尺寸变化了就调用resize方法。监听窗口的变化的方法很简单window.onresize可以在创建组件对象的时候都添加上一个window.onresize方法。

注意:如果网页只有一个图表那么这么写是可以的,如果项目中图表不只一个的话,每个图表组件难道在后面都写一个window.onresize方法吗?这样写的话只有最后创建的组件会自适应屏幕尺寸大小,因为每创建一个组件都重新将window.onresize赋予为新的函数体了。

解决:我们可以写一个公用方法,每一次创建组件的时候都加入到一个数组中,当屏幕尺寸变化的时候,都去循环遍历这个数组中的每一项,然后调用resize方法。

src/util.js

const echartsDom = []; //所有echarts图表的数组 /** * 当屏幕尺寸变化时,循环数组里的每一项调用resize方法来实现自适应。 * @param {*} eDom */ export function echartsResize(eDom) { echartsDom.push(eDom); window.onresize = () => { echartsDom.forEach((it)=>{ it.resize(); }) }; } 复制代码

写好方法之后,在每个图表组件设置好option之后将他添加到此数组内,然后当屏幕尺寸变化后就可以将每个图表变成自适应的了。

这样之后每个图表就都可以自适应屏幕尺寸啦~

gif

结语

本文主要介绍了如何在react中更安全高效的使用eCharts,所涉及的ts都为最基础的类型检查(有兴趣的同学可以自行拓展),只是为了给各位提供一个我在写一个eCharts项目的时候如何去做和管理项目,文章有错误的地方欢迎指出,大佬勿喷,大家伙儿有更好的思路和想法欢迎大家积极留言。感谢观看~



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有