基于vue3,EChart5.4.3版本
Line
<script setup lang="ts">
import {onBeforeUnmount, onMounted, ref, watch} from "vue"
import {useEcharts, type ECOption} from "@/composables"
import * as echarts from "echarts/core";
const chartOptions = ref<ECOption>();
const {domRef: chart} = useEcharts(chartOptions);
const props = defineProps({
chartXData: {
type: Array,
default: []
},
chartYData: {
type: Array,
default: []
},
seriesData: {
type: Array,
default: []
},
seriesNameList: {
type: Array,
default: []
},
yName: {
type: String,
default: ''
},
lineColorList: {
type: Array,
default: ['rgba(1, 145, 219, 1)', 'rgba(9, 162, 51, 1)', 'rgba(191, 153, 18, 1)']
},
isAreaStyle: {
type: Boolean,
default: false
},
areaColorStyle: {
type: Array,
default: [new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(3, 200, 242, 0.64)',
},
{
offset: 1,
color: 'rgba(3, 200, 242, 0)',
},
]), new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(4, 148, 44, 0.16)',
},
{
offset: 1,
color: 'rgba(4, 148, 44, 0)',
},
]), new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#BF9912AB',
},
{
offset: 1,
color: '#BF991200',
},
])]
},
stack: {
type: String,
default: ''
},
isSmooth: {
type: Boolean,
default: false
},
symbol: {
type: String,
default: ''
},
title: {
type: String,
default: ''
},
topGrid: {
type: String,
default: '25'
},
})
const watcher = watch(()=> props.seriesData, (value: any) => {
chartOptions.value.series = getSeriesData(value)
})
const watcherTitle = watch(()=> props.title, (value: any) => {
chartOptions.value.title['text'] = value
})
const watcherXData = watch(()=> props.chartXData, (value: any) => {
chartOptions.value.xAxis.data = value
})
onBeforeUnmount(() => {
watcher();
watcherTitle();
watcherXData();
})
const getChartData = () => {
updateChartOptions();
}
const updateChartOptions = () => {
chartOptions.value = {
title: {
text: props.title,
left: 0,
top: 5,
textStyle: {
fontSize: 16,
},
},
backgroundColor: 'white',
tooltip: {
trigger: 'axis',
color: '#fff', // 设置文字颜色为白色
backgroundColor: 'rgba(16,24,41)', // 设置背景颜色为黑色,透明度为0.7
borderColor: 'rgba(16,24,41)', // 设置边框颜色为白色
borderWidth: 1, // 设置边框宽度为1px
},
legend: {
left: 'right',
top: 10,
itemWidth: 8,
itemHeight: 8,
itemGap: 16,
borderRadius: 4,
color: 'rgba(202,231,254,0.5)',
fontSize: 10,
},
xAxis: {
type: 'category',
data: props.chartXData,
boundaryGap: false,
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
interval: 1,
show: true,
color: 'rgba(202,231,254,0.5)', //X轴文字颜色
},
},
yAxis: [
{
type: 'value',
nameTextStyle: {
color: '#CAE7FE80',
// fontFamily: 'Alibaba PuHuiTi',
fontSize: 10,
fontWeight: 600,
// padding: [0, 0, 0, 40], // 四个数字分别为上右下左与原位置距离
},
nameGap: 10, // 表现为上下位置
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
color: 'rgba(202,231,254,0.5)',
fontSize: 10,
// interval: 2, // 设置为0表示每隔一个显示一个标签
},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(147,219,209,0.16)',
},
},
},
{
type: 'value',
// name: '金额:万元',
nameTextStyle: {
color: 'rgba(202,231,254,0.5)',
fontFamily: 'Alibaba PuHuiTi',
fontSize: 10,
fontWeight: 600,
// padding: [0, 0, 0, 40], // 四个数字分别为上右下左与原位置距离
},
position: 'right',
splitLine: {
show: false,
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
axisLabel: {
show: true,
formatter: '{value}', //右侧Y轴文字显示
textStyle: {
color: 'rgba(202,231,254,0.5)',
},
},
},
],
series: getSeriesData(props.seriesData),
grid:{ // 让图表占满容器
top:"50px",
left:"20px",
right:"50px",
bottom:"0px",
containLabel: true,
}
};
}
const getSeriesData = (seriesData: any) => {
const length = props.seriesNameList?.length
let seriesArray = []
for (let i = 0; i < length; i++) {
seriesArray.push({
name: props.seriesNameList?.[i],
type: 'line',
showAllSymbol: true, //显示所有图形。
// stack: props.stack,//stack1
smooth: props.isSmooth,
areaStyle: {
// 设置堆叠效果的颜色和透明度
color: props.areaColorStyle?.[i],
},
symbol: props.symbol, //标记的图形为实心圆 rect
symbolSize: 4, //标记的大小
lineStyle: {
color: props.lineColorList?.[i],
},
itemStyle: {
color: props.lineColorList?.[i]
},
data: seriesData?.[i],
})
}
return seriesArray
}
onMounted(() => {
getChartData();
})
</script>
<template>
<div class="wh-full" ref="chart"></div>
</template>
<style scoped>
</style>
Bar
<script setup lang="ts">
import {onMounted, ref,onBeforeUnmount,watch} from "vue"
import {useEcharts, type ECOption} from "@/composables"
import * as echarts from "echarts/core";
const chartOptions = ref<ECOption>();
const {domRef: chart} = useEcharts(chartOptions);
const props = defineProps({
chartXData: {
type: Array,
default: []
},
chartYData: {
type: Array,
default: []
},
seriesData: {
type: Array,
default: []
},
seriesNameList: {
type: Array,
default: []
},
yName: {
type: String,
default: ''
},
barWidth: {
type: String,
default: '16'
},
title: {
type: String,
default: ''
},
topGrid: {
type: String,
default: '40px'
},
lineColorList: {
type: Array,
default: ['rgba(1, 145, 219, 1)', 'rgba(191, 153, 18, 1)', 'rgba(9, 162, 51, 1)']
},
areaColorStyle: {
type: Array,
default: [new echarts.graphic.LinearGradient(0, 0, 1, 1, [
{
offset: 0,
color: '#3A65F7FF',
},
{
offset: 1,
color: '#20C2F0FF',
},
]), new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#BF9912AB',
},
{
offset: 1,
color: '#BF991200',
},
]), new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#03C8F200',
},
{
offset: 1,
color: 'rgba(4, 148, 44, 0)',
},
])]
},
})
const watcher = watch(()=> props.seriesData, (value: any) => {
chartOptions.value.series[0].data = value
})
const watcherXData = watch(()=> props.chartXData, (value: any) => {
chartOptions.value.yAxis[0].data = value
})
onBeforeUnmount(() => {
watcher();
watcherXData();
})
const getChartData = () => {
updateChartOptions();
}
const updateChartOptions = () => {
chartOptions.value = {
backgroundColor: '#FFFFFF',
title: {
text: props.title,
left: 16,
top: 10,
textStyle: {
fontSize: 16,
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
// 坐标轴指示器,坐标轴触发有效
type: 'shadow', // 默认为直线,可选为:'line' | 'shadow'
},
confine: true,
textStyle: {
color: '#fff', // 设置文字颜色为白色
},
backgroundColor: 'rgba(16,24,41)', // 设置背景颜色为黑色,透明度为0.7
borderColor: 'rgba(16,24,41)', // 设置边框颜色为白色
borderWidth: 1, // 设置边框宽度为1px
},
legend: {
left: 'right',
top: 20,
textStyle: {
color: '#FFFFFFE6',
fontSize: 14,
},
itemWidth: 10,
itemHeight: 10,
itemGap: 15,
},
xAxis: {
type: 'value',
axisLine: {
show: true,
lineStyle: {
color: '#FFFFFF4D',
},
},
axisTick: {
show: false,
},
},
yAxis: [
{
type: 'category',
data: props.chartXData,
nameTextStyle: {
color: '#FFFFFF4D',
fontFamily: 'Alibaba PuHuiTi',
fontSize: 14,
fontWeight: 600,
// padding: [0, 0, 0, 40], // 四个数字分别为上右下左与原位置距离
},
nameGap: 10, // 表现为上下位置
axisLine: {
show: true,
lineStyle: {
color: '#FFFFFF4D',
},
},
axisTick: {
show: false,
},
axisLabel: {
color: '#FFFFFFE6',
fontSize: 14,
},
splitLine: {
show: false,
lineStyle: {
color: 'rgba(147,219,209,0.16)',
},
},
},
],
series: [
{
type: 'bar',
data: props.seriesData,
barWidth: `${props.barWidth}rem`,
itemStyle: {
// 设置堆叠效果的颜色和透明度
color: props.areaColorStyle?.[0],
},
lineStyle: {
color: props.lineColorList?.[0],
},
showBackground: true,
backgroundStyle: {
color: '#20C2F01A'
}
},
],
grid: { // 让图表占满容器
top: `${props.topGrid}px`,
left: "16px",
right: "30px",
bottom: "24px",
containLabel: true,
}
};
}
const getSeriesData = () => {
const length = props.seriesNameList?.length
let seriesArray = []
for (let i = 0; i < length; i++) {
seriesArray.push({
name: props.seriesNameList?.[i],
type: 'bar',
barWidth: `${props.barWidth}rem`,
itemStyle: {
// 设置堆叠效果的颜色和透明度
color: props.areaColorStyle?.[i],
},
lineStyle: {
color: props.lineColorList?.[i],
},
data: props.seriesData?.[i],//props.seriesData?.[i]
})
}
return seriesArray
}
onMounted(() => {
getChartData();
})
</script>
<template>
<div class="wh-full" ref="chart"></div>
</template>
<style scoped>
</style>
Pie
<script setup lang="ts">
import {onMounted, ref,onBeforeUnmount,watch} from "vue"
import {useEcharts, type ECOption} from "@/composables"
import * as echarts from "echarts/core";
const chartOptions = ref<ECOption>();
const {domRef: chart} = useEcharts(chartOptions);
const props = defineProps({
percentData: {
type: Number,
default: 0
},
})
const watcher = watch(()=> props.percentData, (value: any) => {
chartOptions.value.series[1].data[1].value = value
chartOptions.value.series[1].data[0].value = 100 - value
})
onBeforeUnmount(() => {
watcher();
})
const getChartData = () => {
updateChartOptions();
}
const updateChartOptions = () => {
chartOptions.value = {
tooltip: {
show: 'false',
},
series: [
{
type: 'pie',
radius: ['65%', '71%'],
tooltip: {
show: false // 禁用该 pie 的悬浮提示
},
avoidLabelOverlap: false,
label: {
show: false,
},
emphasis: {
disabled: false,
scale: false,
},
color: ['#0e2a4dFF'],
data: [
{ value: 100},
]
},
{
type: 'pie',
radius: ['71%', '86%'],
tooltip: {
show: false // 禁用该 pie 的悬浮提示
},
avoidLabelOverlap: false,
label: {
show: false,
},
emphasis: {
disabled: false,
},
itemStyle: {
borderColor: '#0F0F11FF',
borderWidth: 1
},
color: ['#257B4FFF','#C8676DFF'],//C8676DFF
data: [
{ value: 100 - props.percentData , name:'1'},
{ value: props.percentData, name:'2' },
]
},
{
type: 'pie',
radius: ['86%', '100%'],
tooltip: {
show: false // 禁用该 pie 的悬浮提示
},
avoidLabelOverlap: false,
label: {
show: false,
},
emphasis: {
disabled: false,
scale: false,
},
color: ['#0e2a4eFF',],
data: [
{ value: 100},
]
}
],
};
}
onMounted(() => {
getChartData();
})
</script>
<template>
<div class="wh-full" ref="chart"></div>
</template>
<style scoped>
</style>
使用
<template>
<Line
class="w-[calc(100%-30px)] h-[calc(100%-40px)] ml-15"
:chartXData="chartXLineData"
:seriesData="seriesLineData"
:seriesNameList="seriesNameList"
stack="stack1"
symbol="rect"
:title="`服务访问总数 ${titleData}`"
top-grid="50"
:isSmooth="true"
></Line>
</template>
<script lang="ts" setup>
import {onMounted, ref} from "vue"
import Line from '../Line.vue'
onMounted(() => {
init();
})
const chartXLineData = ref([])
const seriesNameList = ref(["", '', ''])
const seriesLineData = ref<number[]>([])
const lineColorList = ["rgba(1, 145, 219, 1)", 'rgba(9, 162, 51, 1)', "rgba(191, 153, 18, 1)"]
const seriesList = []
</script>
<style lang="scss" scoped>
</style>