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

feat(legend): multiline labels with maxLines option #1285

Merged
merged 16 commits into from Aug 6, 2021

Conversation

nickofthyme
Copy link
Collaborator

@nickofthyme nickofthyme commented Aug 4, 2021

Summary

The labelOptions.maxLines property is now available in on Theme.legend type to set the max number of lines a legend label can take-up before it is truncated.

Screen Recording 2021-08-06 at 05 02 36 PM

Details

When enabled the multiline mode will trigger items to be align from the top (i.e. flex-start). These style changes have no affect on existing single line legend labels.

Screen.Recording.2021-08-05.at.11.43.31.AM.mp4

Issues

#1245

Checklist

  • The proper chart type label was added (e.g. :xy, :partition) if the PR involves a specific chart type
  • The proper feature label was added (e.g. :interactions, :axis) if the PR involves a specific chart feature
  • Whenever possible, please check if the closing issue is connected to a running GH project
  • Any consumer-facing exports were added to packages/charts/src/index.ts (and stories only import from ../src except for test data & storybook)
  • This was checked for cross-browser compatibility
  • Proper documentation or storybook story was added for features that require explanation or tutorials
  • Unit tests were updated or added to match the most common scenarios

@nickofthyme nickofthyme added enhancement New feature or request :legend Legend related issue :styling Styling related issue :all Applies to all chart types labels Aug 4, 2021
@@ -43,6 +48,7 @@ $legendItemHeight: #{$euiFontSizeXS * $euiLineHeight};
display: flex;
justify-content: center;
align-items: center;
height: $legendItemHeight;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

makes the focus size of the action the same as the color dot

});

