export type ChartRow<T> = { item: T; value: number; even: boolean };
|
|
/** 图表取值:0 不画;碳减排可为负,展示时取绝对值。 */
|
export function chartValue(raw: number, carbon = false) {
|
const n = Number(raw);
|
if (!Number.isFinite(n) || n === 0) return 0;
|
return carbon ? Math.abs(n) : n;
|
}
|
|
/**
|
* 分类图数据:
|
* - 部分有值:只保留当前指标 > 0 的类
|
* - 全部为 0:evenSplit 时均分扇区(value=1 仅用于几何,even 标记给 tooltip 显示 0)
|
*/
|
export function chartSeries<T>(
|
items: T[] | undefined,
|
pick: (item: T) => number,
|
opts?: { carbon?: boolean; evenSplit?: boolean }
|
): ChartRow<T>[] {
|
const list = items || [];
|
const rows = list.map(item => ({
|
item,
|
raw: chartValue(pick(item), opts?.carbon)
|
}));
|
const positive = rows.filter(e => e.raw > 0);
|
if (positive.length) {
|
return positive.map(e => ({ item: e.item, value: e.raw, even: false }));
|
}
|
if (opts?.evenSplit === false) {
|
return rows.map(e => ({ item: e.item, value: 0, even: false }));
|
}
|
return rows.map(e => ({ item: e.item, value: 1, even: true }));
|
}
|
|
export function pieTooltipFormatter(unit = '') {
|
return (p: any) => {
|
const val = p.data?.even ? 0 : p.value;
|
const u = unit ? ` ${unit}` : '';
|
const pct = p.percent != null ? ` (${p.percent}%)` : '';
|
return `${p.name}<br/>${val}${u}${pct}`;
|
};
|
}
|
|
export function toPieData<T>(
|
rows: ChartRow<T>[],
|
name: (item: T) => string,
|
color: (item: T) => string | undefined
|
) {
|
return rows.map(row => ({
|
name: name(row.item),
|
value: row.value,
|
even: row.even,
|
itemStyle: { color: color(row.item) }
|
}));
|
}
|