此处统计分析指的是将数据可视化的方式在前端展示,包括但不限于堆叠柱状图、表格、折线图。返给前端的格式数据比较复杂。前一整子第一次写统计分析,跟前端约定格式的时候让我随便给,然后每个都花了很多时间,每张统计图的格式都有点不同,花费了很多无用功。这次第二次做新的统计分析,明显感觉能把握的住了。对于前后端传递的格式,就直接以ECharts使用的格式完全相同。
ECharts官方所有示例地址
此处可能有一些话引入和一些感谢,以后不起来
动态表格指的是表格的列是不固定的,根据
// 最终返回类 @Data @ToString public class VO { /** * 表格数据 */ private List<TableChart> tableChartList = new ArrayList<>(); } // 表格结构 @Data @ToString public class TableChart { /** * 表格的最左边一列 */ private String rowTitle; /** * 所有动态列的数量总数 */ private Integer count; /** * 最大类型名称 */ private String maxType; /** * 最大类型占比 */ private String maxProportion; /** * 排序字段 */ private Integer sort; /** * 动态表格列列表 */ private List<TableBase> tableBaseList; } // 动态列格式 @Data @ToString public class TableBase { /** * 列名 */ private String columnName; /** * 列值 */ private Integer columnValue; /** * 占比 */ private String proportion; } // 数据库查询出的数据 @Data public class ChartBaseVo { /** * 行名称 */ private String abscissa; /** * 动态列的名称 */ private String type; /** * 值 */ private Integer value; }
public class Service { public VO select(Request request) { // 行名称 List<String> lineNameList; // 动态列名称 List<String> columnNameList; // 构造表格结构 List<TableChart> tableChartList = constructTableStructure(lineName, columnNameList); // 数据库查询出的数据 List<ChartBaseVo> chartBaseVoList; // 填充表格数据 fillDataForTable(tableChartList, chartBaseVoList); // 表格数据按总数倒序排 tableChartList.sort(Comparator.comparing(TableChart::getCount).reversed()); // 返回类型 VO vo = new VO(); vo.setTableChart(barChart); return vo; } /** * @description: 表格的多行填充 * @param tableChartList: 表格数据列表 * @param chartBaseVoList: 数据库查出的数据 */ private void fillDataForTable(List<TableChart> tableChartList, List<ChartBaseVo> chartBaseVoList) { for (TableChart table : tableChartList) { fillOneDataForTable(table, chartBaseVoList); } } /** * @description: 表格的单行填充 * @param table: 单个表格 * @param chartBaseVoList: 数据库数据 */ private void fillOneDataForTable(TableChart table, List<ChartBaseVo> chartBaseVoList) { List<ChartBaseVo> tableList = chartBaseVoList.stream().filter(p -> table.getRowTitle().equals(p.getAbscissa())).collect(Collectors.toList()); Map<String, Integer> chartBaseVoMap = chartBaseVoList.stream().filter(p -> table.getRowTitle().equals(p.getAbscissa())).collect(Collectors.toMap(ChartBaseVo::getType, ChartBaseVo::getValue, (item1, item2) -> item1)); // 求责任单位处理总数 int sum = tableList.stream().mapToInt(ChartBaseVo::getValue).sum(); table.setCount(sum); // 数量赋值和求比例 for (TableBase tableBase : table.getTableBaseList()) { Integer value = chartBaseVoMap.get(tableBase.getColumnName()); value = Objects.nonNull(value) ? value : 0; tableBase.setColumnValue(value); if (0 == value || 0 == sum) { tableBase.setProportion("0%"); } else { tableBase.setProportion(String.format("%.2f", (float) tableBase.getColumnValue() / (float) sum * 100) + '%'); } } } }
据我所知,柱状图的结构大概大差不差,至少普通柱状图和堆叠条形图结构上是一致的,ECharts官网中只是普通柱状图xData和堆叠条形图的yAxis命名上的区别
// 最终返回类 @Data @ToString public class VO { /** * 柱状图数据 */ private BarChart barChart; } // 柱状图结构 @Data @ToString public class BarChart { /** * 横坐标轴(横向柱状图时可充当竖向坐标轴) */ private List<String> xData; /** * 图例条目 */ private List<String> legend; /** * 统计图具体数据 */ private List<Series> series; } // 统计图一条图例数据 @Data @ToString public class Series { /** * 图例名称 */ private String name; /** * 一条图例的具体数据 */ private List<Double> data; } // 数据库查询出的数据 @Data public class ChartBaseVo { /** * 行名称 */ private String abscissa; /** * 动态列的名称 */ private String type; /** * 值 */ private Integer value; }
public class Service { public VO select(Request request) { // 横坐标轴 List<String> xDataList; // 条例名称 List<String> legendList; // 数据库查询出的数据 List<ChartBaseVo> chartBaseVoList; // 构建柱状图 BarChart barChart = constructBarTable(xDataList, projectTypeList, chartBaseVoList); // 返回类型 VO vo = new VO(); vo.setBarChart(barChart); } /** * @description: 柱状图数据构建 * @param xDataList: 横坐标轴数据 * @param legendList: 柱状图条例分类 (比如一个大数据中心部门对应三个柱子,分别是民生实事、城建工程、重点产业三类) * @param chartBaseVoList: 数据库中直接取出的数据,tableChartVoListForBar结构不适合数据读取,故从chartBaseVoList中取数据 * @return: 柱状图 */ private BarChart constructBarTable(List<String> xDataList, List<String> legendList, List<ChartBaseVo> chartBaseVoList) { // 柱状图数据赋值 BarChart barChart = new BarChart(); barChart.setXData(xDataList); barChart.setLegend(legendList); List<Series> seriesList = new ArrayList<>(); for (String legend : legendList) { Series series = new Series(); series.setName(legend); // 数据序列 List<Double> data = new ArrayList<>(); List<ChartBaseVo> collect = null; for (String xData : xDataList) { collect = chartBaseVoList.stream().filter(p -> legend.equals(p.getType()) && xData.equals(p.getAbscissa())).collect(Collectors.toList()); if (collect.size() > 0) { data.add(Convert.toDouble(collect.get(0).getValue()) ); } else { data.add(0d); } } series.setData(data); seriesList.add(series); } barChart.setSeries(seriesList); return barChart; } }