whole_func_string: function computeNodeBreadths(graph, iterations, id) {
      var columns = nest().key(function (d) {
        return d.column;
      }).sortKeys(ascending).entries(graph.nodes).map(function (d) {
        return d.values;
      });
  
      initializeNodeBreadth(id);
      resolveCollisions();
  
      for (var alpha = 1, n = iterations; n > 0; --n) {
        relaxLeftAndRight(alpha *= 0.99, id);
        resolveCollisions();
      }
  
      function initializeNodeBreadth(id) {
  
        //override py if nodePadding has been set
        if (paddingRatio) {
          var padding = Infinity;
          columns.forEach(function (nodes) {
            var thisPadding = y1 * paddingRatio / (nodes.length + 1);
            padding = thisPadding < padding ? thisPadding : padding;
          });
          py = padding;
        }
  
        var ky = min(columns, function (nodes) {
          return (y1 - y0 - (nodes.length - 1) * py) / sum(nodes, value);
        });
  
        //calculate the widths of the links
        ky = ky * scale;
  
        graph.links.forEach(function (link) {
          link.width = link.value * ky;
        });
  
        //determine how much to scale down the chart, based on circular links
        var margin = getCircleMargins(graph);
        var ratio = scaleSankeySize(graph, margin);
  
        //re-calculate widths
        ky = ky * ratio;
  
        graph.links.forEach(function (link) {
          link.width = link.value * ky;
        });
  
        columns.forEach(function (nodes) {
          var nodesLength = nodes.length;
          nodes.forEach(function (node, i) {
            if (node.depth == columns.length - 1 && nodesLength == 1) {
              node.y0 = y1 / 2 - node.value * ky;
              node.y1 = node.y0 + node.value * ky;
            } else if (node.depth == 0 && nodesLength == 1) {
              node.y0 = y1 / 2 - node.value * ky;
              node.y1 = node.y0 + node.value * ky;
            } else if (node.partOfCycle) {
              if (numberOfNonSelfLinkingCycles(node, id) == 0) {
                node.y0 = y1 / 2 + i;
                node.y1 = node.y0 + node.value * ky;
              } else if (node.circularLinkType == 'top') {
                node.y0 = y0 + i;
                node.y1 = node.y0 + node.value * ky;
              } else {
                node.y0 = y1 - node.value * ky - i;
                node.y1 = node.y0 + node.value * ky;
              }
            } else {
              if (margin.top == 0 || margin.bottom == 0) {
                node.y0 = (y1 - y0) / nodesLength * i;
                node.y1 = node.y0 + node.value * ky;
              } else {
                node.y0 = (y1 - y0) / 2 - nodesLength / 2 + i;
                node.y1 = node.y0 + node.value * ky;
              }
            }
          });
        });
      }
  
      // For each node in each column, check the node's vertical position in relation to its targets and sources vertical position
      // and shift up/down to be closer to the vertical middle of those targets and sources
      function relaxLeftAndRight(alpha, id) {
        var columnsLength = columns.length;
  
        columns.forEach(function (nodes) {
          var n = nodes.length;
          var depth = nodes[0].depth;
  
          nodes.forEach(function (node) {
            // check the node is not an orphan
            var nodeHeight;
            if (node.sourceLinks.length || node.targetLinks.length) {
              if (node.partOfCycle && numberOfNonSelfLinkingCycles(node, id) > 0) ; else if (depth == 0 && n == 1) {
                nodeHeight = node.y1 - node.y0;
  
                node.y0 = y1 / 2 - nodeHeight / 2;
                node.y1 = y1 / 2 + nodeHeight / 2;
              } else if (depth == columnsLength - 1 && n == 1) {
                nodeHeight = node.y1 - node.y0;
  
                node.y0 = y1 / 2 - nodeHeight / 2;
                node.y1 = y1 / 2 + nodeHeight / 2;
              } else {
                var avg = 0;
  
                var avgTargetY = mean(node.sourceLinks, linkTargetCenter);
                var avgSourceY = mean(node.targetLinks, linkSourceCenter);
  
                if (avgTargetY && avgSourceY) {
                  avg = (avgTargetY + avgSourceY) / 2;
                } else {
                  avg = avgTargetY || avgSourceY;
                }
  
                var dy = (avg - nodeCenter(node)) * alpha;
                // positive if it node needs to move down
                node.y0 += dy;
                node.y1 += dy;
              }
            }
          });
        });
      }
  
      // For each column, check if nodes are overlapping, and if so, shift up/down
      function resolveCollisions() {
        columns.forEach(function (nodes) {
          var node,
              dy,
              y = y0,
              n = nodes.length,
              i;
  
          // Push any overlapping nodes down.
          nodes.sort(ascendingBreadth);
  
          for (i = 0; i < n; ++i) {
            node = nodes[i];
            dy = y - node.y0;
  
            if (dy > 0) {
              node.y0 += dy;
              node.y1 += dy;
            }
            y = node.y1 + py;
          }
  
          // If the bottommost node goes outside the bounds, push it back up.
          dy = y - py - y1;
          if (dy > 0) {
            y = node.y0 -= dy, node.y1 -= dy;
  
            // Push any overlapping nodes back up.
            for (i = n - 2; i >= 0; --i) {
              node = nodes[i];
              dy = node.y1 + py - y;
              if (dy > 0) node.y0 -= dy, node.y1 -= dy;
              y = node.y0;
            }
          }
        });
      }
    }
