| 
          /* Modified to work with d3.v4 build */ | 
        
        
           | 
          (function (global, factory) { | 
        
        
           | 
            typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-arrays'), require('d3-interpolate')) : | 
        
        
           | 
            typeof define === 'function' && define.amd ? define('d3-sankey', ['exports', 'd3-arrays', 'd3-interpolate'], factory) : | 
        
        
           | 
            factory((global.d3_sankey = {}),global.d3_arrays,global.d3_interpolate); | 
        
        
           | 
          }(this, function (exports,d3Arrays,d3Interpolate) { 'use strict'; | 
        
        
           | 
          
 | 
        
        
           | 
            // Stolen from https://github.com/d3/d3-plugins/tree/master/sankey | 
        
        
           | 
          
 | 
        
        
           | 
            function sankey() { | 
        
        
           | 
              var sankey = {}, | 
        
        
           | 
                nodeWidth = 24, | 
        
        
           | 
                nodePadding = 8, | 
        
        
           | 
                size = [1, 1], | 
        
        
           | 
                nodes = [], | 
        
        
           | 
                links = []; | 
        
        
           | 
          
 | 
        
        
           | 
              sankey.nodeWidth = function(_) { | 
        
        
           | 
                if (!arguments.length) return nodeWidth; | 
        
        
           | 
                nodeWidth = +_; | 
        
        
           | 
                return sankey; | 
        
        
           | 
              }; | 
        
        
           | 
          
 | 
        
        
           | 
              sankey.nodePadding = function(_) { | 
        
        
           | 
                if (!arguments.length) return nodePadding; | 
        
        
           | 
                nodePadding = +_; | 
        
        
           | 
                return sankey; | 
        
        
           | 
              }; | 
        
        
           | 
          
 | 
        
        
           | 
              sankey.nodes = function(_) { | 
        
        
           | 
                if (!arguments.length) return nodes; | 
        
        
           | 
                nodes = _; | 
        
        
           | 
                return sankey; | 
        
        
           | 
              }; | 
        
        
           | 
          
 | 
        
        
           | 
              sankey.links = function(_) { | 
        
        
           | 
                if (!arguments.length) return links; | 
        
        
           | 
                links = _; | 
        
        
           | 
                return sankey; | 
        
        
           | 
              }; | 
        
        
           | 
          
 | 
        
        
           | 
              sankey.size = function(_) { | 
        
        
           | 
                if (!arguments.length) return size; | 
        
        
           | 
                size = _; | 
        
        
           | 
                return sankey; | 
        
        
           | 
              }; | 
        
        
           | 
          
 | 
        
        
           | 
              sankey.layout = function(iterations) { | 
        
        
           | 
                computeNodeLinks(); | 
        
        
           | 
                computeNodeValues(); | 
        
        
           | 
                computeNodeBreadths(); | 
        
        
           | 
                computeNodeDepths(iterations); | 
        
        
           | 
                computeLinkDepths(); | 
        
        
           | 
                return sankey; | 
        
        
           | 
              }; | 
        
        
           | 
          
 | 
        
        
           | 
              sankey.relayout = function() { | 
        
        
           | 
                computeLinkDepths(); | 
        
        
           | 
                return sankey; | 
        
        
           | 
              }; | 
        
        
           | 
          
 | 
        
        
           | 
              sankey.link = function() { | 
        
        
           | 
                var curvature = .5; | 
        
        
           | 
          
 | 
        
        
           | 
                function link(d) { | 
        
        
           | 
                  var x0 = d.source.x + d.source.dx, | 
        
        
           | 
                    x1 = d.target.x, | 
        
        
           | 
                    xi = d3.interpolateNumber(x0, x1), | 
        
        
           | 
                    x2 = xi(curvature), | 
        
        
           | 
                    x3 = xi(1 - curvature), | 
        
        
           | 
                    y0 = d.source.y + d.sy + d.dy / 2, | 
        
        
           | 
                    y1 = d.target.y + d.ty + d.dy / 2; | 
        
        
           | 
                  return "M" + x0 + "," + y0 + "C" + x2 + "," + y0 + " " + x3 + "," + y1 + " " + x1 + "," + y1; | 
        
        
           | 
                } | 
        
        
           | 
          
 | 
        
        
           | 
                link.curvature = function(_) { | 
        
        
           | 
                  if (!arguments.length) return curvature; | 
        
        
           | 
                  curvature = +_; | 
        
        
           | 
                  return link; | 
        
        
           | 
                }; | 
        
        
           | 
          
 | 
        
        
           | 
                return link; | 
        
        
           | 
              }; | 
        
        
           | 
          
 | 
        
        
           | 
              // Populate the sourceLinks and targetLinks for each node. | 
        
        
           | 
              // Also, if the source and target are not objects, assume they are indices. | 
        
        
           | 
              function computeNodeLinks() { | 
        
        
           | 
                nodes.forEach(function(node) { | 
        
        
           | 
                  node.sourceLinks = []; | 
        
        
           | 
                  node.targetLinks = []; | 
        
        
           | 
                }); | 
        
        
           | 
                links.forEach(function(link) { | 
        
        
           | 
                  var source = link.source, | 
        
        
           | 
                    target = link.target; | 
        
        
           | 
                  if (typeof source === "number") source = link.source = nodes[link.source]; | 
        
        
           | 
                  if (typeof target === "number") target = link.target = nodes[link.target]; | 
        
        
           | 
                  source.sourceLinks.push(link); | 
        
        
           | 
                  target.targetLinks.push(link); | 
        
        
           | 
                }); | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              // Compute the value (size) of each node by summing the associated links. | 
        
        
           | 
              function computeNodeValues() { | 
        
        
           | 
                nodes.forEach(function(node) { | 
        
        
           | 
                  node.value = Math.max( | 
        
        
           | 
                    d3.sum(node.sourceLinks, value), | 
        
        
           | 
                    d3.sum(node.targetLinks, value) | 
        
        
           | 
                  ); | 
        
        
           | 
                }); | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              // Iteratively assign the breadth (x-position) for each node. | 
        
        
           | 
              // Nodes are assigned the maximum breadth of incoming neighbors plus one; | 
        
        
           | 
              // nodes with no incoming links are assigned breadth zero, while | 
        
        
           | 
              // nodes with no outgoing links are assigned the maximum breadth. | 
        
        
           | 
              function computeNodeBreadths() { | 
        
        
           | 
                var remainingNodes = nodes, | 
        
        
           | 
                  nextNodes, | 
        
        
           | 
                  x = 0; | 
        
        
           | 
          
 | 
        
        
           | 
                while (remainingNodes.length) { | 
        
        
           | 
                  nextNodes = []; | 
        
        
           | 
                  remainingNodes.forEach(function(node) { | 
        
        
           | 
                    node.x = x; | 
        
        
           | 
                    node.dx = nodeWidth; | 
        
        
           | 
                    node.sourceLinks.forEach(function(link) { | 
        
        
           | 
                      if (nextNodes.indexOf(link.target) < 0) { | 
        
        
           | 
                        nextNodes.push(link.target); | 
        
        
           | 
                      } | 
        
        
           | 
                    }); | 
        
        
           | 
                  }); | 
        
        
           | 
                  remainingNodes = nextNodes; | 
        
        
           | 
                  ++x; | 
        
        
           | 
                } | 
        
        
           | 
          
 | 
        
        
           | 
                // | 
        
        
           | 
                moveSinksRight(x); | 
        
        
           | 
                scaleNodeBreadths((size[0] - nodeWidth) / (x - 1)); | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              function moveSourcesRight() { | 
        
        
           | 
                nodes.forEach(function(node) { | 
        
        
           | 
                  if (!node.targetLinks.length) { | 
        
        
           | 
                    node.x = d3.min(node.sourceLinks, function(d) { | 
        
        
           | 
                      return d.target.x; | 
        
        
           | 
                    }) - 1; | 
        
        
           | 
                  } | 
        
        
           | 
                }); | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              function moveSinksRight(x) { | 
        
        
           | 
                nodes.forEach(function(node) { | 
        
        
           | 
                  if (!node.sourceLinks.length) { | 
        
        
           | 
                    node.x = x - 1; | 
        
        
           | 
                  } | 
        
        
           | 
                }); | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              function scaleNodeBreadths(kx) { | 
        
        
           | 
                nodes.forEach(function(node) { | 
        
        
           | 
                  node.x *= kx; | 
        
        
           | 
                }); | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              function computeNodeDepths(iterations) { | 
        
        
           | 
                var nodesByBreadth = d3.nest() | 
        
        
           | 
                  .key(function(d) { | 
        
        
           | 
                    return d.x; | 
        
        
           | 
                  }) | 
        
        
           | 
                  .sortKeys(d3.ascending) | 
        
        
           | 
                  .entries(nodes) | 
        
        
           | 
                  .map(function(d) { | 
        
        
           | 
                    return d.values; | 
        
        
           | 
                  }); | 
        
        
           | 
          
 | 
        
        
           | 
                // | 
        
        
           | 
                initializeNodeDepth(); | 
        
        
           | 
                resolveCollisions(); | 
        
        
           | 
                for (var alpha = 1; iterations > 0; --iterations) { | 
        
        
           | 
                  relaxRightToLeft(alpha *= .99); | 
        
        
           | 
                  resolveCollisions(); | 
        
        
           | 
                  relaxLeftToRight(alpha); | 
        
        
           | 
                  resolveCollisions(); | 
        
        
           | 
                } | 
        
        
           | 
          
 | 
        
        
           | 
                function initializeNodeDepth() { | 
        
        
           | 
                  var ky = d3.min(nodesByBreadth, function(nodes) { | 
        
        
           | 
                    return (size[1] - (nodes.length - 1) * nodePadding) / d3.sum(nodes, value); | 
        
        
           | 
                  }); | 
        
        
           | 
          
 | 
        
        
           | 
                  nodesByBreadth.forEach(function(nodes) { | 
        
        
           | 
                    nodes.forEach(function(node, i) { | 
        
        
           | 
                      node.y = i; | 
        
        
           | 
                      node.dy = node.value * ky; | 
        
        
           | 
                    }); | 
        
        
           | 
                  }); | 
        
        
           | 
          
 | 
        
        
           | 
                  links.forEach(function(link) { | 
        
        
           | 
                    link.dy = link.value * ky; | 
        
        
           | 
                  }); | 
        
        
           | 
                } | 
        
        
           | 
          
 | 
        
        
           | 
                function relaxLeftToRight(alpha) { | 
        
        
           | 
                  nodesByBreadth.forEach(function(nodes, breadth) { | 
        
        
           | 
                    nodes.forEach(function(node) { | 
        
        
           | 
                      if (node.targetLinks.length) { | 
        
        
           | 
                        var y = d3.sum(node.targetLinks, weightedSource) / d3.sum(node.targetLinks, value); | 
        
        
           | 
                        node.y += (y - center(node)) * alpha; | 
        
        
           | 
                      } | 
        
        
           | 
                    }); | 
        
        
           | 
                  }); | 
        
        
           | 
          
 | 
        
        
           | 
                  function weightedSource(link) { | 
        
        
           | 
                    return center(link.source) * link.value; | 
        
        
           | 
                  } | 
        
        
           | 
                } | 
        
        
           | 
          
 | 
        
        
           | 
                function relaxRightToLeft(alpha) { | 
        
        
           | 
                  nodesByBreadth.slice().reverse().forEach(function(nodes) { | 
        
        
           | 
                    nodes.forEach(function(node) { | 
        
        
           | 
                      if (node.sourceLinks.length) { | 
        
        
           | 
                        var y = d3.sum(node.sourceLinks, weightedTarget) / d3.sum(node.sourceLinks, value); | 
        
        
           | 
                        node.y += (y - center(node)) * alpha; | 
        
        
           | 
                      } | 
        
        
           | 
                    }); | 
        
        
           | 
                  }); | 
        
        
           | 
          
 | 
        
        
           | 
                  function weightedTarget(link) { | 
        
        
           | 
                    return center(link.target) * link.value; | 
        
        
           | 
                  } | 
        
        
           | 
                } | 
        
        
           | 
          
 | 
        
        
           | 
                function resolveCollisions() { | 
        
        
           | 
                  nodesByBreadth.forEach(function(nodes) { | 
        
        
           | 
                    var node, | 
        
        
           | 
                      dy, | 
        
        
           | 
                      y0 = 0, | 
        
        
           | 
                      n = nodes.length, | 
        
        
           | 
                      i; | 
        
        
           | 
          
 | 
        
        
           | 
                    // Push any overlapping nodes down. | 
        
        
           | 
                    nodes.sort(ascendingDepth); | 
        
        
           | 
                    for (i = 0; i < n; ++i) { | 
        
        
           | 
                      node = nodes[i]; | 
        
        
           | 
                      dy = y0 - node.y; | 
        
        
           | 
                      if (dy > 0) node.y += dy; | 
        
        
           | 
                      y0 = node.y + node.dy + nodePadding; | 
        
        
           | 
                    } | 
        
        
           | 
          
 | 
        
        
           | 
                    // If the bottommost node goes outside the bounds, push it back up. | 
        
        
           | 
                    dy = y0 - nodePadding - size[1]; | 
        
        
           | 
                    if (dy > 0) { | 
        
        
           | 
                      y0 = node.y -= dy; | 
        
        
           | 
          
 | 
        
        
           | 
                      // Push any overlapping nodes back up. | 
        
        
           | 
                      for (i = n - 2; i >= 0; --i) { | 
        
        
           | 
                        node = nodes[i]; | 
        
        
           | 
                        dy = node.y + node.dy + nodePadding - y0; | 
        
        
           | 
                        if (dy > 0) node.y -= dy; | 
        
        
           | 
                        y0 = node.y; | 
        
        
           | 
                      } | 
        
        
           | 
                    } | 
        
        
           | 
                  }); | 
        
        
           | 
                } | 
        
        
           | 
          
 | 
        
        
           | 
                function ascendingDepth(a, b) { | 
        
        
           | 
                  return a.y - b.y; | 
        
        
           | 
                } | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              function computeLinkDepths() { | 
        
        
           | 
                nodes.forEach(function(node) { | 
        
        
           | 
                  node.sourceLinks.sort(ascendingTargetDepth); | 
        
        
           | 
                  node.targetLinks.sort(ascendingSourceDepth); | 
        
        
           | 
                }); | 
        
        
           | 
                nodes.forEach(function(node) { | 
        
        
           | 
                  var sy = 0, | 
        
        
           | 
                    ty = 0; | 
        
        
           | 
                  node.sourceLinks.forEach(function(link) { | 
        
        
           | 
                    link.sy = sy; | 
        
        
           | 
                    sy += link.dy; | 
        
        
           | 
                  }); | 
        
        
           | 
                  node.targetLinks.forEach(function(link) { | 
        
        
           | 
                    link.ty = ty; | 
        
        
           | 
                    ty += link.dy; | 
        
        
           | 
                  }); | 
        
        
           | 
                }); | 
        
        
           | 
          
 | 
        
        
           | 
                function ascendingSourceDepth(a, b) { | 
        
        
           | 
                  return a.source.y - b.source.y; | 
        
        
           | 
                } | 
        
        
           | 
          
 | 
        
        
           | 
                function ascendingTargetDepth(a, b) { | 
        
        
           | 
                  return a.target.y - b.target.y; | 
        
        
           | 
                } | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              function center(node) { | 
        
        
           | 
                return node.y + node.dy / 2; | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              function value(link) { | 
        
        
           | 
                return link.value; | 
        
        
           | 
              } | 
        
        
           | 
          
 | 
        
        
           | 
              return sankey; | 
        
        
           | 
            }; | 
        
        
           | 
          
 | 
        
        
           | 
            var version = "0.2.0"; | 
        
        
           | 
          
 | 
        
        
           | 
            exports.version = version; | 
        
        
           | 
            exports.sankey = sankey; | 
        
        
           | 
          
 | 
        
        
           | 
          })); |