Skip to content

Sankey: add attributes node.(x|y) #3583

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

Merged
merged 7 commits into from
Mar 21, 2019
Merged

Sankey: add attributes node.(x|y) #3583

merged 7 commits into from
Mar 21, 2019

Conversation

antoinerg
Copy link
Contributor

@antoinerg antoinerg commented Feb 26, 2019

This closes parts of #2520.

It adds attributes node.(x|y) to specify the position of nodes.

Upon reordering the nodes by dragging them with the mouse, we update those attributes to persist the state. This allow saving the current state of the figure to an image whereas it used to always export the initial position of the nodes.

This PR also greatly improves our Sankey tests by testing drag operations for every arrangement! This allowed me to catch a regression as discussed in #3583 (comment) .

@antoinerg
Copy link
Contributor Author

One thing I dislike about the current branch is that ky, the ratio between the height in pixel of a node and its value, is computed by the underlying Sankey generator. So although the user can position the nodes by specifying node.(x|y), there's no way of knowing how tall the nodes will be. This makes it impossible to decide ahead of times what would be good values of node.y to prevent nodes from overlapping vertically...

I am thinking we might want to add a new attribute node.scale 🤔 What do you think?

cc @alexcjohnson @plotly/plotly_js

@alexcjohnson
Copy link
Collaborator

When you drag nodes around by GUI, the others slide around to avoid overlaps. What if we did the same here? You provide positions but then we slide them around, keeping the ordering fixed, to avoid overlaps. It would still have some weird aspects, like if you're on a column that doesn't span the whole height and you want the nodes clustered in certain places you'd have to artificially squish them and trust us to sort it out.

node.scale could still be an interesting idea - though it's not just nodes, it applies to links too. But that seems like a separate feature, and in any case we don't want to allow overlapping nodes so we'll have to reserve the right to modify any positioning the user provides.

@antoinerg
Copy link
Contributor Author

Thank you @alexcjohnson for the quick reply! I will give this a bit more thought. In the meantime, here are a few comments:

in any case we don't want to allow overlapping nodes

If the arrangement is freeform or perpendicular, we actually allow nodes to overlap. In fact, dragging in freeform allow nodes to be anywhere! This is why I set out to support arbitrary positioning via node.(x|y) to be on par with what can be done with the mouse.

If we decide to get rid of overlapping nodes, I could definitely try to implement your suggestion:

you provide positions but then we slide them around, keeping the ordering fixed, to avoid overlaps.

Finally,

node.scale could still be an interesting idea - though it's not just nodes, it applies to links too.

You're right: it should be a top-level attribute (ie. scale instead of node.scale).

@alexcjohnson
Copy link
Collaborator

Ah OK, I guess I hadn't seen the interaction modes that allow overlaps to persist. In that case those should still be allowed, and should play nice with explicit positioning. But seems to me the default mode should be to respect explicit positioning but then push apart overlaps.

@antoinerg antoinerg changed the title Draft PR - Sankey: add attributes node.(x|y) Sankey: add attributes node.(x|y) Feb 28, 2019
@antoinerg
Copy link
Contributor Author

Issue #3563 is also present for arrangement freeform and perpendicular (and hence in master) but it is fixed in the current PR and now has proper tests.

@etpinard etpinard added this to the v1.46.0 milestone Mar 1, 2019
@antoinerg antoinerg marked this pull request as ready for review March 1, 2019 23:03
@antoinerg antoinerg added bug something broken feature something new status: reviewable regression this used to work and removed status: discussion needed bug something broken labels Mar 1, 2019
@antoinerg
Copy link
Contributor Author

But seems to me the default mode should be to respect explicit positioning but then push apart overlaps.

@alexcjohnson After the nodes are pushed apart in snap mode (which is the default), should I update the node.(x|y) to reflect the new positions of the nodes?

@antoinerg
Copy link
Contributor Author

@alexcjohnson After the nodes are pushed apart in snap mode (which is the default), should I update the node.(x|y) to reflect the new positions of the nodes?

I elected to not update node.(x|y) if the user specified them explicitly. This way, the user can switch from freeform to snap to freeform again.

peek 2019-03-05 12-06

@chriddyp
Copy link
Member

chriddyp commented Mar 6, 2019

Will this work with uirevision?

@antoinerg
Copy link
Contributor Author

antoinerg commented Mar 8, 2019

Will this work with uirevision?

@chriddyp it now does with commit 8ddfe7e ! Thanks for suggesting the improvement! 😸

@etpinard
Copy link
Contributor

@antoinerg what's the status on this one? Are planning on adding anything else to this PR?

@etpinard
Copy link
Contributor

etpinard commented Mar 20, 2019

but it is fixed in the current PR and now has proper tests.
Will this work with uirevision?
@chriddyp it now does with commit 8ddfe7e !

Amazing work 🎉

"data": [
{
"type": "sankey",
"arrangement": "freeform",
Copy link
Contributor

@etpinard etpinard Mar 20, 2019

Choose a reason for hiding this comment

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

Do all the possible values of arrangement have an effect of the node layout when node.x and node.y are set?

Copy link
Contributor Author

@antoinerg antoinerg Mar 20, 2019

Choose a reason for hiding this comment

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

Do all the possible values of arrangement have an effect of the node layout when node.x and node.y are set?

Short answer: only snap can override node.(x|y)

Long answer:
When node.(x|y) is set, the nodes are forced to sit at the specified locations except in the snap arrangement. When drag and dropping, snap is the only arrangement in which we forbid nodes from overlapping so I made sure we keep honoring this promise.

The goal of this PR was to make it possible to replicate any state accessible via drag and drop via node.(x|y) and hence allowing to export images.

Copy link
Contributor

@etpinard etpinard Mar 20, 2019

Choose a reason for hiding this comment

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

Ok, thanks for the info!

Could we then make arrangement default to 'freeform' whenever node.(x|y) are set? That way, a user that wants to programmatically tweak the node position via node.(x|y) can do so w/o having to worry about changing the arrangement value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 65c7201

@antoinerg
Copy link
Contributor Author

@antoinerg what's the status on this one? Are planning on adding anything else to this PR?

I wasn't planning on adding anything else to this PR. It is bigger than I initially anticipated and I don't want to complicate it further at this stage.

@etpinard
Copy link
Contributor

Nicely done 💃 💃

@antoinerg antoinerg merged commit e76536b into master Mar 21, 2019
@antoinerg antoinerg deleted the draft-sankey2-x-y branch March 21, 2019 19:08
@antoinerg antoinerg mentioned this pull request Mar 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new regression this used to work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants