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

兼容d3.js的类矩阵网格及行过渡动画实现问题

问题概述

我设计了一个3列多行的网格,行结构类似文件夹层级(父项可包含子项,子项还能嵌套),最终要实现点击父项展开/收起子项的折叠效果。目前遇到两个核心问题:

  • 添加行时是瞬间出现,无法实现缓入动画
  • 尝试了display: contents和subgrid两种布局,subgrid作为构建类矩阵结构的标准方案,却无法强制第二列宽度统一

解决方案

1. 实现添加行的缓入动画

display: contents的元素不生成盒模型,无法直接应用过渡动画。调整结构让每行作为独立网格项,通过CSS过渡控制透明度和高度:

  • 给.row设置基础过渡样式,初始隐藏新行
  • 使用D3的transition()方法在新行插入后触发动画

2. 统一subgrid列宽

subgrid的核心是子网格继承父网格的列定义,之前的错误在于子网格自行定义列模板。正确配置:

  • 父容器定义统一的列尺寸
  • 子行使用grid-template-columns: subgrid完全继承父列宽,确保所有行的对应列宽度一致

修改后的完整代码

JavaScript

function update(data) {
  const rows = d3.selectAll('.grid_container')
    .selectAll('.row')
    .data(data, (d) => d.id)
    .join(
      enter => enter.append('div')
        .classed('row', true)
        .style('opacity', 0)
        .style('height', 0)
        .call(enter => enter.each(function(d) {
          d3.select(this)
            .selectAll('div')
            .data(d.content)
            .join('div')
            .text(d => d);
        }))
        .transition().duration(300)
        .style('opacity', 1)
        .style('height', 'auto'),
      update => update,
      exit => exit.transition().duration(300)
        .style('opacity', 0)
        .style('height', 0)
        .remove()
    );
}

function genRow(i) {
  return {
    id: i,
    content: [...Array(3)].map((_, j) => i === 0 && j === 1 ?
      'Super Long Line' : `Cell ${i + 1}/${j + 1}`)
  }
}

function addRow() {
  data.push(genRow(data.length));
  update(data);
}

const data = [...Array(2)].map((_, i) => genRow(i));
update(data);

CSS

/* 统一基础网格样式 */
.grid_container {
  display: grid;
  grid-template-columns: 110px max-content auto;
  gap: 5px;
  margin-bottom: 20px;
}

/* 行样式:使用subgrid继承父列宽 */
.row {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: 1 / -1;
  transition: all 0.3s ease;
  overflow: hidden;
}

.row > div {
  padding: 10px;
}

.row:nth-child(odd) > div {
  background-color: forestgreen;
}

.row:nth-child(even) > div {
  background-color: purple;
}

button {
  margin-bottom: 10px;
  padding: 8px 16px;
}

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
<button onclick="addRow()">Add Row</button>

<h1><code>subgrid 统一列宽 + 动画版</code></h1>
<div id="contents" class="grid_container">
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:55:56