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

refactor(xy): drop triple equals true on booleans #1350

Closed

Conversation

wayneseymour
Copy link
Member

@wayneseymour wayneseymour commented Sep 1, 2021

Summary

Refactor textContrast check to use truthy,
instead of using === true.

Details

Remove a little duplication,
while in the "neighbourhood".

Issues

Helps with: #1303

  • Addresses check for === true, === false, return true etc. redundancy candidates and eliminate

@wayneseymour wayneseymour force-pushed the refactor/triple-equals-true branch from f40d049 to a095403 Compare September 1, 2021 15:00
@wayneseymour
Copy link
Member Author

Please feel free to close this, make fun of it, tell me it sucks, etc! hahahaaa @monfera

@monfera monfera changed the title refactor[code improvements]: Drop triple equals true on booleans refactor(xy): drop triple equals true on booleans Sep 1, 2021
@@ -142,6 +142,12 @@ export function colorIsDark(color: Color): boolean {
return luminance < 0.2;
}

const colors = (tr: any) => (tg: any) => (tb: any) => ({
Copy link
Contributor

Choose a reason for hiding this comment

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

Good idea to abstract out this util indeed! In this case there's no current or foreseeable partial application per color channel, so it could be a single parameter list, and the symbols can simplify to r, g, b as the t prefix carries no meaning in the scope of this function

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, that makes sense.

Copy link
Member

Choose a reason for hiding this comment

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

This function is basically a way to invert color channels.
There was also another, definitely simplifiable, piece of code:

? to === undefined
        ? `rgb(${255 - tr}, ${255 - tg}, ${255 - tb})`
        : `rgba(${255 - tr}, ${255 - tg}, ${255 - tb}, ${to})`

that just create an rgb or an rgba color string depending if the opacity is defined or not.

I think we can easily replace this by always rendering rgba strings (non rgbA 😉) where the opacity is always 1 if the param is undefined, something along those lines:

function invertColor(r:RGB, g:RGB, b:RGB, o = 1) {
   return `rgba(${255 - r}, ${255 -g},${255 - b},${o})`;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Wow, that's waaaaaay more simple!

Copy link
Member Author

Choose a reason for hiding this comment

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

Full disclosure, I had no idea of the context of all this rgb "stuff" lol

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, I'm going to push what I have so far, but I'm also going to go back through and change it to have this invertColor fn. I really like the simplicity.

@monfera
Copy link
Contributor

monfera commented Sep 1, 2021

Hi @wayneseymour thanks for the contrib!

There's an eslint issue: we recently got rid of husky (blame me), so the code autoformatting on commit went away, we pretty much lean on our editors linking to the ever current eslint rules, not just for the red squigglies but also for reformatting on autosave:
image

The "Semantic Pull Request" check was red as it enforces commitizen rules, in this case,

  • one of refactor, test, chore, feat,
  • plus, if applicable, the area in braces, such as xy, partition, heatmap etc.

It's late and I haven't checked the actual logic, but it looks like at least the 3rd visual regression test may have picked up a logic change, worth checking, as here the outcomes are expected to remain the same. Glad to get you started on ways to run the VRT locally for a sometimes faster turnaround

@@ -155,27 +161,29 @@ export function getTextColorIfTextInvertible(
): Color {
const inverseForContrast = specifiedTextColorIsDark === backgroundIsDark;
const { r: tr, g: tg, b: tb, opacity: to } = stringToRGB(textColor);
if (!textContrast) {
Copy link
Member Author

Choose a reason for hiding this comment

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

You know, something about all the conditionals in this fn, are driving me nuts.
It's probably purely academic, but the fact that it checks for truthy against
inverseForContrast three times keeps bothering me.

Again, not worth it, but it flows terribly in my eyes, just a personal style nit though.
Not worth upsetting anyone. I did the same code elsewhere in Kibana, and it still bothers me.
I just didnt feel like writing my own cond fn lol.

Cond
A fn takes a list of predicate fns and then executes different fns, based on the predicates passed in. I'm not even sure how best to impl that. Interesting thought exercise though.

Kinda like: https://ramdajs.com/docs/#cond

I'm just venting emotionally though hahahahaaa

Copy link
Member Author

Choose a reason for hiding this comment

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

@monfera
Copy link
Contributor

monfera commented Sep 2, 2021

jenkins test this

@@ -142,6 +142,10 @@ export function colorIsDark(color: Color): boolean {
return luminance < 0.2;
}

const reducer = (acc: any, curr: any, idx: any) => (idx !== 0 ? `${acc}, ${curr}` : `${curr}`);

const invert = (r: number, g: number, b: number) => [r, g, b].map((x) => 255 - x).reduce(reducer, '');
Copy link
Contributor

@monfera monfera Sep 2, 2021

Choose a reason for hiding this comment

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

[].join(', ') removes the need for the [].reduce and the overly generically named reducer, though even with that, the mild repetition

const invert = (r: number, g: number, b: number) => `${255 - r}, ${255 - g}, ${255 - b}`

would likely lead to fewer cycles, fewer bytes allocated and a bit shorter code, plus the code reader sees what's going on on a 1st blink. I wouldn't name it invert though as it returns a partial CSS color string, besides the inversion.

Combined with Marko's pitch for using rgba even if rgb would suffice, it could be

const invertedColor = 
  (r: number, g: number, b: number, a: number) => `rgba(${255 - r}, ${255 - g}, ${255 - b}, a)`

Copy link
Member Author

Choose a reason for hiding this comment

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

Ahhh, ok. That makes a lot of sense. I'll update.

Copy link
Member Author

Choose a reason for hiding this comment

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

Does that mean rgb and rgbA are nearly interchangeable?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ahh, I see, it's about opacity. I get it now.

@wayneseymour
Copy link
Member Author

jenkins test this

Refactor to use truthy,
remove a little duplication using
native bind method.

Signed-off-by: Tre' Seymour <[email protected]>
with ternary expression.
Less code is the best code :)
parameter list.  Also, remove
partial application.
Use Marco's inversion fn instead, also lifted.
Make it a little DRY-er.
I'm not super happy with this commit.
I've considered binding the
makeHighContrastColor fn, and partially
applying it, but the amount of code that
takes seems not worth it.

This way, at least it's only evaluated if
textContrast is a number.

We could also lift this out of this fn,
and instead of using hoisting, it'd be
truly first-class, but then the parameter
list would be huge.

Lots of pros and cons, but the vrt is happy!
@monfera
Copy link
Contributor

monfera commented Sep 9, 2021

@wayneseymour the resolution for the axis_utils.ts conflict is this:

  return axisSpec.showDuplicatedTicks ? allTicks : getUniqueValues(allTicks, 'axisTickLabel', true);

I did this conversion to ternary when we looked at axis code together, but then I also introduced axisTickLabel so you can just accept the current one on merge

@wayneseymour
Copy link
Member Author

Running the vrt now on my latest changes, if it passes, I'll push

@wayneseymour wayneseymour force-pushed the refactor/triple-equals-true branch from 4219fbd to d59bdd2 Compare September 9, 2021 11:13
: makeHighContrastColor(textColor, backgroundColor, textContrast);
? makeHighContrastColor(`rgb(${inverted})`, backgroundColor, ratio || undefined)
: makeHighContrastColor(`rgba(${inverted}, ${to})`, backgroundColor, ratio || undefined)
: makeHighContrastColor(textColor, backgroundColor, ratio || undefined);
Copy link
Member Author

Choose a reason for hiding this comment

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

Now that I think about it, this could be simply , ratio...should be undefined if it's not passed.

Copy link
Member Author

Choose a reason for hiding this comment

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

@monfera thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

I can explain my way why we should refactor this function in a different way:

  1. calling makeHighContrastColor with an rgba or rgb color is exactly the same. The internal code take care of the values.
  2. we can always write an rgba color starting from an rgb color adding opacity 1
  3. the ratio or is defined and a number if not it should be left undefined living the makeHighContrastColor use the default value
export function getTextColorIfTextInvertible(
  textColorIsDark: boolean,
  backgroundIsDark: boolean,
  textColor: Color,
  textContrast: TextContrast,
  backgroundColor: Color,
): Color {
  const finalTextColor = textColorIsDark === backgroundIsDark ? invertColor(stringToRGB(textColor)) : textColor;
  const contrastRatio = typeof textContrast === 'number' ? textContrast : undefined;
  return textContrast === false
    ? finalTextColor
    : makeHighContrastColor(finalTextColor, backgroundColor, contrastRatio);
}

function invertColor({ r, g, b, opacity }: RgbObject): Color {
  return `rgba(${255 - r}, ${255 - g}, ${255 - b}, opacity: ${opacity})`;
}

I have some doubts on the real need of this function anyway, but if we extract it out of the context this is my solution

@wayneseymour
Copy link
Member Author

jenkins test this

@wayneseymour wayneseymour marked this pull request as ready for review September 9, 2021 15:25
@wayneseymour wayneseymour requested a review from monfera September 9, 2021 15:26
@wayneseymour
Copy link
Member Author

jenkins test this

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

Successfully merging this pull request may close these issues.

3 participants