使 D3 响应式:viewBox vs resize()

Making D3 responsive: viewBox vs resize()?

本文关键字:vs resize viewBox D3 响应      更新时间:2023-09-26

我必须构建在平板电脑、桌面显示器以及在某些情况下非常大的 4k+ 高分辨率影院大小显示器上都能很好地工作的 d3 可视化。

所以我试图弄清楚在使用 SVG 的"viewBox"属性和"保留纵横比"与调用一个调整大小函数以在窗口调整大小事件上重新渲染并使用绝对值之间的权衡。 大多数例子,例如这篇博客文章(http://eyeseast.github.io/visible-data/2013/08/28/responsive-charts-with-d3/)都建议后者,我在其中做了这样的事情:

d3.select(window).on('resize', resize)
resize() {
// rerender each individual element with the new width+height of the parent node
d3.select('svg')
 .attr('width', newWidth)
//etc... and many lines of code depending upon how complex my visualisation is
}

但是,为什么我不能只使用 SVG viewBox 让我的 SVG 像这样调整大小:

d3.select('svg')
  .attr( 'preserveAspectRatio',"xMinYMin meet")
  .attr("viewBox", "0 0 900 500")
  .attr('width', '100%')

我只是假设我的宽度和高度是 900x500px(或其他什么),并利用 SVG 是一种矢量格式的事实,可以处理所有繁琐的细节,例如文本大小和边距。我很难理解为什么这么多人在给出使用 D3 的响应式或可扩展可视化的示例时更喜欢 resize() 函数,而且我非常担心如果我沿着 viewBox 路线走下去,我会错过一些东西。

编辑:

因此,除了mef在下面所说的之外,还有一个想法是,使用viewBox,我被困在特定的纵横比上。因此,我可能希望可视化的高度保持固定,例如在折线图或条形图的情况下,但它会响应其宽度。使用固定的纵横比,这是不可能的,因为宽度的变化需要高度的变化。这种情况需要一个 resize() 函数来重新渲染以适应新的纵横比。

因此,尽管具有固定纵横比的 viewBox 明显更容易实现,但有很多常见情况需要更大的控制,这需要一个 resize() 函数,并解释了社区对更复杂的解决方案的偏好作为第一和最后的手段。我的用例可能更喜欢 viewBox 解决方案,当您的要求是响应能力时,这有点不寻常。

我建议使用以下逻辑:

  • 如果您的可视化可以在您希望使用 viewBox 技术支持的最小屏幕上使用,请坚持下去,无需进一步查看(幸运的是您:))
  • 否则:缩小可视化效果时可能会遇到以下问题:
    • 细节太多,在较小的屏幕上无法区分
    • 文本太小,在较小的屏幕中无法阅读

然后,您需要使用javascript根据屏幕尺寸调整可视化效果。这篇博客文章认真对待可视化的响应能力。

哦,不要忘记取消调整大小事件侦听器的抖动。