Refactor financial chart implementation
This commit is contained in:
+52
-4
@@ -27,6 +27,27 @@ export const PALETTE = {
|
||||
axisLine: '#d0d0d0',
|
||||
};
|
||||
|
||||
/**
|
||||
* 试行语义色:柱线组合图中,柱采用低饱和辅助色,折线保留单一强调色。
|
||||
* 待页面视觉确认后再固化为新增图表的正式规范。
|
||||
*/
|
||||
export const FINANCIAL_COLORS = {
|
||||
operatingCashFlow: '#6E9A83',
|
||||
investingCashFlow: '#7897B2',
|
||||
financingCashFlow: '#B18A66',
|
||||
netCashIncrease: '#A8465C',
|
||||
netProfit: '#C9885C',
|
||||
cashConversion: '#6B4A6C',
|
||||
};
|
||||
|
||||
export const CHANNEL_COLORS = {
|
||||
retail: '#597A9B',
|
||||
online: '#C87368',
|
||||
robotStore: '#98A77A',
|
||||
wholesale: '#BB9A5C',
|
||||
revenueGrowth: '#775D8B',
|
||||
};
|
||||
|
||||
/** 坐标轴通用样式:只留浅色横向网格,去掉轴线的存在感 */
|
||||
export const axisCommon = {
|
||||
axisLine: { show: false },
|
||||
@@ -104,13 +125,14 @@ export const LAYOUT = {
|
||||
gridTop: 145, // 绘图区顶部边距(图例到绘图区约 60px)
|
||||
};
|
||||
|
||||
// 统一图例图标宽度,同时保留 ECharts 按系列类型生成的形状。
|
||||
export const LEGEND_ITEM_WIDTH = 20;
|
||||
|
||||
export const legendStyle = {
|
||||
top: 62, // ⚠️ 已废弃:请改用 LAYOUT.legendTop 或 standardLegend()
|
||||
itemGap: 26,
|
||||
itemWidth: 18,
|
||||
// ❌ 删除 icon: 'roundRect'
|
||||
// 原因:它会覆盖 ECharts 按系列类型自动生成的图例样式(折线图的"短线+空心圆")
|
||||
// 现在让每个图表按需设置,或使用 standardLegend() 获得正确默认值
|
||||
itemWidth: LEGEND_ITEM_WIDTH,
|
||||
// 不设置 icon:柱状图自动使用矩形,折线图自动使用“短线 + 空心圆”。
|
||||
textStyle: {
|
||||
color: PALETTE.ink,
|
||||
fontSize: 14,
|
||||
@@ -139,6 +161,7 @@ export function labelStyle(color, position = 'top') {
|
||||
export function standardLegend(data, options = {}) {
|
||||
return {
|
||||
top: LAYOUT.legendTop,
|
||||
itemWidth: LEGEND_ITEM_WIDTH,
|
||||
itemGap: options.itemGap ?? 28,
|
||||
textStyle: {
|
||||
color: PALETTE.ink,
|
||||
@@ -176,6 +199,31 @@ export function lineSeries({ name, data, color, labelPosition = 'top', formatter
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 柱线组合图的折线标签:正值放在点上方、负值放在点下方;
|
||||
* 若与同期间柱值接近,则加大距离,避免文字压在柱体端点附近。
|
||||
*/
|
||||
export function lineDataWithSafeLabels(rows, { lineKey, barKeys, distance = 8, closeDistance = 14 }) {
|
||||
const values = rows.map((row) => row[lineKey]).filter(Number.isFinite);
|
||||
const range = Math.max(...values) - Math.min(...values) || 1;
|
||||
const threshold = range * 0.06;
|
||||
|
||||
return rows.map((row) => {
|
||||
const value = row[lineKey];
|
||||
const nearestBarGap = Math.min(...barKeys
|
||||
.map((key) => row[key])
|
||||
.filter(Number.isFinite)
|
||||
.map((barValue) => Math.abs(value - barValue)));
|
||||
return {
|
||||
value,
|
||||
label: {
|
||||
position: value < 0 ? 'bottom' : 'top',
|
||||
distance: nearestBarGap <= threshold ? closeDistance : distance,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 柱状图系列标准配置
|
||||
* 强制显示所有标签(overflow: 'none'),避免小柱子标签被 ECharts 自动隐藏
|
||||
|
||||
Reference in New Issue
Block a user