如何在 Morris Bar 图表中动态设置悬停标签(Labels)字段

1次阅读

如何在 Morris Bar 图表中动态设置悬停标签(Labels)字段

本文详解如何通过 php 动态生成 morris.js 柱状图的 labels 数组,避免硬编码导致的灵活性缺失,确保悬停提示准确显示数据库中的自定义字段(如 account),并提供安全、可维护的 json 数据构造方案。

本文详解如何通过 php 动态生成 morris.js 柱状图的 labels 数组,避免硬编码导致的灵活性缺失,确保悬停提示准确显示数据库中的自定义字段(如 account),并提供安全、可维护的 json 数据构造方案。

Morris Bar 图表的 labels 选项用于定义图例或悬停提示中显示的文本内容。在原始代码中,labels: ‘account’ 实际上是错误用法——Morris.js 的 labels 参数不接受字符串字段名,而应是一个与 data 数组长度一致的字符串数组(例如 [‘UserA’, ‘UserB’, …])。将 ‘account’ 直接赋值给 labels 会导致图表无法正确渲染悬停信息,甚至报错。

正确的做法是:在 PHP 层分离数据主体与标签文本,分别构造合规的 JSON 数组。关键在于两点:

  1. sql 查询需明确别名,使字段名与前端期望一致(如将子查询结果命名为 employee,而非保留 emp_id);
  2. 严禁手动拼接 JSON 字符串(如 “{‘key’:'”.$val.”‘}”),极易引发语法错误或 xss 风险;必须使用 json_encode() 保证输出合法、安全。

以下是优化后的完整实现:

<?php $conn = mysqli_connect("localhost", "root", "", "database_name"); // ✅ 修正 SQL:为子查询结果使用语义化别名 'employee',并确保 ORDER BY 使用该别名 $sql = "SELECT              account,              (SELECT fullname FROM employees AS d WHERE r.emp_id = d.employee_code) AS employee,              COUNT(username) AS total         FROM logins AS r          GROUP BY account          ORDER BY employee ASC          LIMIT 10";  $most_link = mysqli_query($conn, $sql); if (!$most_link) {     die('Query failed: ' . mysqli_error($conn)); }  // ✅ 安全构建数据与标签数组 $data_arr = []; $label_arr = [];  while ($row = mysqli_fetch_assoc($most_link)) {     $data_arr[] = $row;           // 包含 account, employee, total 的关联数组     $label_arr[] = $row['account']; // 动态提取 account 作为悬停标签 }  // ✅ 使用 json_encode() 输出标准 JSON,自动处理引号、转义与编码 $json_data = json_encode($data_arr); $json_labels = json_encode($label_arr); ?> <script> new Morris.Bar({     element: 'most',     data: <?php echo $json_data; ?>,     xkey: 'employee',      // X 轴显示员工姓名     ykeys: ['total'],      // Y 轴绑定 total 字段     labels: <?php echo $json_labels; ?>, // ✅ 动态标签数组,如 ["ACC-001", "ACC-002"]     hideHover: 'auto',     barColors: ['#F5761A'],     // 可选:增强可读性     xLabelAngle: 45,     resize: true }); </script>

⚠️ 重要注意事项

  • 永远不要手动拼接 JSON:原始代码中 $most_sold .= “{ accounnt:’…’}” 存在严重隐患——若 account 值含单引号、换行或 Unicode 字符,将直接破坏 JavaScript 语法。json_encode() 是唯一可靠方案。
  • 字段名一致性:SQL 中 AS employee 必须与 xkey: ’employee’ 严格匹配;同理,$row[‘account’] 必须与数据库实际列名一致。
  • 错误处理:添加 mysqli_query 错误检查,避免静默失败。
  • 字符集安全:确保数据库连接使用 UTF-8(mysqli_set_charset($conn, ‘utf8mb4’)),防止中文等字符乱码。

通过此方案,图表悬停时将精准显示每个柱子对应的 account 值(如 ACC-001),同时保持代码健壮性与可维护性。Morris.js 虽已停止维护,但该数据构造原则适用于所有基于 JSON 的前端图表库(如 Chart.js、ApexCharts),核心逻辑始终是:后端交付结构清晰、格式合规的 JSON,前端专注可视化逻辑

text=ZqhQzanResources