需求描述
如上图所见,在开发过程中经常会遇到容器自适应展示的功能,那么如果在需要自适应宽高的容器内,echarts折线图要怎么处理呢?
改造前代码实现流程
import React, { useRef, useEffect } from 'react'; import ReactDom from 'react-dom'; import * as echarts from 'echarts'; const Test = () => { const divRef = useRef < HTMLDivElement > (null); const chart = useRef < echarts.ECharts > (null); const fontColor = "#30eee9"; useEffect(() => { if (!divRef.current) return; let myChart = chart.current; if (!myChart) { chart.current = myChart; myChart = echarts.init(divRef.current); const option = { backgroundColor: "#11183c", grid: { left: "5%", right: "10%", top: "20%", bottom: "15%", containLabel: true, }, tooltip: { show: true, trigger: "item", }, legend: { show: true, x: "center", y: "35", icon: "stack", itemWidth: 10, itemHeight: 10, textStyle: { color: "#1bb4f6", }, data: ["已采纳", "已发布"], }, xAxis: [ { type: "category", boundaryGap: false, axisLabel: { color: fontColor, }, axisLine: { show: true, lineStyle: { color: "#397cbc", }, }, axisTick: { show: false, }, splitLine: { show: false, lineStyle: { color: "#195384", }, }, data: [ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", ], }, ], yAxis: [ { type: "value", name: "", min: 0, max: 1000, axisLabel: { formatter: "{value}", textStyle: { color: "#2ad1d2", }, }, axisLine: { lineStyle: { color: "#27b4c2", }, }, axisTick: { show: false, }, splitLine: { show: true, lineStyle: { color: "#11366e", }, }, }, ], series: [ { name: "已采纳", type: "line", stack: "总量", symbol: "circle", symbolSize: 8, itemStyle: { normal: { color: "#0092f6", lineStyle: { color: "#0092f6", width: 1, } }, }, markPoint: { itemStyle: { normal: { color: "red", }, }, }, data: [120, 132, 101, 134, 90, 230, 210, 182, 191, 234, 290, 330], }, { name: "已发布", type: "line", stack: "总量", symbol: "circle", symbolSize: 8, itemStyle: { normal: { color: "#00d4c7", lineStyle: { color: "#00d4c7", width: 1, }, }, }, data: [220, 182, 191, 234, 290, 330, 310, 201, 154, 190, 330, 410], }, ], }; option && myChart.setOption(option); } }, []); return <div style={{ width: '100%', height: 280 }} ref={divRef}/> };
代码思路
以上的功能实现是基于react 和 react hook,在页面展示前先获取dom元素,如果dom成功获取到以后,为这个dom插入option相关的配置,那么现在并没有根据容器的宽度自适应的显示折线图,现在是把获取dom和渲染的方法放在了useEfft中,那么要如何监听自身的容器宽高,并动态的渲染变化呢??
处理方案
使用ResizeObserver对象来监听指定Dom元素(div…)的变化(width、height等等)。一般,浏览器不支持该监听对象,所以需要引入第三方库支持-resize-observer-polyfill
第一步,安装 npm install resize-observer-polyfill;
第二步,页面中引入 import ResizeObserver from 'resize-observer-polyfill';
第三步, 利用 ResizeObserver 对渲染折线图的dom进行监听,如果监听到渲染折线图所在的dom元素宽高发生变化,利用echarts本身提供的resize事件重绘。
第四部, 页面销毁时,取消所有被ResizeObserver对象监听的节点
最终代码
import React, { useRef, useEffect } from 'react'; import ReactDom from 'react-dom'; import * as echarts from 'echarts'; // 关键代码 import ResizeObserver from 'resize-observer-polyfill'; const Test = () => { const divRef = useRef < HTMLDivElement > (null); const chart = useRef < echarts.ECharts > (null); // 关键代码 const myObserver = useRef < ResizeObserver > (null); const fontColor = "#30eee9"; useEffect(() => { if (!divRef.current) return; let myChart = chart.current; if (!myChart) { chart.current = myChart; myChart = echarts.init(divRef.current); const option = { backgroundColor: "#11183c", grid: { left: "5%", right: "10%", top: "20%", bottom: "15%", containLabel: true, }, tooltip: { show: true, trigger: "item", }, legend: { show: true, x: "center", y: "35", icon: "stack", itemWidth: 10, itemHeight: 10, textStyle: { color: "#1bb4f6", }, data: ["已采纳", "已发布"], }, xAxis: [ { type: "category", boundaryGap: false, axisLabel: { color: fontColor, }, axisLine: { show: true, lineStyle: { color: "#397cbc", }, }, axisTick: { show: false, }, splitLine: { show: false, lineStyle: { color: "#195384", }, }, data: [ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", ], }, ], yAxis: [ { type: "value", name: "", min: 0, max: 1000, axisLabel: { formatter: "{value}", textStyle: { color: "#2ad1d2", }, }, axisLine: { lineStyle: { color: "#27b4c2", }, }, axisTick: { show: false, }, splitLine: { show: true, lineStyle: { color: "#11366e", }, }, }, ], series: [ { name: "已采纳", type: "line", stack: "总量", symbol: "circle", symbolSize: 8, itemStyle: { normal: { color: "#0092f6", lineStyle: { color: "#0092f6", width: 1, } }, }, markPoint: { itemStyle: { normal: { color: "red", }, }, }, data: [120, 132, 101, 134, 90, 230, 210, 182, 191, 234, 290, 330], }, { name: "已发布", type: "line", stack: "总量", symbol: "circle", symbolSize: 8, itemStyle: { normal: { color: "#00d4c7", lineStyle: { color: "#00d4c7", width: 1, }, }, }, data: [220, 182, 191, 234, 290, 330, 310, 201, 154, 190, 330, 410], }, ], }; //关键代码, 利用observe监听折线图所在容器的宽度变化(divRef.current),在ResizeObserver回掉函数中entries返回的内容可以获取的到;最后将获取到宽度赋值给resize方法进行重绘 myObserver.current = new ResizeObserver((entries) => { myChart?.resize(entries[0]?.contentRect.width); }); myObserver.current.observe(divRef.current); myChart.setOption(option); } //关键代码 return () => { if (chart?.current) chart.current.dispose(); //取消所有被ResizeObserver对象监听的节点 myObserver.current?.disconnect(); }; }, []); return ( <div className='line' style={{ width: '100%', height: 280 }} ref={divRef} /> ) };
总结
到此这篇关于Echarts折线图如何根据容器宽度自适应展示的文章就介绍到这了,更多相关Echarts折线图宽度自适应内容请搜索阿兔在线工具以前的文章或继续浏览下面的相关文章希望大家以后多多支持阿兔在线工具!