Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

d3-sankey-circular #3406

Merged
merged 41 commits into from
Feb 14, 2019
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
03a3cb5
merge @Plotly/d3-sankey into plotly.js (es6 -> es5, tests in jasmine)
antoinerg Dec 12, 2018
2504dc3
fix header for d3-sankey.js
antoinerg Dec 12, 2018
fd19907
move data conversion into its own function and run in calc() phase
antoinerg Dec 13, 2018
bde2a79
refactor d3-sankey to look more similar to upstream
antoinerg Dec 13, 2018
5f89d78
fix indentation
antoinerg Dec 13, 2018
1ad9586
updating to d3-sankey 0.7.1
antoinerg Dec 15, 2018
ee7088a
generate link path appropriately, reattach mouse events
antoinerg Dec 17, 2018
5418d25
fix dragging, snapping, pushing and pass all tests
antoinerg Dec 19, 2018
be1acc8
initial rough integration of d3-sankey-circular
antoinerg Jan 7, 2019
067869f
implement dragging
antoinerg Jan 7, 2019
f8bf7fe
fallback to d3-sankey if no circularity is present
antoinerg Jan 7, 2019
54523db
Merge remote-tracking branch 'origin' into sankey-circular, fix lint
antoinerg Jan 7, 2019
ed87295
testing features of d3-sankey-circular
antoinerg Jan 8, 2019
c1404fb
change stroke-opacity on hover
antoinerg Jan 8, 2019
d268b73
use index as unique identifier for nodes
antoinerg Jan 8, 2019
09d2aa6
delete tests dealing with removal of circular nodes
antoinerg Jan 14, 2019
3e5b160
on update, change circular link type based on nodes' position
antoinerg Jan 14, 2019
3ed9ba5
circular-sankey, sort links per node on update
antoinerg Jan 14, 2019
00e5d28
change node's identifier
antoinerg Jan 14, 2019
f63e2b5
update tests for Sankey generators
antoinerg Jan 14, 2019
6fb3fb4
document that link.line.(width|color) is not supported with circularity
antoinerg Jan 14, 2019
51085c4
add mocks and baselines for circular Sankey
antoinerg Jan 14, 2019
9ca4d5d
use tomshanley/d3-circular-sankey now that our changes got merged in
antoinerg Jan 18, 2019
d1d852a
render circular links as closed paths
antoinerg Jan 18, 2019
2382d74
update sankey_circular baseline
antoinerg Jan 18, 2019
04a186c
move function defined in convert-to-d3-sankey.js into calc.js
antoinerg Jan 18, 2019
dee73b8
remove npm packages not used
antoinerg Jan 18, 2019
b3bcdd6
improve style
antoinerg Jan 18, 2019
4539d28
combine all sankey tests into a single file
antoinerg Jan 18, 2019
225d310
position hover label above circular links
antoinerg Jan 18, 2019
9b36090
update d3-sankey-circular and test update() API
antoinerg Jan 22, 2019
48a8b1b
sankey-circular: add baseline with subplots and vertical orientation
antoinerg Jan 22, 2019
777dc97
update Sankey deps
antoinerg Jan 31, 2019
ebe613b
nest API tests for d3-sankey-circular in its own describe block
antoinerg Feb 5, 2019
04d53ff
d3-sankey-circular test large dataset
antoinerg Feb 5, 2019
003704c
remove gap between circular links
antoinerg Feb 11, 2019
3625234
update d3-sankey-circular and associated baselines
antoinerg Feb 11, 2019
59dbef4
update d3-sankey-circular deps
antoinerg Feb 11, 2019
4ed7634
update dep of d3-sankey-circular
antoinerg Feb 14, 2019
ba2a485
Merge pull request #3535 from plotly/pr-large-sankey-circular
antoinerg Feb 14, 2019
063784a
test switching to circular Sankey on Plotly.react
antoinerg Feb 14, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,17 @@
},
"dependencies": {
"3d-view": "^2.0.0",
"@plotly/d3-sankey": "^0.5.1",
"alpha-shape": "^1.0.0",
"array-range": "^1.0.1",
"canvas-fit": "^1.5.0",
"color-normalize": "^1.3.0",
"convex-hull": "^1.0.3",
"country-regex": "^1.1.0",
"d3": "^3.5.12",
"d3-sankey": "git://github.com/antoinerg/d3-sankey.git#4f37ed8d3578b545a8569ecd74583f373768e900",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minimal changes over latest d3-sankey d3/d3-sankey@master...antoinerg:fix-large-padding

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. So we no longer need https://github.com/plotly/d3-sankey ? I thought i read that we made changes in our @plotly/d3-sankey that got rejected by d3/d3-sankey.

Copy link
Contributor Author

@antoinerg antoinerg Jan 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those changes were minimal. One of the biggest was that we generated the SVG path for the links in it. As you found out in this PR, we can do this operation in plotly.js instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok that make sense. Do you think we have a shot at getting

d3/d3-sankey@master...antoinerg:fix-large-padding

merged into d3/d3-sankey?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There hasn't been anything merged into master in d3/d3-sankey since Jul 13, 2017 so I'm not sure... I opened a PR almost a month ago d3/d3-sankey#63 and there has been no activity since then.

"d3-sankey-circular": "git://github.com/antoinerg/d3-sankey-circular.git#ad8c6e345583cb4ed2a5cb2353678fb6b2d54c71",
"d3-force": "^1.0.6",
"d3-interpolate": "1",
"delaunay-triangulate": "^1.1.6",
"es6-promise": "^3.0.2",
"fast-isnumeric": "^1.1.2",
Expand Down
89 changes: 78 additions & 11 deletions src/traces/sankey/calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,77 @@ var tarjan = require('strongly-connected-components');
var Lib = require('../../lib');
var wrap = require('../../lib/gup').wrap;

var isArrayOrTypedArray = Lib.isArrayOrTypedArray;
var isIndex = Lib.isIndex;


function convertToD3Sankey(trace) {
var nodeSpec = trace.node;
var linkSpec = trace.link;

var links = [];
var hasLinkColorArray = isArrayOrTypedArray(linkSpec.color);
var linkedNodes = {};

var nodeCount = nodeSpec.label.length;
var i;
for(i = 0; i < linkSpec.value.length; i++) {
var val = linkSpec.value[i];
// remove negative values, but keep zeros with special treatment
var source = linkSpec.source[i];
var target = linkSpec.target[i];
if(!(val > 0 && isIndex(source, nodeCount) && isIndex(target, nodeCount))) {
continue;
}

source = +source;
target = +target;
linkedNodes[source] = linkedNodes[target] = true;

var label = '';
if(linkSpec.label && linkSpec.label[i]) label = linkSpec.label[i];

links.push({
pointNumber: i,
label: label,
color: hasLinkColorArray ? linkSpec.color[i] : linkSpec.color,
source: source,
target: target,
value: +val
});
}

var hasNodeColorArray = isArrayOrTypedArray(nodeSpec.color);
var nodes = [];
var removedNodes = false;
var nodeIndices = {};

for(i = 0; i < nodeCount; i++) {
if(linkedNodes[i]) {
var l = nodeSpec.label[i];
nodeIndices[i] = nodes.length;
nodes.push({
pointNumber: i,
label: l,
color: hasNodeColorArray ? nodeSpec.color[i] : nodeSpec.color
});
} else removedNodes = true;
}

// need to re-index links now, since we didn't put all the nodes in
if(removedNodes) {
for(i = 0; i < links.length; i++) {
links[i].source = nodeIndices[links[i].source];
links[i].target = nodeIndices[links[i].target];
}
}

return {
links: links,
nodes: nodes
};
}

function circularityPresent(nodeList, sources, targets) {

var nodeLen = nodeList.length;
Expand All @@ -36,20 +107,16 @@ function circularityPresent(nodeList, sources, targets) {
}

module.exports = function calc(gd, trace) {

var circular = false;
if(circularityPresent(trace.node.label, trace.link.source, trace.link.target)) {
Lib.error('Circularity is present in the Sankey data. Removing all nodes and links.');
trace.link.label = [];
trace.link.source = [];
trace.link.target = [];
trace.link.value = [];
trace.link.color = [];
trace.node.label = [];
trace.node.color = [];
circular = true;
}

var result = convertToD3Sankey(trace);

return wrap({
link: trace.link,
node: trace.node
circular: circular,
_nodes: result.nodes,
_links: result.links
});
};
18 changes: 12 additions & 6 deletions src/traces/sankey/plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ function linkNonHoveredStyle(d, sankey, visitNodes, sankeyLink) {
var label = sankeyLink.datum().link.label;

sankeyLink.style('fill-opacity', function(d) {return d.tinyColorAlpha;});

if(label) {
ownTrace(sankey, d)
.selectAll('.' + cn.sankeyLink)
Expand Down Expand Up @@ -152,16 +151,23 @@ module.exports = function plot(gd, calcData) {
var obj = d.link.trace.link;
if(obj.hoverinfo === 'none' || obj.hoverinfo === 'skip') return;
var rootBBox = gd._fullLayout._paperdiv.node().getBoundingClientRect();
var boundingBox = element.getBoundingClientRect();
var hoverCenterX = boundingBox.left + boundingBox.width / 2;
var hoverCenterY = boundingBox.top + boundingBox.height / 2;
var hoverCenterX;
var hoverCenterY;
if(d.link.circular) {
hoverCenterX = (d.link.circularPathData.leftInnerExtent + d.link.circularPathData.rightInnerExtent) / 2 + d.parent.translateX;
hoverCenterY = d.link.circularPathData.verticalFullExtent + d.parent.translateY;
} else {
var boundingBox = element.getBoundingClientRect();
hoverCenterX = boundingBox.left + boundingBox.width / 2 - rootBBox.left;
hoverCenterY = boundingBox.top + boundingBox.height / 2 - rootBBox.top;
}

var hovertemplateLabels = {valueLabel: d3.format(d.valueFormat)(d.link.value) + d.valueSuffix};
d.link.fullData = d.link.trace;

var tooltip = Fx.loneHover({
x: hoverCenterX - rootBBox.left,
y: hoverCenterY - rootBBox.top,
x: hoverCenterX,
y: hoverCenterY,
name: hovertemplateLabels.valueLabel,
text: [
d.link.label || '',
Expand Down
Loading