
d3.chart("hierarchy").extend("cluster-tree", {

  initialize : function() {

    var chart = this;

    var counter = 0;

    chart.radius(chart._radius || 4.5);
    chart.levelGap(chart._levelGap || "auto");

    chart._width  = chart.base.attr("width");
    chart._height = chart.base.attr("height");

    chart.layers.links = chart.layers.base.append("g").classed("links", true);
    chart.layers.nodes = chart.layers.base.append("g").classed("nodes", true);


    chart.layer("nodes", chart.layers.nodes, {

      dataBind: function(data) {
        return this.selectAll(".node").data(data, function(d) { return d._id || (d._id = ++counter); });
      },

      insert: function() {
        return this.append("g").classed("node", true);
      },

      events: {
        "enter": function() {
          this.append("circle")
            .attr("r", 0)
            .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

          this.append("text")
            .attr("dy", ".35em")
            .text(function(d) { return d[chart._name]; })
            .style("fill-opacity", 0);

          this.on("click", function(event) {
            chart.trigger("node:click", event);
          });
        },

        "merge:transition": function() {
          this.select("circle")
            .attr("r", chart._radius)
            .style("stroke", function(d) { return d.path ? "brown" : "steelblue"; })
            .style("fill", function(d) {
                return d.path && ! d.parent.path ? "#E2A76F"
                                                 : d._children ? "lightsteelblue" : "#fff"; });

          this.select("text")
            .style("fill-opacity", 1);
        },

        "exit:transition": function() {
          this.duration(chart._duration)
            .remove();

          this.select("circle")
            .attr("r", 0);

          this.select("text")
            .style("fill-opacity", 0);
        },
      }
    });


    chart.layer("links", chart.layers.links, {
      dataBind: function(data) {
        return this.selectAll(".link")
          .data(chart.d3.layout.links(data), function(d) { return d.target._id; });
      },

      insert: function() {
        return this.append("path").classed("link", true);
      },

      events: {
        "enter": function() {
          this
            .attr("d", function(d) {
              var o = { x: chart.source.x0, y: chart.source.y0 };
              return chart.d3.diagonal({ source: o, target: o });
            });
        },

        "merge:transition": function() {
          this.duration(chart._duration)
            .attr("d", chart.d3.diagonal)
            .attr("stroke", function(d) { return d.source.path && d.target.path ? "#dd7b7b" : "#ccc"; })
            .style("stroke-width", function(d) { return d.path ? 1 : 1.5; });
        },

        "exit:transition": function() {
          this.duration(chart._duration)
            .attr("d", function(d) {
              var o = { x: chart.source.x, y: chart.source.y };
              return chart.d3.diagonal({ source: o, target: o });
            })
            .remove();
        },
      },
    });
  },



  transform: function(nodes) {
    var chart = this;

    // Adjust gap between node levels.
    if( chart._levelGap && chart._levelGap !== "auto" ) {
      nodes.forEach(function (d) { d.y = d.depth * chart._levelGap; });
    }
    
    return nodes;
  },



  radius: function(_) {
    if( ! arguments.length ) {
      return this._radius;
    }

    if( _ === "_COUNT" ) {
      this._radius = function(d) {
        if( d._children ) {
          return d._children.length;
        } else if( d.children ) {
          return d.children.length;
        }
        return 1;
      };

    } else {
      this._radius = _;
    }

    this.trigger("change:radius");
    if( this.root ) {
      this.draw(this.root);
    }

    return this;
  },


  /**
   * Sets a gap between node levels. Acceps eithe number of pixels or string
   * "auto". When level gap set to "auto", gap between node levels will be
   * maximized, so the tree takes full width.
   * 
   * @author: Basil Gren @basgren
   *
   * @param _
   * @returns {*}
   */
  levelGap: function(_) {
    if( ! arguments.length ) {
      return this._levelGap;
    }

    this._levelGap = _;
    this.trigger("change:levelGap");

    if( this.root ) {
      this.draw(this.root);
    }

    return this;
  },


  collapsible: function(_) {
    var chart = this;

    var depth = _;

    chart.once("collapse:init", function() {

      if( depth !== undefined ) {

        chart.walker(

          chart.root,

          function(d) { if( d.depth == depth ) { collapse(d); }},

          function(d) {
            if( d.children && d.children.length > 0 && d.depth < depth ) {
              return d.children;
            } else if( d._children && d._children.length > 0 && d.depth < depth ) {
              return d._children;
            } else {
              return null;
            }
          }
        );
      }
    });



    chart.on("node:click", function(d) {
      d = toggle(d);
      chart.trigger("transform:stash");
      chart.draw(d);
    });


    function toggle(d) {
      if( d.children ) {
        d._children = d.children;
        d.children = null;
      } else if( d._children ) {
        d.children = d._children;
        d._children = null;
      }
      return d;
    }


    function collapse(d) {
      if( d.children ) {
        d._children = d.children;
        d._children.forEach(collapse);
        d.children = null;
      }
    }

    return chart;
  },
});



@@ -784,32 +784,67 @@
 %22: function() %7B%0A
+%0A          chart._initNode(this);%0A%0A
           this.a
@@ -888,100 +888,8 @@
 , 0)
-%0A            .style(%22fill%22, function(d) %7B return d._children ? %22lightsteelblue%22 : %22#fff%22; %7D)
 ;%0A%0A 
@@ -1177,35 +1177,24 @@
       %22merge
-:transition
 %22: function(
@@ -1211,96 +1211,70 @@
     
-this.select(%22circle%22)%0A            .attr(%22r%22, chart._radius)%0A            .style(%22stroke%22,
+chart._initNode(this);%0A        %7D,%0A%0A        %22merge:transition%22:
  fun
@@ -1283,250 +1283,100 @@
 ion(
-d
 ) %7B
- return d.path ? %22brown%22 : %22steelblue%22; %7D)%0A            .style(%22fill%22, function(d) %7B%0A                return d.path && ! d.parent.path ? %22#E2A76F%22%0A                                                 : d._children ? %22lightsteelblue%22 : %22#fff%22; %7D
+%0A          this.select(%22circle%22)%0A            .attr()%0A            .attr(%22r%22, chart._radius
 );%0A%0A
@@ -2412,190 +2412,8 @@
 nal)
-%0A            .attr(%22stroke%22, function(d) %7B return d.source.path && d.target.path ? %22#dd7b7b%22 : %22#ccc%22; %7D)%0A            .style(%22stroke-width%22, function(d) %7B return d.path ? 1 : 1.5; %7D)
 ;%0A  
@@ -4178,16 +4178,17 @@
   chart.
+_
 walker(%0A

Remove color style settings