You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

子弹图(Bullet Chart)鼠标悬停显示指标值功能实现咨询

嘿,我来帮你搞定这个子弹图的数值配置和悬停查看功能!咱们一步步来,先理清楚核心要点,再完善代码~

第一步:先把数据源规范好

首先得确保你的bulletchartdata数组里,每个项都包含四类指标的数值,最好加上指标名称方便识别。比如:

const bulletchartdata = [
  {
    name: "用户活跃度",
    satisfactoryVal: 80, // 满意区间的宽度(可以是像素或百分比,建议统一单位)
    badVal: 40, // 较差区间的宽度
    targetVal: 70, // 目标线的位置
    measureVal: 65 // 当前实际达成的数值
  },
  {
    name: "转化率",
    satisfactoryVal: 90,
    badVal: 30,
    targetVal: 85,
    measureVal: 88
  }
];
第二步:完善子弹图组件,添加悬停提示

结合你已有的代码,我补充了目标线和当前值条的实现,同时加上了两种悬停查看数值的方案:

方案1:用原生title属性快速实现

这是最简单的方式,直接把要显示的数值拼接成文本,绑定到外层容器的title属性上:

{bulletchartdata.map((item, index) => {
  // 组装悬停时要显示的文本
  const hoverInfo = `
    指标:${item.name}
    满意区间:${item.satisfactoryVal}
    较差区间:${item.badVal}
    目标值:${item.targetVal}
    当前值:${item.measureVal}
  `.trim();

  return (
    <div 
      key={index}
      className="bullet-chart-wrapper"
      style={{ position: 'relative', height: 40, marginBottom: 15, paddingLeft: 10 }}
      title={hoverInfo} // 原生悬停提示
    >
      {/* 满意区间底色 */}
      <div 
        className="satisfactory"
        style={{
          backgroundColor: '#f2f2f2',
          height: 20,
          width: `${item.satisfactoryVal}%`, // 用百分比适配容器更灵活
          position: 'absolute',
          top: 10,
          left: 0
        }}
      >
        {/* 较差区间 */}
        <div 
          className="badcolor"
          style={{
            backgroundColor: '#d8d6d6',
            height: 20,
            width: `${(item.badVal / item.satisfactoryVal) * 100}%`, // 按比例计算宽度
            position: 'relative'
          }}
        ></div>
      </div>
      {/* 目标线(要设置z-index确保在最上层) */}
      <div
        className="target-line"
        style={{
          position: 'absolute',
          top: 5,
          left: `${item.targetVal}%`,
          width: 3,
          height: 30,
          backgroundColor: '#ff4d4f',
          zIndex: 2
        }}
      ></div>
      {/* 当前实际值条 */}
      <div
        className="measure-bar"
        style={{
          position: 'absolute',
          top: 10,
          left: 0,
          width: `${item.measureVal}%`,
          height: 20,
          backgroundColor: '#1890ff',
          zIndex: 1
        }}
      ></div>
      {/* 指标名称标签 */}
      <div style={{ position: 'absolute', top: 12, left: '105%', fontWeight: 500 }}>
        {item.name}
      </div>
    </div>
  );
})}

方案2:自定义美观的Tooltip(进阶版)

如果觉得原生title不够好看,可以自己写一个Tooltip组件,通过状态控制显示隐藏:
首先添加状态(React示例):

import { useState } from 'react';

// 在组件内部定义状态
const [hoveredItem, setHoveredItem] = useState(null);
const [tooltipPos, setTooltipPos] = useState({ x: 0, y: 0 });

然后修改子弹图项的鼠标事件:

<div 
  key={index}
  className="bullet-chart-wrapper"
  style={{ position: 'relative', height: 40, marginBottom: 15, paddingLeft: 10 }}
  onMouseEnter={(e) => {
    setHoveredItem(item);
    setTooltipPos({ x: e.clientX + 10, y: e.clientY + 10 });
  }}
  onMouseMove={(e) => {
    setTooltipPos({ x: e.clientX + 10, y: e.clientY + 10 });
  }}
  onMouseLeave={() => setHoveredItem(null)}
>
  {/* 内部的区间、目标线、值条代码和方案1一致 */}
</div>

最后在组件末尾添加自定义Tooltip:

{hoveredItem && (
  <div
    style={{
      position: 'fixed',
      top: tooltipPos.y,
      left: tooltipPos.x,
      backgroundColor: '#333',
      color: '#fff',
      padding: '8px 12px',
      borderRadius: '4px',
      fontSize: '14px',
      zIndex: 999,
      whiteSpace: 'pre-line',
      boxShadow: '0 2px 8px rgba(0,0,0,0.2)'
    }}
  >
    指标:{hoveredItem.name}
    满意区间:{hoveredItem.satisfactoryVal}
    较差区间:{hoveredItem.badVal}
    目标值:{hoveredItem.targetVal}
    当前值:{hoveredItem.measureVal}
  </div>
)}
几个关键注意点
  • 单位统一:所有数值建议用百分比或者统一的像素值,避免视觉错乱
  • 层级控制:通过z-index确保目标线和当前值条显示在区间底色的上方
  • 灵活性:如果需要适配不同屏幕,用百分比比固定像素更合适

内容的提问来源于stack exchange,提问作者Fahad Bayabao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:05:50