Javascript 更改现有d3树的大小

Javascript 更改现有d3树的大小,javascript,d3.js,svg,tree,Javascript,D3.js,Svg,Tree,我正在尝试创建一个查看树的web应用程序。我使用d3树布局来生成我的树。我想做的是在任意轴上缩放树的大小。换句话说,能够缩放查看器的x轴和y轴。这将有效地增加节点之间的垂直距离或增加分支的长度 我一直无法做到这一点。我试图更改树布局的nodeSize(),然后进行更新,但没有效果。我还尝试修改每个节点的x或y坐标,但同样没有效果。我已经完全无法修改树的物理布局,一旦它被渲染 我已阅读并尝试在以下线程中进行修复: 但他们没有解决我的问题 我正在实现一个TreeGenerator对象,它使用

我正在尝试创建一个查看树的web应用程序。我使用d3树布局来生成我的树。我想做的是在任意轴上缩放树的大小。换句话说,能够缩放查看器的x轴和y轴。这将有效地增加节点之间的垂直距离或增加分支的长度

我一直无法做到这一点。我试图更改树布局的nodeSize(),然后进行更新,但没有效果。我还尝试修改每个节点的x或y坐标,但同样没有效果。我已经完全无法修改树的物理布局,一旦它被渲染

我已阅读并尝试在以下线程中进行修复:

但他们没有解决我的问题

我正在实现一个TreeGenerator对象,它使用原型函数处理SVG的所有呈现。我想要全屏的感觉,所以TreeGenerator将SVG附加到一个div中,宽度为100%;高度:100%。我应该知道我已经实现了缩放和平移功能

以下是构造函数:

下面是从构造函数调用的两个函数_loadSVG和_tree:

和_树:


我知道代码有点凌乱,但它充满了我在试图修复此问题时所做的注释。我感谢任何能提供的帮助。希望我包含了足够的信息。

