官方范例: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_remark
FROM mytable
WHERE main_category IS NOT NULL
AND sub_category IS NOT NULL
GROUP 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_remark
FROM mytable
WHERE main_category IS NOT NULL
AND sub_category IS NOT NULL
GROUP 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_remark
FROM mytable
WHERE main_category IS NOT NULL
AND sub_category IS NOT NULL
GROUP 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 = {};