Skip to content

Comments

feat(legend): add "list" layout for horizontal legends#2784

Open
maryam-saeidi wants to merge 52 commits intoelastic:mainfrom
maryam-saeidi:kibana-238777-list-legend
Open

feat(legend): add "list" layout for horizontal legends#2784
maryam-saeidi wants to merge 52 commits intoelastic:mainfrom
maryam-saeidi:kibana-238777-list-legend

Conversation

@maryam-saeidi
Copy link
Member

@maryam-saeidi maryam-saeidi commented Jan 27, 2026

Summary

A new List legend layout is now available for horizontal legends (top/bottom), offering a more space-efficient alternative to the existing GridList/Table layout. In the list layout each legend item flows inline — label, color marker, and values are arranged in a compact row that wraps naturally, making it easier to scan many series without excessive scrolling.

The list layout supports all standard legend features: series highlighting, filtering via actions, CurrentAndLastValue display with stable column widths, and label truncation.

image

Example usage

<Chart>
    <Settings
        showLegend
        legendPosition={Position.Bottom}
        legendLayout="list"  // <-- new prop
        legendValues={[LegendValue.CurrentAndLastValue]}
    />
    <Axis id="bottom" position={Position.Bottom} />
    <Axis id="left" position={Position.Left} />
    <BarSeries
        id="bars"
        xScaleType={ScaleType.Ordinal}
        yScaleType={ScaleType.Linear}
        xAccessor={0}
        yAccessors={[1]}
        data={[
            ["A", 10],
            ["B", 20],
            ["C", 15],
        ]}
    />
</Chart>

Demo

Screen.Recording.2026-02-17.at.10.40.26.mov

Details

Layout & rendering

  • Added legendLayout: 'list' option to the Settings spec, enabling the list layout for horizontal legends
  • Created LegendList component (legend_list.tsx) that renders legend items as inline <li> elements with label, color, values, and optional action grouped together
  • Legend values display a title prefix in list layout (e.g. VALUE: 42, AVG: 10)
  • CurrentAndLastValue shows a placeholder when no value is available (e.g. on hover)
  • Labels are truncated by pixel width limit in list layout (controlled by theme.legend.labelOptions.widthLimit)

Stable column widths

  • Added getLegendMaxFormattedValue to the ChartSelectors interface, allowing each chart type to provide the longest formatted Y domain value
  • Implemented the XY chart selector that formats the max Y domain value through each series' tick formatter and returns the longest result
  • The max formatted value width is computed via canvas text measurement (withTextMeasure) and used as minWidth on CurrentAndLastValue cells, preventing layout shift on hover

Legend sizing

  • Added computeHorizontalLegendRowCount utility that measures items and lays them out greedily row-by-row to determine if the legend fits in 1, 2, or 3+ rows — short-circuiting as soon as a third row is reached
  • Legend height is computed based on the row count (single-line, two-line, or multi-line)
  • Added shouldDisplayGridList and shouldDisplayTable helpers to select the correct layout mode based on legend values, position, and layout config

Other

  • Renamed _legend.scss_legend_grid_list.scss for clarity
  • Added storybook story for the new layout (2_legend_layout.story.tsx)
  • Added unit tests for computeHorizontalLegendRowCount and the shouldDisplay* helpers

Issues

Related to elastic/kibana#238777

Checklist

  • The proper feature labels have been added (e.g. :interactions, :axis)
  • All related issues have been linked (i.e. closes #123, fixes #123)
  • New public API exports have been added to packages/charts/src/index.ts
  • Unit tests have been added or updated to match the most common scenarios
  • The proper documentation and/or storybook story has been added or updated
  • The code has been checked for cross-browser compatibility (Chrome, Firefox, Safari, Edge)
  • Visual changes have been tested with light and dark themes

🤖 This pull request was assisted by Cursor

@maryam-saeidi maryam-saeidi self-assigned this Jan 27, 2026
@maryam-saeidi maryam-saeidi added the :legend Legend related issue label Jan 27, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new "list" layout option for chart legends to improve space efficiency and usability when displaying many data series. The list layout is now the default for legends positioned at the top or bottom, while maintaining backward compatibility through an optional legendLayout prop that allows users to switch between list and table views.

Changes:

  • Added new LegendLayout enum with List and Table options as a public API
  • Implemented list-based legend rendering with horizontal wrapping for top/bottom positions
  • Enhanced label truncation to support both line-based and pixel-based width limits

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/charts/src/utils/common.tsx Defines new LegendLayout enum and Layout type
packages/charts/src/specs/settings.tsx Adds legendLayout prop to LegendSpec interface
packages/charts/src/utils/themes/theme.ts Extends LegendLabelOptions with widthLimit property and makes maxLines optional
packages/charts/src/components/legend/legend.tsx Updates rendering logic to conditionally render grid list or list layout
packages/charts/src/components/legend/legend_item_list.tsx New component implementing horizontal list layout for legends
packages/charts/src/components/legend/label.tsx Enhances label truncation with pixel-based width limiting
packages/charts/src/common/legend.ts Adds logic to determine when to display table vs grid list vs list layouts
packages/charts/src/state/selectors/get_legend_size.ts Improves legend height calculation for multi-row list layouts
storybook/stories/legend/2_legend_layout.story.tsx New story demonstrating the legend layout feature

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@maryam-saeidi
Copy link
Member Author

buildkite update vrt

@maryam-saeidi
Copy link
Member Author

buildkite update vrt

@maryam-saeidi
Copy link
Member Author

buildkite update vrt

@maryam-saeidi
Copy link
Member Author

buildkite update vrt

@maryam-saeidi maryam-saeidi changed the title feat(legend): Add additional "list" layout feat(legend): add "list" layout for horizontal legends Feb 17, 2026
@maryam-saeidi
Copy link
Member Author

buildkite update vrt

@maryam-saeidi maryam-saeidi marked this pull request as ready for review February 17, 2026 11:30
@delanni
Copy link
Collaborator

delanni commented Feb 18, 2026

buildkite build this

@maryam-saeidi maryam-saeidi added the enhancement New feature or request label Feb 19, 2026
@elastic-datavis
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request :legend Legend related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Lens] New "List" legend by default

2 participants