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

如何在D3可缩放旭日图中实现可点击弧形并更新信息面板?

问题描述

刚完成编程训练营数月,目前工作中需用D3实现数据可视化示例。因D3相关资源较少,对诸多操作仍存困惑。当前需求为制作可缩放旭日图,使每个弧形具备点击交互性,点击后更新HTML中的div,展示对应标题与信息文本。已完成页面布局及基础图表的HTML搭建,数据已在JS文件中硬编码,各对象均包含需调用的信息,但不知如何实现该交互功能,恳请指导。

旭日图布局示意图

现有HTML代码

<div class="container">
    <h1 class="text-center" style="padding: 2rem;">Growth Opportunities</h1>
</div>
</br>
<div class="d-flex justify-content-center">
    <div style="margin-right: 8rem; margin-left: 2rem;">
        <svg></svg>
    </div>
    <div class="card" style="width: 50rem; margin-right: 5rem;">
        <h2 class="card-header text-center" style="padding: 1rem;">Title</h2>
        <div class="card-body">
            <p class="card-text" style="padding: 1rem">Test Text</p>
        </div>
    </div>
</div>

现有JavaScript代码

// Variables
var width = 750;
var height = 750;
var radius = Math.min(width, height) / 2;
var color = d3.scaleOrdinal(d3.schemeCategory20b);

// Create primary <g> element
var g = d3.select('svg')
  .attr('width', width)
  .attr('height', height)
  .append('g')
  .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');

// Data strucure
var partition = d3.partition()
  .size([2 * Math.PI, radius]);

// Find data root
var root = d3.hierarchy(nodeData)
  .sum(function (d) { return d.size});

// Size arcs
partition(root);
var arc = d3.arc()
  .startAngle(function (d) { return d.x0 })
  .endAngle(function (d) { return d.x1 })
  .innerRadius(function (d) { return d.y0 })
  .outerRadius(function (d) { return d.y1 });

// Put it all together
g.selectAll('path')
  .data(root.descendants())
  .enter().append('path')
  .attr("display", function (d) { return d.depth ? null : "none"; })
  .attr("d", arc)
  .style('stroke', '#fff')
  .style("fill", function (d) { return color((d.children ? d : d.parent).data.name); })

解决方案

核心实现思路

通过给弧形绑定点击事件,同时处理卡片内容更新和旭日图缩放两个核心需求,用D3的过渡动画保证交互流畅性。

修改后的完整JavaScript代码

// Variables
var width = 750;
var height = 750;
var radius = Math.min(width, height) / 2;
var color = d3.scaleOrdinal(d3.schemeCategory20b);

// Create primary <g> element
var g = d3.select('svg')
  .attr('width', width)
  .attr('height', height)
  .append('g')
  .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');

// Data structure
var partition = d3.partition()
  .size([2 * Math.PI, radius]);

// Arc generator
var arc = d3.arc()
  .startAngle(function (d) { return d.x0; })
  .endAngle(function (d) { return d.x1; })
  .innerRadius(function (d) { return d.y0; })
  .outerRadius(function (d) { return d.y1; });

// 绘制/更新图表的通用函数
function updateChart(currentRoot) {
  partition(currentRoot);
  
  var paths = g.selectAll('path')
    .data(currentRoot.descendants());
  
  // 新增弧形元素并绑定交互
  paths.enter().append('path')
    .attr("display", function (d) { return d.depth ? null : "none"; })
    .style('stroke', '#fff')
    .style("fill", function (d) { return color((d.children ? d : d.parent).data.name); })
    .on('click', function(event, d) {
      // 更新右侧卡片内容(根据你的nodeData字段名调整)
      d3.select('.card-header').text(d.data.title || d.data.name);
      d3.select('.card-text').text(d.data.description || '暂无详细信息');
      
      // 缩放至点击的节点
      zoomTo(d);
    })
    .merge(paths) // 合并现有元素,应用过渡动画
    .transition().duration(750)
    .attr("d", arc);
  
  // 移除多余元素
  paths.exit().remove();
}

// 旭日图缩放函数
function zoomTo(d) {
  var scale = radius / d.y1;
  g.transition().duration(750)
    .attr('transform', `translate(${width/2},${height/2}) scale(${scale}) translate(${-d.x0 * scale},${-d.y0 * scale})`);
}

// 初始化图表
var root = d3.hierarchy(nodeData)
  .sum(function (d) { return d.size; });
updateChart(root);

// 默认展示根节点信息
d3.select('.card-header').text(root.data.title || root.data.name);
d3.select('.card-text').text(root.data.description || '暂无详细信息');

关键说明

  1. 交互绑定:在创建弧形元素时,通过.on('click', ...)绑定点击事件,直接操作DOM更新卡片内容。
  2. 缩放逻辑:zoomTo函数通过计算缩放比例,结合D3过渡动画实现平滑的节点聚焦效果。
  3. 数据适配:代码中假设你的nodeData包含title(标题)和description(描述)字段,如果实际字段名不同,直接修改d.data.xxx部分即可。
  4. 动态更新:updateChart函数负责处理图表的初始化和更新,确保缩放后图表能重新渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 06:35:48