D3.js树调整大小以适应SVG画布

时间:2018-05-18 23:04:08

标签: javascript d3.js

我正在尝试将d3.js树的大小调整为包含SVG的树。网上有很多解决方案,但似乎没有一个解决方案适合我的情况。 我知道(或多或少)当我设法检索包含的svg的大小和包含的树的大小时该做什么,但我的问题是我在检索树的大小时遇到​​了问题。

我认为我的问题来自于我在创建SVG时使用preserveAspectRatio这一事实。以下是代码的主要部分:

var width  = 1500,
    height =  600;
var svg = d3.select('svg')
            .attr('preserveAspectRatio', 'xMinYMin meet')
            .attr('viewBox', '0 0 ' + width + ' ' + height)
            .classed('svg-content-responsive', true);

zoombehavior = d3.behavior.zoom().scaleExtent([0.2, 5]).on('zoom', redraw);
svg.call(zoombehavior);

// Append title
svg.append('text');

// ...

// Append Legend
svg.append('g');

// ...

// Append Tree
var vis  = svg.append('svg:g').attr('class', 'vis');

var draw = vis.append('svg:g').attr('class', 'draw')
              .attr('transform', 'translate(' + (width-rectW)/2 + ',' + 100 + ')');

我正在使用此解决方案,以便我只能在redraw上调用vis,即仅在可视化树上调用,而不会影响标题或图例。

之后,我创建了一个层次结构在draw下面的树:

var tree = d3.layout.tree()
           .nodeSize([rectW+20, rectH])
           .separation(function separation(a, b) {
              return (a.parent == b.parent ? 1 : 1.4);
            });
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
    links = tree.links(nodes);

// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 100; });

// Declare the nodes.
var node = draw.selectAll('g.node');

以下是第一个问题:我的svg是响应式的,这意味着它的实际大小与我在开头分配的widthheight不同。例如。在我的显示器上,它目前是2222 * 888

但是,有了几个技巧,我设法检索了svg元素的实际位置:

var svgcnt = document.getElementById("svg-container");

var svgw = svgcnt.clientWidth;
var svgh = svgcnt.clientWidth * height / width;

现在,我需要树的大小。现在,在大多数示例中,我应该调用draw.node().getBBox()之类的东西来获取树的大小,但在我的情况下,我获得的回报是错误的。

例如,在我的最新测试中,我得到了149.9820556640625 77,而实际显示的draw的大小(没有任何缩放)是571 376。这在尺寸上都是错误的,并且在纵横比方面也很重要。出于这个原因,我用来缩放树的函数(我正在使用this jsfiddle)过度扩展我的树。为了完整起见,这里还有完整的HTML DOM,以便您可以根据需要进行检查:

<div id="svg-container" class="svg-container">
    <svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 1500 600" class="svg-content-responsive">
        <text dx="750" dy="40" class="title filename" text-anchor="middle">icra</text>
        <g class="legendcnt" transform="translate(20,20)"></g>
        <g class="vis" transform="translate(0,0) scale(1)"><g class="draw">
            <path class="link" x="70" y="20" d="M230,220C230,270 150,270 150,320"></path><path class="link" x="70" y="20" d="M230,220C230,270 310,270 310,320"></path><path class="link" x="70" y="20" d="M70,120C70,170 -90,170 -90,220"></path><path class="link" x="70" y="20" d="M70,120C70,170 70,170 70,220"></path><path class="link" x="70" y="20" d="M70,120C70,170 230,170 230,220"></path><path class="link" x="70" y="20" d="M70,20C70,70 -90,70 -90,120"></path><path class="link" x="70" y="20" d="M70,20C70,70 70,70 70,120"></path><path class="link" x="70" y="20" d="M70,20C70,70 230,70 230,120"></path><g class="node " transform="translate(160,100)"><rect width="110.37815856933594" height="40" class="label" x="14.810920715332031"></rect><text x="70" y="20" dy=".35em" text-anchor="middle">Mount Chair</text></g><g class="node human" transform="translate(240,300)"><rect width="86.00652313232422" height="40" class="label" x="26.99673843383789"></rect><text x="70" y="20" dy=".35em" text-anchor="middle">Place top</text></g><g class="node robot" transform="translate(80,300)"><rect width="79.91361236572266" height="40" class="label" x="30.043193817138672"></rect><text x="70" y="20" dy=".35em" text-anchor="middle">Take  top</text></g><g class="node " transform="translate(160,200)"><rect width="96.16136932373047" height="40" class="label" x="21.919315338134766"></rect><text x="70" y="20" dy=".35em" text-anchor="middle">Mount top</text><g class="combination"><rect width="36" height="36" x="52" y="41"></rect><text x="70" y="8" dy="2.2em" text-anchor="middle">→</text></g></g><g class="node  collapsed" transform="translate(0,200)"><rect width="99.20782470703125" height="40" class="label" x="20.396087646484375"></rect><text x="70" y="20" dy=".35em" text-anchor="middle">Mount legs</text><g class="combination"><rect width="36" height="36" x="52" y="41"></rect><text x="70" y="8" dy="2.2em" text-anchor="middle">||</text></g></g><g class="node robot" transform="translate(-160,200)"><rect width="149.98207092285156" height="40" class="label" x="-4.991035461425781"></rect><text x="70" y="20" dy=".35em" text-anchor="middle">Take central frame</text></g><g class="node " transform="translate(0,100)"><rect width="108.3471908569336" height="40" class="label" x="15.826404571533203"></rect><text x="70" y="20" dy=".35em" text-anchor="middle">Mount Stool</text><g class="combination"><rect width="36" height="36" x="52" y="41"></rect><text x="70" y="8" dy="2.2em" text-anchor="middle">→</text></g></g><g class="node " transform="translate(-160,100)"><rect width="115.4555892944336" height="40" class="label" x="12.272205352783203"></rect><text x="70" y="20" dy=".35em" text-anchor="middle">Mount Bench</text></g><g class="node " transform="translate(0,0)"><rect width="124.5949478149414" height="40" class="label" x="7.702526092529297"></rect><text x="70" y="20" dy=".35em" text-anchor="middle">Available Tasks</text><g class="combination"><rect width="36" height="36" x="52" y="41"></rect><text x="70" y="8" dy="2.2em" text-anchor="middle">v</text></g></g></g>
        </g>
    </svg>
</div>

有什么建议吗?

0 个答案:

没有答案