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

d3可滚动热力图y轴滚动时固定x轴位置的实现问题

核心问题说明

你的实现存在三个核心问题:

  1. 承载x轴的svg被放在了带滚动属性的#my_dataviz容器内部,滚动时会跟着内容一起移动
  2. x轴的svg插入顺序晚于热力图容器,所以默认渲染在热力图下方
  3. svg内部元素不支持CSSposition: fixed属性,你给x轴文本加这个属性无效,反而会导致文本渲染异常

修改方案

拆分固定x轴区域和滚动内容区域,调整对应样式和渲染逻辑,修改后x轴会固定在顶部,y轴滚动时不会移动,x轴标签文本完整显示,位置正确。
完整可运行代码如下:

HTML

<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="container">
  <!-- 固定x轴区域 -->
  <div id="x-axis-container"></div>
  <!-- 滚动热力图区域 -->
  <div id="my_dataviz"></div>
</div>

CSS

.rect {
  opacity: 0.8;
}
#container {
  width: 610px;
}
#x-axis-container {
  width: 100%;
  height: 70px;
  overflow: hidden;
}
#my_dataviz {
  width: 100%;
  height: 500px;
  overflow-y: scroll;
}

JS

var width = 500,
  height = 600,
  margintop = 0,
  marginbottom = 50,
  marginright = 10,
  marginleft = 50
d3.csv("https://raw.githubusercontent.com/Lea1216/d3/main/heatmap.csv", function(data) {

  var svg = d3.select("#my_dataviz")
              .append("div")
              .classed("chart",true)
              .append("svg")
                .attr("width",width +marginleft + marginright)
                .attr("height",height+margintop + marginbottom)
                .append("g")
                .attr("transform",
                      "translate(" + marginleft + "," + margintop + ")");

 // x轴渲染到固定容器内
 var axis = d3.select("#x-axis-container")
                   .append("svg")
                   .attr("width", width + marginleft +marginright)
                   .attr("height",70)
                   .append("g")
                   .attr("transform", "translate(" + marginleft + ", 20)");


  var x_axis = d3.scaleBand()
    .range([0, width])
    .domain(data.map(function(d) {
      return d.group;
    }))
    .padding(0.01);

  axis.call(d3.axisTop(x_axis))
                .selectAll("text")
                .style("text-anchor", "end")
                .attr("dx",15)
                .attr("dy",5)
                .attr("transform", "rotate(-65)");

  var y_axis = d3.scaleBand()
    .range([height, 0])
    .domain(data.map(function(d) {
      return d.activity;
    }))
    .padding(0.01);

  svg.append("g")
    .call(d3.axisLeft(y_axis))
    .attr("class", "y_axis")
    .selectAll("text")
    .on("click", function(d) {
      window.open(d.url, "_blank")
    });

  var myColor = d3.scaleLinear()
    .range(["white", "#C37B89"])
    .domain([1, 100])

  svg.selectAll()
    .data(data, function(d) {
      return d.group + ':' + d.activity;
    })
    .enter()
    .append("rect")
    .attr("x", function(d) {
      return x_axis(d.group)
    })
    .attr("y", function(d) {
      return y_axis(d.activity)
    })
    .attr("width", x_axis.bandwidth())
    .attr("height", y_axis.bandwidth())
    .style("fill", function(d) {
      return myColor(d.value)
    })
    .style("stroke-width", 1)
    .style("stroke", "none")
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 00:24:05