d3-constrained-semantic-zooming

http://stackoverflow.com/questions/21505605/d3-constrained-semantic-zooming-on-a-tree-layout

by Nivaldo

HTML

<div id="myTree"></div>

JavaScript

var w = 410,
    h = 280,
    viewportSize = [w - 10, h - 20],
    translationVector = [10, 275],
    myTree = d3.select('#myTree'),
    treeLayout = d3.layout.tree();

var sizeFunction = function (d) {
    var isLeafless = d.children || !d.size;
    if (isLeafless) {
        return 0;
    }

    var sizeScale = d3.scale.log()
        .domain([1, 8000])
        .range([1, 10]);

    return sizeScale(d.size);
};

var colorFunction = function (d) {
    var rdYlGn0 = d3.scale.log().range(['#1a9850', '#91cf60']),
        rdYlGn1 = d3.scale.log().range(['#91cf60', '#d9ef8b']),
        rdYlGn2 = d3.scale.log().range(['#d9ef8b', '#fee08b']),
        rdYlGn3 = d3.scale.log().range(['#fee08b', '#fc8d59']),
        rdYlGn4 = d3.scale.log().range(['#fc8d59', '#d73027']),
        rdYlGnColorScales = [rdYlGn0, rdYlGn1, rdYlGn2, rdYlGn3, rdYlGn4];

    var colorScale = d3.scale.quantize()
        .domain([1, 100])
        .range([0, 1, 2, 3, 4]);

    var colorLevel = colorScale(d.percentage);
    var rdYlGnColorScale = rdYlGnColorScales[colorLevel];
    rdYlGnColorScale.domain(colorScale.invertExtent(colorLevel));

    return rdYlGnColorScale(d.percentage);
};

treeLayout.size(viewportSize);
var visData = getVisData(),
    nodesData = treeLayout.nodes(visData),
    linksData = treeLayout.links(nodesData);

var svg = myTree
    .append('svg')
    .attr('width', w)
    .attr('height', h);

var boundary = svg
    .append('rect')
    .attr('width', w)
    .attr('height', h)
    .style('fill', 'none')
    .style('pointer-events', 'all')
    .style('stroke', 'black')
    .style('stroke-width', 1);

var viewport = svg
    .append('g')
    .attr('name', 'viewport');

// nodes
viewport
    .selectAll('.node')
    .data(nodesData)
    .enter()
    .append('g')
    .attr('class', 'node')
    .attr('title', function (d) {
        return d.name + ' (' + d.percentage + '%)';
    })
    .append('circle')
    .transition()
    .duration(1000)
    .each('start', function () { // <-- Executes...