Closed alexcjohnson closed 6 years ago
I can imagine it would work, but is it too ugly to use a flag in the plot schema to prevent pruning but allow it by default?
Ohhh, never mind. Yeah, that's the coupling obviously. Then my vote is to allow pruning, or at least move pruning to a dedicated step that is aware of the plot schema and perhaps not run so frequently.
Ohhh, never mind. Yeah, that's the coupling obviously.
and worse, nestedProperty
isn't always called with a trace or complete layout
as the root object.
Yeah, I think it's excellent to keep it fully decoupled and (as) unaware of the schema (as possible). It seems to me like pruning is both a perfectly nice/valid thing and also something that shouldn't be related to nested properties.
cc @bpostlethwaite and @VeraZab can you think of any potential problems that stopping pruning empty containers could cause in W2?
I'm not sure I understand what the situation would look like without pruning..
So instead of calling restyle(gd, {'line.color': null})
I would call restyle(gd, line: {})
?
Of the top of my head, I can think of one situation where we use null
ing:
when I want to remove a shape or an image, I call relayout(gd, {'images[2]': null})
How would I do this now?
@VeraZab I don't think anything would change in how you call restyle
or relayout
- the only difference is that occasionally you'd end up with an empty container (like line: {}
) where now we notice the empty container and delete it in the pruning step. It doesn't seem to me like the workspace would be bothered by these containers lingering, but @etpinard is absolutely right to check on it.
Calls like relayout(gd, {'images[2]': null})
still hit logic to turn that into splicing the item out of the array - and #1403 standardizes that logic to work across all the container arrays in layout
.
@alexcjohnson thanks for the clarification. Alright, well I don't see any blockers on this for the workspace.
Update: I notice one case that {}
is different from undefined
, and that's rangeslider
, eg:
Plotly.newPlot(gd,[{x:[1,2,3]}],{xaxis:{rangeslider: {}}})
Changing that will probably have to wait for v2... interestingly once you have a rangeslider
we add some things to it (in the input layout
copy) so the bug I was expecting (eg Plotly.relayout(gd, {'xaxis.title': null})
accidentally deleting the rangeslider
) is not manifest, but there is a related bug: you can't add a rangeslider by Plotly.relayout(gd, {'xaxis.rangeslider': {}})
because nestedProperty
sees {}
and prunes it.
Anyway, unless something has changed in the 14 months 🙄 that this issue has lain dormant, seems like we're agreed that we can :hocho: the pruning check. I need to remove it at least within supplyDefaults
- where it's always been useless (and wasteful 🐎) but now is actually causing me other bugs while I try to fix #2508. Would be easier to just remove than to make a special version to use in supplyDefaults
More on the range slider topic. Here's one weird test:
that uses relayout(gd, 'xaxis.rangeslider', 'exists')
to add a range slider. Tests
are a little aligned with the rest of our components.
seems like we're agreed that we can hocho the pruning check. I need to remove it at least within supplyDefaults - where it's always been useless (and wasteful racehorse) but now is actually causing me other bugs while I try to fix #2508. Would be easier to just remove than to make a special version to use in supplyDefaults
As I wrote in a private convo yesterday, :+1: for :hocho:ing the prune check during supplyDefaults
. Today, I would even go one step further: the only place where pruning empty containers makes sense (and even that's debatable) is during restyle/relayout/update.
the only place where pruning empty containers makes sense (and even that's debatable) is during restyle/relayout/update.
Right, I guess I'm arguing for not even pruning {}
during restyle/relayout/update - the only place this could have a practical effect (rangeslider
) it doesn't anyway due to our clandestine mutations.
In fact... currently we also prune []
with exceptions for data arrays, which we determine in the negative by matching the attribute string against a hard-coded collection of known info_array
names
https://github.com/plotly/plotly.js/blob/4ed586a6402073cc5c50a40cad5f652d7472fcce/src/lib/nested_property.js#L138
yet there too we have a note:
* Info arrays can be safely deleted, but not deleting them has no ill effects other
* than leaving a trace or layout object with some cruft in it.
Honestly this has probably never actually happened to a user - using restyle
etc to remove all items from an info_array
like range
or domain
, and expecting the array container to disappear? So as much as it was a nice idea that a restyle
and then its undo operation should put the object back into its original state exactly, the fact is with no pruning we get the same practical result with far less complexity and coupling. I've come around to thinking we shouldn't treat []
as something to delete either - and I'm going to do that now, along with 🔪 the rest of the pruning stuff, unless anyone objects.
I'm big fan of making nestedProperty
less coupled. So :+1: for all things listed in the above comment :arrow_heading_up:
As a side-note, making nestedProperty
less coupled should make it easier to publish as a standalone module (if ever we choose that path) -> https://github.com/plotly/plotly.js/issues/2138
Lib.nestedProperty
started as a nice compact, decoupled way to manage edits to traces and layout objects. We have a system that prunes empty containers, which was originally meant so that unnecessary pieces would not be left around after multiple operations. For example, you have a line trace with default properties:{x: [1, 2, 3], y: [1, 2, 3]}
then you edit the line color
restyle(gd, {'line.color': 'red'})
{x: [1, 2, 3], y: [1, 2, 3], line: {color: 'red'}}
And you don't like that, so you undo it
restyle(gd, {'line.color': null})
. Without pruning you get:{x: [1, 2, 3], y: [1, 2, 3], line: {}}
Which is functionally the same, but it's not a perfect undo.
However, some empty containers cannot be removed (see https://github.com/plotly/plotly.js/pull/1403#discussion_r102331575 and https://github.com/plotly/plotly.js/pull/1403#discussion_r102759815 ) so this has gotten too coupled to our particular JSON structure. Can we live without doing any pruning since it would simplify the logic so much? @etpinard and I are leaning toward doing that but wanted to invite discussion.