-
-
Notifications
You must be signed in to change notification settings - Fork 43
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 colormap option to replace surfaceColors #129
Conversation
This fixes two issues with the loop condition `currentHue < endHue`: - if the math is exact, this leeds to adding a total of `stops` values to rgbColors; the last one with hue = (endHue-startHue) / stops * (stops-1) = (endHue-startHue) * (1 - 1/stops) i.e. by a (endHue-startHue)/stops smaller than I would expect - however, one cannot even really depend on the math being exact here (since this is floating point), so we might as well get in some cases a total array length of `stops + 1`, with the last value being approximately equal to endHue.
When `ratio * colorStops` is an exact integer, it follows that `startIndex = endIndex`, and hence a divide by zero occurs. This was pretty much guaranteed to happen in some cases (consider e.g. value=vMin or vMax).
This can e.g. happen due to limited numerical precision.
This makes most of the code agnostic as to what colormap is actually used – rather than explicitly calculation hue.
Reasons to introduce a new option rather than extending surfaceColors: - surfaceColors applies only to 'surface' styles, as the name suggests, letting it work for other styles may break backward compatibility with some users - colormap is the more common name - IMO, it is more natural to list colors in the order from minimal to maximal values, which surfaceColors did in reverse.
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.
Do you have any examples how to use the function version of colormap?
Hi, thanks for taking the time to review this.
it's explained in the docs, but I could add an example somewhere.. |
7619ec4
to
b957349
Compare
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.
Seems to work well, there are still some detail to polish though.
Btw: while doing this PR, I initially contemplated removing the |
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.
Some more minor issues in the code.
Also input validation:
options.colormap = {
hue: {
start: +"ř",
end: +"ř",
saturation: +"ř",
brightness: +"ř",
colorStops: +"ř" // How many colour gradients do we want
}
};
crashes with very unhelpful error message.
With proper inputs it works great, though.
Keep in mind, that I didn't change anything about this syntax... If you want to have better input validation for that, I think it should be done in a separate PR (and I won't do it, because I disagree that it is useful, and I would remove this syntax anyway). |
You had to change something because it doesn't crash upstream. Also, having an option to simply use a range of colors seems really handy to me. What's wrong with that? |
I changed the check - if (hues.saturation < 0 || hues.saturation > 100) {
+ if (!(hues.saturation >= 0 && hues.saturation <= 100)) {
throw new Error('Saturation is out of bounds. Expected range is 0-100.');
} by your request. And yes, it is an improvement over the old version. Now you get at least an error that informs you that the variable is out of bounds. Previously it failed quietly without any error message (but of course still didn't work).
I'm not argueing against the Take a quick look at the changes in the colormodule branch I mentioned before. It includes all the tools to let the user do exactly that. |
Also, I'm personally not a big fan of too much input validation (in non-security critical code of course). In my experience this often prevents uses that would actually make sense but were not anticipated by the developer. I mean if the user wants, they can always break it. My opinion is, let them have the freedom to do that, but when they're doing something that's not documented, they're on their own with that (consenting adults...). (Edit: I'm of course referring only to arguments that are passed in by library users (i.e. other developers) here, not to arguments passed in directly from the end user) |
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.
Okay, I see your point now. Do you plan to get the colormap to production too? Anyway thank you very much.
🎉 This PR is included in version 5.8.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Not sure.. While I think that branch has structural improvements, it currently doesn't provide an good user-level API with thought-through names. For now I'm happy with being able to specify a function and personally use that to plug in chroma.js.
Thanks as well! |
Hi,
first, this fixes a few remaining issues with the
surfaceColors
implementation.Next, I've wanted to have an option that allows specifying a function that maps a value between 0 and 1 to an RGB value. This makes it possible to e.g. plug in colormaps from chroma.js or use any custom user logic.
I believe it is probably best not to reuse
surfaceColors
for this, but replace it with acolormap
becausesurfaceColors
implies it works only with surface plots, but I think the colormap should be usable for all plot stylessurfaceColors
option previously worked only for surface plots, i.e. if we would change it to work with other styles, this might be a (minor) break in backward compatibilitycolormap
is the more commonly used namesurfaceColors
option takes colors in the order from vMax to vMin, whereas I think that it is more intuitive to pass colors in ascending orderIf you disagree, it is of course trivial to just add this capability to the existing surfaceColors option.