Skip to content

Conversation

@Qxisylolo
Copy link
Contributor

@Qxisylolo Qxisylolo commented Nov 17, 2025

Description

This pr adds value mapping for remaining charts

Screenshot

pie-value

2025-11-17.14.33.53.mp4

pie-range

2025-11-17.14.34.36.1.mp4

Testing the changes

Changelog

  • feat: add value mapping for pie

Check List

  • All tests pass
    • yarn test:jest
    • yarn test:jest_integration
  • New functionality includes testing.
  • New functionality has been documented.
  • Update CHANGELOG.md
  • Commits are signed per the DCO using --signoff

Summary by CodeRabbit

Release Notes

  • New Features

    • Added value mapping support to pie, bar, heatmap, scatter, histogram, and state timeline visualizations for enhanced color-based data representation.
    • Introduced a new color mode selector UI replacing previous threshold controls, providing options for value mapping, threshold highlighting, and standard coloring across visualization types.
  • Tests

    • Updated visualization tests to reflect new color configuration options and value mapping workflows.

✏️ Tip: You can customize this high-level summary in your review settings.

opensearch-changeset-bot bot added a commit to Qxisylolo/OpenSearch-Dashboards that referenced this pull request Nov 17, 2025
@Qxisylolo Qxisylolo changed the title [WIP][Explore Vis]add value mapping for pie and heatmap [WIP][Explore Vis]add value mapping for pie and histogram Nov 17, 2025
@codecov
Copy link

codecov bot commented Nov 17, 2025

Codecov Report

❌ Patch coverage is 58.58124% with 181 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.80%. Comparing base (92d926d) to head (4ce2309).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
...ualizations/state_timeline/state_timeline_utils.ts 47.19% 31 Missing and 16 partials ⚠️
...s/style_panel/value_mapping/value_mapping_utils.ts 75.28% 10 Missing and 12 partials ⚠️
...nts/visualizations/state_timeline/to_expression.ts 57.14% 3 Missing and 18 partials ⚠️
...components/visualizations/scatter/to_expression.ts 46.42% 6 Missing and 9 partials ⚠️
...re/public/components/visualizations/utils/utils.ts 0.00% 15 Missing ⚠️
...lic/components/visualizations/bar/to_expression.ts 63.33% 2 Missing and 9 partials ⚠️
...ents/visualizations/visualization_builder_utils.ts 60.00% 2 Missing and 8 partials ⚠️
...blic/components/visualizations/table/table_vis.tsx 12.50% 5 Missing and 2 partials ⚠️
...c/components/visualizations/bar/bar_chart_utils.ts 79.31% 1 Missing and 5 partials ⚠️
...components/visualizations/heatmap/to_expression.ts 44.44% 2 Missing and 3 partials ⚠️
... and 12 more
Additional details and impacted files
@@           Coverage Diff            @@
##             main   #10923    +/-   ##
========================================
  Coverage   60.79%   60.80%            
========================================
  Files        4532     4535     +3     
  Lines      122275   122579   +304     
  Branches    20501    20637   +136     
========================================
+ Hits        74337    74533   +196     
- Misses      42697    42760    +63     
- Partials     5241     5286    +45     
Flag Coverage Δ
Linux_1 26.56% <ø> (ø)
Linux_2 38.92% <ø> (ø)
Linux_3 39.51% <ø> (ø)
Linux_4 33.84% <58.58%> (+0.10%) ⬆️
Windows_1 26.57% <ø> (ø)
Windows_2 38.90% <ø> (ø)
Windows_3 39.51% <ø> (ø)
Windows_4 33.84% <58.58%> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Qxisylolo Qxisylolo changed the title [WIP][Explore Vis]add value mapping for pie and histogram [WIP][Explore Vis]add value mapping for remaining chart type-part 1 Nov 17, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 27, 2025

Walkthrough

This PR introduces value mapping functionality for pie chart visualizations and extends it across bar, heatmap, histogram, scatter, and state_timeline charts. It replaces boolean threshold color flags with a ColorModeOption union type supporting multiple coloring modes: 'none', 'useThresholdColor', 'useValueMapping', and 'highlightValueMapping'.

Changes

