feat(bar_chart): add shadow prop for value labels#785
feat(bar_chart): add shadow prop for value labels#785dej611 merged 13 commits intoelastic:masterfrom
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.
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.
I also increased the size of the value font size to 12.
There was a problem hiding this comment.
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.
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.
@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.
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.
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
| fontStyle: 'normal', | ||
| padding: 0, | ||
| fill: color('value color', '#000'), | ||
| shadowColor: color('shadow color', 'transparent'), |
There was a problem hiding this comment.
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.
by default in the chart config or just on this one story?
There was a problem hiding this comment.
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.
|
elizabetdev
left a comment
There was a problem hiding this comment.
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.
markov00
left a comment
There was a problem hiding this comment.
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
| textInvertible: boolean; | ||
| textContrast?: number | boolean; | ||
| textBorder?: boolean; | ||
| }; |
There was a problem hiding this comment.
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.
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
| 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.
This probably is a breaking change that needs to be notified
stories/bar/bars.stories.tsx
Outdated
| 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.
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.
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.
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:
transparentbe the default value? I think so, but maybe there's a better idea.shadowor something else? I started with abox shadowtechnique to start with, hence the nameshadow. But now it is probably something different.Checklist
src/index.ts(and stories only import from../srcexcept for test data & storybook)