feat: 优化泡泡玛特的图表

This commit is contained in:
R524809
2026-09-10 17:44:09 +08:00
parent a6387f8220
commit 417116b928
14 changed files with 327 additions and 299 deletions
+18 -7
View File
@@ -1,7 +1,7 @@
import {
PALETTE, FONT, axisCommon, categoryAxis, titleStyle,
financialViewDisclosure, financialViewLabel, shortStandalonePeriod,
standardLegend, barSeries, footnote, watermarks, LAYOUT,
standardLegend, barSeries, fanTinyLabelOffsets, stackedSharePoint, footnote, watermarks, LAYOUT,
} from '../theme.js';
/**
@@ -40,8 +40,14 @@ export function ppmtIpShareHistoryChart(rows, { width, height, view = 'all' }) {
const periods = Object.keys(rows[0]).filter((k) => k !== 'ip');
const names = rows.map((r) => r.ip);
const totals = periods.map((p) => rows.reduce((s, r) => s + r[p], 0));
// 归一化:各 IP 占当期合计的比重,逐期加总恰为 100%
const toPct = (r) => periods.map((p, i) => (r[p] / totals[i]) * 100);
// 归一化:各 IP 占当期合计的比重,逐期加总恰为 100%。
// 转成「期间 × 系列」的行结构,供 fanTinyLabelOffsets 逐柱计算矮段偏移。
const pctRows = periods.map((p, i) => Object.fromEntries(
rows.map((r) => [r.ip, (r[p] / totals[i]) * 100]),
));
// 绘图区像素高:画布高 − grid top 145 − grid bottom 70;轴固定 0–100%
const pxPerUnit = (height - LAYOUT.gridTop - 70) / 100;
const rowOffsets = fanTinyLabelOffsets(pctRows, names, pxPerUnit);
return {
backgroundColor: '#fff',
@@ -83,9 +89,14 @@ export function ppmtIpShareHistoryChart(rows, { width, height, view = 'all' }) {
interval: 20,
axisLabel: { ...axisCommon.axisLabel, formatter: '{value}%' },
},
series: rows.map((r) => barSeries({
// 每个非零占比都要展示:塞得进段内的段内白字,矮段外置到柱体右侧(深字白描边)
series: rows.map((r, ci) => barSeries({
name: r.ip,
data: toPct(r),
data: pctRows.map((pr, ri) => stackedSharePoint(pr[r.ip], {
pxPerUnit,
labelColor: '#fff',
dy: rowOffsets[ri][ci] ?? 0,
})),
color: COLORS[r.ip] ?? PALETTE.grey,
barWidth: 40,
stack: 'share',
@@ -96,8 +107,8 @@ export function ppmtIpShareHistoryChart(rows, { width, height, view = 'all' }) {
fontSize: 11,
fontFamily: FONT,
fontWeight: 500,
// 低于 4% 的段塞不进字,留空靠 tooltip 读数
formatter: (p) => (p.value >= 4 ? `${p.value.toFixed(1)}%` : ''),
overflow: 'none',
formatter: (p) => `${p.value.toFixed(1)}%`,
},
emphasis: { focus: 'series' },
})),