-
Notifications
You must be signed in to change notification settings - Fork 121
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(legend): add point shape styles to legend item #1227
Conversation
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 haven't runtime tested; please consider some code changes, see the comments
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 took a look at the point shapes example and looks like that square doesn't support the fill property as specified in the chart. We should fully align the shapes styles to the one in the chart. If the square has a red border and a yellow fill, we should reflect this in the legend
This makes a lot of sense to me - I have removed the fill for the square icon in this commit 37cf9c1 |
packages/charts/src/chart_types/xy_chart/state/selectors/compute_legend.ts
Show resolved
Hide resolved
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.
Ok sorry for all the back and forth. I think this is good to merge now. We can discuss my changes tomorrow and modify them as you see fit.
packages/charts/src/chart_types/xy_chart/renderer/shapes_paths.ts
Outdated
Show resolved
Hide resolved
@@ -196,6 +206,7 @@ export class LegendListItem extends Component<LegendItemProps, LegendItemState> | |||
isSeriesHidden={isSeriesHidden} | |||
hasColorPicker={hasColorPicker} | |||
onClick={this.handleColorClick(hasColorPicker)} | |||
pointStyle={alignLegendPointStyles ? pointStyle : undefined} |
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.
Used to explicitly control legend point style alignment by user. We could infer when to apply the styles as a fallback by comparing the local [area/line/bubble]SeriesStyles.point
to the respective value on the Theme
. This could be something like...
deepEqual(areaSeriesStyles.point, theme.area.point, true); // true for partial comparison
But that seems a bit much for now.
@@ -46,14 +46,14 @@ export const Color = memo( | |||
title="change series color" | |||
ref={ref} | |||
> | |||
<Icon type="dot" color={color} aria-label={`Change series color, currently ${color}`} /> | |||
<LegendIcon pointStyle={pointStyle} color={color} ariaLabel={`Change series color, currently ${color}`} /> |
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'm not sure about this in the future. When the point styles take over this could mean the series color being selected/set would not be reflected in the color icon. Should revisit at a later time.
@markov00 @nickofthyme updated the vrts in 46ab4e4. The large file change is because of the styling for the pointStyles are taken from the theme by default with the empty fill. Let me know if this looks good to you thanks! |
@elastic/eui-design do you mind providing a review on this PR please? |
jenkins test this please |
@miukimiu the basic changes here is that for any area, line or bubble chart that has visible points we use the point styles on the legend icon. This would mean all area, line and bubble series styles now have hollow points with white fill. 👇🏼 If this is not desirable we could only apply the styles to the legend icon with they differ from the main them styles. |
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.
tl;dr using solid colored shapes would help readability and accessibility, for when there's no solid/holey shape ambiguity on a given chart. WCAG guidelines don't sufficiently address, yet still acknowledge the impact of shape size and aspect ratio when it comes to distinguishing colors or contrast. An example: given the same bounding box for the marker in the legend, the full paint of that bounding box will be more ink than a solid disk in that bounding box, which is still better than, say, an empty circle with a thin border.
Thanks for letting in a late comment after the Kibana testing week and PTO. I'd still like to squeeze in a question relating to this as a significant BREAKING change, specifically, the mass changes to mocks due to solid to hollow markers, as those can't be solved well with a follow-up PR.
If there's a variety of markers, it's indeed great to give the user a marker shape cue, as in this change, which is good for cross-referencing and accessibility:
Yet most charts, thankfully, don't have a plethora of marker types. In fact it's often unhelpful to mix marker types, as
- on line charts, it's redundant, and the markers themselves introduce noise (see the above example for this as well - it's exaggerated, but real line charts will turn to such barbed wire charts easily)
- on scatterplots, each marker type has different characteristics (ink surface area; ink bounding box; occlusion effects; crowding effects; perceptibility, saliency etc.) so a medium or high overplotting scatterplot will be a bit of a mess
- etc
Mixing marker types can be great for aiding accessibility, if the data and chart configuration are conducive to it (not too many lines; not too large, yet discernible markers etc) as a redundant way to disambiguate lines, but then the same shape (eg. empty circle) shouldn't be reused with diverse colors.
The upshot is that most of the charts won't need legend disambiguation for marker shape.
Using holey markers (circle instead of disk etc.) has the negative that the legend ink area is diminished to a fraction of it, which reduces the ability to find the right legend item, discern colors etc. and is thus an accessibility issue. Even if the shape is holey on the line, it's easier to discern the color of a long line than of a small circle. Even if we disregard it, it's useful if at least the legend colors have significant "meat", for easier cross-referencing.
Proposal:
- use solid markers in the legend if there's no ambiguity about holey vs solid markers on a given chart
- even if the user opts for some other marker, eg.
x
everywhere on a chart, use solid colors in the legend (*) - if it's needed, please point a well discussed use case (eg. issue comments, PR comments here and conclusions) and add an option for enforcing the behavior currently in this PR commit; eg. which user team would need holey legends on non-ambiguous charts, and why
(*) Comments for where it might be heading, post this PR:
Currently, the legends area is a singleton on the chart. Therefore the encoded information of the markers are conflated. For example, it's currently not possible to have three distinct legends for color, marker type and size. This impairs readability of each encoding channel. So the long term thing is to treat legends as data visualizations in and of themselves (a recurring theme) so that a legend is not a singleton on the chart, and also, so that multiple charts can share some legend(s).
In light of such future, we can restate my request this way: when there's no marker ambiguity, let's NOT EVEN try to use the legend swatch to convey anything about marker shape; it's just a color swatch.
Also, having decoupled the marker shape from the color assignment for non-ambiguous cases, we can do better and switch to squares or rectangles for the color swatch (with or without rounded corner) to further increase the color ink area.
function getPointStyle(spec: BasicSeriesSpec, theme: Theme): PointStyle | undefined { | ||
const mergeOptions: MergeOptions = { mergeOptionalPartialValues: true }; | ||
if (isBubbleSeriesSpec(spec)) { | ||
return mergePartial(theme.bubbleSeriesStyle.point, spec.bubbleSeriesStyle?.point, mergeOptions); | ||
} else if (isLineSeriesSpec(spec)) { | ||
return mergePartial(theme.lineSeriesStyle.point, spec.lineSeriesStyle?.point, mergeOptions); | ||
} else if (isAreaSeriesSpec(spec)) { | ||
return mergePartial(theme.areaSeriesStyle.point, spec.areaSeriesStyle?.point, mergeOptions); | ||
} | ||
} |
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's not a PR comment, yet a great example for how TS leads to hoops we have to jump through (in the code, as well as runtime) to satisfy its type verification operations. TS requires a specific, and sometimes artificial coding style. Maybe we could eventually move the series type to distinct classes, as class instances have both static and runtime type, and something like this if
cascade would become a simple method call
For the scope of this PR, after discussing with the team, we will make sure the legend icon is filled in all cases. Subsequent PRs can handle the stroke width computations and potential styling where the icon would not be filled or have unique styling (such as the marker on the series being one color, the stroke border being another color, then the icon in the legend could reflect this). I opened issue 1267 for tracking discussions beyond this PR. Thanks! |
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.
Changes looks good to me!
# [33.1.0](v33.0.2...v33.1.0) (2021-07-28) ### Bug Fixes * persisted color via color picker ([#1265](#1265)) ([4205a7f](4205a7f)) ### Features * **legend:** add point shape styles to legend item ([#1227](#1227)) ([46be1d1](46be1d1)) * **partition:** waffle chart ([#1255](#1255)) ([156662a](156662a))
🎉 This PR is included in version 33.1.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Summary
By assigning a
pointStyle.shape
to a line, bubble or area series, legend item icons now show the appropriate shape of the markers. For instance, if a user specifies a hollowsquare
shape, that is what will render for the legend marker for that series. By default, the legend icons are filled.Details
Subsequent PRs will handle the stroke width computations and potential styling where the icon would not be filled or have unique styling (such as the marker on the series being one color, the stroke border being another color, then the icon in the legend could reflect this).
Issues
Closes #1081
Checklist