Files
smart-fin-chart/js/charts/ppmt_region_channel.js
2026-08-23 21:23:41 +08:00

126 lines
3.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
PALETTE, FONT, titleStyle, footnote, watermarks,
LAYOUT, } from '../theme.js';
/**
* 泡泡玛特区域渠道分布图(2026H1)
* 使用交错正负轴展示不同区域和渠道的收入
*/
export function regionChannelChart(rows, { width, height }) {
// 数据结构重组:按区域分组
const regions = ['中国', '海外', '亚太', '美洲', '欧洲及其他'];
const channels = ['线下渠道', '线上渠道', '批发及其他'];
// 构建数据映射
const dataMap = {};
rows.forEach(row => {
const key = `${row.region}_${row.channel}`;
dataMap[key] = row.value;
});
// 为每个渠道构建系列数据
const seriesData = channels.map(channel => {
return regions.map(region => {
const key = `${region}_${channel}`;
const value = dataMap[key] || 0;
// 线上渠道显示为负值(左侧),其他为正值(右侧)
return channel === '线上渠道' ? -value : value;
});
});
// 配色
const channelColors = {
'线下渠道': PALETTE.navy,
'线上渠道': PALETTE.coral,
'批发及其他': PALETTE.sage,
};
return {
backgroundColor: '#fff',
title: {
...titleStyle,
text: '泡泡玛特区域渠道分布(2026H1',
subtext: '左侧:线上渠道 | 右侧:线下渠道、批发及其他,单位:亿元',
top: 18,
},
legend: {
data: channels.map(name => ({ name, icon: 'rect' })), // 全部堆叠柱状图
top: LAYOUT.legendTop,
itemGap: 32,
textStyle: { fontFamily: FONT, fontSize: 13 },
},
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' },
textStyle: { fontFamily: FONT },
formatter: (params) => {
let result = `<b>${params[0].axisValue}</b><br/>`;
params.forEach(p => {
const value = Math.abs(p.value);
result += `${p.marker}${p.seriesName}: ${value.toFixed(2)} 亿元<br/>`;
});
return result;
},
},
grid: {
left: 100,
right: 100,
top: 145,
bottom: 90,
containLabel: false,
},
xAxis: {
type: 'value',
position: 'top',
splitLine: {
show: true,
lineStyle: { color: '#e8e8e8', width: 1 }
},
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
formatter: (value) => Math.abs(value),
fontFamily: FONT,
fontSize: 12,
color: '#8c8c8c',
},
},
yAxis: {
type: 'category',
data: regions,
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
fontFamily: FONT,
fontSize: 13,
color: '#333',
fontWeight: '500',
},
inverse: false,
},
series: channels.map((channel, idx) => ({
name: channel,
type: 'bar',
stack: channel === '线上渠道' ? 'left' : 'right',
data: seriesData[idx],
itemStyle: { color: channelColors[channel] },
label: {
show: true,
position: channel === '线上渠道' ? 'left' : 'right',
formatter: (params) => {
const value = Math.abs(params.value);
return value > 0 ? value.toFixed(1) : '';
},
fontFamily: FONT,
fontSize: 11,
color: '#333',
},
barWidth: 22,
})),
graphic: [
...watermarks(width, height),
footnote('数据来源:泡泡玛特财报 | @思考的Joey'),
],
};
}