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

Add midpoint attr to color scales #3549

Merged
merged 7 commits into from
Feb 19, 2019
Merged

Add midpoint attr to color scales #3549

merged 7 commits into from
Feb 19, 2019

Conversation

nicolaskruchten
Copy link
Contributor

Closes #3509

LMK what kinds of extra tests you'd like or if you want me to just modify an existing mock or something, or if I've mangled some of the coercion machinery :)

@nicolaskruchten
Copy link
Contributor Author

I've love to get this into 1.45 if it's uncontroversial :)

@etpinard
Copy link
Contributor

etpinard commented Feb 15, 2019

I'm still 100% convinced cmid is the right name for this attribute. I'd like make this attribute consistent with a future axis attribute coerced when we have rangemode: 'symmetric'. Maybe rangemid would be better?

@etpinard
Copy link
Contributor

At present rangemode: 'symmetric' means an axis range centered around 0, but we could make that more general in the future.

@nicolaskruchten
Copy link
Contributor Author

I think we should stick with the current naming convention for right now, and when we do something range-related in the future we can carry mid along with it.

@etpinard
Copy link
Contributor

the current naming convention

which is?

@nicolaskruchten
Copy link
Contributor Author

marker.rangemid is really... unintuitive, in the same way as marker.showscale is... what range? what scale?

@nicolaskruchten
Copy link
Contributor Author

the current naming convention
which is?

cmin, cmax, cmid ...?

@etpinard
Copy link
Contributor

ok, but we're planning on changing cmin / cmax for crange


Does anyone in @plotly/plotly_js have an opinion about this?

@nicolaskruchten
Copy link
Contributor Author

In future when we have layout.coloraxis I think we should use axis-like terminology like range etc for sure but I feel cmid fits in nicely with what's here atm.

That said, if rangemid is what it takes to get this merged in, I can change it. Might be odd in the histogram2d case where it's zmin/zmax at the trace level tho. trace.rangemid ?

@nicolaskruchten
Copy link
Contributor Author

ok, but we're planning on changing cmin / cmax for crange

And the day we do that, we should change cmid also, is what I'm saying.

@etpinard
Copy link
Contributor

etpinard commented Feb 15, 2019

Making changes to attributes is never fun. This is exactly what I'm trying to avoid.

@nicolaskruchten
Copy link
Contributor Author

What's the rationale for cmin/cmax -> crange ?

@etpinard
Copy link
Contributor

etpinard commented Feb 15, 2019

What's the rationale for cmin/cmax -> crange ?

Bring color "axis" attribute closer to data coordinate axis attributes.

@nicolaskruchten
Copy link
Contributor Author

Bring color "axis" attribute closer to data axis attributes.

I would leave the existing cmin/cmax attributes alone (and add cmin!), and then use the range terminology only in the future layout.coloraxis object. Then in V2 we can drop the trace-specific colorscale/colorbar stuff.

@etpinard
Copy link
Contributor

I would leave the existing cmin/cmax attributes alone (and add cmid)!

If you really want to merge this ASAP, sure what can that!

Now, are you planning on fixing the tests (we should also add jasmine tests making sure restyle and react work ok in and out of cmid) or you want me to take this thing to the finish line?

@etpinard etpinard added this to the v1.45.0 milestone Feb 15, 2019
@nicolaskruchten
Copy link
Contributor Author

I can finish it up, just wanted to get feedback on the approach, make sure I didn't miss anything obvious.

@nicolaskruchten
Copy link
Contributor Author

If you really want to merge this ASAP, sure what can that!

Mostly as you say it's a pain to change existing attrs, so I think we should plan to leave the existing cmin/cmax alone for that reason.

@nicolaskruchten
Copy link
Contributor Author

So I'm trying to fix the tests and confused about why the scattergeo one is failing but there is scattermapbox code in the stack trace. I'm not sure why execution is going down that path... any hints?

@etpinard
Copy link
Contributor

So I'm trying to fix the tests and confused about why the scattergeo one is failing

projection: {
type: {
valType: 'enumerated',
role: 'info',
values: Object.keys(constants.projNames),
description: 'Sets the projection type.'
},

Thanks for uncovering a pretty embarrassing typo. Switching to scattergeo makes the scattergeo_test.js suite pass.

Now, for scattermapbox, you'll need to add cmid to

marker: {
symbol: {
valType: 'string',
dflt: 'circle',
role: 'style',
arrayOk: true,
description: [
'Sets the marker symbol.',
'Full list: https://www.mapbox.com/maki-icons/',
'Note that the array `marker.color` and `marker.size`',
'are only available for *circle* symbols.'
].join(' ')
},
opacity: markerAttrs.opacity,
size: markerAttrs.size,
sizeref: markerAttrs.sizeref,
sizemin: markerAttrs.sizemin,
sizemode: markerAttrs.sizemode,
color: markerAttrs.color,
colorscale: markerAttrs.colorscale,
cauto: markerAttrs.cauto,
cmax: markerAttrs.cmax,
cmin: markerAttrs.cmin,
autocolorscale: markerAttrs.autocolorscale,
reversescale: markerAttrs.reversescale,
showscale: markerAttrs.showscale,
colorbar: colorbarAttrs,

as scattermapbox doesn't use the colorscale attribute generator (yet).

@nicolaskruchten
Copy link
Contributor Author

Thanks for looking into it @etpinard ! I'm confused about what the "typo" is in the code you linked above... can you clarify please?

@etpinard
Copy link
Contributor

I'm confused about what the "typo" is in the code you linked above... can you clarify please?

Oops. Wrong link:

var base = { type: 'scattermapbox' };

@nicolaskruchten
Copy link
Contributor Author

Ahhh that makes much more sense, thank you :)

@nicolaskruchten
Copy link
Contributor Author

OK despite best intentions I havent found the time to write tests here unfortunately... could someone in @plotly/plotly_js take over the restyle/relayout tests plz? :)

