React+Antd多页签缓存后,函数式组件中echarts图自适应的编写规范

总所周知,echarts的自适应有时候会出现各种各样的bug,尤其在添加了多页签缓存后,echarts的自适应问题会更加明显。

在编写代码时,通常会将echarts的父级div的width设置为100%,然后在添加resize()方法进行页面的自适应。这种方式在react项目的普通页面中是可以正常使用的,但是在添加了多页签缓存后,就会出现在一个页签中改变分辨率,再恢复,另一个页面中的echarts图无法自适应的问题。

在经过一系列排查后,终于找到了问题的关键所在,这是因为没有添加多页签缓存页面时,一旦切换页面,页面上的各种元素被卸载,再次进入时再次加载,但是加入多页签缓存之后的页面再次进入时元素不会重新加载,并且这时echarts的宽度会失效,被识别为100px。为了解决这一问题,我尝试了各种各样的方法,最终成功将这问题解决,以下是我成功之后的代码。

import React, { useEffect, useState, useRef } from 'react';

import * as echarts from 'echarts';


const evaChart = ({ chartData }) => {

  const ref = useRef(null);

  const sort = (chartData) => {

    //柱状图数据排序

    for (let i = 0; i < chartData.length; i++) {

      for (let j = i + 1; j < chartData.length; j++) {

        if (Number(chartData[i].count) < Number(chartData[j].count)) {

          let a = chartData[i];

          chartData[i] = chartData[j];

          chartData[j] = a;

        }

      }

    }

  };

  useEffect(() => {

    if (chartData && chartData.length != 0) {

      let xData = [];

      let yData = [];

      chartData.forEach((item) => {

        xData.push(item._id);

        yData.push(item.count);

      });

      sort(chartData);

      initOsChart(xData, yData);

    }

  }, [chartData]);


  const initOsChart = (xData, yData) => {

    // 基于准备好的dom,初始化echarts实例

    var myChart = echarts.init(ref.current);


    //配置项

    const option = {

      tooltip: {

        trigger: 'axis',

        axisPointer: {

          type: 'shadow', // 默认为直线,可选为:'line' | 'shadow'

          shadowStyle: {

            color: 'rgba(220, 220, 220, 0.2)',

          },

        },

        formatter: function (params) {

          return params[0].marker + params[0].name + '&nbsp;&nbsp;&nbsp;' + params[0].value + ' 元';

        },

      },

      grid: {

        left: '13%',

        right: '13%',

      },

      dataZoom: [

        {

          type: 'slider',

          // startValue: 0,

          // endValue: 10,

        },

      ],

      xAxis: {

        data: xData,

        name: '测试数据',

      },

      yAxis: { name: '金额/元', minInterval: 1 },

      series: {

        barWidth: xData.length <= 10 ? 40 : xData.length <= 20 ? 25 : 10,

        itemStyle: {

          normal: {

            color: (arg) => {

              var colorList = [

                '#ea7ccc',

                '#9a60b4',

                '#fc8452',

                '#3ba272',

                '#73c0de',

                '#ee6666',

                '#fac858',

                '#91cc75',

                '#5470c6',

              ];

              return colorList[(arg.dataIndex / 6).toFixed()];

            },

          },

        },

        type: 'bar',

        data: yData,

        encode: { x: '_id', y: 'count' },

        datasetIndex: 1,

        label: {

          normal: {

            show: true,

            position: 'top',

          },

        },

      },

    };


    // 使用刚指定的配置项和数据显示图表

    myChart.setOption(option);

    // 响应式布局和自适应大小

    window.addEventListener('resize', () => {

      myChart.resize({ width: window.innerWidth * (1 / 2) - 120 + 'px' });

    });

  };


  return (

    <div>

      <div

        ref={ref}

        style={{ height: '280px', width: window.innerWidth * (1 / 2) - 120 + 'px' }}

        id="card"

      ></div>

    </div>

  );

};

export default evaChart;

其中,不在使用100%为echarts的父元素设定宽度,而是直接获取屏幕的分辨率,根据自己需要的比率计算出宽度来赋予。当然,在reszie()中也得将宽度这样赋予,这样就能保证echarts图的完美自适应。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值