官方范例:https://echarts.apache.org/examples/zh/editor.html?c=bar-multi-drilldown
看了一眼范例直接晕了,你这,一堆数据直接写死,这怎么用啊!
一般来说,实现步骤是:
1)后台:把下钻数据从数据库里拿出来
2)后台:整理成官方范例里要求的模样
3)前端:把后台处理好的数据绑定到前端
假设我有一个表mytable,其中有数据:
statistics_date | main_category | sub_category | payment_amount |
2024/3/18 | 食品 | 饼干 | 46 |
2024/3/18 | 食品 | 面包 | 66 |
2024/3/18 | 服装 | 西装 | 88 |
2024/3/19 | 食品 | 饼干 | 99 |
2024/3/19 | 服装 | 西装 | 11 |
我要按照顺序:statistics_date>main_category>sub_category进行下钻,对应显示payment_amount的值,那么,该如何配置代码:
此处我用的是Thinkphp框架——
后台:
先看构建方法:
//参数说明:
//$Model:模型&$sql:sql语句 这俩都是给ThinkPHP用来连接数据库查询数据的,你可以按实际使用场景调整
//$level_sign:1普通层 2底层 因为下钻的底层的构建方式和其他层不同,所以你要告知方法这是哪一层
//$level_name_now:当前层级的名字
//$level_name_prev:上一层级的名字
//$value_name:数值的字段名
//$level_remark:层级标志,(很重要!用来建立下钻关系!)function fetchAndAssignData($Model, $sql, $level_sign, $level_name_now, $level_name_prev, $value_name, $level_remark){$list = $Model->query($sql);//查询数据库$de_json = json_decode(json_encode($list), TRUE);//将结果数组 $list 编码为 PHP 数组。如果你用的是别的方法获取数据库数据就修改这俩行代码,反正到这一步你得让$de_json里有PHP 数组。// 初始化新数组$new_array = [];$array = $de_json;foreach ($array as $item) {// 构建新数组的键名$key = $item[$level_name_prev];// 构建新数组的值(注意,底层的构建方式和其他层不同)if ($level_sign == 1) {//普通层$value = [[$item[$level_name_now], (float) $item[$value_name], $item[$level_name_prev], $item[$level_remark]]];} elseif ($level_sign == 2) {//底层$value = [[$item[$level_name_now], (float) $item[$value_name], $item[$level_name_prev]]];}// 如果新数组中已经存在相同的键名,则将值添加到已有的值数组中if (isset ($new_array[$key])) {$new_array[$key] = array_merge($new_array[$key], $value);} else {// 如果新数组中不存在相同的键名,则创建一个新的值数组$new_array[$key] = $value;}}// 将新数组编码为 JSON 格式并输出$json_data = json_encode($new_array, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);$data = $json_data;$data = substr($json_data, 1);$data = substr($data, 0, -1) . ",";//此处因为要拼接json,所以掐头去尾用逗号连接……return $data;}
再看如何调用:
//注意,按官方范例,第一层的“前一层标志”默认为'things',当然也可以改……这里就用默认
//下钻所需的各种标志(level_name_now、level_name_prev、level_remark)都直接用sql生成出来,注意我这边的写法!//初始化
$Model = M(mytable);//我这里是用的thinkphp的数据库连接方法……可以按实际情况调整
$temp = "";//创建一个空字符串用来接处理好的数据// Level-1$sql = "SELECT statistics_date, SUM(payment_amount) AS payment_amount_all, statistics_date AS level_name_now, 'things' AS level_name_prev,statistics_date AS level_remarkFROM mytableWHERE main_category IS NOT NULLAND sub_category IS NOT NULLGROUP BY statistics_date";$data = $this->fetchAndAssignData($Model, $sql, 1, 'level_name_now', 'level_name_prev', 'payment_amount_all', 'level_remark');//把模型对象(也就是查询的表),sql语句,以及各个关键的参数都发给方法fetchAndAssignData()去处理$temp .= $data;//接收方法处理好的结果//Level-2-注意看下钻所需的各种标志的写法!
$sql = "SELECT statistics_date, main_category, SUM(payment_amount) AS payment_amount_all, main_category AS level_name_now,statistics_date AS level_name_prev,concat(statistics_date, '-', main_category) AS level_remarkFROM mytableWHERE main_category IS NOT NULLAND sub_category IS NOT NULLGROUP BY statistics_date, main_category";$data = $this->fetchAndAssignData($Model, $sql, 1, 'level_name_now', 'level_name_prev', 'payment_amount_all', 'level_remark');$temp .= $data;//Level-3-注意,这是底层,所以$level_sign填2,告知方法fetchAndAssignData()用底层的方法去处理$sql = "SELECT statistics_date, main_category, sub_category, SUM(payment_amount) AS payment_amount_all, sub_category AS level_name_now,concat(statistics_date, '-', main_category) AS level_name_prev, concat(statistics_date, '-', main_category, '-', sub_category) AS level_remarkFROM mytableWHERE main_category IS NOT NULLAND sub_category IS NOT NULLGROUP BY statistics_date, main_category, sub_category";
$data = $this->fetchAndAssignData($Model, $sql, 2, 'level_name_now', 'level_name_prev', 'payment_amount_all', 'level_remark');
$temp .= $data;//结束$temp ="{".$temp."}";//最后用花括号框起来,发给前端
$this->assign("temp", $temp);//发射!
前端
前端这里当然也要优化,范例写死了,但我们实际应用肯定不能写死……
//对照官方范例就知道我改的是哪一段了……
const dataMap={$temp}//$temp是从后端传给前端的参数
const allLevelData = [];
for (const key in dataMap) {allLevelData.push(dataMap[key]);
}const allOptions = {};