vue3之echarts markLine自定义
效果如下:
版本:
echarts": "^5.5.1
核心代码:
<template>
<div ref="charts" class="chart"></div>
</template>
<script lang="ts" setup>
import * as echarts from 'echarts';
import { onMounted, reactive, ref, onBeforeUnmount } from 'vue';
// 自定义的两张markLine图片
import red from '@/assets/img/rectangle-red.png';
import yellow from '@/assets/img/rectangle-yellow.png';
const charts: any = ref(null);
const data = reactive({
xAxis: ['考核点1', '考核点2', '考核点1', '考核点1', '考核点1', '考核点1', '考核点1', '考核点1', '考核点9', '考核点10', '考核点11', '考核点12'],
list: [
{
name: '红',
value: 90,
},
{
name: '红',
value: 86,
},
{
name: '红',
value: 80,
},
{
name: '红',
value: 75,
},
{
name: '红',
value: 70,
},
{
name: '红',
value: 60,
},
{
name: '红',
value: 50,
},
{
name: '红',
value: 50,
},
{
name: '黄',
value: 28.9,
},
{
name: '黄',
value: 28.9,
},
{
name: '黄',
value: 28.9,
},
{
name: '黄',
value: 28.9,
},
],
lineData: [
{
name: '红',
xAxis: 14,
},
{
name: '黄',
xAxis: 7,
},
],
});
let myechart: any = null;
const initChart = () => {
if (charts.value) {
myechart = echarts.init(charts.value);
}
const option = {
tooltip: {
trigger: 'axis',
backgroundColor: '#fff',
borderWidth: 1,
borderColor: '#D5D9E0',
formatter(params: any) {
// 提示框自定义
const param = params.filter((item: any) => item.seriesName !== '模拟y轴');
return formatterTip(param);
},
},
grid: {
top: '6%',
left: '0%',
right: '9%',
bottom: '0%',
containLabel: true,
},
legend: {
show: false,
},
xAxis: {
type: 'value',
axisTick: {
show: false,
},
axisLine: {
show: false,
},
axisLabel: {
color: '#A9AEB8',
fontSize: 12,
fontFamily: 'PingFang SC',
lineHeight: 20,
formatter: function (value: any) {
return `${value}%`;
},
},
},
yAxis: [
{
triggerEvent: true,
show: true,
inverse: true,
data: data.xAxis,
axisLine: {
show: true,
lineStyle: {
color: '#E5E6EB',
width: 1,
type: 'solid',
},
},
splitLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
interval: 0,
color: '#6B7785',
margin: 8,
fontSize: 12,
fontFamily: 'PingFang SC',
},
},
],
series: [
{
name: '红黄灯预警', //这个是Bar图
type: 'bar',
barWidth: '16',
barGap: '135%',
markLine: {
symbol: ['none', 'none'], // 隐藏默认的箭头符号
data: data.lineData.map((item: any) => {
return {
...item,
lineStyle: {
color: item.name.includes('红') ? '#F2515B' : '#F8AA44', // 线条颜色
width: 1, // 线条宽度
type: 'solid', // 线条类型:'solid', 'dashed', 'dotted'
cap: 'round',
},
// 自定义 markLine 上的标签
label: {
distance: 1,
show: true,
position: 'start',
fontSize: 12,
fontFamily: 'PingFang SC',
formatter: (params: any) => {
return [`{a|${params.value}%}`, '{b|}'].join('\n');
},
rich: {
a: {
color: item.name.includes('红') ? '#F2515B' : '#F8AA44',
lineHeight: 16,
},
b: {
// 设置三角形的图片
backgroundColor: {
image: item.name.includes('红') ? red : yellow,
},
width: 11,
height: 8,
},
},
},
};
}),
},
data: data.list.map((item: any) => {
return {
...item,
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: item.name.includes('红') ? 'rgba(242, 81, 91, 0.2)' : 'rgba(248, 170, 68, 0.2)', // 0% 处的颜色
},
{
offset: 1,
color: item.name.includes('红') ? 'rgba(242, 81, 91, 1)' : 'rgba(248, 170, 68, 1)', // 100% 处的颜色
},
],
globalCoord: false, // 缺省为 false
},
borderColor: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{
offset: 0,
color: item.name.includes('红') ? 'rgba(242, 81, 91, 0.2)' : 'rgba(248, 170, 68, 0.2)', // 0% 处的颜色
},
{
offset: 1,
color: item.name.includes('红') ? 'rgba(242, 81, 91, 1)' : 'rgba(248, 170, 68, 1)', // 100% 处的颜色
},
],
globalCoord: false, // 缺省为 false
},
borderRadius: 2,
},
label: {
show: true,
width: 6,
height: 16,
distance: 2,
backgroundColor: item.name.includes('红') ? '#F2515B' : '#F8AA44',
fontSize: 12,
color: 'transparent',
position: 'right',
borderRadius: 2,
},
};
}),
z: 1,
},
{
// 这里可以直接y轴,另外一种写法
name: '模拟y轴',
type: 'bar',
barWidth: 20,
barGap: '-100%',
itemStyle: {
normal: {
color: 'transparent',
},
},
label: {
show: true,
position: 'right',
color: '#333333',
fontSize: 12,
offset: [10, 0],
formatter: function (value: any) {
return data.list[value.dataIndex].value + '%';
},
},
z: 0,
data: new Array(data.list.length).fill(100),
},
],
};
myechart.setOption(option);
};
// 提示框自定义
const formatterTip = (params: any) => {
let tip = `<div letter-spacing: 2px;">
<span style="font-size: 14px; font-family: Source Han Sans CN; font-weight: 500; color: #A9AEB8;">${params[0]?.axisValue}</span>
</div>`;
params.forEach((param: any, index: number) => {
tip += `<div style="margin-top: ${index ? 2 : 0}px;display:flex;align-items:center;font-size: 12px;font-family: 'PingFang SC';color: #A9AEB8;font-size: 12px;">
<div style="width:12px;height:8px;background: linear-gradient(90deg, ${param.color.colorStops[0].color} 0%, ${param.color.colorStops[1].color} 100%);margin-right:6px;border-radius: 2px;"></div>
<div style="margin-right: 10px;">${param?.seriesName}</div>
<div>${param?.value}</div>
</div>`;
});
return tip;
};
onMounted(() => {
initChart();
});
onBeforeUnmount(() => {
if (myechart) {
myechart.clear();
myechart.dispose();
myechart = null;
}
});
</script>
<style scoped lang="scss">
.chart {
width: 616px;
height: 475px;
}
</style>