Skip to content

Parcoords: Use paper background color for text shadow for better dark mode #5506

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

Merged
merged 6 commits into from
Feb 19, 2021

Conversation

jonmmease
Copy link
Contributor

Extracted from #5500.

Overview

Simple change to parcoords to use the figure's paper_bgcolor as the text shadow color and the axis brush border color. Before, these colors were hard-coded to white. This makes parcoords usable with a dark background.

Before

parcoords_dark_before

After

parcoords_dark_after

@archmoj archmoj added status: reviewable bug something broken labels Feb 16, 2021
@archmoj archmoj added this to the NEXT milestone Feb 16, 2021
@archmoj archmoj requested a review from alexcjohnson February 16, 2021 03:32
@jonmmease
Copy link
Contributor Author

Thanks for the feedback @archmoj, it all makes good sense! I'll try to make the updates this evening.

@jonmmease
Copy link
Contributor Author

@archmoj, I believe all of your suggestions are implemented now. Thanks!

@archmoj
Copy link
Contributor

archmoj commented Feb 17, 2021

Discussing this PR with @alexcjohnson, we thought we need a layout attribute to control the color of (text) shadows depending on light/dark backgrounds.
@alexcjohnson could you please spec that out?

paperColor + ' 1px 1px 2px, ' +
paperColor + ' 1px -1px 2px, ' +
paperColor + ' -1px -1px 2px')
.style('text-shadow', svgTextUtils.makeTextShadow(1, 1, 2, paperColor))
Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting to see that parcats uses different "2" for blur-radius instead of 1.
@alexcjohnson do you think we should declare and unify this in a new layout container?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Good 👁️
To me the 1 vs 2 doesn't make much visible difference, I'd probably standardize on 1. Also given that the purpose here is really outlining rather than a 3D-like shadow I'd combine offsetX and offsetY into a single offset.

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 fine switching to 1 and regenerating the parcats baselines. And fine with combining the offsets.

var x = offsetX + 'px ';
var y = offsetY + 'px ';
var b = blurRadius + 'px ';
var clr = color + ' ';
Copy link
Collaborator

Choose a reason for hiding this comment

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

what's this space for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nothing, will 🔪

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in #9871117

@alexcjohnson
Copy link
Collaborator

Discussing this PR with @alexcjohnson, we thought we need a layout attribute to control the color of (text) shadows depending on light/dark backgrounds.
@alexcjohnson could you please spec that out?

I was thinking a trace attribute actually, named to correspond with whatever trace attribute sets the color of the text we're outlining. I wonder actually whether we could put this attribute into that font container, or if that would cause problems given that font containers have a standardized structure?

Anyway, the logic for the default outline color, as @archmoj and I discussed:

  • If the font color is light and the paper color is dark or vice versa, default to the paper color.
  • If both are light, default to black
  • If both are dark, default to white
    Looks to me as though this can be implemented using just Color.contrast (which gives #444 rather than #000 for dark but I think that may be what we want?):
var fontContrast = Color.contrast(fontColor);
var paperContrast = Color.contrast(paperColor);
var dfltOutlineColor = (fontContrast === paperContrast) ? fontContrast : paperColor;

@alexcjohnson
Copy link
Collaborator

For now we could probably just use that logic without adding a new outline color attribute.

@jonmmease
Copy link
Contributor Author

A potential issue choosing the shadow automatically is that, for parcats and sankey, it's not the background color you would want to consider to determine contrast, it's the path color that the text is on top of.

@alexcjohnson
Copy link
Collaborator

it's not the background color you would want to consider to determine contrast, it's the path color that the text is on top of.

The point is just to create contrast with the text color. If it looks like the paper color will do that we would use it because we know this will fit with the overall style of the plot, otherwise use black or white. There can be lots of path colors, and your labels can bleed off the paths and onto the background, so I don't think we should involve path color at all.

@jonmmease
Copy link
Contributor Author

Ok, here's what the auto cases look like for parcats:

newplot (18)

newplot (19)

These make it pretty obvious that we don't currently use a shadow for the dimension labels, so it's not really usable this way in current form unless we add dimension label shadows as well.

My perspective on this is that currently, if a user changes to a dark paper color they already need to change the font color to something light for basically any of our traces to look good. By having the shadow always match the paper color, the internal parcats/parcoords/sankey labels have the same color contrast characteristics as any other text that ends up being drawn on the paper (titles, tick labels, etc.).

It doesn't really feel helpful to me for these labels to be special cases in terms of their contrast behavior. Unless our long-term goals is to go all in here and add shadows to all text when we determine there is poor contrast.

@alexcjohnson
Copy link
Collaborator

By having the shadow always match the paper color, the internal parcats/parcoords/sankey labels have the same color contrast characteristics as any other text that ends up being drawn on the paper (titles, tick labels, etc.).

Sold. Those examples with similar text & paper colors look hideous using my proposed logic.

Unless our long-term goals is to go all in here and add shadows to all text when we determine there is poor contrast.

Probably not automatically, but I am starting to think we should add shadow support to all fonts at some point, and then this can just be used as the default shadow for the relevant fonts.

@@ -755,6 +755,16 @@ function alignHTMLWith(_base, container, options) {
};
}

exports.makeTextShadow = function(offset, color) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Now that offset is always 1, let's simplify this function:

exports.makeTextShadow = function(color) {
    return (
       '1px 1px 1px' + color + ', ' +
       '-1px -1px 1px' + color + ', ' +
       '1px -1px 1px' + color + ', ' +
       '-1px 1px 1px' + color
   );
};

But wait why do we need these four corners?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@archmoj
Copy link
Contributor

archmoj commented Feb 18, 2021

Nicely done.
💃

@jonmmease jonmmease merged commit c99b6c2 into master Feb 19, 2021
@jonmmease
Copy link
Contributor Author

Thanks @archmoj !

@alexcjohnson alexcjohnson deleted the parcoords_text_shadow branch March 2, 2021 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants