lcw
This commit is contained in:
@ -1,67 +1,89 @@
|
||||
<template>
|
||||
<div style="height:100%;width:100%" :id="echartsId"></div>
|
||||
<div style="height: 100%; width: 100%" :id="echartsId"></div>
|
||||
</template>
|
||||
<script setup>
|
||||
import * as echarts from "echarts";
|
||||
import { onMounted, ref, reactive, defineProps, onUnmounted, watch, nextTick } from "vue";
|
||||
import {
|
||||
onMounted,
|
||||
ref,
|
||||
reactive,
|
||||
defineProps,
|
||||
onUnmounted,
|
||||
watch,
|
||||
nextTick,
|
||||
onBeforeUnmount
|
||||
} from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
echartsId:{
|
||||
type:String,
|
||||
default:'barId'
|
||||
echartsId: {
|
||||
type: String,
|
||||
default: "barId"
|
||||
},
|
||||
data:{
|
||||
type:Object,
|
||||
default:{
|
||||
title:'', // 图表标题
|
||||
color:[], //['#EB00FF','#F57100']
|
||||
list:[], //[{label:'总数',val:[80,70,60,50]}, {label:'已处置',val:[70,40,30,80]}, ]
|
||||
xData:[] ,//['09-01','09-02','09-03','09-04']
|
||||
labelColor:'#000', //横坐标颜色 - 纵坐标颜色 - 标题颜色
|
||||
rotate:0, //横坐标旋转角度
|
||||
interval:0, //横坐标间隔
|
||||
isVertical:false,//是否竖排垂直展示
|
||||
data: {
|
||||
type: Object,
|
||||
default: {
|
||||
title: "", // 图表标题
|
||||
color: [], //['#EB00FF','#F57100']
|
||||
list: [], //[{label:'总数',val:[80,70,60,50]}, {label:'已处置',val:[70,40,30,80]}, ]
|
||||
xData: [], //['09-01','09-02','09-03','09-04']
|
||||
labelColor: "#000", //横坐标颜色 - 纵坐标颜色 - 标题颜色
|
||||
rotate: 0, //横坐标旋转角度
|
||||
interval: 0, //横坐标间隔
|
||||
isVertical: false //是否竖排垂直展示
|
||||
}
|
||||
},
|
||||
dataZoom:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
dataZoom: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
rotate:{
|
||||
type:Number,
|
||||
default:0
|
||||
rotate: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
});
|
||||
watch(()=>props.data,val=>{
|
||||
nextTick(()=>{
|
||||
init(val)
|
||||
})
|
||||
},{immediate:true,deep:true})
|
||||
|
||||
// 保存图表实例和 resize 处理函数
|
||||
let myChart = null;
|
||||
const handleResize = () => {
|
||||
myChart && myChart.resize();
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
(val) => {
|
||||
nextTick(() => {
|
||||
init(val);
|
||||
});
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
|
||||
// 初始化
|
||||
function init (val) {
|
||||
function init(val) {
|
||||
let color = val.color;
|
||||
let list = val.list
|
||||
let series = list.map((item ,idx)=>{
|
||||
let list = val.list;
|
||||
let series = list.map((item, idx) => {
|
||||
return {
|
||||
type: "bar",
|
||||
name:item.label,
|
||||
data:item.val,
|
||||
itemStyle:{normal: { color: color[idx] }},
|
||||
showSymbol:false,
|
||||
barWidth: '30%', // 柱状图宽度
|
||||
}
|
||||
})
|
||||
chartFn(series)
|
||||
name: item.label,
|
||||
data: item.val,
|
||||
itemStyle: { normal: { color: color[idx] } },
|
||||
showSymbol: false,
|
||||
barWidth: "30%" // 柱状图宽度
|
||||
};
|
||||
});
|
||||
chartFn(series);
|
||||
}
|
||||
|
||||
function chartFn(series) {
|
||||
var myChart = echarts.init(document.getElementById(props.echartsId));
|
||||
// 复用已有的图表实例,避免重复创建
|
||||
if (!myChart) {
|
||||
myChart = echarts.init(document.getElementById(props.echartsId));
|
||||
}
|
||||
var option = {
|
||||
title: {
|
||||
text: props.data.title || '',
|
||||
left: 'center',
|
||||
text: props.data.title || "",
|
||||
left: "center",
|
||||
textStyle: {
|
||||
color: props.data.color[0] || "#000",
|
||||
fontSize: 14
|
||||
@ -71,11 +93,13 @@ function chartFn(series) {
|
||||
top: "25%",
|
||||
right: "0%",
|
||||
left: "0%",
|
||||
bottom: "0%", // 增加底部空间,为两行X轴标签留出空间
|
||||
bottom: "0%",
|
||||
containLabel: true
|
||||
},
|
||||
legend: {
|
||||
data: props.data.list.map(v => { return v.label }),
|
||||
data: props.data.list.map((v) => {
|
||||
return v.label;
|
||||
}),
|
||||
textStyle: {
|
||||
color: props.data.color[0] || "#409EFF",
|
||||
fontSize: 12
|
||||
@ -86,7 +110,7 @@ function chartFn(series) {
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
type: "shadow"
|
||||
},
|
||||
backgroundColor: "rgba(255,255,255,1)",
|
||||
padding: [5, 10],
|
||||
@ -104,18 +128,17 @@ function chartFn(series) {
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: props.rotate, // 设置标签旋转角度
|
||||
rotate: props.rotate,
|
||||
show: true,
|
||||
color: props.data.color[0] || "#409EFF",
|
||||
fontSize: 10,
|
||||
interval: props.data.interval || 0, // 强制显示所有标签
|
||||
formatter: function(value, index) {
|
||||
// 组合显示数量和年龄范围,数量在上,范围在下
|
||||
interval: props.data.interval || 0,
|
||||
formatter: function (value, index) {
|
||||
const bottomValues = props.data.bottomValues || [];
|
||||
const bottomValue = bottomValues[index] || '';
|
||||
const bottomValue = bottomValues[index] || "";
|
||||
return `${bottomValue}\n${value}`;
|
||||
},
|
||||
margin: 10 // 调整边距
|
||||
margin: 10
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
@ -123,12 +146,12 @@ function chartFn(series) {
|
||||
axisLabel: {
|
||||
color: props.data.color[0] || "#409EFF",
|
||||
fontSize: 10,
|
||||
formatter: '{value}%' // 显示百分比
|
||||
formatter: "{value}%"
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
type: "solid",
|
||||
color: props.data.color[0] || "#409EFF"
|
||||
}
|
||||
},
|
||||
@ -144,9 +167,8 @@ function chartFn(series) {
|
||||
...item,
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: function(params) {
|
||||
// 显示顶部百分比标签
|
||||
position: "top",
|
||||
formatter: function (params) {
|
||||
return `占比 ${params.value}%`;
|
||||
},
|
||||
color: props.data.color[0] || "#409EFF",
|
||||
@ -157,29 +179,24 @@ function chartFn(series) {
|
||||
color: item.itemStyle.normal.color
|
||||
}
|
||||
}
|
||||
})),
|
||||
// // 底部数值标签
|
||||
// graphic: props.data.bottomValues ? props.data.bottomValues.map((value, idx) => {
|
||||
// const percent = (idx + 0.5) / props.data.xData.length * 100;
|
||||
// return {
|
||||
// type: 'text',
|
||||
// left: `${percent}%`,
|
||||
// bottom: '5%', // 调整到底部,显示在x轴标签下方
|
||||
// style: {
|
||||
// text: value,
|
||||
// fill: '#000',
|
||||
// fontSize: 12
|
||||
// }
|
||||
// };
|
||||
// }) : []
|
||||
}))
|
||||
};
|
||||
option && myChart.setOption(option);
|
||||
window.addEventListener('resize', function() {
|
||||
myChart.resize();
|
||||
})
|
||||
}
|
||||
|
||||
// 组件挂载时添加 resize 监听
|
||||
onMounted(() => {
|
||||
window.addEventListener("resize", handleResize);
|
||||
});
|
||||
|
||||
// 组件卸载时清理资源
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
if (myChart) {
|
||||
myChart.dispose();
|
||||
myChart = null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
Reference in New Issue
Block a user