开发前端大屏时使用echarts插件问题总结

resize页面后,图表大小调整

浏览器窗口缩放,可以触发onResize事件,然后调用echart的resize API可以更改。

js 复制代码
    myChart?.resize();

以上 API 可以解决大部分问题,此时监听到的是整个页面的dom的变化,如果需要变化的DOM比较多,或者页面上的数据量大,会对性能有影响,产生页面卡顿。

使用新的API ResizeObserver对单一的DOM尺寸变化进行监听,然后重置echart的大小。

vue 复制代码
<template>
<div ref="detailChart"></div>
</template>
<script lang="ts">
  // 定义生成echart图表的dom
  const latestChartWidth = ref<string>('');
  
  const resizeObserver = new ResizeObserver(entries => {
  latestChartWidth.value = entries[0].contentRect.width+'px'
  // console.log(latestChartWidth.value, '11111')
  myChart?.resize(latestChartWidth.value);
  });

  // 在页面初始化时,调用resizeObserver的observe方法。
  resizeObserver.observe(detailChart.value);
</script>
                                   

解决图表设置width设为100%时显示100px

起因:使用tab进行组件切换看到一些echart组件宽度只有100px,设置的宽度并不生效。这是因为在隐藏时使用v-show,给echart图表组件隐藏后,echart给自己设置宽度为100%; 解决办法:将 echart 图表抽取为一个独立组件,然后引入到tab中。使用v-if进行显示隐藏控制。

js 复制代码
<template>
  <div class="line-chart">
    <div ref="lineChart" :style="{ width: width, height: height }"></div>
  </div>
</template>
 
<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch, nextTick } from 'vue';
import * as echarts from 'echarts/core';
import { GridComponent, TooltipComponent, GraphicComponent } from 'echarts/components';
import { LineChart } from 'echarts/charts';
import { UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
 
echarts.use([
  GridComponent,
  TooltipComponent,
  GraphicComponent,
  LineChart,
  CanvasRenderer,
  UniversalTransition,
]);
let myChart: any = null;
const lineChart = ref();
const props = defineProps({
  width: {
    type: String,
    default: '100%',
  },
  height: {
    type: String,
    default: '100%',
  },
  chartOption: {
    type: Object,
    default: () => {
      return {
        xAxis: {
          type: 'category',
          data: [],
        },
        yAxis: {
          type: 'value',
        },
        tooltip: {
          trigger: 'axis',
        },
        grid: {
          x: 35,
          y: 15,
          x2: 5,
          y2: 5,
          borderWidth: 1,
        },
        series: [],
      };
    },
  },
});
watch(
  () => props.chartOption,
  (propData) => {
    nextTick(() => {
      chartResize();
      myChart?.setOption(propData, true);
    });
  },
  { deep: true, immediate: true }
);
onMounted(() => {
  myChart = echarts.init(lineChart.value);
  myChart?.setOption(props.lineData, true);
  window.addEventListener('resize', chartResize);
});
onUnmounted(() => {
  myChart?.dispose();
  window.removeEventListener('resize', chartResize);
});
const chartResize = () => {
  myChart?.resize();
};
</script>
<style lang="scss" scoped>
#lineChart {
  width: 100%;
  height: 300px;
}
</style>

在父组件中进行引入调用

js 复制代码
<MyChart
    :lineOption="lineOption"
    v-if="chartData.length>0"
    height="200px"
/>

多个Y轴数据,Y轴数据无法对齐

如果存在多个Y轴,即便是设置了splitNumber为固定值,也难以避免像上图一样出现Y数据不能对齐。

echart会根据接收到的series中的data自动计算间隔划分。

为了解决这个问题,可以从maxinterval这2个配置参数下手。

  • max:坐标轴刻度最大值
  • interval:强制设置坐标轴分割间隔,因为 splitNumber 是预估的值,实际根据策略计算出来的刻度可能无法达到想要的效果,这时候可以使用 interval 配合 minmax 强制设定刻度划分,一般不建议使用。

官网上不建议使用,可能是这样设置计算太过于麻烦。为了解决上面的bug,只能采用该方法。

定义一个函数:计算Y轴的最大值,和划分尺度

getMaxAndInterval(data: number[], settingInterval: number),接收 2 个参数,

  • series中的data数组,
  • 设置的interval数量;
js 复制代码
/**
 * @description: 计算Y轴的最大值,和划分尺度
 * @param {number} arr
 * @param {number} settingInterval
 * @return {*}
 */
export const getYInterval = (arr: number[], settingInterval: number = 3) => {
  const returnError = () => {
    return {
      interval: undefined,
      max: undefined,
    };
  };

  let max = 0;
  let interval = 0;

  if (!arr) {
    return returnError();
  }

  try {
    arr.forEach((item) => {
      max = Math.max(max, item);
    });
  } catch (e) {
    return returnError();
  }
  max === 0 ? max = 1 : '';
  interval = max / settingInterval;

  if (interval !== parseInt(interval + '')) {
    interval = Math.ceil(interval);
    // 将最大值取整
    max = interval * settingInterval;
  }
  
  return {
    interval,
    max,
  };
};

console.log(getYInterval([0.23, 100, 2, 3000.58], 3))

之后在yAxis的数据中进行配置

js 复制代码
yAxis: [{
  // ....
  min: 0,
  max: getYInterval(data, 5).max,
  interval: getYInterval(data, 5).interval,
}]

现在显示的Y轴数据刻度就可以对齐;

相关推荐
腾讯TNTWeb前端团队3 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰6 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪6 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪7 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy7 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom8 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom8 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom8 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom8 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom8 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试