-
Notifications
You must be signed in to change notification settings - Fork 122
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
feat(bar_chart): add shadow prop for value labels #785
Conversation
I would consider increasing the shadow size, or making it configurable. |
Technically is possible, but I would leave it as last resort. |
@dej611 we should get some feedback from @miukimiu here as a design eye can be very useful. |
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.
Ideally, we should by default set the value color to white or black based on the contrast of the bar fill. And always ensure a shadow to increase the readability. Like this example from highcharts.
But if it's not possible right now, I would just improve the example by changing the value labels to white, add a shadow and increase the font-size.
@@ -61,6 +61,7 @@ export const Example = () => { | |||
fontStyle: 'normal', | |||
padding: 0, | |||
fill: color('value color', '#000'), |
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 also increased the size of the value font size to 12.
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 think it should be a default setting or just a better starting point for this example?
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 was seeing the other charts where we have labels/values on top and normally they are black or with textInvertible: true
So for consistency, I think we should keep the value labels black and just increase the size to 12.
How do you feel of then creating a second example to show that the value label can be customized? In this new example, you would use white value labels with a shadow.
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.
@miukimiu which would you prefer?
- Changing color contrast of the shadow
- Changing color contrast of the text itself
- Either of the above depending on if a shadow is enabled
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.
From my understanding when it flips the color on text the shadow should change too.
But you are right, there is also the additional scenario where the shadow is not enabled (transparent
?) and only the text changes.
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.
Yeah thats true but I was actually thinking that the shadow be null
or undefined
, as it's not needed when the text contrast is dynamic.
stories/bar/2_label_value.tsx
Outdated
@@ -61,6 +61,7 @@ export const Example = () => { | |||
fontStyle: 'normal', | |||
padding: 0, | |||
fill: color('value color', '#000'), | |||
shadowColor: color('shadow color', 'transparent'), |
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 we should enforce the use of a shadow:
shadowColor: color('shadow color', 'transparent'), | |
shadowColor: color('shadow color', 'rgba(0,0,0,1)'), |
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.
by default in the chart config or just on this one story?
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.
Forgotten to report here, just the story.
Codecov Report
@@ Coverage Diff @@
## master #785 +/- ##
==========================================
- Coverage 70.01% 69.97% -0.04%
==========================================
Files 321 336 +15
Lines 10508 10198 -310
Branches 2221 2035 -186
==========================================
- Hits 7357 7136 -221
+ Misses 3142 2995 -147
- Partials 9 67 +58
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
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.
Tested locally and LGTM! 🎉
The shadow definitely improves the readability and it makes it possible to read value labels when a bar is too small in height.
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.
LGTM, tested locally.
I've just wrote a few comments with small improvements.
I think we can also reduce the scope of the storybook story to a smaller dataset and a smaller number of options or highlighting them on a different tab
api/charts.api.md
Outdated
textInvertible: boolean; | ||
textContrast?: number | boolean; | ||
textBorder?: boolean; | ||
}; |
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.
It would be great to add also the border width as a customizable option. This can help create different themes and adjust the theme when consuming the chart
ctx.lineWidth = 1.5; | ||
ctx.strokeStyle = font.shadow; | ||
ctx.strokeText(text, origin.x, origin.y); | ||
ctx.shadowBlur = 0; |
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.
shadowBlur is by default 0, probably you want to disable the shadowBlur
if configured in the context somewhere else and probably before writing the stroke, so moving this before the strokeText call or before the if statement you want to apply that reset also to the fillText
src/utils/themes/theme.ts
Outdated
export type DisplayValueStyle = Omit<TextStyle, 'fill'> & { | ||
offsetX: number; | ||
offsetY: number; | ||
fill: | ||
| Color | ||
| { color: Color; borderColor?: Color } | ||
| { | ||
textInvertible: boolean; | ||
textContrast?: number | boolean; | ||
textBorder?: boolean; | ||
}; |
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.
This probably is a breaking change that needs to be notified
stories/bar/bars.stories.tsx
Outdated
@@ -35,6 +35,7 @@ export { Example as withLinearXAxisNoLinearInterval } from './6_linear_no_linear | |||
export { Example as withTimeXAxis } from './7_with_time_xaxis'; | |||
export { Example as withLogYAxis } from './8_with_log_yaxis'; | |||
export { Example as withStackedLogYAxis } from './9_with_stacked_log'; | |||
export { Example as withValueLabelAdvanced } from './50_label_value_advanced'; |
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.
can you move this right after the other withValueLabel
so the user can play directly with the advanced settings?
Codecov Report
@@ Coverage Diff @@
## master #785 +/- ##
==========================================
- Coverage 70.01% 69.97% -0.04%
==========================================
Files 321 336 +15
Lines 10508 10198 -310
Branches 2221 2035 -186
==========================================
- Hits 7357 7136 -221
+ Misses 3142 2995 -147
- Partials 9 67 +58
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
Codecov Report
@@ Coverage Diff @@
## master #785 +/- ##
==========================================
+ Coverage 69.76% 70.08% +0.32%
==========================================
Files 321 336 +15
Lines 10566 10889 +323
Branches 2171 2211 +40
==========================================
+ Hits 7371 7632 +261
- Misses 3186 3242 +56
- Partials 9 15 +6
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
}; | ||
|
||
const debug = boolean('debug', false); | ||
const useInverted = boolean('textInverted', false); |
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 was a bit surprised that the inverted colors aren't configurable in any way, was this intentional?
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. There are basically three configurations available for DisplayValueLabels
text:
// basic coloring
Color
|
// advanced coloring
{
color: Color;
borderColor?: Color;
borderWidth?: number;
}
|
// let the library compute it
{
textInvertible: boolean;
textContrast?: number | boolean;
textBorder?: number | boolean;
};
The only way to influence the library color pick in case of automatic color assignment is the textContrast
parameter, which influence the threshold for the automatic switch between black and white.
This is consistent with other DisplayValueLabels
APIs like the partitions one.
# [24.0.0](v23.2.1...v24.0.0) (2020-10-19) ### Bug Fixes * **annotation:** annotation rendering with no yDomain or groupId ([#842](#842)) ([f173b49](f173b49)), closes [#438](#438) [#798](#798) ### Features * **bar_chart:** add Alignment offset to value labels ([#784](#784)) ([363aeb4](363aeb4)) * **bar_chart:** add shadow prop for value labels ([#785](#785)) ([9b29392](9b29392)) * **bar_chart:** scaled font size for value labels ([#789](#789)) ([3bdd1ee](3bdd1ee)), closes [#788](#788) * **heatmap:** allow fixed right margin ([#873](#873)) ([16cf73c](16cf73c)) ### BREAKING CHANGES * **bar_chart:** The `DisplayValueStyle` `fontSize` property can now express an upper and lower bound as size, used for the automatic scaling. * **bar_chart:** The `DisplayValueStyle` `fill` property can now express a border color and width, or let the library pick the best match based on contrast using the textInvertible parameter.
🎉 This PR is included in version 24.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
# [24.0.0](elastic/elastic-charts@v23.2.1...v24.0.0) (2020-10-19) ### Bug Fixes * **annotation:** annotation rendering with no yDomain or groupId ([opensearch-project#842](elastic/elastic-charts#842)) ([6bad0d7](elastic/elastic-charts@6bad0d7)), closes [opensearch-project#438](elastic/elastic-charts#438) [opensearch-project#798](elastic/elastic-charts#798) ### Features * **bar_chart:** add Alignment offset to value labels ([opensearch-project#784](elastic/elastic-charts#784)) ([106d924](elastic/elastic-charts@106d924)) * **bar_chart:** add shadow prop for value labels ([opensearch-project#785](elastic/elastic-charts#785)) ([de95b44](elastic/elastic-charts@de95b44)) * **bar_chart:** scaled font size for value labels ([opensearch-project#789](elastic/elastic-charts#789)) ([8b74a9d](elastic/elastic-charts@8b74a9d)), closes [opensearch-project#788](elastic/elastic-charts#788) * **heatmap:** allow fixed right margin ([opensearch-project#873](elastic/elastic-charts#873)) ([dd34574](elastic/elastic-charts@dd34574)) ### BREAKING CHANGES * **bar_chart:** The `DisplayValueStyle` `fontSize` property can now express an upper and lower bound as size, used for the automatic scaling. * **bar_chart:** The `DisplayValueStyle` `fill` property can now express a border color and width, or let the library pick the best match based on contrast using the textInvertible parameter.
Summary
This is just a small PoC that came up while talking with @markov00 about value labels readability.
This PR introduces a new "stroke" level around the value labels in order to increase the contrast with the bar colour: this is particular efficient when the value text color is white and the stroke is some dark color. Using a darker color for the text fill does not provide the same quality result.
There are still some open questions, like:
transparent
be the default value? I think so, but maybe there's a better idea.shadow
or something else? I started with abox shadow
technique to start with, hence the nameshadow
. But now it is probably something different.Checklist
src/index.ts
(and stories only import from../src
except for test data & storybook)