做数据分析的时候,很多业务都需要展示数据的前N个数值、剩余的汇总为“其他”,比如全国人口分布top 10。一般的业务场景都需要支持单一维度的饼图和可以多维度的柱状图。
这样的数据处理可以放在DB层,用order by加上limit的sql来完成,但是这样就依赖于底层DB的类型,一旦有新增的数据底层则必须为此再写一套处理逻辑;另一个选择就是独立成模块,规定统一的输入格式,为这套数据格式写算法做topN的统计。我选择了后者,这样可以应对DB、api等不同来源的数据。
单一维度的饼图很好处理,最简单的方式就是排序后取出前N个数据、剩下的求和就行:
饼图的算法核心部分(伪代码):
private Array getTopNData(quota, dimensions, data, n) {
sortedData = getSortPieData(quota, data);
allTotal = topTotal = 0;
foreach (sortedData as key => value) {
allTotal += value;
if (count(topDataResult) < n) {
topTotal += value;
topDataResult[key] = value;
}
}
//topN之外的其他值归并为图中第N+1个元素
other = getOtherPieData(quota, dimensions, allTotal-topTotal);
topDataResult[“other”] = other;
return topDataResult;
}
而柱状图的多维度数据就比较麻烦。原始数据的维度数量、维度名称、指标