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

基于d3.js实现图像打包气泡图及悬浮饼图Tooltip技术咨询

D3.js 打包气泡图+悬浮饼图+Tooltip 实现方案

一、基础打包气泡图实现

  • 数据准备:构造层级化数据,每个节点需包含气泡大小的value,以及饼图所需的细分pieData
// 示例数据结构
const data = {
  name: "root",
  children: [
    {
      name: "分类A",
      value: 30,
      pieData: [{label: "A1", value: 10}, {label: "A2", value: 20}]
    },
    {
      name: "分类B",
      value: 50,
      pieData: [{label: "B1", value: 25}, {label: "B2", value: 25}]
    }
  ]
};
  • 生成打包布局:用d3.pack()计算气泡的位置与半径
const root = d3.hierarchy(data).sum(d => d.value);
const packLayout = d3.pack().size([width, height]).padding(2);
packLayout(root);
  • 绘制气泡:绑定数据到SVG的<circle>元素
const svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height);

const bubbles = svg.selectAll("circle")
  .data(root.descendants().filter(d => !d.children))
  .enter()
  .append("circle")
  .attr("cx", d => d.x)
  .attr("cy", d => d.y)
  .attr("r", d => d.r)
  .style("fill", "#69b3a2")
  .style("opacity", 0.8)
  .on("mouseover", showPieAndTooltip)
  .on("mouseout", hidePieAndTooltip);

二、悬浮显示饼图实现

  • 初始化饼图布局:用d3.pie()和d3.arc()生成饼图路径
const pie = d3.pie().value(d => d.value);
const arc = d3.arc().innerRadius(0).outerRadius(d => d.r);
  • 鼠标悬浮/移出事件处理:动态创建/移除饼图组
function showPieAndTooltip(event, d) {
  // 在气泡中心定位饼图组
  const pieGroup = svg.append("g")
    .attr("transform", `translate(${d.x}, ${d.y})`)
    .attr("class", "pie-group");

  const arcs = pie(d.data.pieData);
  pieGroup.selectAll("path")
    .data(arcs)
    .enter()
    .append("path")
    .attr("d", arc)
    .style("fill", (_, i) => d3.schemeCategory10[i])
    .style("opacity", 0.9);
}

function hidePieAndTooltip() {
  svg.selectAll(".pie-group").remove();
}

三、Tooltip 添加方案

方式1:原生SVG Tooltip(快速实现)

直接给气泡绑定<title>元素,浏览器会自动处理悬浮显示

bubbles.append("title")
  .text(d => `${d.data.name}\n总数值: ${d.data.value}`);

方式2:自定义HTML Tooltip(灵活可控)

创建独立的HTML容器,通过鼠标事件控制显示/隐藏与内容

// 初始化隐藏的Tooltip容器
const tooltip = d3.select("body")
  .append("div")
  .style("position", "absolute")
  .style("background", "#fff")
  .style("padding", "8px 12px")
  .style("border", "1px solid #ddd")
  .style("border-radius", "4px")
  .style("box-shadow", "0 2px 4px rgba(0,0,0,0.1)")
  .style("display", "none");

// 更新悬浮事件函数,加入Tooltip控制
function showPieAndTooltip(event, d) {
  // ... 饼图绘制代码
  tooltip.style("display", "block")
    .style("left", `${event.pageX + 10}px`)
    .style("top", `${event.pageY + 10}px`)
    .html(`<strong>${d.data.name}</strong><br>
           总数值: ${d.data.value}<br>
           ${d.data.pieData.map(item => `${item.label}: ${item.value}`).join("<br>")}`);
}

function hidePieAndTooltip() {
  svg.selectAll(".pie-group").remove();
  tooltip.style("display", "none");
}

内容的提问来源于stack exchange,提问作者Rigved Alankar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:42:28