feat(highlight): Add support to configure dimmed (unhighlight) colors for Bar and Partition charts#2774
Conversation
- Add dimmed property to RectStyle and ArcStyle interfaces - Define barFill and arcFill in LIGHT_DIMMED_COLORS and DARK_DIMMED_COLORS - Implement dimmed.fill color rendering in buildBarStyle function - Use reference equality to detect unhighlighted state (geometryStateStyle === sharedStyle.unhighlighted) - Update all theme variants (light, dark, legacy, amsterdam) with dimmed configurations - Add dimmed opacity (0.25) to legacy and amsterdam themes for consistency - Update bar.test.ts to include sharedStyle parameter - Enhance Storybook stories with more series for testing dimming behavior - Add useDimmedColors control to sunburst story for arc testing - Add TODO comments in partition chart renderer for future arc dimming implementation Subject to visual review and calibration of shade values.
Option B: Hybrid Approach - SVG overlay (HighlighterFromHover) for direct slice hover - Canvas dimming for legend hover (consistent with bar/line/area charts) Implementation: - Add highlightedLegendPath to partition chart canvas renderer props - Pass legend path through rendering pipeline to all three renderers - Calculate highlighted quads using highlightedGeoms utility - Apply dimmed.fill colors in renderSectors and renderRectangles - Remove HighlighterFromLegend component (no longer needed) - Keep HighlighterFromHover for immediate slice hover feedback - Update sunburst story to use theme's default dimmed colors Benefits: - Minimally invasive - no architectural changes to hover highlighting - Consistent dimming behavior across all chart types - Better performance (no SVG overlay for legend interactions) - Single source of truth for legend dimming
… renderers The legend hover wasn't working because: 1. highlightedGeoms needs legendStrategy and flatLegend from settings 2. Dimmed fill color needs to come from theme.arcSeriesStyle, not style.arcSeriesStyle (ShapeViewModel.style is Theme['partition'], not the full theme) Changes: - Add legendStrategy and flatLegend to partition canvas renderer props - Add arcSeriesStyle from theme to props - Pass all three through to renderPartitionCanvas2d and other renderers - Use arcSeriesStyle.arc.dimmed.fill instead of style.arcSeriesStyle - Call highlightedGeoms with proper legendStrategy and flatLegend settings
Added controls to test different shade colors for dimmed/unhighlighted states: 1. New Story: Stylings -> Dimmed Colors (27_dimmed_colors.story.tsx) - Permanent feature for users to configure dimmed colors - Shows mixed chart types (bars + lines + areas with points) - Provides shade selection for all XY chart types 2. Enhanced: Legend -> Piechart (10_sunburst.story.tsx) - Added shade color selector for partition charts - Supports all partition layouts (sunburst, treemap, mosaic, waffle) - Allows testing different opacity levels 3. Enhanced: Interactions -> Bar Clicks (1_bar_clicks.story.tsx) - Added shade color selector for bar charts - Allows comparison with existing series Shade Options: - Light mode: shade30 @ 15% to 50% (default: 35%) - Dark mode: shade60 @ 15% to 50% (default: 35%) - 5% increment intervals for fine-tuning This allows visual review and calibration of dimmed colors across all chart types as mentioned in GitHub issue elastic#2416.
… for testing shade/alpha combinations. The story offers: - Test different shade colors from EUI Borealis palette (shade15-shade145) - Test different alpha/opacity values (10%-100% in 5% increments) - See dimmed effect on both partition charts (sunburst/treemap) and XY charts (bar/line/area) - View real-time info panel showing current dimmed color and hovered series
|
buildkite test this |
- Fix LegendPath import path (from state/actions/legend) - Fix LegendStrategy import path (from layout/utils/highlighted_geoms) - Add AnimationState import in canvas_renderers - Add proper type guards for dimmed.fill to handle union type - Update Jest snapshots for bar rendering tests
Revert the test-only additions to 1_bar_clicks.story.tsx and 10_sunburst.story.tsx to avoid VRT baseline changes. The dedicated 27_dimmed_highlight_style.story.tsx serves the testing purpose.
|
buildkite update vrt |
|
buildkite test this |
|
buildkite build this |
|
Thank you @awahab07 for putting this together, I finally got time to look at it and it works great! I think we just have a couple of things to settle before proceeding:
Thanks again Abdul! |
Default shades have been updated to reflect these values.
I've kept them as before.
This should be tackled in #2514, as a follow-up, as mentioned in. But could be evaluated/discussed to see if a separate on-the-fly border should be implemented just for highlight/unhighlight purposes. |
|
buildkite update vrt |
|
buildkite test this |
…-state-style-for-partition-charts-and-barcharts # Conflicts: # e2e/screenshots/legend_stories.test.ts-snapshots/legend-stories/should-all-values-in-stacked-chart-with-filtered-series-nick-chrome-linux.png # e2e/screenshots/legend_stories.test.ts-snapshots/legend-stories/should-render-legend-action-on-mouse-hover-chrome-linux.png
|
buildkite update vrt |
| const isUnhighlighted = highlightedQuadSet.size > 0 && !highlightedQuadSet.has(quad); | ||
| const dimmed = arcSeriesStyle.arc.dimmed; | ||
| const dimmedFill = dimmed && 'fill' in dimmed ? dimmed.fill : undefined; | ||
| const useDimmedColor = isUnhighlighted && dimmedFill; |
There was a problem hiding this comment.
Can we extract this into a function and reuse it?
Probably we have probably a function that is used everytime we need to pick up the a dimmed or non-dimmed color and reuse it elsewhere also on area/line/point charts
| dimmed?: | ||
| | { opacity: number } | ||
| | { |
There was a problem hiding this comment.
This style is actually not used for a Partition chart. the Partition has the PartitionStyle in the theme
| areaPointFill: SEMANTIC_COLORS.plainLight, | ||
|
|
||
| barFill: SEMANTIC_COLORS.shade15, | ||
| arcFill: SEMANTIC_COLORS.shade15, |
There was a problem hiding this comment.
I get where this comes from ArcStyle but we should call it differently, because the same style will be applied on every partition chart, not just the pie chart
| quad.fillColor = dimmedFill; | ||
| if (quad.x0 !== quad.x1) renderTaperedBorder(ctx, quad); | ||
| quad.fillColor = originalFillColor; // Restore |
There was a problem hiding this comment.
if we need to update the color just for that call, I prefer instead passing just the required properties (in case also by revisiting the renderTaperedBorder arguments to accept just the required props and passing them, rather then modifing and restore that value.
| _focus: unknown, | ||
| _animationState: AnimationState, |
There was a problem hiding this comment.
I see where this function get called, we probably need to fix there and call the relative functions with just the minimal amount of arguments, living these arguments there doesn't have much sense
|
buildkite build this |


Summary
Unhighlighted series in bar and partition charts now display a neutral dimmed color instead of reduced opacity, matching the existing behavior in line and area charts.
When hovering over a legend item or series, unhighlighted elements render with a solid neutral gray color:
#ECF1F9) at 100% opacity#384861) at 100% opacityThis provides better visual distinction and consistency across all chart types.
245829_neautral_color_for_unhighlighted_chart_items.mov
Details
Theme Configuration
blueGrey110(#384861) toPRIMITIVE_COLORSandshade110toSEMANTIC_COLORSinbase_colors.tsto align with the latest EUI Borealis paletteLIGHT_DIMMED_COLORS.barFillandarcFillto use solidshade15(#ECF1F9)DARK_DIMMED_COLORS.barFillandarcFillto use solidshade110(#384861)Storybook
Issues
Implements the feature required by elastic/kibana#245829.
Checklist
:xy,:partition):interactions,:axis)closes #123,fixes #123)packages/charts/src/index.tslightanddarkthemes