-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Rework groupby style syntax into array #1465
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
Conversation
@@ -35,14 +35,24 @@ exports.attributes = { | |||
].join(' ') | |||
}, | |||
style: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@etpinard @alexcjohnson Comparing this to similar cases, I'm not 100% sure what _isLinkedToArray
does or whether it's needed here. I've omitted it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should probably let @etpinard handle this but I think you want both _isLinkedToArray
and _arrayAttrRegexps
- the latter of which won't get used yet but when we extend the array editing stuff I did in relayout
to restyle
it will be important.
see https://github.com/plotly/plotly.js/blob/master/src/components/updatemenus/attributes.js#L17-L52
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was my template, but I had a hard time tracking down exactly what it does. See: registry.js#L100-L105. It seems like since groupby
has no layoutAttributes
, this key will have no effect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, at the moment _arrayAttrRegexps
doesn't do anything inside traces, it's just a question of if we want to put it in so we don't forget about this when we do get to implementing it. Maybe better not to include it, in case we implement it a different way. I think _isLinkedToArray
matters to plot_schema already though, doesn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added _isLinkedToArray
but did not add _arrayAttrRegexps
, which I think only applies to nested array attributes like updatemenus[...].buttons
. Granted this is transforms[...].styles
, but I'm not totally sure where this would need to be added. At the transform level vs. inside styles, perhaps? Glad to add it blindly, but without really knowing how to test it, I think maybe better to omit for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should name this attributes styles
instead? All (I think) isLinkedToArray
attribute have plural names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that an acceptable change for cleanData?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes 👍
src/transforms/groupby.js
Outdated
'marker points in group *\'a\'* will be drawn in red.' | ||
].join(' ') | ||
target: { | ||
valType: 'any', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does valType: 'any'
make sense or should it be strings? As-is styling by numbers is implicitly converted to a string-keyed object anyway, so I'm not 100% sure the right answer here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not so weird:
0.20000000000000001 === 0.2
true
We definitely want numbers treated as strings for these purposes, so target: 1
should match '1'
in the data, and vice versa.
valType: 'string'
might make sense to help accomplish this - with strict
omitted so numbers get stringified. That would cause us to ignore array, object, null, and undefined targets, which seems right. All else equal I might have permitted booleans to pass through (stringified) but if it simplifies things - which it looks like it does - then lets leave those out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. I guess my discomfort is just in relying upon implicit conversion of keys to strings to sort out numerical identity. Like if your group were 0.2
and your style key were computed in JS as 0.3 - 0.1
, I don't think it would find the right style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that would still be a problem with numeric keys, unless you implement some sort of fuzzy equality, which sounds even more dangerous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. FWIW almost-equal
combines absolute and relative tolerance in a way that seems generally desirable, but I think definitely best to ignore it and just keep in mind that it's a little picky.
src/transforms/groupby.js
Outdated
// If the styles are an array, then translate it into an index keyed on the | ||
// target. Otherwise just use the object provided for the sake of backward | ||
// compatibility. | ||
if(Array.isArray(style)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: I could have translated the object in to array style format to get a nice consistent result on fullData
, except the useful format is actually as originally defined since it needs a lookup so that it would just have to be translated back to the key-value style down below. That way would be a bit cleaner and may need to happen; this way just minimizes the back and forth. No strong feelings here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
backward-compatibility fixes should go in cleanData so they only happen when new data comes in, and they change the data to current format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Failed to initially appreciate the full meaning of "only when new data comes in." Moved to cleanData. 👍
Noticed a small typo in the style docs. No rush on the review, but I'm content with this for now. |
} | ||
}, { | ||
target: 'b', | ||
value: { | ||
mode: 'markers+lines', // heterogeonos attributes are OK: group 'a' doesn't need to define this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not that this is new, but heterogeneous
But that makes me wonder: you don't need to supply style
for every group, do you? If you omit it entirely for a group, you just get the styling contained in the parent trace, yes? Want to test that?
This has an interesting use case, I think, that wouldn't have worked (at least not nearly as well) the old way: you could have a "highlight" style to do something special to one group you're focusing on, and to focus on a different group you just change target
. And if you want to focus on none, change target
to some value that's not a group at all (does this work or does it complain?)
Also, there's a case we couldn't have previously: what if two targets are the same? I could imagine wanting to do this in exactly the "focus style" example... you have styles for each group (say, different marker colors) but then there's a different style you want to move between groups... in that case the actual style to apply to a given group would be the composition of all styles targeting the group. Should we support this? Or do something else if you get the same target more than once?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you omit it entirely for a group, you just get the styling contained in the parent trace, yes? Want to test that?
That should be already part of the suite. But yes, we should test that.
in that case the actual style to apply to a given group would be the composition of all styles targeting the group. Should we support this? Or do something else if you get the same target more than once?
I don't see a problem with supporting multiple styles item with the same target
. Style items with the same target
would simply be applied in sequence to the transformed traces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexcjohnson No, you don't need to specify for all. Or to be more precise, you don't need to now if you didn't before. 😄
At the moment, I'm internally transforming the style array into a key-value index that matches the old specification format. So if two are the same, the last in the array will overwrite other instances. I think merging would be an appropriate use case mergeDeepNoArrays. I don't personally find it a particularly compelling use-case, but it's a pretty straightforward change to add support for pretty weird user input.
Trying to close out PRs. Reading through this, I'm not sure if I have anything to add to it. |
Looks like https://github.com/plotly/plotly.js/pull/1465/files#r105486264 was never addressed. |
As discussed, groupby transform styling permits arbitrary keys which, in addition to not fitting into the plot schema, will fail if a group ends with
*src
. This PR starts the switch to array-of-objects style by first simply breaking all of the tests.