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

为何折叠面板中SVG的getBoundingClientRect()无法获取正确尺寸?

折叠面板中D3.js获取SVG宽高返回0的问题

我用D3.js制作图表时,一直通过element.node().getBoundingClientRect()获取HTML中SVG的宽高。现在在折叠面板(accordion)内创建图表,发现这个函数返回的宽高均为0。

我的HTML代码

<h2 class="accordion-header" id="headingFour">
  <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
    <span>Content</span>
  </button>
</h2>
<div id="collapseFour" class="accordion-collapse collapse" aria-labelledby="headingFour" data-bs-parent="#accordionExample">
  <div class="accordion-body middle-align linechart-container-accordion">
    <svg id="accordion-chart"></svg>
  </div>
</div>

我的JavaScript代码

function filledLineChart(ID)
{
    let svg = d3.select("#" + ID),

    let svgObject = svg.node().getBoundingClientRect(),
         width = svgObject.width,
         height = svgObject.height;

    console.log(width);
    console.log(height);
}

问题原因及解决办法

原因

折叠面板初始带有collapse类,元素处于隐藏状态,getBoundingClientRect()对于未渲染的隐藏元素会返回宽高0——因为元素没有在页面上占据实际空间。

解决办法1:监听面板展开事件

利用Bootstrap折叠组件的shown.bs.collapse事件,在面板完全展开后再初始化图表,此时元素已渲染,能正确获取尺寸:

document.getElementById('collapseFour').addEventListener('shown.bs.collapse', function() {
  filledLineChart('accordion-chart');
});

解决办法2:给容器设置固定尺寸

给SVG的父容器设置固定宽高样式,确保即使面板隐藏,容器也有明确尺寸,再通过父容器获取尺寸:

.linechart-container-accordion {
  width: 100%;
  height: 400px;
}

修改JS代码,获取父容器尺寸并设置给SVG:

function filledLineChart(ID) {
    let svg = d3.select("#" + ID);
    // 获取父容器的尺寸
    let container = svg.node().parentNode.getBoundingClientRect();
    let width = container.width;
    let height = container.height;
    // 给SVG设置宽高
    svg.attr("width", width).attr("height", height);
    console.log(width, height);
    // 后续图表绘制逻辑...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:01:01