vue3使用echarts图表,大小自适应
vue3使用echarts图表,图表大小自适应
·
当页面窗口变化或者导航栏缩进展开时echarts图表自适应
主要自适应代码块如下
// 监听当容器大小变化时随之变化
let resizeObserver = null;
resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
if (entry.target === chartRef.value) {
if (chart != null) {
chart.resize();
}
}
}
});
resizeObserver.observe(chartRef.value);
以下是封装的图表组建
折线图代码示例
<template>
<div ref="chartRef" class="chart-container"></div>
</template>
<script setup>
import { onMounted, ref, onUnmounted, watch } from 'vue';
import useAppStore from '@/store/modules/app';
import * as echarts from 'echarts';
const appStore = useAppStore();
const chartRef = ref(null);
const props = defineProps({
color: Array,
xaxisData: Array,
legendData: Array,
dataV: Array,
unit: String
});
let chart = null;
let resizeObserver = null;
onMounted(() => {
chart = echarts.init(chartRef.value);
const render = () => {
chart.setOption({
tooltip: { trigger: 'axis' },
legend: { data: props.legendData, icon: 'stack', right: '28px' },
grid: { left: '0', right: '4%', bottom: '0', containLabel: true },
xAxis: { type: 'category', boundaryGap: true, data: props.xaxisData },
yAxis: { type: 'value', name: props.unit },
color: props.color,
series: props.dataV
}, true);
};
render();
// 监听当容器大小变化时随之变化
resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
if (entry.target === chartRef.value) {
if (chart != null) {
chart.resize();
}
}
}
});
resizeObserver.observe(chartRef.value);
const handleResize = () => chart.resize();
// 窗口缩放时图表自适应
// window.addEventListener('resize', handleResize);
watch(() => props.dataV, render, { deep: true });
// 监听 Vuex store 中的状态变化
watch(
() => appStore.sidebar.opened,
(opened) => {
console.log('Sidebar opened state changed:', opened);
// 根据需要更新图表或执行其他操作
if (opened) {
// 执行某些操作,例如重新渲染图表
render();
}
},
{ immediate: true }
);
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
chart.dispose();
});
});
</script>
<style scoped>
.chart-container {
width: 100%;
height: calc(100% - 20px);
position: relative;
}
</style>

多个环状图一个legend示例
<template>
<div ref="chartRef" style="width: 100%; height: calc(100% - 20px)"></div>
</template>
<script setup>
import { onMounted, ref, watch, onUnmounted } from 'vue';
import * as echarts from 'echarts';
const chartRef = ref(null);
let resizeObserver = null;
const props = defineProps({
dataV: Array,
title: Array
});
// 解析数据并生成 ECharts 配置
const render = (data) => {
const option = {
legend: {
right: '20px'
},
tooltip: {},
title: props.title,
color: ['#6488FE', '#FF6F6F', '#FEE177', '#2AF0CF', '#FFD700'],
series: data.map((device, index) => ({
name: device.deviceName,
type: 'pie',
radius: ['35%', '65%'],
center: [`${index * 25 + 12.5}%`, '50%'],
avoidLabelOverlap: false,
padAngle: 4,
label: {
show: true,
position: 'inner',
color: '#666',
formatter: '{d}%'
},
emphasis: {
label: {
show: true,
fontSize: '12',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
itemStyle: {
shadowBlur: 20,
shadowColor: 'rgba(100,136,254,0.6)',
shadowOffsetX: 0,
shadowOffsetY: 0
},
data: device.alarmTypes.map(type => ({
value: parseFloat(type.proportion),
name: type.alarmType
}))
}))
};
return option;
};
onMounted(() => {
const chart = echarts.init(chartRef.value);
const option = render(props.dataV);
chart.setOption(option);
watch(() => props.dataV, (newData) => {
chart.setOption(render(newData));
}, { deep: true });
// 监听当容器大小变化时随之变化
resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
if (entry.target === chartRef.value) {
if (chart != null) {
chart.resize();
}
}
}
});
resizeObserver.observe(chartRef.value);
const handleResize = () => chart.resize();
// 窗口变化自适应
// window.addEventListener('resize', handleResize);
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
chart.dispose();
});
});
</script>

柱状图示例
<template>
<div ref="chartRef" style="width: 100%; height: calc(100% - 32px);"></div>
</template>
<script setup>
import { onMounted, ref, watch, onUnmounted } from 'vue';
import * as echarts from 'echarts';
const chartRef = ref(null);
let resizeObserver = null;//监听页面大小变化
const props = defineProps({
dataV: Array,
keyNameMap: Object,
unit: String
});
// 键名替换映射
// 解析数据并生成 ECharts 配置
const render = (data) => {
const dates = data.map(item => item.timeNode);
const categories = data.map(item => item.timeNode);
const seriesData = Object.keys(props.keyNameMap).reduce((acc, key) => {
acc[key] = data.map(item => parseFloat(item[key]));
return acc;
}, {});
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: Object.values(props.keyNameMap),
right: '20px'
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: dates,
}
],
yAxis: [
{
type: 'value',
name: props.unit
}
],
color: ['#478BFE', '#27CEBA'],
dataZoom: [
// { // 添加滚动条组件以支持缩放和滚动查看。
// type: 'slider', // 这个 dataZoom 组件是滑动条类型。
// start: 10, // 左边在 10% 的位置。
// end: 50 // 右边在 50% 的位置。
// },
{
type: 'inside'
}
],
series: Object.keys(seriesData).map(key => ({
name: props.keyNameMap[key],
type: 'bar',
barMaxWidth: '18px',
data: seriesData[key],
emphasis: {
focus: 'series'
},
label: {
show: false,
position: 'top',
textStyle: {
color: '#999999'
}
}
}))
};
return option;
};
onMounted(() => {
const chart = echarts.init(chartRef.value);
// 假设 props.dataV 已经包含了解析好的数据
const option = render(props.dataV);
chart.setOption(option);
watch(() => props.dataV, (newData) => {
chart.setOption(render(newData));
}, { deep: true });
// 监听当容器大小变化时随之变化
resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
if (entry.target === chartRef.value) {
if (chart != null) {
chart.resize();
}
}
}
});
resizeObserver.observe(chartRef.value);
const handleResize = () => chart.resize();
// window.addEventListener('resize', handleResize);
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
chart.dispose();
});
});
</script>

以上记录一下封装的组件
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)