饼图与柱状图的topN处理
来源:互联网 发布:新媒体沟通软件 编辑:程序博客网 时间:2024/05/01 04:54
做数据分析的时候,很多业务都需要展示数据的前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; }
而柱状图的多维度数据就比较麻烦。原始数据的维度数量、维度名称、指标都是不确定的,而且还有未经分组汇总的情况(也就是数据没有group by的情况),所以在编码时不能限定维度数量。
原始数据格式example:
{“科目”=>”科目一”, “成绩”=>”合格”, “驾校”=>”x”, “人数”=>”26”},
{“科目”=>”科目一”, “成绩”=>”合格”, “驾校”=>”x”, “人数”=>”49”},
{“科目”=>”科目二”, “成绩”=>”合格”, “驾校”=>”y”, “人数”=>”13”}…
x轴是“驾校”,指标是“人数”,维度列是2个:“科目”、“成绩”
核心算法伪代码:
private Array getTopData(horizontal, quota, data, n) { if(hasManyDimensions()) {//多维度单指标的情况 validDimensions = getDimensionalityName(horizontal, quota, data);//维度列的列名:“科目”、“成绩” validDimensionsValues;//维度列的值的组合:“科目一_合格”、“科目二_合格”等等 valuesOfValidDimensions;//维度列的值与列名的映射关系:“科目一”=>”科目”、“合格”=>”成绩" detail4Horizontal;//维度列值_x轴列值 为键的数据:”科目一_合格_x”=>75、”科目二_合格_y”=>13 total4Horizontal;//x轴列值 为键的数据:“x”=>249、”y=>54" for (eachData : data) { nowDimensionalityValues = ""; for (key : validDimensions) { value = eachData.get(key); valuesOfValidDimensions.put(value, key); nowDimensionalityValues = nowDimensionalityValues + "_" + value; } nowDimensionalityValues = nowDimensionalityValues.substring(1, nowDimensionalityValues.length());//维度列的值的拼接 validDimensionsValues.add(nowDimensionalityValues); nowHorizontalData = eachData.get(horizontal);//x轴列的值 if (!total4Horizontal.containsKey(nowHorizontalData)) { total4Horizontal.put(nowHorizontalData, 0); } quotaValue = getValidIndicatorValue(eachData, quota); total4Horizontal.put(nowXData, total4Horizontal.get(nowHorizontalData) + quotaValue); detail4Horizontal.put(nowDimensionalityValues + "_" + nowHorizontalData, quotaValue); } topAndOtherList = getTopAndOtherList(total4Horizontal, n);//获取排序后的数据 topXDataNameList = topAndOtherList.get("top"); otherXDataNameList = topAndOtherList.get("other"); topDataResult = getTopResult(validDimensionsValues, quota, horizontal, otherXDataNameList, topXDataNameList, detail4Horizontal, valuesOfValidDimensions); return topDataResult; }}
之所以制造下面这5个数组或List,是为了排序和对汇总后的数据按维度来拆分:
validDimensions//维度列的列名
validDimensionsValues//维度列的值的组合
valuesOfValidDimensions//维度列的值与列名的映射关系
detail4Horizontal//维度列值_x轴列值 为键的数据
total4Horizontal//x轴列值 为键的数据
getTopResult()实现了对“其他”数据的按维度拆分,算法如下:
for (value : validDimensionsValues) { other4EachValidDimensionsKey.put(value, 0L);//初始化 for (xDataValue : otherXDataNameList) { if (detail4Horizontal.containsKey(value + "_" + horizontal)) { other4EachValidDimensionsKey.put(value, other4EachValidDimensionsKey.get(value) + detail4Horizontal.get(value + "_" + horizontal)); } } }//装载topN之外的"其他"汇总数据 for (entry : other4EachValidDimensionsKey.entrySet()) { nowValues = entry.getKey().split("_");//将维度列的值的组合分解成数组 for (value : nowValues) { key = valuesOfValidDimensions.get(value);//从映射关系中找到维度列的列名 other.put(key, value); } other.put(horizontal, "其他"); other.put(quota, entry.getValue()); topDataResult.add(other); }
不过如果数据的值中包含了“_”,这个算法的分隔符就要更换了。
- 饼图与柱状图的topN处理
- chart.js异步加载柱状图与饼图,柱状图添加点击事件,自定义柱状图的颜色
- jfreechart的柱状图处理
- TopN算法与排行榜
- 推荐系统中TopN与kNN的区别
- 饼状图与柱状图的使用
- vml 的饼图柱状图和线图
- 漂亮的饼图和柱状图
- ios-饼图和柱状图的绘制
- 利用DevExpress的WebChartControl绘制柱状图,线状图与饼状图示例
- 选择合适的图表类型:长条图与柱状图
- Echarts柱状图与折线图的基本使用
- 柱状图跟饼图
- Echarts图标使用实例(柱状图与饼图)
- 4.案例:查询各个级别分销商的数量(饼图和柱状图)-Servlet(柱状图)
- 求的数组的topN
- 基于JFree框架编写的饼图,柱状图,折线图
- 柱状图,折线图,饼图的js插件
- javascript touch事件
- 修改angular post提交json数据的格式_ $httpProvider配置
- oc语言类 便利初始化函数 便利构造器 属性
- hdu 4545 魔法串 (模拟)
- tmpl 模板化引擎加载数据 Jquery
- 饼图与柱状图的topN处理
- 关于mybatis扫描所有namespace时报错,最终原因是resultMap不能使用(我的错误记录)
- NSURL学习
- 【beautifulsoup】python标准库解析器解析网页问题解决
- React:创建同时受控与非受控的组件
- LightOJ 1021 Painful Bases 【状压DP+数位DP】
- android studio add fragment from layout
- Maven 手动添加 JAR 包到本地仓库
- 图解HTTPS