如何在 Morris.js 条形图中动态设置悬停标签(labels)字段

7次阅读

如何在 Morris.js 条形图中动态设置悬停标签(labels)字段

本文详解如何通过 php 动态生成 morris bar 图的 labels 数组,替代硬编码字符串,确保悬停提示准确显示数据库中的账户名(account),并避免手动拼接 json 导致的格式错误与安全风险。

本文详解如何通过 php 动态生成 morris bar 图的 labels 数组,替代硬编码字符串,确保悬停提示准确显示数据库中的账户名(account),并避免手动拼接 json 导致的格式错误与安全风险。

Morris.js 是一款轻量级、易集成的数据可视化库,常用于快速渲染条形图、折线图等。但在实际开发中,一个常见痛点是:labels 参数需为 JavaScript 字符串数组(如 [‘Alice’, ‘Bob’, ‘Charlie’]),而开发者常误将其设为字段名字符串(如 ‘account’),导致悬停提示失效或显示字段名而非真实值

问题根源在于原始代码中 labels:’account’ 的写法——这并非合法的 Morris 配置项(labels 应接收数组,而非字符串键名),且 data 数组也因手动拼接 json 字符串存在严重隐患:易产生语法错误(如未转义单引号)、sql 注入风险、中文乱码及 xss 漏洞。

✅ 正确解法是:分离数据结构与标签逻辑,用 json_encode() 安全生成标准 JSON,再由 Morris.js 原生支持的 labels 数组参数消费

步骤一:优化 SQL 查询,统一字段别名

确保子查询返回的员工姓名字段名为 employee(与 Morris 的 xkey 保持一致),同时保留 account 字段用于标签:

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  -- 注意:原 ORDER BY emp_id ASC 无对应字段,应改为 employee LIMIT 10;

⚠️ 注意:ORDER BY emp_id ASC 在原始 SQL 中引用了不存在的别名 emp_id,已修正为 employee;若需按员工编码排序,请确保子查询中 d.employee_code 可被外层引用,或改用 JOIN 提升可读性与性能。

步骤二:PHP 安全构建数据与标签数组

摒弃字符串拼接,改用关联数组 + json_encode():

<?php $conn = mysqli_connect("localhost", "root", "", "database_name"); $sql = "SELECT ... "; // 上述优化后的 SQL  $most_link = mysqli_query($conn, $sql); $data_arr = []; $labels_arr = [];  while ($row = mysqli_fetch_assoc($most_link)) {     $data_arr[] = $row;                // ['account'=>'A001','employee'=>'张三','total'=>24]     $labels_arr[] = $row['account'];    // ['A001', 'A002', ...] }  $data_json = json_encode($data_arr); $labels_json = json_encode($labels_arr); ?>

步骤三:前端 Morris 初始化(关键配置)

在 <script> 中正确注入 JSON 数据,并显式指定 labels:</script>

<div id="most"></div> <script> new Morris.Bar({     element: 'most',     data: <?php echo $data_json; ?>,     xkey: 'employee',      // X 轴显示员工全名(柱状图横坐标)     ykeys: ['total'],      // Y 轴绑定登录次数     labels: <?php echo $labels_json; ?>, // ✅ 动态悬停标签:显示 account 值     hideHover: 'auto',     barColors: ['#F5761A'],     // 可选:增强可读性     xLabelAngle: 45,     resize: true }); </script>

关键注意事项

  • labels 必须是与 data 数组长度一致的字符串数组,顺序严格对应每条数据项;
  • xkey(如 ’employee’)控制柱子横坐标文本,labels 控制悬停框顶部标题(即 tooltip header),二者可不同;
  • 始终使用 mysqli_fetch_assoc()(非 fetch_array())避免索引混淆;
  • 生产环境务必添加错误处理(如 mysqli_connect_error()、mysqli_error($conn));
  • 若 account 含特殊字符(如单引号、换行符),json_encode() 自动转义,无需额外处理。

通过此方案,你将获得完全动态、安全可靠且符合 Morris.js 规范的悬停标签系统——既满足业务需求,又筑牢代码质量底线。

text=ZqhQzanResources