feat: 构建泡泡玛特相关图表
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import {
|
||||
PALETTE, FONT, titleStyle, footnote, watermarks,
|
||||
} from '../theme.js';
|
||||
|
||||
/**
|
||||
* 泡泡玛特利润流向桑基图(2026H1)
|
||||
* 从营业收入到非GAAP归母净利润的完整流程
|
||||
*/
|
||||
export function sankeyChart(rows, { width, height }) {
|
||||
// 从 CSV 构建桑基图的 links 数据
|
||||
const links = rows.map(row => ({
|
||||
source: row.source,
|
||||
target: row.target,
|
||||
value: row.value,
|
||||
}));
|
||||
|
||||
// 定义节点颜色
|
||||
const nodeColors = {
|
||||
'营业收入': PALETTE.navy,
|
||||
'营业成本': PALETTE.grey,
|
||||
'毛利': PALETTE.sage,
|
||||
'销售费用': PALETTE.orange,
|
||||
'管理费用': PALETTE.purple,
|
||||
'财务费用': PALETTE.brown,
|
||||
'营业利润': PALETTE.green,
|
||||
'投资收益': PALETTE.blue,
|
||||
'公允价值变动': PALETTE.blue,
|
||||
'其他收入': PALETTE.blue,
|
||||
'利润总额': PALETTE.sage,
|
||||
'所得税费用': PALETTE.grey,
|
||||
'净利润': PALETTE.green,
|
||||
'少数股东损益': PALETTE.grey,
|
||||
'归母净利润': PALETTE.coral,
|
||||
'非GAAP调整项': PALETTE.blue,
|
||||
'非GAAP归母净利润': PALETTE.red,
|
||||
};
|
||||
|
||||
return {
|
||||
backgroundColor: '#fff',
|
||||
title: {
|
||||
...titleStyle,
|
||||
text: '泡泡玛特利润流向分析(2026H1)',
|
||||
subtext: '从营业收入到非GAAP归母净利润的完整流程,单位:亿元',
|
||||
top: 18,
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
triggerOn: 'mousemove',
|
||||
textStyle: { fontFamily: FONT, fontSize: 13 },
|
||||
formatter: (params) => {
|
||||
if (params.dataType === 'edge') {
|
||||
return `${params.data.source} → ${params.data.target}<br/><b>${params.data.value.toFixed(2)} 亿元</b>`;
|
||||
} else {
|
||||
return `<b>${params.name}</b><br/>总额: ${params.value.toFixed(2)} 亿元`;
|
||||
}
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'sankey',
|
||||
layout: 'none',
|
||||
emphasis: {
|
||||
focus: 'adjacency',
|
||||
},
|
||||
nodeAlign: 'left',
|
||||
layoutIterations: 0,
|
||||
nodeWidth: 26,
|
||||
nodeGap: 14,
|
||||
left: 120,
|
||||
right: 180,
|
||||
top: 110,
|
||||
bottom: 90,
|
||||
data: Object.keys(nodeColors).map(name => ({
|
||||
name,
|
||||
itemStyle: { color: nodeColors[name] },
|
||||
})),
|
||||
links,
|
||||
label: {
|
||||
color: PALETTE.ink,
|
||||
fontFamily: FONT,
|
||||
fontSize: 12,
|
||||
fontWeight: 'normal',
|
||||
formatter: (params) => {
|
||||
// 给每个节点标注名称和数值
|
||||
return `{name|${params.name}}\n{value|${params.value.toFixed(2)}亿}`;
|
||||
},
|
||||
rich: {
|
||||
name: {
|
||||
fontSize: 12,
|
||||
fontFamily: FONT,
|
||||
color: PALETTE.ink,
|
||||
},
|
||||
value: {
|
||||
fontSize: 11,
|
||||
fontFamily: FONT,
|
||||
color: PALETTE.grey,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
},
|
||||
},
|
||||
lineStyle: {
|
||||
color: 'gradient',
|
||||
curveness: 0.5,
|
||||
opacity: 0.3,
|
||||
},
|
||||
levels: [
|
||||
{
|
||||
depth: 0,
|
||||
label: { position: 'left' },
|
||||
},
|
||||
{
|
||||
depth: 1,
|
||||
label: { position: 'right' },
|
||||
},
|
||||
{
|
||||
depth: 2,
|
||||
label: { position: 'right' },
|
||||
},
|
||||
{
|
||||
depth: 3,
|
||||
label: { position: 'right' },
|
||||
},
|
||||
{
|
||||
depth: 4,
|
||||
label: { position: 'right' },
|
||||
},
|
||||
{
|
||||
depth: 5,
|
||||
label: { position: 'right' },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
graphic: [
|
||||
...watermarks(width, height),
|
||||
footnote('数据来源:泡泡玛特财报 | @思考的Joey'),
|
||||
],
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user