func_code_string: function computeNodeBreadths(graph, iterations, id) {
      var columns = nest().key(function (d) {
        return d.column;
      }).sortKeys(ascending).entries(graph.nodes).map(function (d) {
        return d.values;
      });
  
      initializeNodeBreadth(id);
      resolveCollisions();
  
      for (var alpha = 1, n = iterations; n > 0; --n) {
        relaxLeftAndRight(alpha *= 0.99, id);
        resolveCollisions();
      }
  
      function initializeNodeBreadth(id) {
  
        //override py if nodePadding has been set
        if (paddingRatio) {
          var padding = Infinity;
          columns.forEach(function (nodes) {
            var thisPadding = y1 * paddingRatio / (nodes.length + 1);
            padding = thisPadding < padding ? thisPadding : padding;
          });
          py = padding;
        }
  
        var ky = min(columns, function (nodes) {
          return (y1 - y0 - (nodes.length - 1) * py) / sum(nodes, value);
        });
  
        //calculate the widths of the links
        ky = ky * scale;
  
        graph.links.forEach(function (link) {
          link.width = link.value * ky;
        });
  
        //determine how much to scale down the chart, based on circular links
        var margin = getCircleMargins(graph);
        var ratio = scaleSankeySize(graph, margin);
  
        //re-calculate widths
        ky = ky * ratio;
  
        graph.links.forEach(function (link) {
          link.width = link.value * ky;
        });
  
        columns.forEach(function (nodes) {
          var nodesLength = nodes.length;
          nodes.forEach(function (node, i) {
            if (node.depth == columns.length - 1 && nodesLength == 1) {
              node.y0 = y1 / 2 - node.value * ky;
              node.y1 = node.y0 + node.value * ky;
            } else if (node.depth == 0 && nodesLength == 1) {
              node.y0 = y1 / 2 - node.value * ky;
              node.y1 = node.y0 + node.value * ky;
            } else if (node.partOfCycle) {
              if (numberOfNonSelfLinkingCycles(node, id) == 0) {
                node.y0 = y1 / 2 + i;
                node.y1 = node.y0 + node.value * ky;
              } else if (node.circularLinkType == 'top') {
                node.y0 = y0 + i;
                node.y1 = node.y0 + node.value * ky;
              } else {
                node.y0 = y1 - node.value * ky - i;
                node.y1 = node.y0 + node.value * ky;
              }
            } else {
              if (margin.top == 0 || margin.bottom == 0) {
                node.y0 = (y1 - y0) / nodesLength * i;
                node.y1 = node.y0 + node.value * ky;
              } else {
                node.y0 = (y1 - y0) / 2 - nodesLength / 2 + i;
                node.y1 = node.y0 + node.value * ky;
              }
            }
          });
        });
      }
  
      // For each node in each column, check the node's vertical position in relation to its targets and sources vertical position
      // and shift up/down to be closer to the vertical middle of those targets and sources
      function relaxLeftAndRight(alpha, id) {
        var columnsLength = columns.length;
  
        columns.forEach(function (nodes) {
          var n = nodes.length;
          var depth = nodes[0].depth;
  
          nodes.forEach(function (node) {
            // check the node is not an orphan
            var nodeHeight;
            if (node.sourceLinks.length || node.targetLinks.length) {
              if (node.partOfCycle && numberOfNonSelfLinkingCycles(node, id) > 0) ; else if (depth == 0 && n == 1) {
                nodeHeight = node.y1 - node.y0;
  
                node.y0 = y1 / 2 - nodeHeight / 2;
                node.y1 = y1 / 2 + nodeHeight / 2;
              } else if (depth == columnsLength - 1 && n == 1) {
                nodeHeight = node.y1 - node.y0;
  
                node.y0 = y1 / 2 - nodeHeight / 2;
                node.y1 = y1 / 2 + nodeHeight / 2;
              } else {
                var avg = 0;
  
                var avgTargetY = mean(node.sourceLinks, linkTargetCenter);
                var avgSourceY = mean(node.targetLinks, linkSourceCenter);
  
                if (avgTargetY && avgSourceY) {
                  avg = (avgTargetY + avgSourceY) / 2;
                } else {
                  avg = avgTargetY || avgSourceY;
                }
  
                var dy = (avg - nodeCenter(node)) * alpha;
                // positive if it node needs to move down
                node.y0 += dy;
                node.y1 += dy;
              }
            }
          });
        });
      }
  
      // For each column, check if nodes are overlapping, and if so, shift up/down
      function resolveCollisions() {
        columns.forEach(function (nodes) {
          var node,
              dy,
              y = y0,
              n = nodes.length,
              i;
  
          // Push any overlapping nodes down.
          nodes.sort(ascendingBreadth);
  
          for (i = 0; i < n; ++i) {
            node = nodes[i];
            dy = y - node.y0;
  
            if (dy > 0) {
              node.y0 += dy;
              node.y1 += dy;
            }
            y = node.y1 + py;
          }
  
          // If the bottommost node goes outside the bounds, push it back up.
          dy = y - py - y1;
          if (dy > 0) {
            y = node.y0 -= dy, node.y1 -= dy;
  
            // Push any overlapping nodes back up.
            for (i = n - 2; i >= 0; --i) {
              node = nodes[i];
              dy = node.y1 + py - y;
              if (dy > 0) node.y0 -= dy, node.y1 -= dy;
              y = node.y0;
            }
          }
        });
      }
    }
func_documentation_string: Assign nodes' breadths, and then shift nodes that overlap (resolveCollisions)