Cohort / File(s) Summary
Changelog & Tests
changelogs/fragments/10923.yml, cypress/integration/.../rule_matching_vis_bar.spec.js, cypress/integration/.../rule_matching_vis_histogram.spec.js
Added changelog fragment and updated Cypress tests to use ColorModeOptionSelect UI control instead of manual threshold button interactions.
Type Definitions & Shared Types
src/plugins/explore/public/components/visualizations/types.ts
Introduced new exported ColorModeOption union type with four string literal values.
Value Mapping Utilities & Shared Panel
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/*
Created new ColorModeOptionSelect component and comprehensive value_mapping_utils module with functions for scale decisions, transform generation, label expressions, and data processing.
Bar Chart Components
src/plugins/explore/public/components/visualizations/bar/bar_*.ts*
Extended bar chart styling (bar_vis_config.ts, bar_exclusive_vis_options.tsx) with colorModeOption and valueMappingOptions; added value mapping support to chart utilities and expression generation; updated tests and UI options rendering.
Heatmap Chart Components
src/plugins/explore/public/components/visualizations/heatmap/heatmap_*.ts*
Replaced useThresholdColor boolean with colorModeOption in config, exclusive options, and expression generation; extended utilities to support value mapping transforms and dynamic scale building.
Histogram Chart Components
src/plugins/explore/public/components/visualizations/histogram/histogram_*.ts*
Updated histogram styling config to use colorModeOption and valueMappingOptions; integrated ValueMappingPanel in options UI; updated color encoding logic in expression generation.
Pie Chart Components
src/plugins/explore/public/components/visualizations/pie/pie_*.ts*
Added colorModeOption and valueMappingOptions to pie config; extended exclusive options component with color mode selection; added comprehensive value mapping tests and integrated transform/scale generation in expression.
Scatter Chart Components
src/plugins/explore/public/components/visualizations/scatter/scatter_*.ts*
Replaced useThresholdColor with colorModeOption across config, options, and expression; added ScatterVisOptionsProps export; integrated ValueMappingPanel and updated color encoding to support combined categories and value mappings.
State Timeline Components
src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_*.ts*
Added colorModeOption to config and exclusive options; refactored numerical/categorical merge utilities with new mergeNumericalDataCore signature supporting value mappings; added createSingleNumericalStateTimeline and createSingleCategoricalStateTimeline exports.
Table Visualization
src/plugins/explore/public/components/visualizations/table/table_*.ts*
Extended table styling config with colorModeOption and valueMappingOptions; added value mapping logic to cell rendering; integrated ColorModeOptionSelect and ValueMappingPanel in options UI.
Utility Functions
src/plugins/explore/public/components/visualizations/utils/*.ts
Added transformBucketToCalculationMethod converter and getValueMappingByValue lookup utility.
Legacy Adaptation
src/plugins/explore/public/components/visualizations/visualization_builder_utils.ts, src/plugins/explore/public/components/visualizations/visualization_builder_utils.test.ts
Extended adaptLegacyData to derive colorModeOption from legacy useThresholdColor flags across bar, heatmap, line, area, state_timeline, scatter, and histogram chart types.
Rule Repository
src/plugins/explore/public/components/visualizations/rule_repository.ts
Wired new createSingleNumericalStateTimeline state timeline chart type into oneMetricOneDateRule with priority 20.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • Value mapping utilities (value_mapping_utils.ts): Dense logic for scale decision, transform generation, and data processing; comprehensive test coverage helps but logic paths are intricate and used across multiple chart types.
  • State timeline refactoring (state_timeline_utils.ts, to_expression.ts): Renamed mergeNumericalData to mergeNumericalDataCore with expanded signatures; introduced new helper functions (fallBackMerge, fallbackForCategorical); requires careful validation of all merge pathways and edge cases (null values, range overlaps).
  • Bar chart expression generation (to_expression.ts): Extensive rework of color encoding logic, transform layer generation, and combined category field handling across six chart variants (bar, stacked bar, double numerical bar, and their time-based/faceted forms); ensure data binding consistency across all paths.
  • Legacy style adaptation (visualization_builder_utils.ts): Complex migration logic across seven chart types converting useThresholdColor boolean to colorModeOption string; verify backward compatibility and edge cases for charts with no thresholds or mixed styling.
  • Cross-visualization consistency: ColorModeOption and valueMappingOptions now used across six chart types (bar, heatmap, histogram, pie, scatter, state_timeline, table); ensure uniform behavior for 'none', 'useThresholdColor', 'useValueMapping', and 'highlightValueMapping' modes across all implementations.

Possibly related PRs

Suggested reviewers

  • virajsanghvi
  • wanglam
  • AMoo-Miki
  • joshuarrrr
  • ps48
  • kavilla
  • ruchidh
  • zhongnansu
  • zengyan-amazon
  • SuZhou-Joe

Poem

🐰 A cottontail's delight at the mapping so bright,
Colors now dance in modes—none, threshold, or light.
From bar charts to pies, each viz now employs
Value's true hues, bringing rabbits such joys!

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The description includes a basic overview and changelog entry, but is missing critical sections: detailed testing steps, screenshot details, and incomplete checklist items. Add specific testing procedures, clarify screenshot context, and document which checklist items have been completed or remain outstanding.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title references 'add value mapping for remaining chart type' which aligns with the PR's core objective of adding value mapping support to pie charts and other visualization types.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@Qxisylolo Qxisylolo force-pushed the feat/valuemapping_pie branch from eabe907 to 0a87590 Compare December 1, 2025 03:45
Signed-off-by: Qxisylolo <[email protected]>
Signed-off-by: Qxisylolo <[email protected]>
@Qxisylolo Qxisylolo force-pushed the feat/valuemapping_pie branch from 5b3e606 to ba1184a Compare December 2, 2025 02:22
Signed-off-by: Qxisylolo <[email protected]>
@Qxisylolo Qxisylolo changed the title [WIP][Explore Vis]add value mapping for remaining chart type-part 1 [Explore Vis]add value mapping for remaining chart type Dec 2, 2025
Signed-off-by: Qxisylolo <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 15

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/plugins/explore/public/components/visualizations/table/table_vis.tsx (1)

283-294: Add optional chaining for nested dependency access.

Line 293 accesses styleOptions?.valueMappingOptions.valueMappings without optional chaining on valueMappingOptions. If valueMappingOptions is undefined, this could cause issues in the dependency array.

Apply this diff:

-        styleOptions?.valueMappingOptions.valueMappings,
+        styleOptions?.valueMappingOptions?.valueMappings,
src/plugins/explore/public/components/visualizations/scatter/scatter_exclusive_vis_options.test.tsx (1)

122-134: Fix incorrect comment about switch count.

Line 132 comment mentions "useThresholdcolor" which no longer exists as a separate switch. The ColorModeOptionSelect uses a combobox (select dropdown), not a switch.

Apply this diff:

     // Check for specific controls
     expect(screen.getAllByRole('combobox')).toHaveLength(2); // Shape selector
-    expect(screen.getAllByRole('switch')).toHaveLength(1); // Filled switch and useThresholdcolor
+    expect(screen.getAllByRole('switch')).toHaveLength(1); // Filled switch
     expect(screen.getByRole('spinbutton')).toBeInTheDocument(); // Angle input
🧹 Nitpick comments (24)
cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/explore/07/rule_matching_vis_histogram.spec.js (1)

63-65: Add explicit wait after color mode selection for consistency.

The color mode selection immediately proceeds to canvas comparison (line 67) without an explicit wait, while other style changes in this test include cy.wait(1000) (lines 75, 84). This inconsistency could lead to test flakiness if the threshold color rendering is asynchronous.

Apply this diff to add a wait for consistency:

 cy.getElementByTestId('colorModeOptionsSelection')
   .should('be.visible')
   .select('Use Threshold Color');
+cy.wait(1000);
 // compare with new canvas
 cy.get('canvas.marks').then((canvas) => {
src/plugins/explore/public/components/visualizations/heatmap/heatmap_chart_utils.test.ts (1)

331-345: Consider enhancing test coverage for value mapping.

The test verifies basic value mapping behavior but could be more comprehensive:

  1. The test passes an empty object {} for styles but tests the value mapping path - this works but doesn't test interaction with colorModeOption.
  2. Consider adding assertions for the scale property returned by decideScale() and legend.labelExpr from generateLabelExpr().
  3. The rangeMappings parameter (6th argument) is not passed, so decideScale receives undefined for that parameter.

Consider adding a more complete test that exercises the full value mapping path:

  it('able to handle value mapping', () => {
    const markLayer = JSON.parse(JSON.stringify(baseMarkLayer));
+   const styles = {
+     ...defaultHeatmapChartStyles,
+     colorModeOption: 'useValueMapping',
+   } as HeatmapChartStyle;
    enhanceStyle(
      markLayer,
-     ({} as unknown) as HeatmapChartStyle,
+     styles,
      transformedData,
      colorField,
      true,
-     [{ type: 'value', value: '10' }]
+     [{ type: 'value', value: '10', color: '#ff0000' }],
+     [{ type: 'range', range: { min: 0, max: 100 }, color: '#00ff00' }]
    );

    expect(markLayer.encoding.color.field).toBe('mappingValue');
    expect(markLayer.encoding.color.type).toBe('nominal');
    expect(markLayer.encoding.color.scale.type).toBeUndefined();
+   // Verify legend label expression is set
+   expect(markLayer.encoding.color.legend.labelExpr).toBeDefined();
  });
src/plugins/explore/public/components/visualizations/utils/utils.ts (1)

322-353: Remove unused generic type parameter.

The generic type <T> is declared but never used in the function. This appears to be copied from the similar getThresholdByValue<T> function above, which also doesn't use its generic. Consider removing it for clarity.

-export function getValueMappingByValue<T>(
+export function getValueMappingByValue(
   value: any,
   valueMappings: ValueMapping[] = []
 ): ValueMapping | undefined {

Also worth noting: the existing getThresholdByValue<T> at line 300 has the same unused generic pattern - this could be cleaned up in a follow-up.

src/plugins/explore/public/components/visualizations/state_timeline/to_expression.test.ts (1)

197-269: Consider splitting this test into separate test cases.

This test case validates two distinct scenarios within a single it block:

  1. Lines 204-245: Value mapping with colorModeOption: 'useValueMapping'
  2. Lines 247-268: No value mapping with colorModeOption: 'none'

Splitting these improves test isolation and makes failures easier to diagnose.

-    it('should able to handle value mappings in numerical state timeline', () => {
+    it('should handle value mappings when colorModeOption is useValueMapping', () => {
       const mockAxisColumnMappings: AxisColumnMappings = {
         [AxisRole.COLOR]: mockNumericalColumns[0],
         [AxisRole.Y]: mockCateColumns[0],
         [AxisRole.X]: mockTimeColumns[0],
       };

       const result = createNumericalStateTimeline(
         // ... first test case only
       );
       // ... assertions for useValueMapping
+    });
+
+    it('should use original field when colorModeOption is none', () => {
+      const mockAxisColumnMappings: AxisColumnMappings = {
+        [AxisRole.COLOR]: mockNumericalColumns[0],
+        [AxisRole.Y]: mockCateColumns[0],
+        [AxisRole.X]: mockTimeColumns[0],
+      };

-      const result2 = createNumericalStateTimeline(
+      const result = createNumericalStateTimeline(
         // ... second test case
       );
-      const markLayer2 = result2.layer[0];
+      const markLayer = result.layer[0];
       // ... assertions for none mode
     });
src/plugins/explore/public/components/visualizations/histogram/to_expression.ts (1)

66-66: Consider handling additional color modes.

The current implementation only checks for colorModeOption === 'useThresholdColor', but the ColorModeOption type includes 'useValueMapping' and 'highlightValueMapping' modes. If histogram visualizations should support value mapping (as indicated by the PR objectives), the color encoding logic may need to be extended.

Verify whether histogram charts should support value mapping:

#!/bin/bash
# Description: Check if histogram config includes valueMappingOptions and if other visualizations handle all color modes

# Check histogram config for valueMappingOptions
rg -n --type=ts 'valueMappingOptions' src/plugins/explore/public/components/visualizations/histogram/histogram_vis_config.ts

# Check how bar visualization handles different color modes as reference
rg -n -A10 --type=ts "colorModeOption.*useValueMapping" src/plugins/explore/public/components/visualizations/bar/to_expression.ts

Also applies to: 150-150

src/plugins/explore/public/components/visualizations/types.ts (1)

344-348: LGTM! Consider adding JSDoc documentation.

The ColorModeOption type is well-defined with clear, descriptive values. To improve maintainability, consider adding JSDoc comments explaining when each mode should be used:

+/**
+ * Color mode options for visualizations
+ * - 'none': No special coloring applied
+ * - 'useThresholdColor': Apply colors based on threshold values
+ * - 'useValueMapping': Apply colors based on value mappings
+ * - 'highlightValueMapping': Highlight data based on value mappings
+ */
 export type ColorModeOption =
   | 'useValueMapping'
   | 'highlightValueMapping'
   | 'none'
   | 'useThresholdColor';
src/plugins/explore/public/components/visualizations/pie/pie_vis_options.test.tsx (1)

270-278: LGTM! Consider adding a more comprehensive test.

The test correctly verifies that value mapping updates trigger onStyleChange with the expected structure. For better coverage, consider adding a test that verifies adding actual value mappings with specific values (not just an empty array).

src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.test.ts (1)

530-537: Test data clarity: misleading displayText.

The value mapping at line 534 has value: '40' but displayText: 'Thirty', which is confusing. While this doesn't affect test correctness, consider using consistent naming for clarity.

         {
           type: 'value',
           value: '40',
-          displayText: 'Thirty',
+          displayText: 'Forty',
           color: '#00ff00',
         },
src/plugins/explore/public/components/visualizations/bar/bar_chart_utils.test.ts (1)

133-141: Consider more complete mock data for ValueMapping objects.

The test mocks for valueMappings and validRanges omit several optional fields (like id, type, displayText). While the tests work, using more complete mock data would better reflect real-world usage and catch potential issues with missing fields.

Example for lines 135 and 155:

-      const valueMappings = [{ value: 'test', color: '#ff0000' }];
+      const valueMappings = [{ 
+        id: '1',
+        type: 'value' as const,
+        value: 'test',
+        displayText: 'Test',
+        color: '#ff0000'
+      }];

Also applies to: 153-168

src/plugins/explore/public/components/visualizations/pie/to_expression.ts (1)

49-51: Simplify the canUseValueMapping condition.

The boolean condition could be more readable by extracting it or adding a comment explaining when value mapping is enabled.

Consider this refactor for clarity:

+  // Value mapping is active when valid mappings exist and not explicitly disabled
   const canUseValueMapping =
     ((validRanges && validRanges.length > 0) || (validValues && validValues.length > 0)) &&
     styleOptions.colorModeOption !== 'none';
src/plugins/explore/public/components/visualizations/scatter/scatter_exclusive_vis_options.test.tsx (1)

55-73: Consider using data-test-subj for more robust tests.

The tests rely on array indices to select elements (e.g., getAllByRole('combobox')[1]), which makes them brittle when the UI structure changes. The component already uses data-test-subj attributes (e.g., "pointFilledSwitch" on line 47).

Consider using data-test-subj selectors for the shape selector:

// In the component (scatter_exclusive_vis_options.tsx), add:
<EuiSelect
  compressed
  data-test-subj="scatterShapeSelect"
  // ... rest of props
/>

// In the test:
const shapeSelector = screen.getByTestId('scatterShapeSelect');

This would make tests more resilient to UI reordering.

src/plugins/explore/public/components/visualizations/bar/bar_vis_options.tsx (1)

130-132: Consider removing the deprecated onUseThresholdColorChange handler.

The onUseThresholdColorChange callback is passed without its corresponding useThresholdColor value prop. Since colorModeOption is now the preferred approach (as indicated by the deprecation comments in bar_vis_config.ts), this handler appears to be dead code.

-              onUseThresholdColorChange={(useThresholdColor) =>
-                updateStyleOption('useThresholdColor', useThresholdColor)
-              }
src/plugins/explore/public/components/visualizations/pie/pie_exclusive_vis_options.tsx (1)

7-7: Unused import: EuiSelect.

EuiSelect is imported but not used in this component. The color mode selection is handled by ColorModeOptionSelect.

-import { EuiFormRow, EuiButtonGroup, EuiSwitch, EuiSelect } from '@elastic/eui';
+import { EuiFormRow, EuiButtonGroup, EuiSwitch } from '@elastic/eui';
src/plugins/explore/public/components/visualizations/heatmap/heatmap_exclusive_vis_options.test.tsx (2)

51-51: Test selector relies on DOM order.

Using getAllByRole('switch')[0] is fragile as it depends on render order. If the component's structure changes, this test could break silently or target the wrong element.

Consider adding data-test-subj to the reverse schema switch in the component for more reliable selection:

-    const reverse = screen.getAllByRole('switch')[0];
+    const reverse = screen.getByTestId('reverseColorSchemaSwitch');

61-63: Fragile selector using array index.

Similar to the switch selector, using getAllByRole('combobox')[1] couples the test to DOM order. If a data-test-subj attribute exists on the color schema select, prefer using getByTestId.

src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_utils.test.ts (2)

300-341: mergeNumericalDataCore “missing fields” / “filter ranges” tests mostly solid, but consider checking all returns

The new tests for:

  • returning original data when timestampField/rangeField are missing, and
  • filtering range mappings based on actual data values,

look correct and line up with mergeNumericalDataCore’s return shape. To make them slightly stronger you might also destructure and assert the third tuple element (validValues) is [] in the “missing fields” case.


376-423: Clarify mapping type in “handle both value mappings and range mappings”

In this test, valueMappings is defined with type: 'range' but uses the value field ({ type: 'range', value: '15', ... }). Today mergeNumericalDataCore only looks at value, so the test passes, but semantically this object is a value mapping and would normally use type: 'value' (consistent with how other callers split valueMappings vs rangeMappings based on type).

Switching this test mapping to type: 'value' would better reflect real usage without changing behavior.

-      const valueMappings: ValueMapping[] = [{ type: 'range', value: '15', displayText: 'low' }];
+      const valueMappings: ValueMapping[] = [{ type: 'value', value: '15', displayText: 'low' }];
src/plugins/explore/public/components/visualizations/histogram/histogram_vis_config.ts (1)

20-22: Histogram style config is aligned with the new color‑mode/value‑mapping model

Adding valueMappingOptions and colorModeOption to HistogramChartStyleOptions, plus:

  • deprecating useThresholdColor, and
  • redefining HistogramChartStyle to treat colorModeOption separately,

brings histograms in line with the shared ColorModeOption/value‑mapping API. The default styles correctly seed valueMappingOptions.valueMappings as an empty array and colorModeOption: 'none'. You might optionally remove the commented‑out old HistogramChartStyle alias to avoid confusion, but functionally this looks good.

Also applies to: 48-54, 56-62, 129-133

src/plugins/explore/public/components/visualizations/state_timeline/to_expression.ts (3)

155-163: Empty object in tooltip array may cause rendering issues.

When colorModeOption === 'none', this creates an empty object {} in the tooltip array. Depending on the Vega-Lite implementation, this could cause unexpected behavior or be silently ignored.

Consider filtering out the empty case entirely:

-          {
-            ...(styleOptions?.colorModeOption === 'none'
-              ? {
-                  field: rangeField,
-                  type: 'nominal',
-                  title: rangeFieldColumn.name,
-                }
-              : {}),
-          },
+          ...(styleOptions?.colorModeOption === 'none'
+            ? [{
+                field: rangeField,
+                type: 'nominal',
+                title: rangeFieldColumn.name,
+              }]
+            : []),

191-191: Inconsistent null check operators in Vega filter expressions.

Line 191 uses != null (loose equality) while lines 369, 553, and 761 use !== null (strict equality). For consistency and to avoid potential bugs with Vega expression evaluation:

  • Line 191: { filter: 'datum.displayText != null' }
  • Lines 369, 553, 761: { filter: 'datum.displayText !== null' }

Standardize on one approach across all filter expressions.

Also applies to: 369-369, 553-553, 761-761


405-590: Consider extracting shared logic to reduce duplication.

The new createSingleCategoricalStateTimeline and createSingleNumericalStateTimeline functions share significant structural similarity with createCategoricalStateTimeline and createNumericalStateTimeline. Key differences are:

  • Use of fakeYAxis field for single-row display
  • Absence of a Y-axis grouping field

Consider extracting common patterns (bar layer encoding, text layer, transform generation) into shared helper functions to improve maintainability.

Also applies to: 592-796

src/plugins/explore/public/components/visualizations/bar/bar_chart_utils.ts (2)

93-94: Typo in parameter name: disbaleAggregationType

The parameter name has a typo - should be disableAggregationType.

-  aggregationType: AggregationType | undefined,
-  disbaleAggregationType: boolean = false
+  aggregationType: AggregationType | undefined,
+  disableAggregationType: boolean = false

198-223: Consider explicitly excluding useThresholdColor mode.

The function returns early for colorModeOption === 'none', but useThresholdColor mode should be handled by buildThresholdColorEncoding instead. To prevent accidental misuse and make intent explicit:

  if (
    styleOptions?.colorModeOption === 'none' ||
+   styleOptions?.colorModeOption === 'useThresholdColor' ||
    (!rangeMappings?.length && !valueMappings?.length)
  )
    return [];
src/plugins/explore/public/components/visualizations/heatmap/heatmap_chart_utils.ts (1)

11-12: Consolidate imports from the same module.

Both imports are from the same module and can be combined into a single import statement.

-import { generateTransformLayer } from '../style_panel/value_mapping/value_mapping_utils';
-import { decideScale, generateLabelExpr } from '../style_panel/value_mapping/value_mapping_utils';
+import { generateTransformLayer, decideScale, generateLabelExpr } from '../style_panel/value_mapping/value_mapping_utils';
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 498a3be and 4ce2309.

📒 Files selected for processing (57)
  • changelogs/fragments/10923.yml (1 hunks)
  • cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/explore/06/rule_matching_vis_bar.spec.js (2 hunks)
  • cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/explore/07/rule_matching_vis_histogram.spec.js (1 hunks)
  • src/plugins/explore/public/components/visualizations/bar/bar_chart_utils.test.ts (2 hunks)
  • src/plugins/explore/public/components/visualizations/bar/bar_chart_utils.ts (7 hunks)
  • src/plugins/explore/public/components/visualizations/bar/bar_exclusive_vis_options.tsx (4 hunks)
  • src/plugins/explore/public/components/visualizations/bar/bar_vis_config.test.ts (1 hunks)
  • src/plugins/explore/public/components/visualizations/bar/bar_vis_config.ts (3 hunks)
  • src/plugins/explore/public/components/visualizations/bar/bar_vis_options.tsx (4 hunks)
  • src/plugins/explore/public/components/visualizations/bar/to_expression.test.ts (5 hunks)
  • src/plugins/explore/public/components/visualizations/bar/to_expression.ts (13 hunks)
  • src/plugins/explore/public/components/visualizations/heatmap/heatmap_chart_utils.test.ts (5 hunks)
  • src/plugins/explore/public/components/visualizations/heatmap/heatmap_chart_utils.ts (5 hunks)
  • src/plugins/explore/public/components/visualizations/heatmap/heatmap_exclusive_vis_options.test.tsx (6 hunks)
  • src/plugins/explore/public/components/visualizations/heatmap/heatmap_exclusive_vis_options.tsx (9 hunks)
  • src/plugins/explore/public/components/visualizations/heatmap/heatmap_vis_config.test.ts (1 hunks)
  • src/plugins/explore/public/components/visualizations/heatmap/heatmap_vis_config.ts (4 hunks)
  • src/plugins/explore/public/components/visualizations/heatmap/heatmap_vis_options.tsx (3 hunks)
  • src/plugins/explore/public/components/visualizations/heatmap/to_expression.test.ts (2 hunks)
  • src/plugins/explore/public/components/visualizations/heatmap/to_expression.ts (5 hunks)
  • src/plugins/explore/public/components/visualizations/histogram/histogram_vis_config.test.ts (1 hunks)
  • src/plugins/explore/public/components/visualizations/histogram/histogram_vis_config.ts (3 hunks)
  • src/plugins/explore/public/components/visualizations/histogram/histogram_vis_options.tsx (3 hunks)
  • src/plugins/explore/public/components/visualizations/histogram/to_expression.ts (2 hunks)
  • src/plugins/explore/public/components/visualizations/pie/pie_exclusive_vis_options.tsx (2 hunks)
  • src/plugins/explore/public/components/visualizations/pie/pie_vis_config.ts (3 hunks)
  • src/plugins/explore/public/components/visualizations/pie/pie_vis_options.test.tsx (4 hunks)
  • src/plugins/explore/public/components/visualizations/pie/pie_vis_options.tsx (2 hunks)
  • src/plugins/explore/public/components/visualizations/pie/to_expression.test.ts (2 hunks)
  • src/plugins/explore/public/components/visualizations/pie/to_expression.ts (3 hunks)
  • src/plugins/explore/public/components/visualizations/rule_repository.ts (3 hunks)
  • src/plugins/explore/public/components/visualizations/scatter/scatter_exclusive_vis_options.test.tsx (5 hunks)
  • src/plugins/explore/public/components/visualizations/scatter/scatter_exclusive_vis_options.tsx (2 hunks)
  • src/plugins/explore/public/components/visualizations/scatter/scatter_vis_config.ts (3 hunks)
  • src/plugins/explore/public/components/visualizations/scatter/scatter_vis_options.tsx (3 hunks)
  • src/plugins/explore/public/components/visualizations/scatter/to_expression.test.ts (2 hunks)
  • src/plugins/explore/public/components/visualizations/scatter/to_expression.ts (11 hunks)
  • src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_config.ts (4 hunks)
  • src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_exclusive_vis_options.tsx (3 hunks)
  • src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_utils.test.ts (12 hunks)
  • src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_utils.ts (10 hunks)
  • src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_vis_options.tsx (1 hunks)
  • src/plugins/explore/public/components/visualizations/state_timeline/to_expression.test.ts (11 hunks)
  • src/plugins/explore/public/components/visualizations/state_timeline/to_expression.ts (16 hunks)
  • src/plugins/explore/public/components/visualizations/style_panel/value_mapping/filter_options_select.test.tsx (1 hunks)
  • src/plugins/explore/public/components/visualizations/style_panel/value_mapping/filter_options_select.tsx (1 hunks)
  • src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.test.ts (1 hunks)
  • src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts (1 hunks)
  • src/plugins/explore/public/components/visualizations/table/table_vis.tsx (4 hunks)
  • src/plugins/explore/public/components/visualizations/table/table_vis_config.test.ts (1 hunks)
  • src/plugins/explore/public/components/visualizations/table/table_vis_config.ts (3 hunks)
  • src/plugins/explore/public/components/visualizations/table/table_vis_options.tsx (5 hunks)
  • src/plugins/explore/public/components/visualizations/types.ts (1 hunks)
  • src/plugins/explore/public/components/visualizations/utils/calculation.ts (2 hunks)
  • src/plugins/explore/public/components/visualizations/utils/utils.ts (2 hunks)
  • src/plugins/explore/public/components/visualizations/visualization_builder_utils.test.ts (1 hunks)
  • src/plugins/explore/public/components/visualizations/visualization_builder_utils.ts (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (39)
src/plugins/explore/public/components/visualizations/pie/pie_vis_options.tsx (2)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_panel.tsx (1)
  • ValueMappingPanel (18-39)
src/plugins/explore/public/components/visualizations/pie/pie_exclusive_vis_options.tsx (1)
  • PieExclusiveVisOptions (22-122)
src/plugins/explore/public/components/visualizations/bar/bar_exclusive_vis_options.tsx (2)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/filter_options_select.tsx (1)
  • ColorModeOptionSelect (11-71)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_chart_utils.test.ts (2)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_chart_utils.ts (1)
  • enhanceStyle (102-155)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_vis_config.ts (1)
  • HeatmapChartStyle (76-79)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/filter_options_select.tsx (1)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/pie/pie_vis_options.test.tsx (1)
src/plugins/explore/public/components/visualizations/pie/pie_vis_options.tsx (1)
  • PieVisStyleControls (20-101)
src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_exclusive_vis_options.tsx (3)
src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_config.ts (1)
  • StateTimeLineChartStyle (56-59)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/filter_options_select.tsx (1)
  • ColorModeOptionSelect (11-71)
src/plugins/explore/public/components/visualizations/table/table_vis_config.ts (1)
src/plugins/explore/public/components/visualizations/types.ts (3)
  • Threshold (220-223)
  • ColorModeOption (344-348)
  • ValueMappingOptions (324-326)
src/plugins/explore/public/components/visualizations/pie/to_expression.ts (1)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts (4)
  • processData (125-224)
  • decideScale (12-32)
  • generateLabelExpr (80-101)
  • generateTransformLayer (45-78)
src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_utils.test.ts (2)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ValueMapping (315-322)
src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_utils.ts (2)
  • mergeCategoricalData (125-184)
  • mergeNumericalDataCore (268-383)
src/plugins/explore/public/components/visualizations/heatmap/to_expression.ts (3)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts (1)
  • processData (125-224)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_chart_utils.ts (2)
  • enhanceStyle (102-155)
  • addTransform (72-100)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • VEGASCHEMA (281-281)
src/plugins/explore/public/components/visualizations/pie/pie_exclusive_vis_options.tsx (3)
src/plugins/explore/public/components/visualizations/pie/pie_vis_config.ts (1)
  • PieChartStyle (45-48)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/filter_options_select.tsx (1)
  • ColorModeOptionSelect (11-71)
src/plugins/explore/public/components/visualizations/utils/utils.ts (1)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ValueMapping (315-322)
src/plugins/explore/public/components/visualizations/table/table_vis.tsx (4)
src/plugins/explore/public/components/visualizations/utils/utils.ts (1)
  • getValueMappingByValue (322-353)
src/plugins/explore/public/components/visualizations/theme/color_utils.ts (1)
  • resolveColor (77-91)
src/plugins/explore/public/components/visualizations/theme/default_colors.ts (1)
  • DEFAULT_GREY (76-76)
src/plugins/explore/public/components/visualizations/table/cell_value.tsx (1)
  • CellValue (26-125)
src/plugins/explore/public/components/visualizations/histogram/histogram_vis_config.ts (1)
src/plugins/explore/public/components/visualizations/types.ts (2)
  • ValueMappingOptions (324-326)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_exclusive_vis_options.tsx (3)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_vis_config.ts (1)
  • HeatmapChartStyle (76-79)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/filter_options_select.tsx (1)
  • ColorModeOptionSelect (11-71)
src/plugins/explore/public/components/visualizations/scatter/to_expression.ts (2)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts (3)
  • processData (125-224)
  • generateTransformLayer (45-78)
  • generateLabelExpr (80-101)
src/plugins/explore/public/components/visualizations/bar/bar_chart_utils.ts (3)
  • buildThresholdColorEncoding (142-196)
  • buildValueMappingColorEncoding (198-223)
  • buildCombinedScale (225-256)
src/plugins/explore/public/components/visualizations/bar/bar_chart_utils.test.ts (2)
src/plugins/explore/public/components/visualizations/bar/bar_vis_config.ts (1)
  • BarChartStyle (70-76)
src/plugins/explore/public/components/visualizations/bar/bar_chart_utils.ts (2)
  • buildValueMappingColorEncoding (198-223)
  • buildCombinedScale (225-256)
src/plugins/explore/public/components/visualizations/bar/bar_vis_config.ts (1)
src/plugins/explore/public/components/visualizations/types.ts (2)
  • ValueMappingOptions (324-326)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts (5)
src/plugins/explore/public/components/visualizations/types.ts (3)
  • ColorModeOption (344-348)
  • ValueMapping (315-322)
  • Threshold (220-223)
src/plugins/explore/public/components/visualizations/theme/color_utils.ts (2)
  • resolveColor (77-91)
  • getCategoryNextColor (72-74)
src/plugins/explore/public/components/visualizations/theme/default_colors.ts (1)
  • DEFAULT_GREY (76-76)
src/plugins/explore/public/components/visualizations/utils/calculation.ts (2)
  • CalculationMethod (11-23)
  • calculateValue (40-105)
src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_utils.ts (1)
  • convertThresholdsToValueMappings (111-120)
src/plugins/explore/public/components/visualizations/bar/to_expression.ts (4)
src/plugins/explore/public/components/visualizations/utils/calculation.ts (1)
  • transformBucketToCalculationMethod (25-33)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts (3)
  • processData (125-224)
  • generateTransformLayer (45-78)
  • generateLabelExpr (80-101)
src/plugins/explore/public/components/visualizations/bar/bar_chart_utils.ts (5)
  • buildThresholdColorEncoding (142-196)
  • buildValueMappingColorEncoding (198-223)
  • buildEncoding (89-113)
  • buildTooltipEncoding (115-140)
  • buildCombinedScale (225-256)
src/plugins/explore/public/components/visualizations/utils/utils.ts (2)
  • getSchemaByAxis (210-223)
  • applyAxisStyling (22-89)
src/plugins/explore/public/components/visualizations/scatter/scatter_exclusive_vis_options.test.tsx (1)
src/plugins/explore/public/components/visualizations/scatter/scatter_exclusive_vis_options.tsx (2)
  • ScatterVisOptionsProps (16-22)
  • ScatterExclusiveVisOptions (24-110)
src/plugins/explore/public/components/visualizations/scatter/scatter_vis_options.tsx (2)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_panel.tsx (1)
  • ValueMappingPanel (18-39)
src/plugins/explore/public/components/visualizations/scatter/scatter_exclusive_vis_options.tsx (1)
  • ScatterExclusiveVisOptions (24-110)
src/plugins/explore/public/components/visualizations/bar/to_expression.test.ts (2)
src/plugins/explore/public/components/visualizations/bar/bar_vis_config.ts (2)
  • BarChartStyle (70-76)
  • defaultBarChartStyles (78-155)
src/plugins/explore/public/components/visualizations/bar/to_expression.ts (1)
  • createDoubleNumericalBarChart (720-834)
src/plugins/explore/public/components/visualizations/scatter/scatter_vis_config.ts (1)
src/plugins/explore/public/components/visualizations/types.ts (3)
  • ThresholdOptions (275-279)
  • ValueMappingOptions (324-326)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/visualization_builder_utils.ts (7)
src/plugins/explore/public/components/visualizations/style_panel/threshold/threshold_utils.ts (2)
  • transformToThreshold (185-204)
  • Colors (99-183)
src/plugins/explore/public/components/visualizations/utils/use_visualization_types.ts (1)
  • StyleOptions (56-68)
src/plugins/explore/public/components/visualizations/bar/bar_vis_config.ts (1)
  • BarChartStyleOptions (29-68)
src/plugins/explore/public/components/visualizations/theme/default_colors.ts (1)
  • getColors (9-74)
src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_config.ts (1)
  • StateTimeLineChartStyleOptions (32-54)
src/plugins/explore/public/components/visualizations/scatter/scatter_vis_config.ts (1)
  • ScatterChartStyleOptions (31-52)
src/plugins/explore/public/components/visualizations/histogram/histogram_vis_config.ts (1)
  • HistogramChartStyleOptions (27-54)
src/plugins/explore/public/components/visualizations/table/table_vis_options.tsx (3)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/filter_options_select.tsx (1)
  • ColorModeOptionSelect (11-71)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_panel.tsx (1)
  • ValueMappingPanel (18-39)
src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_config.ts (1)
src/plugins/explore/public/components/visualizations/types.ts (2)
  • ThresholdOptions (275-279)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/filter_options_select.test.tsx (2)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/filter_options_select.tsx (1)
  • ColorModeOptionSelect (11-71)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/state_timeline/to_expression.ts (3)
src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_utils.ts (2)
  • convertThresholdsToValueMappings (111-120)
  • mergeNumericalDataCore (268-383)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts (4)
  • convertThresholdsToValueMappings (226-235)
  • decideScale (12-32)
  • generateLabelExpr (80-101)
  • generateTransformLayer (45-78)
src/plugins/explore/public/components/visualizations/utils/utils.ts (2)
  • applyAxisStyling (22-89)
  • getSwappedAxisRole (173-208)
src/plugins/explore/public/components/visualizations/pie/pie_vis_config.ts (1)
src/plugins/explore/public/components/visualizations/types.ts (2)
  • ValueMappingOptions (324-326)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/state_timeline/state_timeline_utils.ts (1)
src/plugins/explore/public/components/visualizations/types.ts (3)
  • RangeValue (216-219)
  • ColorModeOption (344-348)
  • ValueMapping (315-322)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_vis_config.ts (1)
src/plugins/explore/public/components/visualizations/types.ts (3)
  • ThresholdOptions (275-279)
  • ValueMappingOptions (324-326)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/scatter/scatter_exclusive_vis_options.tsx (3)
src/plugins/explore/public/components/visualizations/scatter/scatter_vis_config.ts (1)
  • ScatterChartStyle (54-60)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/filter_options_select.tsx (1)
  • ColorModeOptionSelect (11-71)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_exclusive_vis_options.test.tsx (2)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ColorModeOption (344-348)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_exclusive_vis_options.tsx (1)
  • HeatmapExclusiveVisOptions (29-187)
src/plugins/explore/public/components/visualizations/bar/bar_vis_options.tsx (2)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_panel.tsx (1)
  • ValueMappingPanel (18-39)
src/plugins/explore/public/components/visualizations/bar/bar_exclusive_vis_options.tsx (1)
  • BarExclusiveVisOptions (45-224)
src/plugins/explore/public/components/visualizations/histogram/histogram_vis_options.tsx (1)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_panel.tsx (1)
  • ValueMappingPanel (18-39)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_vis_options.tsx (2)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_panel.tsx (1)
  • ValueMappingPanel (18-39)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_exclusive_vis_options.tsx (1)
  • HeatmapExclusiveVisOptions (29-187)
src/plugins/explore/public/components/visualizations/bar/bar_chart_utils.ts (4)
src/plugins/explore/public/components/visualizations/types.ts (2)
  • VisColumn (62-69)
  • ValueMapping (315-322)
src/plugins/explore/public/components/visualizations/bar/bar_vis_config.ts (1)
  • BarChartStyle (70-76)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts (2)
  • decideScale (12-32)
  • generateLabelExpr (80-101)
src/plugins/explore/public/components/visualizations/theme/color_utils.ts (2)
  • getCategoryNextColor (72-74)
  • resolveColor (77-91)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_chart_utils.ts (3)
src/plugins/explore/public/components/visualizations/heatmap/heatmap_vis_config.ts (1)
  • HeatmapChartStyle (76-79)
src/plugins/explore/public/components/visualizations/types.ts (1)
  • ValueMapping (315-322)
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts (3)
  • generateTransformLayer (45-78)
  • decideScale (12-32)
  • generateLabelExpr (80-101)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (67)
  • GitHub Check: Run functional tests on Windows (ciGroup13)
  • GitHub Check: Run functional tests on Windows (ciGroup8)
  • GitHub Check: Run functional tests on Windows (ciGroup6)
  • GitHub Check: Run functional tests on Windows (ciGroup5)
  • GitHub Check: Run functional tests on Windows (ciGroup2)
  • GitHub Check: Run functional tests on Windows (ciGroup4)
  • GitHub Check: Run functional tests on Windows (ciGroup7)
  • GitHub Check: Run functional tests on Windows (ciGroup3)
  • GitHub Check: Run functional tests on Windows (ciGroup12)
  • GitHub Check: Run functional tests on Linux (ciGroup11)
  • GitHub Check: Run functional tests on Windows (ciGroup9)
  • GitHub Check: Run functional tests on Linux (ciGroup12)
  • GitHub Check: Run functional tests on Windows (ciGroup11)
  • GitHub Check: Run functional tests on Windows (ciGroup10)
  • GitHub Check: Run functional tests on Linux (ciGroup13)
  • GitHub Check: Run functional tests on Linux (ciGroup8)
  • GitHub Check: Run functional tests on Windows (ciGroup1)
  • GitHub Check: Run functional tests on Linux (ciGroup10)
  • GitHub Check: Run functional tests on Linux (ciGroup6)
  • GitHub Check: Run cypress tests (osd:ciGroup17Explore)
  • GitHub Check: Run functional tests on Linux (ciGroup4)
  • GitHub Check: Run functional tests on Linux (ciGroup9)
  • GitHub Check: Run functional tests on Linux (ciGroup5)
  • GitHub Check: Run functional tests on Linux (ciGroup3)
  • GitHub Check: Run functional tests on Linux (ciGroup7)
  • GitHub Check: Run cypress tests (osd:ciGroup12Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup13Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup16Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup10Explore)
  • GitHub Check: Run cypress tests (osd:ciGroup15)
  • GitHub Check: Run cypress tests (osd:ciGroup14Explore)
  • GitHub Check: Run functional tests on Linux (ciGroup2)
  • GitHub Check: Run cypress tests (osd:ciGroup15Explore)
  • GitHub Check: Run functional tests on Linux (ciGroup1)
  • GitHub Check: Run cypress tests (osd:ciGroup14)
  • GitHub Check: Run cypress tests (osd:ciGroup9)
  • GitHub Check: Run cypress tests (osd:ciGroup11)
  • GitHub Check: Run cypress tests (osd:ciGroup13)
  • GitHub Check: Run plugin functional tests on Windows
  • GitHub Check: Run cypress tests (osd:ciGroup5)
  • GitHub Check: Run cypress tests (osd:ciGroup12)
  • GitHub Check: Run cypress tests (osd:ciGroup10Fast)
  • GitHub Check: Run cypress tests (osd:ciGroup8)
  • GitHub Check: Run cypress tests (osd:ciGroup10Slow)
  • GitHub Check: Run cypress tests (osd:ciGroup3)
  • GitHub Check: Run cypress tests (osd:ciGroup1)
  • GitHub Check: Run cypress tests (osd:ciGroup6)
  • GitHub Check: Run cypress tests (osd:ciGroup4)
  • GitHub Check: Run cypress tests (osd:ciGroup7)
  • GitHub Check: Run cypress tests (osd:ciGroup2)
  • GitHub Check: Build and Verify on Windows (ciGroup4)
  • GitHub Check: Build min release artifacts on Linux x64
  • GitHub Check: Build min release artifacts on Linux ARM64
  • GitHub Check: Build min release artifacts on macOS ARM64
  • GitHub Check: Build min release artifacts on macOS x64
  • GitHub Check: Build and Verify on Windows (ciGroup2)
  • GitHub Check: Build min release artifacts on Windows x64
  • GitHub Check: Build and Verify on Windows (ciGroup3)
  • GitHub Check: Build and Verify on Linux (ciGroup2)
  • GitHub Check: Build and Verify on Windows (ciGroup1)
  • GitHub Check: Build and Verify on Linux (ciGroup1)
  • GitHub Check: Build and Verify on Linux (ciGroup4)
  • GitHub Check: Run plugin functional tests on Linux
  • GitHub Check: Build and Verify on Linux (ciGroup3)
  • GitHub Check: Lint and validate
  • GitHub Check: bundle-analyzer
  • GitHub Check: lighthouse

Comment on lines +1 to +2
feat:
- Add value mapping for pie ([#10923](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/10923)) No newline at end of file
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Changelog entry incomplete - missing heatmap mention.

According to the PR objectives and the code changes, this PR adds value mapping support for both pie and heatmap chart types. The changelog should reflect both additions.

 feat:
-- Add value mapping for pie ([#10923](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/10923))
+- Add value mapping for pie and heatmap ([#10923](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/10923))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
feat:
- Add value mapping for pie ([#10923](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/10923))
feat:
- Add value mapping for pie and heatmap ([#10923](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/10923))
🤖 Prompt for AI Agents
In changelogs/fragments/10923.yml around lines 1 to 2, the changelog only
mentions adding value mapping for pie but omits heatmap; update the fragment to
include both chart types by adding a parallel entry for heatmap (e.g., "Add
value mapping for pie and heatmap") or add a separate line for heatmap so the
changelog accurately reflects both additions from the PR.

Comment on lines +247 to +250
const colors = [
...(categorical2Options ?? []).map((c, i) => getCategoryNextColor(i)),
...items.map((m, i) => resolveColor(m.color) || getCategoryNextColor(i)),
];
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Color index collision when mapping has no explicit color.

When a mapping item lacks an explicit color, getCategoryNextColor(i) uses the item's index within the items array (starting from 0), which can produce duplicate colors with the categorical options. The index should be offset by the number of categorical options.

  const colors = [
    ...(categorical2Options ?? []).map((c, i) => getCategoryNextColor(i)),
-   ...items.map((m, i) => resolveColor(m.color) || getCategoryNextColor(i)),
+   ...items.map((m, i) => resolveColor(m.color) || getCategoryNextColor((categorical2Options?.length ?? 0) + i)),
  ];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const colors = [
...(categorical2Options ?? []).map((c, i) => getCategoryNextColor(i)),
...items.map((m, i) => resolveColor(m.color) || getCategoryNextColor(i)),
];
const colors = [
...(categorical2Options ?? []).map((c, i) => getCategoryNextColor(i)),
...items.map((m, i) => resolveColor(m.color) || getCategoryNextColor((categorical2Options?.length ?? 0) + i)),
];
🤖 Prompt for AI Agents
In src/plugins/explore/public/components/visualizations/bar/bar_chart_utils.ts
around lines 247-250, the color array construction can produce duplicate colors
because getCategoryNextColor(i) for items uses the item's index without
accounting for preceding categorical2Options entries; change the items mapping
to offset the index by the number of categorical options (use an offset =
(categorical2Options ?? []).length and call getCategoryNextColor(i + offset)) so
items without explicit color pick the next non-colliding category color; ensure
the code handles categorical2Options being undefined (treat length as 0).

styleOptions.colorModeOption === 'useThresholdColor'
? buildThresholdColorEncoding(yAxis, styleOptions, true)
: buildValueMappingColorEncoding(styleOptions, validValues, validRanges);
// const colorEncodingLayer = buildThresholdColorEncoding(yAxis, styleOptions);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Remove commented-out code.

Lines 770 and 787 contain commented-out code that should be removed to keep the codebase clean.

-  // const colorEncodingLayer = buildThresholdColorEncoding(yAxis, styleOptions);
-
...
-        // aggregate: styles?.bucket?.aggregationType,

Also applies to: 787-787

🤖 Prompt for AI Agents
In src/plugins/explore/public/components/visualizations/bar/to_expression.ts
around lines 770 and 787, remove the two commented-out lines (the unused calls
to buildThresholdColorEncoding) to clean up dead code; simply delete those
commented lines and ensure surrounding formatting/indentation remains correct
and no trailing commas or syntax issues are introduced.

Comment on lines +140 to +154
if (canUseValueMapping) {
markLayer.encoding.color.field = 'mappingValue';
markLayer.encoding.color.type = 'nominal';
markLayer.encoding.color.scale = decideScale(
styles?.colorModeOption,
rangeMappings,
valueMappings
);
delete markLayer.encoding.color.scale.type;
markLayer.encoding.color.legend.labelExpr = generateLabelExpr(
rangeMappings,
valueMappings,
styles?.colorModeOption
);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Potential null reference when setting legend.labelExpr.

If styles.addLegend is false, markLayer.encoding.color.legend could be null, causing a runtime error on Line 149 when attempting to set labelExpr.

  if (canUseValueMapping) {
    markLayer.encoding.color.field = 'mappingValue';
    markLayer.encoding.color.type = 'nominal';
    markLayer.encoding.color.scale = decideScale(
      styles?.colorModeOption,
      rangeMappings,
      valueMappings
    );
    delete markLayer.encoding.color.scale.type;
-   markLayer.encoding.color.legend.labelExpr = generateLabelExpr(
-     rangeMappings,
-     valueMappings,
-     styles?.colorModeOption
-   );
+   if (markLayer.encoding.color.legend) {
+     markLayer.encoding.color.legend.labelExpr = generateLabelExpr(
+       rangeMappings,
+       valueMappings,
+       styles?.colorModeOption
+     );
+   }
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (canUseValueMapping) {
markLayer.encoding.color.field = 'mappingValue';
markLayer.encoding.color.type = 'nominal';
markLayer.encoding.color.scale = decideScale(
styles?.colorModeOption,
rangeMappings,
valueMappings
);
delete markLayer.encoding.color.scale.type;
markLayer.encoding.color.legend.labelExpr = generateLabelExpr(
rangeMappings,
valueMappings,
styles?.colorModeOption
);
}
if (canUseValueMapping) {
markLayer.encoding.color.field = 'mappingValue';
markLayer.encoding.color.type = 'nominal';
markLayer.encoding.color.scale = decideScale(
styles?.colorModeOption,
rangeMappings,
valueMappings
);
delete markLayer.encoding.color.scale.type;
if (markLayer.encoding.color.legend) {
markLayer.encoding.color.legend.labelExpr = generateLabelExpr(
rangeMappings,
valueMappings,
styles?.colorModeOption
);
}
}
🤖 Prompt for AI Agents
In
src/plugins/explore/public/components/visualizations/heatmap/heatmap_chart_utils.ts
around lines 140-154, the code assumes markLayer.encoding.color.legend is
present which can be null when styles.addLegend is false; guard against this by
checking styles.addLegend (or markLayer.encoding.color.legend) before assigning
legend.labelExpr and if needed instantiate markLayer.encoding.color.legend = {}
(or an object with required properties) so the assignment is safe; ensure the
guard wraps the generateLabelExpr assignment (and any other legend property
writes) to prevent null-reference runtime errors.

Comment on lines +119 to +121
colorModeOption={styleOptions?.colorModeOption}
onColorModeOptionChange={(option) => updateStyleOption('colorModeOption', option)}
hasDate={true}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

hasDate is hardcoded to true, which will always disable value mapping for histograms.

In bar_vis_options.tsx (line 43), hasDate is dynamically computed based on axis schema. Since hasDate is passed to BarExclusiveVisOptions where it controls disableValueMapping={hasDate}, hardcoding it to true will always disable value mapping for histogram charts, contradicting this PR's intent.

Consider computing hasDate dynamically:

+  const hasDate = axes.some((axis) => axis?.schema === VisFieldType.Date);
+
   // The mapping object will be an empty object if no fields are selected on the axes selector.

Then update line 121:

-              hasDate={true}
+              hasDate={hasDate}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
src/plugins/explore/public/components/visualizations/histogram/histogram_vis_options.tsx
around lines 119 to 121, hasDate is hardcoded to true which always disables
value mapping; compute hasDate dynamically from the axis schema (like in
bar_vis_options.tsx) by checking whether series?.[0]?.x.scale?.type === 'date'
or inspecting the x-axis schema for a date field, then pass that computed
boolean to the component (replace hasDate={true} with hasDate={computedHasDate})
so value mapping is only disabled when the x axis is actually a date.

Comment on lines +78 to +84
it('should use validValues when validRanges is not empty', () => {
const result = decideScale(undefined, undefined, mockValidValues);

expect(result).toEqual({
domain: ['A', 'B'],
range: ['#ff0000', '#00ff00'],
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clarify test description.

The test description states "when validRanges is not empty" but the test passes undefined for validRanges (line 79). This is confusing.

Consider updating to:

-    it('should use validValues when validRanges is not empty', () => {
+    it('should use validValues when validRanges is empty or undefined', () => {
       const result = decideScale(undefined, undefined, mockValidValues);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it('should use validValues when validRanges is not empty', () => {
const result = decideScale(undefined, undefined, mockValidValues);
expect(result).toEqual({
domain: ['A', 'B'],
range: ['#ff0000', '#00ff00'],
});
it('should use validValues when validRanges is empty or undefined', () => {
const result = decideScale(undefined, undefined, mockValidValues);
expect(result).toEqual({
domain: ['A', 'B'],
range: ['#ff0000', '#00ff00'],
});
🤖 Prompt for AI Agents
In
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.test.ts
around lines 78 to 84, the test title incorrectly says "when validRanges is not
empty" while the call passes undefined for validRanges; update the test
description to accurately reflect the scenario (e.g., "should use validValues
when validRanges is undefined" or "should use validValues when validRanges is
not provided") so the test name matches the inputs used.

Comment on lines +88 to +100
const mappings = [
...(validValues?.map((m) => `'${m.value}': '${m.displayText || m.value}'`) ?? []),
...(validRanges?.map((m) => {
const key = `[${m.range?.min},${m.range?.max ?? '∞'})`;
return `'${key}': '${m.displayText || key}'`;
}) ?? []),
];

if (colorModeOption === 'highlightValueMapping') {
mappings.push("null: 'unmatched'");
}

return `{${mappings.join(', ')}}[datum.label] || datum.label`;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Values containing quotes may break the generated expression.

If m.value or m.displayText contains single quotes, the generated expression string will be malformed. Consider escaping quotes in user-provided values.

+const escapeQuotes = (str: string) => str.replace(/'/g, "\\'");
+
  const mappings = [
-   ...(validValues?.map((m) => `'${m.value}': '${m.displayText || m.value}'`) ?? []),
+   ...(validValues?.map((m) => `'${escapeQuotes(m.value ?? '')}': '${escapeQuotes(m.displayText || m.value || '')}'`) ?? []),
    ...(validRanges?.map((m) => {
      const key = `[${m.range?.min},${m.range?.max ?? '∞'})`;
-     return `'${key}': '${m.displayText || key}'`;
+     return `'${key}': '${escapeQuotes(m.displayText || key)}'`;
    }) ?? []),
  ];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const mappings = [
...(validValues?.map((m) => `'${m.value}': '${m.displayText || m.value}'`) ?? []),
...(validRanges?.map((m) => {
const key = `[${m.range?.min},${m.range?.max ?? '∞'})`;
return `'${key}': '${m.displayText || key}'`;
}) ?? []),
];
if (colorModeOption === 'highlightValueMapping') {
mappings.push("null: 'unmatched'");
}
return `{${mappings.join(', ')}}[datum.label] || datum.label`;
const escapeQuotes = (str: string) => str.replace(/'/g, "\\'");
const mappings = [
...(validValues?.map((m) => `'${escapeQuotes(m.value ?? '')}': '${escapeQuotes(m.displayText || m.value || '')}'`) ?? []),
...(validRanges?.map((m) => {
const key = `[${m.range?.min},${m.range?.max ?? '∞'})`;
return `'${key}': '${escapeQuotes(m.displayText || key)}'`;
}) ?? []),
];
if (colorModeOption === 'highlightValueMapping') {
mappings.push("null: 'unmatched'");
}
return `{${mappings.join(', ')}}[datum.label] || datum.label`;
🤖 Prompt for AI Agents
In
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts
around lines 88-100, the generated expression uses single-quoted user strings
which will break if m.value, m.displayText or the range key contain single
quotes or backslashes; update the generation to safely escape single quotes and
backslashes (or prefer producing values via JSON.stringify) when building each
mapping key and displayText so the resulting '{...}[datum.label] || datum.label'
expression remains valid; ensure range keys are escaped the same way and the
"null: 'unmatched'" entry remains syntactically correct.

Comment on lines +112 to +121
const generateValue = (mapping: ValueMapping) => {
return useRangeMappings
? `'[${mapping?.range?.min},${mapping?.range?.max ?? '∞'})'`
: mapping.value;
};

return mappings?.map((v, i) => ({
test: `datum['${field}']=== ${generateValue(v)}`,
value: resolveColor(v.color) || getCategoryNextColor(i),
}));
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Inconsistent quoting in test expression for value mappings.

For range mappings, generateValue returns a quoted string (e.g., '[0,∞)'), but for value mappings, it returns the raw value without quotes. This results in malformed test expressions for value mappings.

    const generateValue = (mapping: ValueMapping) => {
      return useRangeMappings
        ? `'[${mapping?.range?.min},${mapping?.range?.max ?? '∞'})'`
-       : mapping.value;
+       : `'${mapping.value}'`;
    };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const generateValue = (mapping: ValueMapping) => {
return useRangeMappings
? `'[${mapping?.range?.min},${mapping?.range?.max ?? '∞'})'`
: mapping.value;
};
return mappings?.map((v, i) => ({
test: `datum['${field}']=== ${generateValue(v)}`,
value: resolveColor(v.color) || getCategoryNextColor(i),
}));
const generateValue = (mapping: ValueMapping) => {
return useRangeMappings
? `'[${mapping?.range?.min},${mapping?.range?.max ?? '∞'})'`
: `'${mapping.value}'`;
};
return mappings?.map((v, i) => ({
test: `datum['${field}']=== ${generateValue(v)}`,
value: resolveColor(v.color) || getCategoryNextColor(i),
}));
🤖 Prompt for AI Agents
In
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts
around lines 112 to 121, the test expression is malformed because generateValue
returns a quoted string for range mappings but raw unquoted values for simple
value mappings; update generateValue to return a properly escaped JS literal for
any mapping (e.g., use JSON.stringify for string values, keep numbers/booleans
as-is, and preserve the range string already wrapped) so the produced test
string datum['field']===<value> is always syntactically correct, ensuring
strings are quoted and other primitives are not.

Comment on lines +172 to +176
const numericalOptions = Array.from(new Set(newRecord.map((t) => t[numericalColumn!])));

const categorical2Options = categoricalColumn2
? Array.from(new Set(newRecord.map((t) => t[categoricalColumn2!])))
: null;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Potential undefined access on numericalColumn.

Lines 172-176 use numericalColumn! (non-null assertion) outside the block that checks if numericalColumn exists (Line 154). If numericalColumn is undefined, accessing t[numericalColumn!] will use undefined as a key.

-  const numericalOptions = Array.from(new Set(newRecord.map((t) => t[numericalColumn!])));
+  const numericalOptions = numericalColumn
+    ? Array.from(new Set(newRecord.map((t) => t[numericalColumn])))
+    : [];

-  const categorical2Options = categoricalColumn2
+  const categorical2Options = categoricalColumn2 && numericalColumn
    ? Array.from(new Set(newRecord.map((t) => t[categoricalColumn2!])))
    : null;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const numericalOptions = Array.from(new Set(newRecord.map((t) => t[numericalColumn!])));
const categorical2Options = categoricalColumn2
? Array.from(new Set(newRecord.map((t) => t[categoricalColumn2!])))
: null;
const numericalOptions = numericalColumn
? Array.from(new Set(newRecord.map((t) => t[numericalColumn])))
: [];
const categorical2Options = categoricalColumn2 && numericalColumn
? Array.from(new Set(newRecord.map((t) => t[categoricalColumn2!])))
: null;
🤖 Prompt for AI Agents
In
src/plugins/explore/public/components/visualizations/style_panel/value_mapping/value_mapping_utils.ts
around lines 172 to 176, the code uses numericalColumn! without ensuring it
exists; change the logic to only compute numericalOptions when numericalColumn
is defined (mirror the categoricalColumn2 pattern) — e.g., if numericalColumn is
truthy, build Array.from(new Set(newRecord.map(t => t[numericalColumn]))),
otherwise set numericalOptions to null (or an empty array depending on expected
consumers); remove the non-null assertion and add a conditional guard so
accessing t[numericalColumn] cannot occur when numericalColumn is undefined.

Comment on lines +247 to +265
let displayText;
if (
columnCellType !== 'auto' &&
styleOptions?.valueMappingOptions?.valueMappings &&
styleOptions?.valueMappingOptions?.valueMappings.length > 0 &&
(styleOptions.colorModeOption === 'highlightValueMapping' ||
styleOptions.colorModeOption === 'useValueMapping')
) {
const mapping = getValueMappingByValue(
cellValue,
styleOptions.valueMappingOptions.valueMappings
);
if (mapping) {
color = resolveColor(mapping.color);
displayText = mapping?.displayText;
} else {
color = DEFAULT_GREY;
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clarify fallback behavior for unmapped values.

When value mapping is active but no mapping matches a cell value, the code falls back to DEFAULT_GREY (line 263). This behavior makes sense for 'highlightValueMapping' mode (unmapped values should be neutral), but for 'useValueMapping' mode, consider whether unmapped values should:

  • Use the default cell color (no special coloring)
  • Show a different indicator that they're unmapped
  • Continue using grey

The current implementation treats both modes identically, which may not align with user expectations.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant