wangrong
8 天以前 72ceaa81f556c6519c97b2391871ba84729a9a6c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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) }
    }));
}