Skip to content

Commit bde2a79

Browse files
committed
refactor d3-sankey to look more similar to upstream
1 parent fd19907 commit bde2a79

File tree

1 file changed

+54
-46
lines changed

1 file changed

+54
-46
lines changed

src/traces/sankey/d3-sankey.js

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,54 @@ var max = d3array.max;
5252
var nest = require('d3-collection').nest;
5353
var interpolateNumber = require('d3-interpolate').interpolateNumber;
5454

55+
// sort links' breadth (ie top to bottom in a column), based on their source nodes' breadths
56+
function ascendingSourceDepth(a, b) {
57+
return ascendingBreadth(a.source, b.source) || (a.originalIndex - b.originalIndex);
58+
}
59+
60+
// sort links' breadth (ie top to bottom in a column), based on their target nodes' breadths
61+
function ascendingTargetDepth(a, b) {
62+
return ascendingBreadth(a.target, b.target) || (a.originalIndex - b.originalIndex);
63+
}
64+
65+
function ascendingBreadth(a, b) {
66+
return a.y - b.y;
67+
}
68+
69+
function value(d) {
70+
return d.value;
71+
}
72+
73+
function nodeCenter(node) {
74+
return node.y + node.dy / 2;
75+
}
76+
77+
function weightedSource(link) {
78+
return nodeCenter(link.source) * link.value;
79+
}
80+
81+
function weightedTarget(link) {
82+
return nodeCenter(link.target) * link.value;
83+
}
84+
5585
module.exports = function() {
5686
var sankey = {},
57-
nodeWidth = 24,
58-
nodePadding = 8,
87+
dx = 24, // nodeWidth
88+
py = 8, // nodePadding
5989
size = [1, 1],
6090
nodes = [],
6191
links = [],
6292
maxPaddedSpace = 2 / 3; // Defined as a fraction of the total available space
6393

6494
sankey.nodeWidth = function(_) {
65-
if(!arguments.length) return nodeWidth;
66-
nodeWidth = +_;
95+
if(!arguments.length) return dx;
96+
dx = +_;
6797
return sankey;
6898
};
6999

70100
sankey.nodePadding = function(_) {
71-
if(!arguments.length) return nodePadding;
72-
nodePadding = +_;
101+
if(!arguments.length) return py;
102+
py = +_;
73103
return sankey;
74104
};
75105

@@ -94,14 +124,14 @@ module.exports = function() {
94124
sankey.layout = function(iterations) {
95125
computeNodeLinks();
96126
computeNodeValues();
97-
computeNodeBreadths();
98-
computeNodeDepths(iterations);
99-
computeLinkDepths();
127+
computeNodeDepths();
128+
computeNodeBreadths(iterations);
129+
computeLinkBreadths();
100130
return sankey;
101131
};
102132

103133
sankey.relayout = function() {
104-
computeLinkDepths();
134+
computeLinkBreadths();
105135
return sankey;
106136
};
107137

@@ -170,14 +200,15 @@ module.exports = function() {
170200
// Nodes are assigned the maximum breadth of incoming neighbors plus one;
171201
// nodes with no incoming links are assigned breadth zero, while
172202
// nodes with no outgoing links are assigned the maximum breadth.
173-
function computeNodeBreadths() {
203+
function computeNodeDepths() {
174204
var remainingNodes = nodes,
175205
nextNodes,
176206
x = 0;
177207

178208
function processNode(node) {
209+
node.depth = x;
179210
node.x = x;
180-
node.dx = nodeWidth;
211+
node.dx = dx;
181212
node.sourceLinks.forEach(function(link) {
182213
if(nextNodes.indexOf(link.target) < 0) {
183214
nextNodes.push(link.target);
@@ -194,7 +225,7 @@ module.exports = function() {
194225

195226
//
196227
moveSinksRight(x);
197-
scaleNodeBreadths((size[0] - nodeWidth) / (x - 1));
228+
scaleNodeBreadths((size[0] - dx) / (x - 1));
198229
}
199230

200231
// function moveSourcesRight() {
@@ -208,6 +239,7 @@ module.exports = function() {
208239
function moveSinksRight(x) {
209240
nodes.forEach(function(node) {
210241
if(!node.sourceLinks.length) {
242+
node.depth = x - 1;
211243
node.x = x - 1;
212244
}
213245
});
@@ -219,7 +251,7 @@ module.exports = function() {
219251
});
220252
}
221253

222-
function computeNodeDepths(iterations) {
254+
function computeNodeBreadths(iterations) {
223255
var nodesByBreadth = nest()
224256
.key(function(d) { return d.x; })
225257
.sortKeys(ascending)
@@ -241,9 +273,9 @@ module.exports = function() {
241273
return nodes.length;
242274
});
243275
var maxNodePadding = maxPaddedSpace * size[1] / (L - 1);
244-
if(nodePadding > maxNodePadding) nodePadding = maxNodePadding;
276+
if(py > maxNodePadding) py = maxNodePadding;
245277
var ky = min(nodesByBreadth, function(nodes) {
246-
return (size[1] - (nodes.length - 1) * nodePadding) / sum(nodes, value);
278+
return (size[1] - (nodes.length - 1) * py) / sum(nodes, value);
247279
});
248280

249281
nodesByBreadth.forEach(function(nodes) {
@@ -263,29 +295,21 @@ module.exports = function() {
263295
nodes.forEach(function(node) {
264296
if(node.targetLinks.length) {
265297
var y = sum(node.targetLinks, weightedSource) / sum(node.targetLinks, value);
266-
node.y += (y - center(node)) * alpha;
298+
node.y += (y - nodeCenter(node)) * alpha;
267299
}
268300
});
269301
});
270-
271-
function weightedSource(link) {
272-
return center(link.source) * link.value;
273-
}
274302
}
275303

276304
function relaxRightToLeft(alpha) {
277305
nodesByBreadth.slice().reverse().forEach(function(nodes) {
278306
nodes.forEach(function(node) {
279307
if(node.sourceLinks.length) {
280308
var y = sum(node.sourceLinks, weightedTarget) / sum(node.sourceLinks, value);
281-
node.y += (y - center(node)) * alpha;
309+
node.y += (y - nodeCenter(node)) * alpha;
282310
}
283311
});
284312
});
285-
286-
function weightedTarget(link) {
287-
return center(link.target) * link.value;
288-
}
289313
}
290314

291315
function resolveCollisions() {
@@ -302,18 +326,18 @@ module.exports = function() {
302326
node = nodes[i];
303327
dy = y0 - node.y;
304328
if(dy > 0) node.y += dy;
305-
y0 = node.y + node.dy + nodePadding;
329+
y0 = node.y + node.dy + py;
306330
}
307331

308332
// If the bottommost node goes outside the bounds, push it back up.
309-
dy = y0 - nodePadding - size[1];
333+
dy = y0 - py - size[1];
310334
if(dy > 0) {
311335
y0 = node.y -= dy;
312336

313337
// Push any overlapping nodes back up.
314338
for(i = n - 2; i >= 0; --i) {
315339
node = nodes[i];
316-
dy = node.y + node.dy + nodePadding - y0;
340+
dy = node.y + node.dy + py - y0;
317341
if(dy > 0) node.y -= dy;
318342
y0 = node.y;
319343
}
@@ -326,7 +350,7 @@ module.exports = function() {
326350
}
327351
}
328352

329-
function computeLinkDepths() {
353+
function computeLinkBreadths() {
330354
nodes.forEach(function(node) {
331355
node.sourceLinks.sort(ascendingTargetDepth);
332356
node.targetLinks.sort(ascendingSourceDepth);
@@ -342,22 +366,6 @@ module.exports = function() {
342366
ty += link.dy;
343367
});
344368
});
345-
346-
function ascendingSourceDepth(a, b) {
347-
return (a.source.y - b.source.y) || (a.originalIndex - b.originalIndex);
348-
}
349-
350-
function ascendingTargetDepth(a, b) {
351-
return (a.target.y - b.target.y) || (a.originalIndex - b.originalIndex);
352-
}
353-
}
354-
355-
function center(node) {
356-
return node.y + node.dy / 2;
357-
}
358-
359-
function value(link) {
360-
return link.value;
361369
}
362370

363371
return sankey;

0 commit comments

Comments
 (0)