@etpinard
Copy link
Contributor

Ok. I'll do that this morning.

valType: 'number',
role: 'info',
dflt: null,
editType: editTypeOverride || 'plot',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@etpinard I wasn't sure what to put for editType and impliedEdits btw so I copied over the settings from max above... maybe it should match auto instead? Or be something else? Likely your tests will expose any problems but I just wanted to shine a light here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Restyle got fixed in 23c1cf0

Is that the behaviour you had in mind?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I must admit I don't fully grok the various nuances of the types of edits, but the test reads fine at first glance!

@@ -1195,6 +1195,77 @@ describe('Test plot api', function() {
.then(done);
});

it('turns on cauto when cmid is edited', function(done) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is an odd description... cmid only has effect if cauto is true, but doesn't turn on cauto per se, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

but doesn't turn on cauto per se, right?

yes, it has to. If not, restyle(gd, 'marker.cmid', 0) wouldn't work.

Copy link
Contributor

@etpinard etpinard Feb 19, 2019

Choose a reason for hiding this comment

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

by "not work" here I mean it wouldn't apply that new cmid value when cmin and cmax are set.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK I see what you mean.

if(auto) {
coerce(prefix + cLetter + 'mid');
} else {
coerce(prefix + cLetter + 'min');
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this line and the next used to always run, but now only conditionally... might this break anything? I'm not sure about the implication of not calling coerce().

Copy link
Contributor

Choose a reason for hiding this comment

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

No tests are failing because of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

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 is a test failure that mentions coerce:

Test surface supplyDefaults should coerce 'c' attributes with 'c' values regardless of `'z' if 'c' is present FAILED

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah good eye.

Well cmin and cmax have no effect

if(auto !== false || min === undefined) {
min = Lib.aggNums(Math.min, null, vals);
}
if(auto !== false || max === undefined) {
max = Lib.aggNums(Math.max, null, vals);
}

when cauto is true.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm easy. Like I said, I don't know the impact of calling coerce and ignoring the attr vs not calling coerce :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Calling the behaviour correct and adapting the test in ff67812

@etpinard
Copy link
Contributor

@plotly/plotly_js can I get a review for this thing?

@archmoj
Copy link
Contributor

archmoj commented Feb 19, 2019

@plotly/plotly_js can I get a review for this thing?

@etpinard - sure, I'll review this.

@archmoj archmoj self-requested a review February 19, 2019 18:57
Copy link
Contributor

@archmoj archmoj left a comment

Choose a reason for hiding this comment

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

Great PR.
I was a bit confused when I was trying to paint a surface elevation using cmid and cmin.
Here a codepen.
I thought as described #3509 (comment) the user may try to declare the minimum and middle range. However; it lookscmin has no effect in the mentioned example when cmid is defined?

@etpinard
Copy link
Contributor

However; it lookscmin has no effect in the mentioned example when cmid is defined?

Right, that's the expected behaviour it seems like:

description: [
'Sets the mid-point of the color domain by scaling ', minFull,
' and/or ', maxFull, ' to be equidistant to this point.',
effectDesc,
' Value should have the same units as ', colorAttrFull, '. ',
'Has no effect when ', autoFull, ' is `false`.'
].join('')

@archmoj
Copy link
Contributor

archmoj commented Feb 19, 2019

Right, that's the expected behaviour it seems like:

Then it may be reasonable to modify the description of cmin and cmax? to include for example:

'Has no effect when `cmid` is defined.'
.

@etpinard
Copy link
Contributor

Then it may be reasonable to modify the description of cmin and cmax? to include for example:

'Has no effect when cmid is defined.'

That's not true. Say you have:

{
  cmin: 0,
  cmax: 2,
  cmid: 2
}

then here cmid is defined, but ignored.

@archmoj
Copy link
Contributor

archmoj commented Feb 19, 2019

Nicely done.
💃

@nicolaskruchten
Copy link
Contributor Author

Yes the idea is that if you want to specify two points on the curve they must be min/max... not min/mid or mid/max. Easier to implement and document. The mid doc is a bit indirect in that it says “no effect if auto false” and then the auto doc says “false if min and max are set” but I figure this is still correct/readable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants