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

d3.js多折线图如何访问双层嵌套数组?附颜色、提示框、悬停动画问题

D3多折线图问题修复方案

核心问题定位与修改

对应你遇到的按lvalue区分颜色、tooltip取值错误、悬停触发所有折线三个问题,修改方案如下:

1. 按lvalue区分折线颜色

你之前错误将stroke属性绑定到外层州分组上,且用state作为颜色输入,无法实现按lvalue区分颜色。首先修正颜色比例尺配置,再将stroke属性绑定到每个折线path上:

// 先动态生成颜色比例尺domain,匹配数据中所有实际存在的lvalue值
const allLvalues = [...new Set(data.map(d => d.lvalue))]
var myColor = d3.scaleOrdinal()
                  .domain(allLvalues)
                  .range(["#884E17", "#0D0FAD", "#0DAD1C"]);
// 删除原selectLegisGroups上的.attr('stroke', ([key, ]) => myColor(key))配置
// 给折线path新增stroke属性绑定
initialPath
  .attr('d', (d) => valueLine(Array.from(d.values())[1]))
  .attr("class", "line2") // 使用你修改后的无CSS优先级冲突的类名
  .attr('fill', 'none')
  .attr('stroke', d => myColor(d[0])) // d[0]就是d3.groups返回的lvalue键值
  .attr('stroke-width', 1.5)

2. 修复tooltip内容

你绑定到path的每一项数据是d3.groups返回的[lvalue值, 同lvalue的所有数据数组]结构,按如下方式取值即可:

.append('title') // Tooltip
.text(function (d) { 
  return d[1][0].state + '\nlvalue: ' + d[0]
})

3. 修复悬停触发所有折线的问题

该问题是因为切换州时旧的路径没有被清理,同一位置叠了多层path导致的,补充update方法的exit清理逻辑即可:

var updateGraph = function(legis){
  var selectLegis = nest.filter(([key, ]) => key == legis)
  var selectLegisGroups = svg.selectAll(".legisGroups")
    .data(selectLegis)
  
  // 移除旧的州分组
  selectLegisGroups.exit().remove()
  
  const newGroups = selectLegisGroups.enter()
    .append("g")
    .attr("class", "legisGroups")
  
  // 合并新旧分组统一处理路径
  const allGroups = newGroups.merge(selectLegisGroups)
  const paths = allGroups.selectAll("path.line2")
    .data(([, values]) => values)
  
  // 移除旧的折线路径
  paths.exit().remove()
  
  // 新增新的折线路径+合并旧路径做过渡
  paths.enter()
    .append("path")
    .attr("class", "line2")
    .attr('fill', 'none')
    .attr('stroke-width', 1.5)
    .attr('stroke', d => myColor(d[0]))
    .on('mouseover', function () {
      d3.select(this)
        .transition()
        .duration(500)
        .attr('stroke-width',3)
    })
    .on('mouseout', function () {
      d3.select(this)
        .transition()
        .duration(500)
        .attr('stroke-width',1.5)
    })
    .append('title')
    .text(function (d) { 
      return d[1][0].state + '\nlvalue: ' + d[0]
    })
    .merge(paths)
    .transition()
    .duration(1000)
    .attr("d", (d) => valueLine(Array.from(d.values())[1]))
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 01:00:02