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

Bullet Chart自定义需求:将Y值水平条形替换为圆点

实现带动态圆点的Bullet Chart

核心思路

把原有Bullet Chart中对应Y值的水平条形,替换为位置随Y值变化、大小与Y值正相关的圆点,同时保留目标值的垂直标记线。以下以常用的D3.js和Plotly.js为例给出实现方案:


方案1:D3.js实现

假设你已经有基础的Bullet Chart配置(包含比例尺、数据结构),只需修改Y值的渲染逻辑:

// 基础SVG容器配置(已省略margin/width/height/xScale/yScale的定义)
const svg = d3.select("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", `translate(${margin.left},${margin.top})`);

// 渲染Bullet Chart的基准背景带(可选,用于展示数值范围)
svg.selectAll(".range")
  .data(data)
  .enter()
  .append("rect")
  .attr("class", "range")
  .attr("x", 0)
  .attr("y", d => yScale(d.category))
  .attr("width", d => xScale(d.maxRange))
  .attr("height", yScale.bandwidth())
  .attr("fill", "#eee");

// 替换水平条形为动态圆点
svg.selectAll(".value-dot")
  .data(data)
  .enter()
  .append("circle")
  .attr("class", "value-dot")
  .attr("cx", d => xScale(d.yValue)) // 圆点X位置匹配Y值大小
  .attr("cy", d => yScale(d.category) + yScale.bandwidth()/2) // 垂直居中于分类栏
  .attr("r", d => Math.sqrt(d.yValue) * 1.5) // 用平方根缩放避免大数值圆点过大,可调整系数
  .attr("fill", "#2ecc71")
  .attr("opacity", 0.8);

// 保留目标值的垂直标记线
svg.selectAll(".target-line")
  .data(data)
  .enter()
  .append("line")
  .attr("class", "target-line")
  .attr("x1", d => xScale(d.targetValue))
  .attr("x2", d => xScale(d.targetValue))
  .attr("y1", d => yScale(d.category))
  .attr("y2", d => yScale(d.category) + yScale.bandwidth())
  .attr("stroke", "#e74c3c")
  .attr("stroke-width", 2);

关键细节说明

  • cx属性直接绑定Y值,让圆点在X轴上的位置精准对应数值
  • 圆点大小用平方根转换Y值,是为了避免大数值导致圆点直径失控,你也可以换成线性缩放(比如d.yValue * 0.1),按需调整
  • cy设置为分类栏的垂直中点,保证圆点对齐美观

方案2:Plotly.js实现

如果用Plotly,需要隐藏原有条形,自定义标记为圆点并绑定大小:

const chartData = [
  // 处理Y值的圆点层(隐藏原有条形)
  {
    type: "bullet",
    y: ["产品A", "产品B"],
    x: [35, 62], // 这里的x对应原需求的Y值
    target: [50, 70], // 目标值
    marker: {
      symbol: "circle",
      size: d => d.x * 0.4, // 大小随数值变化
      color: "#2ecc71"
    },
    opacity: 0, // 隐藏默认的水平条形
    showlegend: false
  },
  // 单独添加目标值的垂直标记线
  {
    type: "scatter",
    mode: "lines",
    x: [50, 50, 70, 70],
    y: ["产品A", "产品A", "产品B", "产品B"],
    line: {color: "#e74c3c", width: 2},
    showlegend: false
  }
];

// 渲染图表
Plotly.newPlot("bullet-chart-container", chartData);

内容的提问来源于stack exchange,提问作者Bhagyesh Bodhe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 19:50:11