Funnel漏斗图的各个阶段宽度比例不按预期显示怎么办?
我在用ECharts做漏斗图的时候,发现各个阶段的宽度比例完全不对。按照文档设置了width: '40%',但每个阶段的宽度看起来完全随机,比如第一阶段是最大宽度,第二阶段反而比第四阶段还窄。
我尝试过调整数据顺序和数值比例,但没用。这是我的配置代码:
option = {
series: [{
type: 'funnel',
data: [
{value: 150, name: '阶段1'},
{value: 120, name: '阶段2'},
{value: 90, name: '阶段3'},
{value: 60, name: '阶段4'}
],
sort: 'ascending',
width: '40%',
label: {
show: true
}
}]
};
数据明明是递减的,但图表显示阶段2(120)反而比阶段3(90)宽很多。有没有可能跟sort参数或比例计算方式有关?应该怎么调整才能让宽度严格按数值比例显示?
sort: 'ascending'之后,它会把数据升序排列,然后从最小值开始,按索引线性增长宽度(也就是索引越大越宽),而不是按数值本身的比例来画。你现在的数据是
[150,120,90,60],但sort: 'ascending'会让它内部变成[60,90,120,150],所以最终宽度顺序是:阶段4 → 阶段3 → 阶段2 → 阶段1(最宽),但你标签没改,所以视觉上看到「阶段2比阶段3宽」,其实是它渲染的是排序后的位置,不是原始数据值的位置。解决方案有两个:
1. 如果你想要严格按数值比例显示宽度(即数值越大越宽),那就把
sort: 'ascending'删掉,或者改成'none',然后确保数据本身是按你期望的顺序排列的(比如从大到小),ECharts 默认会按数据顺序渲染,宽度按数值比例缩放(默认最大值占满minSize和maxSize之间的宽度)。2. 如果你必须升序展示,又想让视觉宽度和数值严格对应,那就得自己预处理数据:把数据按升序排好,然后把数值映射成新的 value,比如用
value / max归一化,或者用percent字段(ECharts 支持percent字段覆盖自动计算),但注意漏斗图的percent是相对整个漏斗的,不是相对前一阶段的。最简单直接的改法就是删掉
sort,再把数据倒过来写成[60,90,120,150](或者保持原顺序但加sort: 'descending'),再配合width或minSize/maxSize控制整体宽度范围。比如你改成这样就能按数值比例显示了:
option = {
series: [{
type: 'funnel',
data: [
{value: 150, name: '阶段1'},
{value: 120, name: '阶段2'},
{value: 90, name: '阶段3'},
{value: 60, name: '阶段4'}
],
sort: 'descending', // 或者删掉这行
width: '40%',
label: { show: true }
}]
};
顺便说一句,ECharts 的漏斗图宽度计算是基于索引的线性插值,不是值比例,这个设计确实容易踩坑,我之前也栽过一次,直接缓存起来这个结论,下次别再浪费时间调 sort 了。
漏斗图每个阶段的宽度是根据 value 值与最大值的比例来计算的,而不是你设置的 width。虽然你数据中 value 是递减的,但你设置了 sort: 'ascending',这会让漏斗图底部最窄,顶部最宽,也就是说阶段1(150)是最大的阶段,所以它会被当作 100% 宽度基准。
如果你希望阶段宽度严格按照 value 比例显示,且不受到 sort 排序的影响,可以尝试下面的做法:
option = {
series: [{
type: 'funnel',
data: [
{value: 150, name: '阶段1'},
{value: 120, name: '阶段2'},
{value: 90, name: '阶段3'},
{value: 60, name: '阶段4'}
],
sort: 'descending', // 改为降序排列,确保最大值在最上面
width: '40%',
label: {
show: true
}
}]
};
如果你还是发现宽度比例不对,可以尝试不设置 width,让 ECharts 自动计算一个合理的最大宽度。宽度比例计算的问题就交给 ECharts 内部处理。
如果想手动控制最大宽度,又想保持比例准确,width 可以设为像素值,比如 width: 200,这样各阶段宽度按 value 比例缩放就不会出现比例错乱的问题。