漏斗图封装
颜色配置
constans.ts
/* ======================== Beautify ========================= */
// 由于 ECharts 默认只提供了 9 个 slice 的颜色, 而业务中上限为 10 个 slice, 所以自定义一个长度为 10 的颜色组
// 前九项为官网的默认值 (ECharts@5.4.2 2023/05/12)
export const SLICE_COLORS: string[] = [
'#5470c6',
'#91cc75',
'#fac858',
'#ee6666',
'#73c0de',
'#3ba272',
'#fc8452',
'#9a60b4',
'#ea7ccc',
'#66cccc',
"#6482db",
"#7fe383",
"#ffd45c",
"#ff5454",
"#72b7e6",
"#61c17e",
"#ff864d",
"#ce84d3",
"#e3aadf",
"#7db5b5"
]
代码展示
import React from 'react';
import ReactEcharts from 'echarts-for-react';
import { SLICE_COLORS } from './constans'
interface Props_FunnelChart {
funnelData: any[]
isFromDashboard?: boolean
isScreen?: boolean
}
const FunnelChart = (props: Props_FunnelChart) => {
const getOption = (funnelData) => {
const { isFromDashboard, isScreen } = props
const seriesData = convertData(funnelData)
return {
color: SLICE_COLORS,
tooltip: {
trigger: 'item',
extraCssText: `max-height: ${isScreen ? '50%' : (isFromDashboard ? '80%' : '250px')}; overflow: auto;margin-left: 20px`,
backgroundColor: 'rgba(255,255,255,0.8)',
confine: true,
enterable: true,
formatter: (params) => {
return `
<div style="display: flex; flexDirection: 'row'; ">
<div>
${params.marker}
</div>
<div>
${params.name}:${params.value ? params.value.toLocaleString() : 0}
</div>
</div>
`
}
},
series: [
{
name: "漏斗图",
type: 'funnel',
min: 0,
top: 0,
right: 150,
minSize: '15%',
height: '100%',
sort: 'descending',
gap: 0,
labelLine: {
show: false,
},
label: {//漏斗外部显示的
position: 'rightTop', //位置
// formatter: 'rate: {d}%', //显示的内容
formatter: (params) => {
return params.data.percent ? `—— 转化率: ${params.data.percent}%` : ''
},
padding: [0, 0, 0, -10],
fontStyle: 'normal',
fontSize: 12,
textBorderColor: '#000',
},
emphasis: { //鼠标移入数据项的tooltip设置
show: false
},
itemStyle: {
opacity: 0.7,
},
data: seriesData,
},
{
name: "辅助",
type: 'funnel',
min: 0,
top: 0,
right: 150,
minSize: '15%',
height: '100%',
sort: 'descending',
gap: 0,
label: { //设置字体放在漏斗内部
position: 'inside',
formatter: '{b} {c}',
fontStyle: 'normal',
fontSize: 12,
color: '#ffffff',
},
emphasis: {
label: {
fontSize: 14 //鼠标移入字体变大 显示toolList
}
},
itemStyle: {
opacity: 0.9,
},
data: seriesData,
z: 100
}
]
};
};
// 计算漏斗率
const convertData = (data) => {
return data.map((item, index, arr) => {
if (index > 0) {
const beforeValue = arr?.[index - 1]?.value;
const percent = ((item.value / beforeValue) * 10000 / 100).toFixed(2);
return {
...item,
percent
}
}
return {
...item,
};
});
}
const { funnelData } = props
return (
<ReactEcharts
option={getOption(funnelData)}
style={{ width: '100%', height: '100%' }}
opts={{ renderer: 'svg' }}
/>
);
};
export default FunnelChart;