漏斗图
为了解决还原设计稿上的漏斗图,并两边附带数据对比,尽可能地用Echarts实现,且不支持自动排序。
代码配置
<template>
<div
ref="customerStageFunnel"
id="customerStageFunnel"
style="height: 280px; width: 100%"
/>
</template>
<script>
// 调用echarts
import echarts from "echarts";
export default {
props: {
funnelData: {
type: Object,
default: () => ({})
}
},
watch: {
funnelData: {
handler(val) {
if (val && val.left && val.center && val.right) {
this.$nextTick(() => {
this.initChart();
});
}
},
deep: true,
immediate: true
}
},
data() {
return {
img: require("@/assets/qwH5/home/dash.png")
};
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.customerStageFunnel);
const option = {
title: [
{
show: true,
text: "阶段名称(经过此阶段客户数量)",
left: "center",
bottom: 0,
padding: [24, 0, 0, 0],
textStyle: {
fontFamily: "PingFangSC-Regular, PingFang SC",
fontSize: 10,
fontWeight: 400,
color: "#999999"
}
},
{
show: true,
text: "无意向客户(转化率)",
left: "left",
bottom: 0,
padding: [24, 0, 0, 0],
textStyle: {
fontFamily: "PingFangSC-Regular, PingFang SC",
fontSize: 10,
fontWeight: 400,
color: "#999999"
}
},
{
show: true,
text: "阶段转化率",
left: "right",
bottom: 0,
padding: [24, 0, 0, 0],
textStyle: {
fontFamily: "PingFangSC-Regular, PingFang SC",
fontSize: 10,
fontWeight: 400,
color: "#999999"
}
}
],
aria: {
enabled: true,
decal: {
show: true
}
},
tooltip: {
show: false
},
toolbox: {
show: false
},
legend: {
show: false
},
color: [
"rgba(78, 112, 240, 1)",
"rgba(78, 112, 240, 0.95)",
"rgba(78, 112, 240, 0.9)",
"rgba(78, 112, 240, 0.85)",
"rgba(78, 112, 240, 0.8)",
"rgba(78, 112, 240, 0.75)",
"rgba(78, 112, 240, 0.7)",
"rgba(78, 112, 240, 0.65)",
"rgba(78, 112, 240, 0.6)",
"rgba(78, 112, 240, 0.55)",
"rgba(78, 112, 240, 0.5)",
"rgba(78, 112, 240, 0.45)"
],
series: [
// 版图
{
type: "funnel",
minSize: "30%",
maxSize: "60%",
// height:500,
top: 16,
bottom: 20,
// gap: 1,
z: 3,
legendHoverLink: false,
label: {
position: "inside",
fontFamily: "PingFangSC-Medium, PingFang SC",
fontSize: 9,
fontWeight: "500",
color: "#fff",
formatter: function(params) {
const name =
params.name.length > 5
? params.name.slice(0, 4) + "..."
: params.name;
return `${name}(${params.value})`;
}
// width: 10,
// overflow: 'truncate',
// formatter: '{b}{xx|}({c})',
// rich: { xx: { padding: [0, 2] } }
},
data: this.funnelData.center || [],
sort: "none"
},
// 左边信息
{
type: "funnel",
minSize: "30%",
maxSize: "30%",
top: 16,
bottom: 20,
left: "-60%",
// funnelAlign: 'left',
gap: 2,
z: 1,
legendHoverLink: false,
label: {
show: true,
position: "inside",
color: "#5B5E7B",
fontSize: 10,
fontWeight: "400",
formatter: function(params) {
const dashed = "{x|}{y|}{x|}{y|}{x|}{y|}{x|}{y|}{x|}{y|}{x|}"; // 手动画虚线
// const dataIndex
const rate = params.data.rate;
const value = params.data.count;
return `${value}(${rate})\n${dashed}`;
},
rich: {
x: {
width: 5,
height: 0.5,
backgroundColor: "#E6E6E6",
lineHeight: 8
},
y: {
width: 5,
height: 0.5,
backgroundColor: "transparent",
lineHeight: 8
}
}
},
labelLine: {
show: false
},
itemStyle: {
color: "transparent"
},
data: this.funnelData.left || [],
sort: "none"
},
{
type: "funnel",
minSize: "30%",
maxSize: "30%",
top: 16,
bottom: 20,
right: "-60%",
// funnelAlign: 'left',
gap: 2,
z: 1,
legendHoverLink: false,
label: {
show: true,
position: "inside",
color: "#5B5E7B",
fontSize: 10,
fontWeight: "400",
padding: [0, 8, 0, 0],
width: 36,
height: 23,
lineHeight: 23,
formatter: function(params) {
// console.log(params);
const rate = params.data.rate;
// const value = params.value;
return `${rate}`;
},
backgroundColor: {
image: this.img,
width: 36,
height: 23
}
},
labelLine: {
show: false
},
itemStyle: {
color: "transparent"
},
data: this.funnelData.right || [],
sort: "none"
}
]
};
this.chart.setOption(option);
// resize
if (window.addEventListener) {
// 所有主流浏览器,除了 IE 8 及更早版本
window.addEventListener("resize", this.chart.resize);
} else if (window.attachEvent) {
// IE 8 及更早版本
window.attachEvent("onresize", this.chart.resize);
}
}
},
};
</script>