可视化展示中, 向下钻取的功能很常见. 这是有必要掌握的技能之一.
首先看官方示例.
实现这种图形展示, 关键点和难点在于数据格式的准备上. 通过查看示例代码, 可以看出, 主要需要两个参数:
series
和drilldown:series
.
经过测试发现,series
可以支持两种格式: 1.json
格式和数组
格式.
为了叙述方便, 这里定义
省
,市
,区/县
表示3级. 本文以实现这样的3级下钻为例.
关键图形参数
series
series: [{
name: '浏览器品牌',
colorByPoint: true,
data: [{
name: 'Microsoft Internet Explorer',
y: 56.33,
drilldown: 'Microsoft Internet Explorer'
}, {..},..]
其中, data中的元素笔者将其称作点(point)
, 包含name
-鼠标悬停显示的分类名称,y
-数值, drilldown
-寻找下钻后的数据的锚, drilldown:series
中会有对应的id
. (注: 最低一级一般不需要drilldown参数, 当然有不会影响显示, 这就为封装数据提供了小便利).
drilldown:series
drilldown: {
series: [{
name: 'Microsoft Internet Explorer',
id: 'Microsoft Internet Explorer',
data: [
[
'v11.0',
24.13
],
[..],...
}]
}
- 所有的需要向下钻取的数据都在
drilldown
字段里. 即市和区的数据都在drilldown
里配置. - 这里的
series
格式和上文的series
格式一样. - 这里的
data
格式为数组
样式. 经测试, 也可以用上文的json
样式. 这又为封装数据提供了便利. 注意:省级和市级由于需要向下钻取, 所以data不能为数组格式(没有那么智能, 差评).
需求
省市区对应了若干小分区. 现需要分组统计出每个省的分区个数占比, 即分布情况. 当下钻某个省时, 显示该省下所有市的分布情况...
数据库格式:
省 | 市 | 区 | 分区 |
---|---|---|---|
安徽 | 合肥 | 滨湖 | 007分区 |
后台数据封装
由于数据需要后台利用
java
查询数据库, 封装数据, 以json
格式响应给highchart. 所以, 封装数据上需要一番研究.
javabean设计
下文两种方式, 基于相同的Javabean设计.
-
Series
对应了highchart
中的series
字段. -
Point
代表一个点的数据, 多个Point构成了data
.
方式一:
思路:
- 先查询出所有省的分组统计结果.
- 准备用两个变量,
series
存储省相关数据,drilldownSeries
存储drilldown
相关数据, 即市和区/县的. - 取数据封装数据, 构建series类, 添加至
drilldownSeries
. 同时, 根据当前遍历到的省份, 根据名称查询旗下的所有市统计数据. - 然后遍历市级数据封装数据, 添加至
drilldownSeries
, 同时根据当前遍历到的市, 查询旗下的所有区/县统计数据. 封装成series类, 添加至drilldownSeries
.
代码:
public Map getData4DrillDownChart() {
// 一级: 省; 二级: 市; 三级: 区/县
// 获取分区总数, 作为分母, 计算百分比.
long s = dao.count();
double sum = s;
// 查询所有省及分组统计数据
List
方式2:
方式1虽然能够实现功能, 但是, 1.查询数据库的次数太多; 2.封装数据的业务逻辑复杂, 且不具有通用性, 硬编码.
方式2内容精彩, 所以另起一篇.
参见: java+highchart实现分类下钻柱形图[续]
附录
Series接口bean
import java.util.ArrayList;
import java.util.List;
/**
* @author Nisus-Liu
* @version 1.0.0
* @email [email protected]
* @date 2018-01-10-22:53
*/
// name: '浏览器品牌',
// id:'brands',
// colorByPoint: true,
// data: [{},{},..]
// 其中data:
// name: 'Chrome',
// y: 24.03,
// drilldown: 'Chrome'
public class Series {
private String name;
private String id;
private boolean colorByPoint = true;
private List data = new ArrayList();
public List getData() {
return data;
}
public void setData(List data) {
this.data = data;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public boolean isColorByPoint() {
return colorByPoint;
}
public void setColorByPoint(boolean colorByPoint) {
this.colorByPoint = colorByPoint;
}
public static class Point{
private String name;
private double y;
private String drilldown;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public String getDrilldown() {
return drilldown;
}
public void setDrilldown(String drilldown) {
this.drilldown = drilldown;
}
}
}