return isToggleable ? (
<button
type="button"
className={labelClassNames}
title={label}
title={options?.multiline ? '' : label} // full text already visible
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't think the title is necessary if the full label is visible

@nickofthyme nickofthyme marked this pull request as ready for review August 5, 2021 14:42
@nickofthyme
Copy link
Collaborator Author

Improves inside legends ability to adapt to small widths. The inside legend styles, still needs some help (not in this pr).

image

Copy link
Contributor

@monfera monfera left a comment

Choose a reason for hiding this comment

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

Looks great so far! Should we breakup long words? Or maybe there's some upper limit to row count at play here:

image

@nickofthyme
Copy link
Collaborator Author

Should we breakup long words?

We could could add another option for overflow-wrap

Or maybe there's some upper limit to row count at play here

We could add a maxLines option like flutter does. I'm not sure if that's needed for the first pass, what do you think?

@@ -1147,6 +1147,11 @@ export interface LegendColorPickerProps {
// @public (undocumented)
export type LegendItemListener = (series: SeriesIdentifier[]) => void;

// @public (undocumented)
export interface LegendLabelOptions {
multiline: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

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

In partition chart, not for the legend, we use a maxRowCount property, which might be useful here and be a slightly more uniform API. So, a value of 1 would be the default, and it could be whatever number incl. Infinity if unbounded. While it's not integral to the task, it feels useful to set some sensible row count, and with a maxRowCount there's no need to break the API in the future, or introduce an additional property, which is only applicable with a multiline: true value. If a row count is deemed useful, we can preemptively cut down on ifs, ternaries and union types 😸

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah so you are thinking change multiline option to maxRowCount?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done here d8be979

@@ -45,6 +46,7 @@ export interface LegendItemProps {
positionConfig: LegendPositionConfig;
extraValues: Map<string, LegendItemExtraValues>;
showExtra: boolean;
labelOptions?: LegendLabelOptions;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: could it be relatively easily solved such that it's only the user facing config API where this is optional, but we can rely on its presence everywhere downstream? Ie. one question mark only

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You saying labelOptions: LegendLabelOptions;?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, it's an internal type, by this time the reification (augmentation with defaults etc.) of the user input should've happened (if we have shared buy-in of how it often simplifies the implementation and prevents us from possibly handling the non-specified nullish case at multiple places, so also a DRY principle)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done here d8be979

interface LabelProps {
label: string;
isSeriesHidden?: boolean;
isToggleable?: boolean;
onClick?: MouseEventHandler;
options?: LegendLabelOptions;
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: same here, maybe all such optionality like can go away except for the single public API enty point. I admit to having done plenty of this in code I wrote, more recently thinking that it'd be more economical to reify user input right away, and then avoid having to worry about partials, optionals etc.

We can think about removing question marks from non-@public types, TS is great for safely allowing such a transition, in the meantime we can consider avoiding them in new code

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done here d8be979

Comment on lines +177 to +178
const getPositionalUrl = (p1: string, p2: string, others: string = '') =>
`http://localhost:9001/?path=/story/legend--inside-chart&knob-vAlign_Legend=${p1}&knob-hAlign_Legend=${p2}${others}`;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixes knob to align with correct vAlign and hAlign properties.

@nickofthyme nickofthyme linked an issue Aug 5, 2021 that may be closed by this pull request
3 tasks
@monfera monfera self-requested a review August 5, 2021 17:06
Copy link
Contributor

@monfera monfera left a comment

Choose a reason for hiding this comment

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

Good improvement 🎉 Approving it as there's no blocker.

Optional notes:

  • if possible, tweak the CSS such that what's hidden now in case of very long, unbroken words would show up, but no need to invest too much time into it, as the user provided formatter function can detect and apply delimiters eg. at every 10 characters (so the user can solve cornercase need)
  • prefer using maxRowCount as it's numerical and reuses a name with the like meaning instead of the boolean, even if we initially support 1 and some other value eg. Infinity (if CSS reasonably supports a row count, we can use it now or in some future PR, or JS if really needed in the future)
  • prefer nullish coalescing of new API properties right at the entrance, so that the entire implementation has a fixed type to work with

@nickofthyme
Copy link
Collaborator Author

Replaced multiline option with maxLines option in d8be979.

  • 0 - true multiline, unconstrained.
  • 1 - as is today simple text-overflow, nowrap, etc.
  • >1 - limit lines of text to a finite value.
Screen.Recording.2021-08-05.at.05.28.28.PM.mp4

@@ -366,6 +366,7 @@ describe('Interactions', () => {
{ left: 282, top: 80 },
{
screenshotSelector: '#story-root',
delay: 1000,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This story was misbehaving, need to look into more later.

@@ -6,12 +6,17 @@ $legendItemHeight: #{$euiFontSizeXS * $euiLineHeight};
display: flex;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
align-items: flex-start;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This caused a slight diff in the inside legends but I think it's acceptable.

Comment on lines +45 to +54
// This div is required to allow multiline text truncation, all ARIA requirements are still met
// https://stackoverflow.com/questions/68673034/webkit-line-clamp-does-not-apply-to-buttons
<div
role="button"
tabIndex={0}
className={labelClassNames}
title={label}
title={title}
onClick={onClick}
onKeyDown={onKeyDown}
aria-pressed={isSeriesHidden}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Converted to button due to this, added all required ARIA props to make it seem like a button.

Comment on lines +203 to +213
<div className="colorWrapper">
<ItemColor
ref={this.colorRef}
color={color}
seriesName={label}
isSeriesHidden={isSeriesHidden}
hasColorPicker={hasColorPicker}
onClick={this.handleColorClick(hasColorPicker)}
pointStyle={pointStyle}
/>
</div>
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is to prevent jitter when using EuiWrappingPopover to display the color picker. Before this was picked using :first-of-type but this is more strict though a little more verbose.

@nickofthyme
Copy link
Collaborator Author

Linting job hung up for 30 minutes for some reason, not cancelable. Ran locally with no errors so gonna merge.

@nickofthyme nickofthyme merged commit e0eb096 into elastic:master Aug 6, 2021
@nickofthyme nickofthyme deleted the multiline-legend-labels branch August 6, 2021 15:31
@nickofthyme nickofthyme changed the title feat(legend): multiline labels feat(legend): multiline labels with maxLines option Aug 6, 2021
github-actions bot pushed a commit that referenced this pull request Aug 6, 2021
# [33.2.0](v33.1.0...v33.2.0) (2021-08-06)

### Bug Fixes

* heatmap snap domain to interval ([#1253](#1253)) ([b439182](b439182)), closes [#1165](#1165)
* hex colors to allow alpha channel ([#1274](#1274)) ([03b4f42](03b4f42))

### Features

* **bullet:** the tooltip shows up around the drawn part of the chart only ([#1278](#1278)) ([a96cbb4](a96cbb4))
* **legend:** multiline labels with maxLines option ([#1285](#1285)) ([e0eb096](e0eb096))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:all Applies to all chart types enhancement New feature or request :legend Legend related issue :styling Styling related issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Legend] Improved readability on long legend values
2 participants