开发前端大屏时使用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轴数据刻度就可以对齐;

相关推荐
懒大王爱吃狼38 分钟前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風5 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
Devil枫5 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦6 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子6 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山7 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享7 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
清灵xmf9 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨9 小时前
VUE+Vite之环境文件配置及使用环境变量
前端
GDAL9 小时前
npm入门教程1:npm简介
前端·npm·node.js