Socket
Socket
Sign inDemoInstall

d3-sankey

Package Overview
Dependencies
Maintainers
2
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

d3-sankey - npm Package Compare versions

Comparing version 0.6.1 to 0.7.0

img/align-center.png

121

build/d3-sankey.js

@@ -1,2 +0,2 @@

// https://github.com/d3/d3-sankey Version 0.6.1. Copyright 2017 Mike Bostock.
// https://github.com/d3/d3-sankey Version 0.7.0. Copyright 2017 Mike Bostock.
(function (global, factory) {

@@ -8,2 +8,24 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array'), require('d3-collection'), require('d3-shape')) :

function targetDepth(d) {
return d.target.depth;
}
function left(node) {
return node.depth;
}
function right(node, n) {
return n - 1 - node.height;
}
function justify(node, n) {
return node.sourceLinks.length ? node.depth : n - 1;
}
function center(node) {
return node.targetLinks.length ? node.depth
: node.sourceLinks.length ? d3Collection.min(node.sourceLinks, targetDepth) - 1
: 0;
}
function constant(x) {

@@ -43,2 +65,6 @@ return function() {

function defaultId(d) {
return d.index;
}
function defaultNodes(graph) {

@@ -52,2 +78,8 @@ return graph.nodes;

function find(nodeById, id) {
var node = nodeById.get(id);
if (!node) throw new Error("missing: " + id);
return node;
}
var sankey = function() {

@@ -57,2 +89,4 @@ var x0 = 0, y0 = 0, x1 = 1, y1 = 1, // extent

py = 8, // nodePadding
id = defaultId,
align = justify,
nodes = defaultNodes,

@@ -77,2 +111,10 @@ links = defaultLinks,

sankey.nodeId = function(_) {
return arguments.length ? (id = typeof _ === "function" ? _ : constant(_), sankey) : id;
};
sankey.nodeAlign = function(_) {
return arguments.length ? (align = typeof _ === "function" ? _ : constant(_), sankey) : align;
};
sankey.nodeWidth = function(_) {

@@ -114,7 +156,8 @@ return arguments.length ? (dx = +_, sankey) : dx;

});
var nodeById = d3Collection.map(graph.nodes, id);
graph.links.forEach(function(link, i) {
link.index = i;
var source = link.source, target = link.target;
if (typeof source === "number") source = link.source = graph.nodes[link.source];
if (typeof target === "number") target = link.target = graph.nodes[link.target];
link.index = i;
if (typeof source !== "object") source = link.source = find(nodeById, source);
if (typeof target !== "object") target = link.target = find(nodeById, target);
source.sourceLinks.push(link);

@@ -140,51 +183,35 @@ target.targetLinks.push(link);

function computeNodeDepths(graph) {
var remainingNodes = graph.nodes,
nextNodes,
depth = 0;
var nodes, next, x;
while (remainingNodes.length) {
nextNodes = [];
remainingNodes.forEach(function(node) {
node.depth = depth;
for (nodes = graph.nodes, next = [], x = 0; nodes.length; ++x, nodes = next, next = []) {
nodes.forEach(function(node) {
node.depth = x;
node.sourceLinks.forEach(function(link) {
if (nextNodes.indexOf(link.target) < 0) {
nextNodes.push(link.target);
if (next.indexOf(link.target) < 0) {
next.push(link.target);
}
});
});
remainingNodes = nextNodes;
++depth;
}
//
moveSinksRight(graph, depth);
scaleNodeDepths(graph, depth);
}
for (nodes = graph.nodes, next = [], x = 0; nodes.length; ++x, nodes = next, next = []) {
nodes.forEach(function(node) {
node.height = x;
node.targetLinks.forEach(function(link) {
if (next.indexOf(link.source) < 0) {
next.push(link.source);
}
});
});
}
// function moveSourcesRight(graph) {
// graph.nodes.forEach(function(node) {
// if (!node.targetLinks.length) {
// node.depth = min(node.sourceLinks, function(d) { return d.target.depth; }) - 1;
// }
// });
// }
function moveSinksRight(graph, depth) {
var kx = (x1 - x0 - dx) / (x - 1);
graph.nodes.forEach(function(node) {
if (!node.sourceLinks.length) {
node.depth = depth - 1;
}
node.x1 = (node.x0 = x0 + Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x)))) * kx) + dx;
});
}
function scaleNodeDepths(graph, depth) {
var kx = (x1 - x0 - dx) / (depth - 1);
graph.nodes.forEach(function(node) {
node.x1 = (node.x0 = x0 + node.depth * kx) + dx;
});
}
function computeNodeBreadths(graph) {
var nodesByDepth = d3Collection.nest()
.key(function(d) { return d.depth; })
var columns = d3Collection.nest()
.key(function(d) { return d.x0; })
.sortKeys(d3Array.ascending)

@@ -205,7 +232,7 @@ .entries(graph.nodes)

function initializeNodeBreadth() {
var ky = d3Array.min(nodesByDepth, function(nodes) {
var ky = d3Array.min(columns, function(nodes) {
return (y1 - y0 - (nodes.length - 1) * py) / d3Array.sum(nodes, value);
});
nodesByDepth.forEach(function(nodes) {
columns.forEach(function(nodes) {
nodes.forEach(function(node, i) {

@@ -222,3 +249,3 @@ node.y1 = (node.y0 = i) + node.value * ky;

function relaxLeftToRight(alpha) {
nodesByDepth.forEach(function(nodes) {
columns.forEach(function(nodes) {
nodes.forEach(function(node) {

@@ -234,3 +261,3 @@ if (node.targetLinks.length) {

function relaxRightToLeft(alpha) {
nodesByDepth.slice().reverse().forEach(function(nodes) {
columns.slice().reverse().forEach(function(nodes) {
nodes.forEach(function(node) {

@@ -246,3 +273,3 @@ if (node.sourceLinks.length) {

function resolveCollisions() {
nodesByDepth.forEach(function(nodes) {
columns.forEach(function(nodes) {
var node,

@@ -314,2 +341,6 @@ dy,

exports.sankey = sankey;
exports.sankeyCenter = center;
exports.sankeyLeft = left;
exports.sankeyRight = right;
exports.sankeyJustify = justify;
exports.sankeyLinkHorizontal = sankeyLinkHorizontal;

@@ -316,0 +347,0 @@

@@ -1,2 +0,2 @@

// https://github.com/d3/d3-sankey Version 0.6.1. Copyright 2017 Mike Bostock.
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-array"),require("d3-collection"),require("d3-shape")):"function"==typeof define&&define.amd?define(["exports","d3-array","d3-collection","d3-shape"],t):t(n.d3=n.d3||{},n.d3,n.d3,n.d3)}(this,function(n,t,e,r){"use strict";function o(n){return function(){return n}}function u(n,t){return c(n.source,t.source)||n.index-t.index}function i(n,t){return c(n.target,t.target)||n.index-t.index}function c(n,t){return n.y0-t.y0}function f(n){return n.value}function s(n){return(n.y0+n.y1)/2}function a(n){return s(n.source)*n.value}function d(n){return s(n.target)*n.value}function h(n){return n.nodes}function l(n){return n.links}function y(n){return[n.source.x1,n.y0]}function g(n){return[n.target.x0,n.y1]}var k=function(){function n(){var n={nodes:z.apply(null,arguments),links:j.apply(null,arguments)};return r(n),y(n),g(n),v(n),E(n),n}function r(n){n.nodes.forEach(function(n,t){n.index=t,n.sourceLinks=[],n.targetLinks=[]}),n.links.forEach(function(t,e){var r=t.source,o=t.target;"number"==typeof r&&(r=t.source=n.nodes[t.source]),"number"==typeof o&&(o=t.target=n.nodes[t.target]),t.index=e,r.sourceLinks.push(t),o.targetLinks.push(t)})}function y(n){n.nodes.forEach(function(n){n.value=Math.max(t.sum(n.sourceLinks,f),t.sum(n.targetLinks,f))})}function g(n){for(var t,e=n.nodes,r=0;e.length;)t=[],e.forEach(function(n){n.depth=r,n.sourceLinks.forEach(function(n){t.indexOf(n.target)<0&&t.push(n.target)})}),e=t,++r;k(n,r),p(n,r)}function k(n,t){n.nodes.forEach(function(n){n.sourceLinks.length||(n.depth=t-1)})}function p(n,t){var e=(m-L-b)/(t-1);n.nodes.forEach(function(n){n.x1=(n.x0=L+n.depth*e)+b})}function v(n){function r(){o.forEach(function(n){var t,e,r,o=x,u=n.length;for(n.sort(c),r=0;r<u;++r)(e=o-(t=n[r]).y0)>0&&(t.y0+=e,t.y1+=e),o=t.y1+q;if((e=o-q-w)>0)for(o=t.y0-=e,t.y1-=e,r=u-2;r>=0;--r)(e=(t=n[r]).y1+q-o)>0&&(t.y0-=e,t.y1-=e),o=t.y0})}var o=e.nest().key(function(n){return n.depth}).sortKeys(t.ascending).entries(n.nodes).map(function(n){return n.values});!function(){var e=t.min(o,function(n){return(w-x-(n.length-1)*q)/t.sum(n,f)});o.forEach(function(n){n.forEach(function(n,t){n.y1=(n.y0=t)+n.value*e})}),n.links.forEach(function(n){n.width=n.value*e})}(),r();for(var u=1,i=H;i>0;--i)!function(n){o.slice().reverse().forEach(function(e){e.forEach(function(e){if(e.sourceLinks.length){var r=(t.sum(e.sourceLinks,d)/t.sum(e.sourceLinks,f)-s(e))*n;e.y0+=r,e.y1+=r}})})}(u*=.99),r(),function(n){o.forEach(function(e){e.forEach(function(e){if(e.targetLinks.length){var r=(t.sum(e.targetLinks,a)/t.sum(e.targetLinks,f)-s(e))*n;e.y0+=r,e.y1+=r}})})}(u),r()}function E(n){n.nodes.forEach(function(n){n.sourceLinks.sort(i),n.targetLinks.sort(u)}),n.nodes.forEach(function(n){var t=n.y0,e=t;n.sourceLinks.forEach(function(n){n.y0=t+n.width/2,t+=n.width}),n.targetLinks.forEach(function(n){n.y1=e+n.width/2,e+=n.width})})}var L=0,x=0,m=1,w=1,b=24,q=8,z=h,j=l,H=32;return n.update=function(n){return E(n),n},n.nodeWidth=function(t){return arguments.length?(b=+t,n):b},n.nodePadding=function(t){return arguments.length?(q=+t,n):q},n.nodes=function(t){return arguments.length?(z="function"==typeof t?t:o(t),n):z},n.links=function(t){return arguments.length?(j="function"==typeof t?t:o(t),n):j},n.size=function(t){return arguments.length?(L=x=0,m=+t[0],w=+t[1],n):[m-L,w-x]},n.extent=function(t){return arguments.length?(L=+t[0][0],m=+t[1][0],x=+t[0][1],w=+t[1][1],n):[[L,x],[m,w]]},n.iterations=function(t){return arguments.length?(H=+t,n):H},n},p=function(){return r.linkHorizontal().source(y).target(g)};n.sankey=k,n.sankeyLinkHorizontal=p,Object.defineProperty(n,"__esModule",{value:!0})});
// https://github.com/d3/d3-sankey Version 0.7.0. Copyright 2017 Mike Bostock.
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-array"),require("d3-collection"),require("d3-shape")):"function"==typeof define&&define.amd?define(["exports","d3-array","d3-collection","d3-shape"],t):t(n.d3=n.d3||{},n.d3,n.d3,n.d3)}(this,function(n,t,e,r){"use strict";function o(n){return n.target.depth}function u(n){return n.depth}function i(n,t){return t-1-n.height}function c(n,t){return n.sourceLinks.length?n.depth:t-1}function f(n){return n.targetLinks.length?n.depth:n.sourceLinks.length?e.min(n.sourceLinks,o)-1:0}function s(n){return function(){return n}}function a(n,t){return d(n.source,t.source)||n.index-t.index}function h(n,t){return d(n.target,t.target)||n.index-t.index}function d(n,t){return n.y0-t.y0}function l(n){return n.value}function y(n){return(n.y0+n.y1)/2}function g(n){return y(n.source)*n.value}function k(n){return y(n.target)*n.value}function p(n){return n.index}function v(n){return n.nodes}function L(n){return n.links}function E(n,t){var e=n.get(t);if(!e)throw new Error("missing: "+t);return e}function x(n){return[n.source.x1,n.y0]}function m(n){return[n.target.x0,n.y1]}var w=function(){function n(){var n={nodes:O.apply(null,arguments),links:H.apply(null,arguments)};return r(n),o(n),u(n),i(n),f(n),n}function r(n){n.nodes.forEach(function(n,t){n.index=t,n.sourceLinks=[],n.targetLinks=[]});var t=e.map(n.nodes,q);n.links.forEach(function(n,e){n.index=e;var r=n.source,o=n.target;"object"!=typeof r&&(r=n.source=E(t,r)),"object"!=typeof o&&(o=n.target=E(t,o)),r.sourceLinks.push(n),o.targetLinks.push(n)})}function o(n){n.nodes.forEach(function(n){n.value=Math.max(t.sum(n.sourceLinks,l),t.sum(n.targetLinks,l))})}function u(n){var t,e,r;for(t=n.nodes,e=[],r=0;t.length;++r,t=e,e=[])t.forEach(function(n){n.depth=r,n.sourceLinks.forEach(function(n){e.indexOf(n.target)<0&&e.push(n.target)})});for(t=n.nodes,e=[],r=0;t.length;++r,t=e,e=[])t.forEach(function(n){n.height=r,n.targetLinks.forEach(function(n){e.indexOf(n.source)<0&&e.push(n.source)})});var o=(w-x-b)/(r-1);n.nodes.forEach(function(n){n.x1=(n.x0=x+Math.max(0,Math.min(r-1,Math.floor(z.call(null,n,r))))*o)+b})}function i(n){function r(){o.forEach(function(n){var t,e,r,o=m,u=n.length;for(n.sort(d),r=0;r<u;++r)(e=o-(t=n[r]).y0)>0&&(t.y0+=e,t.y1+=e),o=t.y1+j;if((e=o-j-M)>0)for(o=t.y0-=e,t.y1-=e,r=u-2;r>=0;--r)(e=(t=n[r]).y1+j-o)>0&&(t.y0-=e,t.y1-=e),o=t.y0})}var o=e.nest().key(function(n){return n.x0}).sortKeys(t.ascending).entries(n.nodes).map(function(n){return n.values});!function(){var e=t.min(o,function(n){return(M-m-(n.length-1)*j)/t.sum(n,l)});o.forEach(function(n){n.forEach(function(n,t){n.y1=(n.y0=t)+n.value*e})}),n.links.forEach(function(n){n.width=n.value*e})}(),r();for(var u=1,i=P;i>0;--i)!function(n){o.slice().reverse().forEach(function(e){e.forEach(function(e){if(e.sourceLinks.length){var r=(t.sum(e.sourceLinks,k)/t.sum(e.sourceLinks,l)-y(e))*n;e.y0+=r,e.y1+=r}})})}(u*=.99),r(),function(n){o.forEach(function(e){e.forEach(function(e){if(e.targetLinks.length){var r=(t.sum(e.targetLinks,g)/t.sum(e.targetLinks,l)-y(e))*n;e.y0+=r,e.y1+=r}})})}(u),r()}function f(n){n.nodes.forEach(function(n){n.sourceLinks.sort(h),n.targetLinks.sort(a)}),n.nodes.forEach(function(n){var t=n.y0,e=t;n.sourceLinks.forEach(function(n){n.y0=t+n.width/2,t+=n.width}),n.targetLinks.forEach(function(n){n.y1=e+n.width/2,e+=n.width})})}var x=0,m=0,w=1,M=1,b=24,j=8,q=p,z=c,O=v,H=L,P=32;return n.update=function(n){return f(n),n},n.nodeId=function(t){return arguments.length?(q="function"==typeof t?t:s(t),n):q},n.nodeAlign=function(t){return arguments.length?(z="function"==typeof t?t:s(t),n):z},n.nodeWidth=function(t){return arguments.length?(b=+t,n):b},n.nodePadding=function(t){return arguments.length?(j=+t,n):j},n.nodes=function(t){return arguments.length?(O="function"==typeof t?t:s(t),n):O},n.links=function(t){return arguments.length?(H="function"==typeof t?t:s(t),n):H},n.size=function(t){return arguments.length?(x=m=0,w=+t[0],M=+t[1],n):[w-x,M-m]},n.extent=function(t){return arguments.length?(x=+t[0][0],w=+t[1][0],m=+t[0][1],M=+t[1][1],n):[[x,m],[w,M]]},n.iterations=function(t){return arguments.length?(P=+t,n):P},n},M=function(){return r.linkHorizontal().source(x).target(m)};n.sankey=w,n.sankeyCenter=f,n.sankeyLeft=u,n.sankeyRight=i,n.sankeyJustify=c,n.sankeyLinkHorizontal=M,Object.defineProperty(n,"__esModule",{value:!0})});
export {default as sankey} from "./src/sankey";
export {center as sankeyCenter, left as sankeyLeft, right as sankeyRight, justify as sankeyJustify} from "./src/align";
export {default as sankeyLinkHorizontal} from "./src/sankeyLinkHorizontal";
{
"name": "d3-sankey",
"version": "0.6.1",
"version": "0.7.0",
"description": "Visualize flow between nodes in a directed acyclic network.",

@@ -37,3 +37,3 @@ "keywords": [

"package-preamble": "0.1.0",
"rollup": "0.42",
"rollup": "0.43",
"tape": "4",

@@ -40,0 +40,0 @@ "uglify-js": "3"

@@ -11,6 +11,4 @@ # d3-sankey

If you use NPM, `npm install d3-sankey`. Otherwise, download the [latest release](https://github.com/d3/d3-sankey/releases/latest).
If you use NPM, `npm install d3-sankey`. Otherwise, download the [latest release](https://github.com/d3/d3-sankey/releases/latest). You can also load directly from [unpkg.com](https://unpkg.com/d3-sankey/). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3` global is exported:
You can also load directly from unpkg.
```html

@@ -31,7 +29,7 @@ <script src="https://unpkg.com/d3-array@1"></script>

<a href="#sankey" name="sankey">#</a> d3.<b>sankey</b>() [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L41 "Source")
<a href="#sankey" name="sankey">#</a> d3.<b>sankey</b>() [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L52 "Source")
Constructs a new Sankey generator with the default settings.
<a href="#_sankey" name="_sankey">#</a> <i>sankey</i>(<i>arguments</i>…) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L49 "Source")
<a href="#_sankey" name="_sankey">#</a> <i>sankey</i>(<i>arguments</i>…) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L62 "Source")

@@ -43,3 +41,3 @@ Computes the node and link positions for the given *arguments*, returning a *graph* representing the Sankey layout. The returned *graph* has the following properties:

<a href="#sankey_update" name="sankey_update">#</a> <i>sankey</i>.<b>update</b>(<i>graph</i>) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L59 "Source")
<a href="#sankey_update" name="sankey_update">#</a> <i>sankey</i>.<b>update</b>(<i>graph</i>) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L72 "Source")

@@ -53,3 +51,3 @@ Recomputes the specified *graph*’s links’ positions, updating the following properties of each *link*:

<a name="sankey_nodes" href="#sankey_nodes">#</a> <i>sankey</i>.<b>nodes</b>([<i>nodes</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L72 "Source")
<a name="sankey_nodes" href="#sankey_nodes">#</a> <i>sankey</i>.<b>nodes</b>([<i>nodes</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L93 "Source")

@@ -73,2 +71,3 @@ If *nodes* is specified, sets the Sankey generator’s nodes accessor to the specified function or array and returns this Sankey generator. If *nodes* is not specified, returns the current nodes accessor, which defaults to:

* *node*.depth - the node’s zero-based graph depth, derived from the graph topology
* *node*.height - the node’s zero-based graph height, derived from the graph topology
* *node*.x0 - the node’s minimum horizontal position, derived from *node*.depth

@@ -81,3 +80,3 @@ * *node*.x1 - the node’s maximum horizontal position (*node*.x0 + [*sankey*.nodeWidth](#sankey_nodeWidth))

<a name="sankey_links" href="#sankey_links">#</a> <i>sankey</i>.<b>links</b>([<i>links</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L76 "Source")
<a name="sankey_links" href="#sankey_links">#</a> <i>sankey</i>.<b>links</b>([<i>links</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L97 "Source")

@@ -100,3 +99,3 @@ If *links* is specified, sets the Sankey generator’s links accessor to the specified function or array and returns this Sankey generator. If *links* is not specified, returns the current links accessor, which defaults to:

For convenience, a link’s source and target may be initialized using the zero-based index of corresponding node in the array of nodes returned by the [nodes accessor](#sankey_nodes) of the [Sankey generator](#_sankey) rather than object references. The following properties are assigned to each link by the [Sankey generator](#_sankey):
For convenience, a link’s source and target may be initialized using numeric or string identifiers rather than object references; ; see [*sankey*.nodeId](#sankey_nodeId). The following properties are assigned to each link by the [Sankey generator](#_sankey):

@@ -108,15 +107,69 @@ * *link*.y0 - the link’s vertical starting position (at source node)

<a name="sankey_nodeWidth" href="#sankey_nodeWidth">#</a> <i>sankey</i>.<b>nodeWidth</b>([<i>width</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L64 "Source")
<a name="sankey_nodeId" href="#sankey_nodeId">#</a> <i>sankey</i>.<b>nodeId</b>([<i>id</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L77 "Source")
If *id* is specified, sets the node id accessor to the specified function and returns this Sankey generator. If *id* is not specified, returns the current node id accessor, which defaults to the numeric *node*.index:
```js
function id(d) {
return d.index;
}
```
The default id accessor allows each link’s source and target to be specified as a zero-based index into the [nodes](#sankey_nodes) array. For example:
```js
var nodes = [
{"id": "Alice"},
{"id": "Bob"},
{"id": "Carol"}
];
var links = [
{"source": 0, "target": 1}, // Alice → Bob
{"source": 1, "target": 2} // Bob → Carol
];
```
Now consider a different id accessor that returns a string:
```js
function id(d) {
return d.id;
}
```
With this accessor, you can use named sources and targets:
```js
var nodes = [
{"id": "Alice"},
{"id": "Bob"},
{"id": "Carol"}
];
var links = [
{"source": "Alice", "target": "Bob"},
{"source": "Bob", "target": "Carol"}
];
```
This is particularly useful when representing graphs in JSON, as JSON does not allow references. See [this example](https://bl.ocks.org/mbostock/f584aa36df54c451c94a9d0798caed35).
<a name="sankey_nodeAlign" href="#sankey_nodeAlign">#</a> <i>sankey</i>.<b>nodeAlign</b>([<i>align</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L81 "Source")
If *align* is specified, sets the node [alignment method](#alignments) the specified function and returns this Sankey generator. If *align* is not specified, returns the current node alignment method, which defaults to [d3.sankeyLeft](#sankeyLeft). The specified function is evaluated for each input *node* in order, being passed the current *node* and the total depth *n* of the graph (one plus the maximum *node*.depth), and must return an integer between 0 and *n* - 1 that indicates the desired horizontal position of the node in the generated Sankey diagram.
<a name="sankey_nodeWidth" href="#sankey_nodeWidth">#</a> <i>sankey</i>.<b>nodeWidth</b>([<i>width</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L85 "Source")
If *width* is specified, sets the node width to the specified number and returns this Sankey generator. If *width* is not specified, returns the current node width, which defaults to 24.
<a name="sankey_nodePadding" href="#sankey_nodePadding">#</a> <i>sankey</i>.<b>nodePadding</b>([<i>padding</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L68 "Source")
<a name="sankey_nodePadding" href="#sankey_nodePadding">#</a> <i>sankey</i>.<b>nodePadding</b>([<i>padding</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L89 "Source")
If *padding* is specified, sets the vertical separation between nodes at each column to the specified number and returns this Sankey generator. If *padding* is not specified, returns the current node padding, which defaults to 8.
<a name="sankey_extent" href="#sankey_extent">#</a> <i>sankey</i>.<b>extent</b>([<i>extent</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L84 "Source")
<a name="sankey_extent" href="#sankey_extent">#</a> <i>sankey</i>.<b>extent</b>([<i>extent</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L105 "Source")
If *extent* is specified, sets the extent of the Sankey layout to the specified bounds and returns the layout. The *extent* bounds are specified as an array \[\[<i>x0</i>, <i>y0</i>\], \[<i>x1</i>, <i>y1</i>\]\], where *x0* is the left side of the extent, *y0* is the top, *x1* is the right and *y1* is the bottom. If *extent* is not specified, returns the current extent which defaults to [[0, 0], [1, 1]].
<a name="sankey_size" href="#sankey_size">#</a> <i>sankey</i>.<b>size</b>([<i>size</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L80 "Source")
<a name="sankey_size" href="#sankey_size">#</a> <i>sankey</i>.<b>size</b>([<i>size</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L101 "Source")

@@ -129,6 +182,34 @@ An alias for [*sankey*.extent](#sankey_extent) where the minimum *x* and *y* of the extent are ⟨0,0⟩. Equivalent to:

<a name="sankey_iterations" href="#sankey_iterations">#</a> <i>sankey</i>.<b>iterations</b>([<i>iterations</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L88 "Source")
<a name="sankey_iterations" href="#sankey_iterations">#</a> <i>sankey</i>.<b>iterations</b>([<i>iterations</i>]) [<>](https://github.com/d3/d3-sankey/blob/master/src/sankey.js#L109 "Source")
If *iterations* is specified, sets the number of relaxation iterations when [generating the layout](#_sankey) and returns this Sankey generator. If *iterations* is not specified, returns the current number of relaxation iterations, which defaults to 32.
### Alignments
See [*sankey*.nodeAlign](#sankey_nodeAlign).
<a name="sankeyLeft" href="#sankeyLeft">#</a> d3.<b>sankeyLeft</b>(<i>node</i>, <i>n</i>) [<>](https://github.com/d3/d3-sankey/blob/master/src/align.js#L7 "Source")
<img alt="left" src="https://raw.githubusercontent.com/d3/d3-sankey/master/img/align-left.png" width="480">
Returns *node*.depth.
<a name="sankeyRight" href="#sankeyRight">#</a> d3.<b>sankeyRight</b>(<i>node</i>, <i>n</i>) [<>](https://github.com/d3/d3-sankey/blob/master/src/align.js#L11 "Source")
<img alt="right" src="https://raw.githubusercontent.com/d3/d3-sankey/master/img/align-right.png" width="480">
Returns *n* - 1 - *node*.height.
<a name="sankeyCenter" href="#sankeyCenter">#</a> d3.<b>sankeyCenter</b>(<i>node</i>, <i>n</i>) [<>](https://github.com/d3/d3-sankey/blob/master/src/align.js#L19 "Source")
<img alt="center" src="https://raw.githubusercontent.com/d3/d3-sankey/master/img/align-center.png" width="480">
Like [d3.sankeyLeft](#sankeyLeft), except that nodes without any incoming links are moved as right as possible.
<a name="sankeyJustify" href="#sankeyJustify">#</a> d3.<b>sankeyJustify</b>(<i>node</i>, <i>n</i>) [<>](https://github.com/d3/d3-sankey/blob/master/src/align.js#L15 "Source")
<img alt="justify" src="https://raw.githubusercontent.com/d3/d3-sankey/master/img/energy.png" width="480">
Like [d3.sankeyLeft](#sankeyLeft), except that nodes without any outgoing links are moved to the far right.
### Links

@@ -135,0 +216,0 @@

import {ascending, min, sum} from "d3-array";
import {nest} from "d3-collection";
import {map, nest} from "d3-collection";
import {justify} from "./align";
import constant from "./constant";

@@ -33,2 +34,6 @@

function defaultId(d) {
return d.index;
}
function defaultNodes(graph) {

@@ -42,2 +47,8 @@ return graph.nodes;

function find(nodeById, id) {
var node = nodeById.get(id);
if (!node) throw new Error("missing: " + id);
return node;
}
export default function() {

@@ -47,2 +58,4 @@ var x0 = 0, y0 = 0, x1 = 1, y1 = 1, // extent

py = 8, // nodePadding
id = defaultId,
align = justify,
nodes = defaultNodes,

@@ -67,2 +80,10 @@ links = defaultLinks,

sankey.nodeId = function(_) {
return arguments.length ? (id = typeof _ === "function" ? _ : constant(_), sankey) : id;
};
sankey.nodeAlign = function(_) {
return arguments.length ? (align = typeof _ === "function" ? _ : constant(_), sankey) : align;
};
sankey.nodeWidth = function(_) {

@@ -104,7 +125,8 @@ return arguments.length ? (dx = +_, sankey) : dx;

});
var nodeById = map(graph.nodes, id);
graph.links.forEach(function(link, i) {
link.index = i;
var source = link.source, target = link.target;
if (typeof source === "number") source = link.source = graph.nodes[link.source];
if (typeof target === "number") target = link.target = graph.nodes[link.target];
link.index = i;
if (typeof source !== "object") source = link.source = find(nodeById, source);
if (typeof target !== "object") target = link.target = find(nodeById, target);
source.sourceLinks.push(link);

@@ -130,51 +152,35 @@ target.targetLinks.push(link);

function computeNodeDepths(graph) {
var remainingNodes = graph.nodes,
nextNodes,
depth = 0;
var nodes, next, x;
while (remainingNodes.length) {
nextNodes = [];
remainingNodes.forEach(function(node) {
node.depth = depth;
for (nodes = graph.nodes, next = [], x = 0; nodes.length; ++x, nodes = next, next = []) {
nodes.forEach(function(node) {
node.depth = x;
node.sourceLinks.forEach(function(link) {
if (nextNodes.indexOf(link.target) < 0) {
nextNodes.push(link.target);
if (next.indexOf(link.target) < 0) {
next.push(link.target);
}
});
});
remainingNodes = nextNodes;
++depth;
}
//
moveSinksRight(graph, depth);
scaleNodeDepths(graph, depth);
}
for (nodes = graph.nodes, next = [], x = 0; nodes.length; ++x, nodes = next, next = []) {
nodes.forEach(function(node) {
node.height = x;
node.targetLinks.forEach(function(link) {
if (next.indexOf(link.source) < 0) {
next.push(link.source);
}
});
});
}
// function moveSourcesRight(graph) {
// graph.nodes.forEach(function(node) {
// if (!node.targetLinks.length) {
// node.depth = min(node.sourceLinks, function(d) { return d.target.depth; }) - 1;
// }
// });
// }
function moveSinksRight(graph, depth) {
var kx = (x1 - x0 - dx) / (x - 1);
graph.nodes.forEach(function(node) {
if (!node.sourceLinks.length) {
node.depth = depth - 1;
}
node.x1 = (node.x0 = x0 + Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x)))) * kx) + dx;
});
}
function scaleNodeDepths(graph, depth) {
var kx = (x1 - x0 - dx) / (depth - 1);
graph.nodes.forEach(function(node) {
node.x1 = (node.x0 = x0 + node.depth * kx) + dx;
});
}
function computeNodeBreadths(graph) {
var nodesByDepth = nest()
.key(function(d) { return d.depth; })
var columns = nest()
.key(function(d) { return d.x0; })
.sortKeys(ascending)

@@ -195,7 +201,7 @@ .entries(graph.nodes)

function initializeNodeBreadth() {
var ky = min(nodesByDepth, function(nodes) {
var ky = min(columns, function(nodes) {
return (y1 - y0 - (nodes.length - 1) * py) / sum(nodes, value);
});
nodesByDepth.forEach(function(nodes) {
columns.forEach(function(nodes) {
nodes.forEach(function(node, i) {

@@ -212,3 +218,3 @@ node.y1 = (node.y0 = i) + node.value * ky;

function relaxLeftToRight(alpha) {
nodesByDepth.forEach(function(nodes) {
columns.forEach(function(nodes) {
nodes.forEach(function(node) {

@@ -224,3 +230,3 @@ if (node.targetLinks.length) {

function relaxRightToLeft(alpha) {
nodesByDepth.slice().reverse().forEach(function(nodes) {
columns.slice().reverse().forEach(function(nodes) {
nodes.forEach(function(node) {

@@ -236,3 +242,3 @@ if (node.sourceLinks.length) {

function resolveCollisions() {
nodesByDepth.forEach(function(nodes) {
columns.forEach(function(nodes) {
var node,

@@ -239,0 +245,0 @@ dy,

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc