(function() {
const dom = document.getElementById('chart-dumbbell');
const myChart = echarts.init(dom);
const categories = ['项目A', '项目B', '项目C', '项目D', '项目E'];
const before = [30, 45, 22, 55, 38];
const after = [42, 50, 35, 48, 60];
myChart.setOption({
tooltip: { trigger: 'axis', formatter: p => {
const cat = categories[p[0].dataIndex];
const b = before[p[0].dataIndex], a = after[p[0].dataIndex];
return cat + '
前期: ' + b + '
后期: ' + a + '
变化: ' + (a - b >= 0 ? '+' : '') + (a - b);
}},
grid: { left: '15%', right: '10%', top: '8%', bottom: '8%' },
xAxis: { type: 'value', name: '数值' },
yAxis: { type: 'category', data: categories },
series: [
{ type: 'custom', name: '哑铃杆', data: categories.map((cat, i) => ({ value: i, b: before[i], a: after[i] })),
renderItem: function(params, api) {
const y = api.coord([0, params.dataIndex])[1];
// 🔴 api.value(1)=before值, api.value(2)=after值(按encode维度序号取值,不可用params.data.xxx)
const x1 = api.coord([api.value(1), 0])[0];
const x2 = api.coord([api.value(2), 0])[0];
return { type: 'line', shape: { x1: x1, y1: y, x2: x2, y2: y }, style: { stroke: '#94a3b8', lineWidth: 2 } };
}, encode: { x: [1, 2], y: 0 }
},
{ type: 'scatter', name: '前期', data: before.map((v, i) => [v, categories[i]]), symbolSize: 14, itemStyle: { color: '#3b82f6' } },
{ type: 'scatter', name: '后期', data: after.map((v, i) => [v, categories[i]]), symbolSize: 14, itemStyle: { color: '#ef4444' } }
]
});
window.addEventListener('resize', () => myChart.resize());
})();