我正在尝试创建一个具有缩放功能的 d3 可折叠垂直树。但是当滚动条可见时,缩放功能无法正常工作。
每次树折叠或展开时,我都会计算树的宽度和高度,并更新 svg 的高度和宽度属性,以使滚动条可见和隐藏(如果树大小小于我的 div(#d3tree)) .
let height = Math.max(finalOpts.height, (bottom.y - top.y) + finalOpts.rectHeight),
width = Math.max(finalOpts.width, (right.x - left.x) + finalOpts.rectWidth);
svg.attr("height", height)
.attr("width", width)
.attr("viewBox", [0, 0, width, height]);
如果树的大小小于我的 div(#d3tree),我会将 g 转换到 div 的中心。 否则,我将 g 转换为根据树最左边节点的 x 属性计算的位置。
// to make the whole tree visible onscroll
g.attr('transform',`translate(${(width > finalOpts.width) ? Math.abs(left.x) + (finalOpts.rectWidth / 2) : width / 2}, 0)`);
我能够实现这一切。但是,如果我缩放,x 轴无法正确平移。仅当滚动条可见时才会发生这种情况。当没有滚动条时缩放工作正常。
下面是我正在努力解决的代码部分。我不明白应该给 zoomTranslateX 变量赋予什么值。这是在小提琴中评论的。请取消注释此缩放功能。
// ZoomTranslate
//var zoomTranslateX = 0
//zoomBehaviours.translateTo(svg, (width > finalOpts.width) ? zoomTranslateX : 0, (target.getBoundingClientRect().height / 2) - 5);
//svg.call(zoomBehaviours);
我在这里错过了什么或做错了什么?请帮忙。我是 d3.js 的新手
我正在使用 d3V6 JS 小提琴链接 - https://jsfiddle.net/2ervdf1q/
问题
问题在于您使用
g
元素上的缩放行为变换覆盖了现有的平移变换。从而删除现有的翻译。
解决方案
在
g
下添加一个新的 svg
元素,并使其成为当前 g
元素的父元素。从而保留现有的翻译并在缩放变换后应用它。
const zoomGroup = svg
.append("g");
const g = zoomGroup.append("g")
.attr('transform',`translate(${finalOpts.width / 2}, 0)`);
const zoomBehaviours = d3.zoom()
.scaleExtent(finalOpts.zoomScale)
.on('zoom', (event) => zoomGroup.attr('transform', event.transform.toString()));
示例