扇形图组件
<template>
<div :id="id" :chartOptions="chartOptions" class="chart"></div>
</template>
<script setup>
import { onMounted, onBeforeUnmount, watch } from "vue";
import * as echarts from "echarts";
const props = defineProps({
id: {
type: String,
default: "chart",
},
chartOptions: {
type: Object,
default: {},
},
});
let myChart;
let chartOptions = props.chartOptions;
onMounted(() => {
setTimeout(() => {
var id = props.id;
var chartDom = document.getElementById(id);
if (myChart) {
myChart.dispose(); //销毁
}
myChart = echarts.init(chartDom);
getEchartsData();
}, 500);
window.addEventListener("resize", () => {
myChart.resize();
});
});
const getEchartsData = () => {
let option = {
grid: {
top: "15%",
left: 0,
containLabel: true, // 确保标签不被剪裁
height: "85%", // 高度为容器高度的80%
width: "100%",
},
tooltip: {
trigger: "item",
},
legend: {
show: true,
},
xAxis: {
data: ["变更改造", "缺陷申报", "其他", "预测性维修", "预防性维修", "点巡检"],
axisLabel: {
interval: 0,
formatter:function(value){
var str = "";
var num = 5; //每行显示字数
var valLength = value.length; //该项x轴字数
var rowNum = Math.ceil(valLength / num); // 行数
if(rowNum > 1) {
for(var i = 0; i < rowNum; i++) {
var temp = "";
var start = i * num;
var end = start + num;
temp = value.substring(start, end) + "\n";
str += temp;
}
return str;
} else {
return value;
}
}
}
},
yAxis: {
splitLine: {
show: true,
lineStyle: {
type: "dashed", //背景色为虚线
},
},
},
series: [
{
name: "申请数量",
type: "bar",
data: chartOptions.data1,
itemStyle: {
color: "#3299EC", // 这里设置柱状图的颜色
},
},
{
name: "审批数量",
type: "bar",
data: chartOptions.data2,
itemStyle: {
color: "#F1AF1F", // 这里设置柱状图的颜色
},
},
],
};
//{ notMerge: true } 数据更新关键
if (myChart) {
myChart.setOption(option, { notMerge: true });
}
};
watch(
() => props.chartOptions,
(val) => {
if (val) {
getEchartsData();
}
},
{ deep: true }
);
onBeforeUnmount(() => {
window.removeEventListener("resize", () => {
myChart.resize();
});
});
</script>
<style scoped lang="scss">
.chart {
width: 100%;
height: 203px;
}
</style>
柱状图组件
<template>
<div :id="id" :chartOptions="chartOptions" class="chart"></div>
</template>
<script setup>
import { onMounted, onBeforeUnmount, watch } from "vue";
import * as echarts from "echarts";
const props = defineProps({
id: {
type: String,
default: "chart",
},
chartOptions: {
type: Object,
default: {},
},
});
let myChart;
let chartOptions = props.chartOptions;
onMounted(() => {
setTimeout(() => {
var id = props.id;
var chartDom = document.getElementById(id);
if (myChart) {
myChart.dispose(); //销毁
}
myChart = echarts.init(chartDom);
getEchartsData();
}, 500);
window.addEventListener("resize", () => {
myChart.resize();
});
});
const getEchartsData = () => {
let option = {
title: {
text: "合计申请工单",
subtext: chartOptions.seriesData[0] ? chartOptions.seriesData[0].num : 0,
left: "center",
top: "42%",
},
tooltip: {
trigger: "item",
},
series:{
name: "访问来源",
type: "pie",
radius: ["64%", "79%"],
labelLine: {
show:true,
length: 5, //第一段线长
length2: 50, //第二段线长
},
label: {
formatter: '{b}:{c}\n'+'{a|{d}%}',
position:'outer',
alignTo:'edge',
padding: [33, -50, 20, -50],
distance: 10,
rich: {
a: {
fontSize: 13,
color: "inherit",
lineHeight: 32,
},
},
},
itemStyle: {
normal: {
color: function (params) {
const colorList = ["#3299EC", "#F1AF1F "];
return colorList[params.dataIndex % colorList.length];
},
},
},
data: chartOptions.seriesData,
},
};
//{ notMerge: true } 数据更新关键
if (myChart) {
myChart.setOption(option, { notMerge: true });
}
};
watch(
() => props.chartOptions,
(val) => {
if(val){
getEchartsData();
}
},
{ deep: true }
);
onBeforeUnmount(() => {
window.removeEventListener("resize", () => {
myChart.resize();
});
});
</script>
<style scoped lang="scss">
.chart {
width: 100%;
height: 203px;
}
</style>
折线+柱状图组件
<template>
<div :id="id" :chartOptions="chartOptions" class="chart"></div>
</template>
<script setup>
import { onMounted, onBeforeUnmount, watch } from "vue";
import * as echarts from "echarts";
const props = defineProps({
id: {
type: String,
default: "chart",
},
chartOptions: {
type: Object,
default: {},
}
});
let myChart;
let chartOptions = props.chartOptions;
onMounted(() => {
setTimeout(() => {
var id = props.id;
var chartDom = document.getElementById(id);
if (myChart) {
myChart.dispose(); //销毁
}
myChart = echarts.init(chartDom);
getEchartsData();
}, 500);
window.addEventListener("resize", () => {
myChart.resize();
});
});
const getEchartsData = () => {
let option = {
grid: {
top: "15%",
left: 0,
containLabel: true, // 确保标签不被剪裁
height: "86%", // 高度为容器高度的80%
width: "100%",
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#283b56",
},
},
},
legend: {},
toolbox: {
show: true,
},
dataZoom: {
show: false,
start: 0,
end: 100,
},
xAxis: [
{
type: "category",
axisPointer: {
type: "shadow",
},
data:
chartOptions.xData.length !== 0
? chartOptions.xData
: [
"第一周",
"第二周",
"第三周",
"第四周",
"第五周",
"第六周",
"第七周",
"第八周",
"第九周",
"第十周",
"第十一周",
"第十二周",
],
axisLabel: {
interval: 0,
rotate:45
},
},
// {
// type: "category",
// boundaryGap: true,
// data:[10,10,10],
// //data: chartOptions.xData.length!==0?chartOptions.xData:['第一周','第二周','第三周'],
// },
],
yAxis: [
{
type: "value",
scale: true,
// name: "数量/个",
max: Math.max(...chartOptions.y1Data),
min: 0,
boundaryGap: [0.2, 0.2],
splitLine: {
show: true,
lineStyle: {
type: "dashed", //背景色为虚线
},
},
},
{
type: "value",
scale: true,
// name: "趋势/%",
axisLabel: {
show: true,
interval: "auto", //居中显示
formatter: (value) => {
return value + "%";
},
},
max: Math.max(...chartOptions.y2Data),
min: Math.floor(Math.min(...chartOptions.y2Data))< 0 ?Math.floor(Math.min(...chartOptions.y2Data)-10) : 0,
boundaryGap: [0.2, 0.2],
splitLine: {
show: true,
lineStyle: {
type: "dashed", //背景色为虚线
},
},
},
],
series: [
{
name: "申请数量",
type: "bar",
//xAxisIndex: 1,
yAxisIndex: 0,
data: chartOptions.y1Data, // 柱状图数据
itemStyle: {
color: "#1CDEA4", // 这里设置柱状图的颜色
},
},
{
name: "申请数量增长趋势",
type: "line",
yAxisIndex: 1,
data: chartOptions.y2Data, // 折线图数据
itemStyle: {
color: "#F1AF1F", // 这里设置柱状图的颜色
},
},
],
};
//{ notMerge: true } 数据更新关键
if (myChart) {
myChart.setOption(option, { notMerge: true });
}
};
watch(
() => props.chartOptions,
(val) => {
if (val) {
getEchartsData();
}
},
{ deep: true }
);
onBeforeUnmount(() => {
window.removeEventListener("resize", () => {
myChart.resize();
});
});
</script>
<style scoped lang="scss">
.chart {
width: 100%;
height: 203px;
}
</style>
父组件
注意:一定必须用reactive,否则不会实现父子组件的响应式效果
const pieOptions = reactive({
seriesData: [],
});
const barLineConfig = reactive({
xData: [], // 横坐标
y1Data: [], // 纵坐标1
y2Data: [], // 纵坐标2
});
const barsConfig = reactive({
data1: ["", "", "", "", "", ""], // 纵坐标1 这块的案例是两个柱状图
data2: ["", "", "", "", "", ""], // 纵坐标2
});
在onMounted里面进行初始化数据给pieOptions,barLineConfig,barsConfig进行赋值
onMounted(() => {
});