您需要更改树布局的大小(使用其
.size()
函数),然后重新运行,然后再次渲染树。您能做一个小提琴来显示您所拥有的吗?在此向您双方道歉!但是我在这里设置了一个JS提琴:我在代码中注释掉了我大多数更改树的规模的尝试。还请注意,树不会加载到scren的中心。我已经尝试添加一个变换来渲染它的中心,直到屏幕被缩放或平移,这会导致树跳回到它当前加载的左上角位置。我也想。你终于找到解决办法了吗,mbiokyle?
TreeGenerator = function(target, treeString) {

    // Set up everything here
    // colors
    this.nodeColor = "#3B6073";
    this.highlightColor = "#F22248";
    this.searchColor = "#0DFFC2";

    this.nodeHeight = 5;
    this.nodeLength = 20;

    this.zoomX = 1;
    this.zoomY = 5;

    this._winHeight = window.innerHeight;
    this._winWidth = window.innerWidth;

    //this.xScale = d3.scale.linear().domain([0,100]).range([0, this._winWidth])
    //this.yScale = d3.scale.linear().domain([0,100]).range([0, this._winHeight])

    // keep the matching results from last search
    this._searchResults = [];

    // path lengths
    this.maxPathLength = 0;
    this._loadSVG(target);
    this._tree(treeString);
}
TreeGenerator.prototype._loadSVG = function(target) {

    var zoom = d3.behavior.zoom()
        //.size([this._winWidth, this._winHeight])
       .scaleExtent([this.zoomX,this.zoomY])
        //.x(this.xScale)
        //.y(this.yScale)
        //.center([height/2, width/2])
        .on("zoom", zoomed);


    var drag = d3.behavior.drag()
        .origin(function(d) { return d; })
        .on("dragstart", dragstarted)
        .on("drag", dragged)
        .on("dragend", dragended);

    this.svg = d3.select(target, ":first-child").append("svg")
      .append("g")
        //.attr("transform", "translate("+width / 2+","+height / 2+")")
        .call(zoom)
        .on("dblclick.zoom", null)

    var rect = this.svg.append("rect")
        .attr("width", "100%")
        .attr("height", "100%")
        .style("fill", "none")
        .style("pointer-events", "all");

    this.container = this.svg.append("g")

    // scope it for d3 funcs
    var container = this.container
    var self = this;

    function dottype(d) {
      d.x = +d.x;
      d.y = +d.y;
      return d;
    }

    function zoomed() {
        container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
    }

    function dragstarted(d) {
        d3.event.sourceEvent.stopPropagation();
        d3.select(this).classed("dragging", true);
    }

    function dragged(d) {
        d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
    }

    function dragended(d) {
        d3.select(this).classed("dragging", false);
    }
}
TreeGenerator.prototype._tree = function (treeString) {

    // needs an array for d3
    this.treeData = this.parseTree(treeString);

    this.root = this.treeData[0];

    // set up the layout
    this.tree = d3.layout.tree()
        .nodeSize([this.nodeHeight,this.nodeLength]);

    // set path dists
    this._setPathDist();
    this.yScale = d3.scale.linear().domain([0, this.maxPathLength]).range([0, 20]);
    this.xScale = d3.scale.linear().domain([1,100]).range([10, 30]);

    var self = this;
    update(this.root);

    function update(source) {
        var i = 0;

        // generator for paths from
        // node ---> node
        var horizontal = d3.svg.line().interpolate('step-before')
            .x(function (d) { return d.x; })
            .y(function (d) { return d.y; });

        // Compute the new tree layout.
        var nodes = self.tree.nodes(source).reverse()

        nodes.forEach(function (d) {
            if(!d.pathLength == 0) {
                d.y = d.y * self.yScale(d.pathLength);
            }
            else if(d.children != undefined) {
                d.y += 5;
            }
        });

        links = self.tree.links(nodes);

        // Declare the nodes
        var node = self.container.selectAll("g.node")
            .data(nodes, function(d) { return d.id || (d.id = ++i); })

        // Enter the nodes.
        doubleclickTimer = false // dont ask

        var nodeEnter = node.enter().append("g")
            .attr("class", "node")
            .attr("id", function(d) { return "node-"+d.id.toString(); })
            .attr("transform", function(d) { 
                return "translate(" + d.y + "," + d.x + ")"; })
            .on("click", clicked);

        nodeEnter.append("circle")
            .attr("r", 1)
            .style("fill", self.nodeColor)

        nodeEnter.append("text")
            .attr("x", function(d) { 
                return d.children || d._children ? -1 : 1; })
            .attr("y", function(d) {
                return d.children == undefined ? 1 : -1;
            })
            .attr("text-anchor", function(d) { 
                return d.children || d._children ? "end" : "start"; })
            .text(function(d) { return d.name; })
            .style("fill-opacity", 1);

        // try and update
        //var nodeUpdate = node.update()
        //  .attr("x", function(d) { return d.x });

        // Declare the links
        var link = self.container.selectAll("path.link")
            .data(links, function(d) { return d.target.id; });

        // Enter the links.
        link.enter().insert("path", "g")
            .attr("class", "link")
            .attr("d", function(d) {
                return horizontal([
                    {y: d.source.x, x: d.source.y},
                    {y: d.target.x, x: d.target.y}
                ]);
            });

        function clicked(d) {

            // need the g group for highlight
            node = this;

            // if double click timer is active, this click is the double click
            if ( doubleclickTimer )
            {
                clearTimeout(doubleclickTimer);
                doubleclickTimer = false;
                collapse(d);
            }

            // otherwise, what to do after single click (double click has timed out)
            else {
                doubleclickTimer = setTimeout( function() {
                    doubleclickTimer = false;
                    highlight(node, d);
                }, 175);
            }
        }

        function highlight(node,d) {

            // we want to bold the text
            // and color the node
            self._unhighlightNode();

            // toggle if clicking again
            if(self._highlightedNode == node) {
                self._highlightedNode = undefined;
                self.selectedNode = undefined;
                return;
            }

            // set the new one
            var circle = d3.select(node).select("circle");
            var text = d3.select(node).select("text");

            circle.style("fill", self.highlightColor);
            text.style("font-size","4px");

            // update the pointer
            self._highlightedNode = node;
            self.selectedNode = d;
        }

        function collapse(d) {

        }
    }
};