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

相关推荐
Highcharts.js25 分钟前
可视化图表之甘特图Gantt:原理、应用与实践指南
甘特图·数据可视化·highcharts·图表渲染
Eloudy31 分钟前
ReAct 原理简介
前端·javascript·人工智能·react.js·agent·gpu
ZJU_统一阿萨姆2 小时前
【DSH】如何将 DeepSeek Harness 嵌入生产环境?万字解构 DeepSeek Agent Harness 的运行机制与安全边界
前端·javascript·安全
用户921080262862 小时前
4. 前端地图大量点位实时更新优化:后端推增量,前端做 diff
前端
SoaringHeart2 小时前
Flutter最佳实践:Web项目中文字体首次加载乱码问题解决
前端·flutter
西安小哥2 小时前
破局与重生:大厂前端如何借力 AI 转型“超级全栈“
前端·人工智能
sunly_3 小时前
TypeScript总结:16、面向对象速查
前端·javascript·typescript
MXN_小南学前端3 小时前
React超长文本域中实现“返回顶部”浮动按钮
前端·javascript·react.js
学习嵌入式的小周3 小时前
Notepad++8.8.7下载安装(附安装包)
前端·notepad++
gs801404 小时前
解构 Cordis:面向“时空可组合性”的 TypeScript 元框架深度剖析
前端·javascript·typescript