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自动计算间隔划分。
为了解决这个问题,可以从max
和interval
这2个配置参数下手。
- max:坐标轴刻度最大值
- interval:强制设置坐标轴分割间隔,因为 splitNumber 是预估的值,实际根据策略计算出来的刻度可能无法达到想要的效果,这时候可以使用 interval 配合 min、max 强制设定刻度划分,一般不建议使用。
官网上不建议使用,可能是这样设置计算太过于麻烦。为了解决上面的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轴数据刻度就可以对齐;