javascript - Change the size of an existing d3 tree -
i attempting make tree viewing web application. using d3 tree layout generate trees. able scale size of tree in either axis. in otherwords being able scale x , y axis of viewer. increase either vertical distance between nodes or increase length of branches.
i have been unable accomplish this. have attempted change nodesize() of tree layout, , update had no effect. have attempted modify x or y coordinate of each node again had no effect. have been unable modify physical layout of tree once has been rendered.
i have read , attempted fixes in following threads:
- dynamically resize d3 tree layout based on number of childnodes
- d3 tree layout separation between nodes using nodesize
but did not solve problem.
i implementing treegenerator object, handles of rendering of svg, using prototyped functions. going full screen feeling, treegenerator appends svg div width: 100%; height: 100%
. should node have implemented both zooming , panning functionality.
here constructor:
treegenerator = function(target, treestring) { // set 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 matching results last search this._searchresults = []; // path lengths this.maxpathlength = 0; this._loadsvg(target); this._tree(treestring); }
and here 2 functions _loadsvg , _tree called constructor:
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 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); } }
and _tree:
treegenerator.prototype._tree = function (treestring) { // needs array d3 this.treedata = this.parsetree(treestring); this.root = this.treedata[0]; // set 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 = 0; // generator paths // node ---> node var horizontal = d3.svg.line().interpolate('step-before') .x(function (d) { return d.x; }) .y(function (d) { return d.y; }); // compute 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 nodes var node = self.container.selectall("g.node") .data(nodes, function(d) { return d.id || (d.id = ++i); }) // enter 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 , update //var nodeupdate = node.update() // .attr("x", function(d) { return d.x }); // declare links var link = self.container.selectall("path.link") .data(links, function(d) { return d.target.id; }); // enter 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 g group highlight node = this; // if double click timer active, click double click if ( doubleclicktimer ) { cleartimeout(doubleclicktimer); doubleclicktimer = false; collapse(d); } // otherwise, after single click (double click has timed out) else { doubleclicktimer = settimeout( function() { doubleclicktimer = false; highlight(node, d); }, 175); } } function highlight(node,d) { // want bold text // , color node self._unhighlightnode(); // toggle if clicking again if(self._highlightednode == node) { self._highlightednode = undefined; self.selectednode = undefined; return; } // set new 1 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 pointer self._highlightednode = node; self.selectednode = d; } function collapse(d) { } } };
i know code bit messy, full of commented out things did in attempt fix issue. appreciate can offered. included enough info.
Comments
Post a Comment