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

2次阅读

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

本文详解如何将 mysql 查询结果中的字段值(如 account)作为 morris.js 条形图的动态悬停标签,避免硬编码,并通过 json 安全、规范地传递 php 数据至前端。

本文详解如何将 mysql 查询结果中的字段值(如 account)作为 morris.js 条形图的动态悬停标签,避免硬编码,并通过 json 安全、规范地传递 php 数据至前端。

Morris.js 的 labels 配置项用于定义图表 X 轴的显示文本,而其 xkey 则指定数据对象中用于定位横坐标的数据字段。许多开发者误以为 labels 可直接设为字符串(如 ‘account’),实则它应是一个字符串数组(如 [‘A001’, ‘A002’, …]),对应每个数据点的自定义标签。若强行传入字符串,图表将无法正确渲染或触发悬停提示。

要实现真正的“动态标签”——即让每个柱子的悬停信息显示对应的 account 值(而非固定文字),关键在于两点:

  1. 后端构造结构化数据:确保 PHP 输出的是合法、安全的 JSON;
  2. 前端正确配置 Morris 实例:labels 接收数组,xkey 指向数据对象中用于排序/定位的字段(如 employee),二者逻辑分离、互不干扰。

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

✅ 正确的 SQL 与 PHP 数据准备

首先调整 SQL,使子查询别名与后续 JSON 字段名一致(推荐使用 AS employee 而非 AS emp_id),并确保 account 字段明确可用:

SELECT      account,     (SELECT fullname FROM employees d WHERE r.emp_id = d.employee_code) AS employee,     COUNT(username) AS total FROM logins r GROUP BY account ORDER BY employee ASC LIMIT 10;

PHP 端不再拼接字符串,而是构建关联数组并调用 json_encode() —— 这是防止 xss、转义特殊字符、保障 JSON 格式合法的唯一可靠方式:

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

✅ 前端 Morris 初始化(关键配置)

在 <script> 中,直接注入已编码的 JSON 数据,并严格匹配字段名:</script>

<div id="most"></div> <script> new Morris.Bar({     element: 'most',     data: <?php echo $json_data; ?>,     xkey: 'employee',           // X 轴依据 employee 排序和定位(如“张三”“李四”)     ykeys: ['total'],     labels: <?php echo $json_labels; ?>, // 悬停/刻度显示 account(如“A001”“A002”)     hideHover: 'auto',     barColors: ['#F5761A'] }); </script>

⚠️ 重要注意事项

  • ❌ 禁止用字符串拼接生成 JSON(如 “{accounnt:'”.$row[“account”].”‘,…}”),极易因单引号、换行、中文等导致语法错误或 XSS 漏洞;
  • ✅ 始终使用 mysqli_fetch_assoc() + json_encode() 组合,它自动处理引号转义、UTF-8 编码及数据类型映射;
  • ? xkey 和 labels 是两个独立配置:xkey 决定柱子顺序与分组依据(通常是可读姓名),labels 决定悬停时显示的文字(此处为账号),二者可完全不同;
  • ? 若需在悬停中同时显示 account 和 employee,可改用 hoverCallback 自定义提示内容,但 labels 本身仅接受一维字符串数组。

通过以上重构,你将获得一个安全、可维护、语义清晰的动态标签 Morris 图表——数据来自数据库,标签随 account 字段实时变化,且完全规避了手动拼接 JSON 的所有风险。

text=ZqhQzanResources