score:4

Accepted answer

Finally I found a solution by myself with some more articles. The main code snippets that helped (after reading a lot more things) were given by this article which was not sufficient explained for me in first instance.

So, the solution with the given example tree code is the following:

To set the initial zoom level you need to add one line to the g-element that is for the zoomlistener to work (it is pretty much on the bottom of the script) that it looks like:

// Append a group which holds all nodes and which the zoom Listener can act upon.
var svgGroup = baseSvg.append("g")
    .attr("transform","translate(100,30)scale(.3,.3)");

I basically just add an attribute to the g-element that holds all other nodes. In this attribute is the initial zoom level set. It seems important that the translate values and the scale are the same (30/100 = 0.3 ;) ). Otherwise it doesn't work propely.

But now is the problem, that when we want to zoom or move accross the tree for the first time it jumps back to scale 1 which is not that nice for the user as he will be confused by this sudden jump.

To have a smooth user experience, I added only a small line to the above mentioned zoomlistener that it looks like this (its the same translate and scale as before):

 var zoomListener = d3.behavior.zoom().translate([100,30]).scale(.3).scaleExtent([0.3, 3]).on("zoom", zoom);

Now the initial zoom level is hardcoded and easily adjustable - and the best of all: it only took two lines :D

I will try a dynamic approach. When I have a solution I'll edit this solution :)

EDIT: I found a dynamic solution - at least for my case: When the data of my tree is created (customizable) with php, I check the depth of the tree (how many nodes are in one row). This depth is written into the SESSION. Before the start of my tree-function in my javascript I initialize and set:

var depth_of_tree = window.SESSION.depth_of_tree;

And the initital scale with 1 divided by the ln of the depth:

var initscale = 1 / Math.log(depth_of_tree); 

Then, I change the zoomlistener with the following lines:

//var initscale = .3;
var inittransx = 100;
var inittransy = inittransx*initscale;

// define the zoomListener which calls the zoom function on the "zoom" event constrained within the scaleExtents
var zoomListener = d3.behavior.zoom().translate([inittransx,inittransy]).scale(initscale).scaleExtent([0.3, 2]).on("zoom", zoom);

and:

// Append a group which holds all nodes and which the zoom Listener can act upon.
var svgGroup = baseSvg.append("g")
    .attr("transform","translate("+inittransx+","+inittransy+")scale("+initscale+","+initscale+")");

This results in pretty nice scales no matter how deep the tree is. (you may have to play a bit with the numbers)


Related Query