toolkit/javascript/d3/src/layout/hierarchy.js
changeset 47 c0b4a8b5a012
equal deleted inserted replaced
46:efd9c589177a 47:c0b4a8b5a012
       
     1 d3.layout.hierarchy = function() {
       
     2   var sort = d3_layout_hierarchySort,
       
     3       children = d3_layout_hierarchyChildren,
       
     4       value = d3_layout_hierarchyValue;
       
     5 
       
     6   // Recursively compute the node depth and value.
       
     7   // Also converts the data representation into a standard hierarchy structure.
       
     8   function recurse(data, depth, nodes) {
       
     9     var childs = children.call(hierarchy, data, depth),
       
    10         node = d3_layout_hierarchyInline ? data : {data: data};
       
    11     node.depth = depth;
       
    12     nodes.push(node);
       
    13     if (childs && (n = childs.length)) {
       
    14       var i = -1,
       
    15           n,
       
    16           c = node.children = [],
       
    17           v = 0,
       
    18           j = depth + 1;
       
    19       while (++i < n) {
       
    20         d = recurse(childs[i], j, nodes);
       
    21         d.parent = node;
       
    22         c.push(d);
       
    23         v += d.value;
       
    24       }
       
    25       if (sort) c.sort(sort);
       
    26       if (value) node.value = v;
       
    27     } else if (value) {
       
    28       node.value = +value.call(hierarchy, data, depth) || 0;
       
    29     }
       
    30     return node;
       
    31   }
       
    32 
       
    33   // Recursively re-evaluates the node value.
       
    34   function revalue(node, depth) {
       
    35     var children = node.children,
       
    36         v = 0;
       
    37     if (children && (n = children.length)) {
       
    38       var i = -1,
       
    39           n,
       
    40           j = depth + 1;
       
    41       while (++i < n) v += revalue(children[i], j);
       
    42     } else if (value) {
       
    43       v = +value.call(hierarchy, d3_layout_hierarchyInline ? node : node.data, depth) || 0;
       
    44     }
       
    45     if (value) node.value = v;
       
    46     return v;
       
    47   }
       
    48 
       
    49   function hierarchy(d) {
       
    50     var nodes = [];
       
    51     recurse(d, 0, nodes);
       
    52     return nodes;
       
    53   }
       
    54 
       
    55   hierarchy.sort = function(x) {
       
    56     if (!arguments.length) return sort;
       
    57     sort = x;
       
    58     return hierarchy;
       
    59   };
       
    60 
       
    61   hierarchy.children = function(x) {
       
    62     if (!arguments.length) return children;
       
    63     children = x;
       
    64     return hierarchy;
       
    65   };
       
    66 
       
    67   hierarchy.value = function(x) {
       
    68     if (!arguments.length) return value;
       
    69     value = x;
       
    70     return hierarchy;
       
    71   };
       
    72 
       
    73   // Re-evaluates the `value` property for the specified hierarchy.
       
    74   hierarchy.revalue = function(root) {
       
    75     revalue(root, 0);
       
    76     return root;
       
    77   };
       
    78 
       
    79   return hierarchy;
       
    80 };
       
    81 
       
    82 // A method assignment helper for hierarchy subclasses.
       
    83 function d3_layout_hierarchyRebind(object, hierarchy) {
       
    84   object.sort = d3.rebind(object, hierarchy.sort);
       
    85   object.children = d3.rebind(object, hierarchy.children);
       
    86   object.links = d3_layout_hierarchyLinks;
       
    87   object.value = d3.rebind(object, hierarchy.value);
       
    88 
       
    89   // If the new API is used, enabling inlining.
       
    90   object.nodes = function(d) {
       
    91     d3_layout_hierarchyInline = true;
       
    92     return (object.nodes = object)(d);
       
    93   };
       
    94 
       
    95   return object;
       
    96 }
       
    97 
       
    98 function d3_layout_hierarchyChildren(d) {
       
    99   return d.children;
       
   100 }
       
   101 
       
   102 function d3_layout_hierarchyValue(d) {
       
   103   return d.value;
       
   104 }
       
   105 
       
   106 function d3_layout_hierarchySort(a, b) {
       
   107   return b.value - a.value;
       
   108 }
       
   109 
       
   110 // Returns an array source+target objects for the specified nodes.
       
   111 function d3_layout_hierarchyLinks(nodes) {
       
   112   return d3.merge(nodes.map(function(parent) {
       
   113     return (parent.children || []).map(function(child) {
       
   114       return {source: parent, target: child};
       
   115     });
       
   116   }));
       
   117 }
       
   118 
       
   119 // For backwards-compatibility, don't enable inlining by default.
       
   120 var d3_layout_hierarchyInline = false;