Skip to content

fix(Area): connectNulls with stackId correctly handles all-null data points#7085

Closed
Harikrushn9118 wants to merge 5 commits into
recharts:mainfrom
Harikrushn9118:fix-area-connect-nulls-stacked-v2
Closed

fix(Area): connectNulls with stackId correctly handles all-null data points#7085
Harikrushn9118 wants to merge 5 commits into
recharts:mainfrom
Harikrushn9118:fix-area-connect-nulls-stacked-v2

Conversation

@Harikrushn9118

@Harikrushn9118 Harikrushn9118 commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Fixes #6985. Follow-up to reverted PR #7041.

Changes

PR #7041 removed the !connectNulls guard entirely, which broke connectNulls={true} for stacked charts — null points in individual series became break points even when the user opted into connecting them, causing visible overlap artifacts (#7070).

This v2 fix preserves the original !connectNulls && guard and adds a targeted allStackedSeriesNull check:

  • When connectNulls={true} and a stacked chart has a data point where only some series are null → connect through (treat as 0) ✅
  • When connectNulls={true} and ALL series in the stack are null for a data point → treat as breakpoint ✅ (avoids overlap regression)
  • When connectNulls={false} → unchanged behavior ✅

Implementation

  1. New selector selectStackDataKeys in areaSelectors.ts — retrieves all dataKeys from sibling graphical items in the same stack group
  2. Pass stackDataKeys into computeArea()
  3. Updated isBreakPoint logic with three conditions:
    • value1 == null — basic null check (unchanged)
    • hasStack && !connectNulls && rawValue == null — original guard (preserved)
    • allStackedSeriesNull — new: only breaks when ALL stacked series are null

Root cause

d3-stack defaults null values to 0 in stacked output, so value1 (from stackedData) is never null for stacked charts. The !connectNulls guard on the second condition was the only thing controlling null behavior in stacks. Removing it entirely (PR #7041) was too aggressive.

Related Issue

Fixes #6985
Fixes #7070

How Has This Been Tested?

  • All 255 Area-related unit tests pass (AreaChart.spec, AreaChart.stacked.spec, Area.spec, Area.animation.spec, Area.typed.spec)
  • Existing test 'Renders null points as 0 if stacked and connectNulls is true' covers the partial-null scenario

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • I have added a storybook story or VR test, or extended an existing story or VR test to show my changes

Summary by CodeRabbit

  • Bug Fixes
    • Area charts now correctly detect breakpoints and handle nulls in stacked series; connectNulls and stacking behave correctly when entire stacks are null.
  • Documentation
    • Added an example showing connectNulls with sparse/undefined data to demonstrate expected stacked-area behavior.

…ies are null

Fixes recharts#6985. PR recharts#7041 removed the !connectNulls guard entirely, which caused
a regression (recharts#7070) where stacked areas overlapped when connectNulls={true}
and only some series had null values.

This v2 fix preserves the original !connectNulls guard and adds a new
allStackedSeriesNull check: when connectNulls is true and a stacked chart has
a data point where ALL series in the stack are null, only then treat it as a
breakpoint. If only some series are null, they are connected through as 0
(the correct stacking behavior).

Changes:
- Added selectStackDataKeys selector to retrieve all dataKeys in a stack group
- Pass stackDataKeys into computeArea
- isBreakPoint now has three conditions:
  1. value1 == null (basic null check)
  2. hasStack && !connectNulls && rawValue == null (original guard, preserved)
  3. allStackedSeriesNull (new: all series null → break even with connectNulls)
@coderabbitai

coderabbitai Bot commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (3)
  • test-vr/__snapshots__/tests/www/AreaChartApiExamples.spec-vr.tsx-snapshots/AreaChartConnectNulls-1-chromium-linux.png is excluded by !**/*.png
  • test-vr/__snapshots__/tests/www/AreaChartApiExamples.spec-vr.tsx-snapshots/AreaChartConnectNulls-1-firefox-linux.png is excluded by !**/*.png
  • test-vr/__snapshots__/tests/www/AreaChartApiExamples.spec-vr.tsx-snapshots/AreaChartConnectNulls-1-webkit-linux.png is excluded by !**/*.png

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6cecaad7-e455-4914-b858-e9b79111bc82

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Adds stack-aware null handling to area layout: computeArea accepts optional stackDataKeys, computes per-point rawValue and allStackedSeriesNull, and extends breakpoint logic so connectNulls behaves correctly for stacked area series.

Changes

Cohort / File(s) Summary
Area Computation Logic
src/cartesian/Area.tsx
Added optional stackDataKeys parameter to computeArea; introduced rawValue and allStackedSeriesNull; expanded isBreakPoint to treat stacked-null cases as breaks when appropriate; applied rawValue consistently for stacked/non-stacked paths.
Area Selectors
src/state/selectors/areaSelectors.ts
Added selectStackDataKeys selector to extract stacked-area data keys; wired stackDataKeys into selectArea and passed it into computeArea; imported DataKey and isNotNil.
Docs / Examples
www/src/docs/exampleComponents/AreaChart/AreaChartConnectNulls.tsx
Added data2 with sparse/undefined values and a new AreaChart example demonstrating connectNulls with stacked series; removed some devtools and a grid from examples.
Manifest / Package
manifest_file, package.json
Minor manifest/package edits recorded (lines changed).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • Issue #6782: Prior changes focused on computeArea adjustments for stacked-series nulls (rawValue / allStackedSeriesNull), which matches this PR's intent.
  • Issue #6985: Reports that stackId and connectNulls don't connect points when values are null/undefined; this PR changes null-handling for stacked areas to address that.
  • Issue #7070: Concerns connectNulls overlaps; this PR modifies null/breakpoint logic that can affect those rendering overlaps.

Possibly related PRs

Suggested reviewers

  • PavelVanecek
  • ckifer
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main fix: addressing connectNulls behavior with stackId for all-null data points.
Description check ✅ Passed The description comprehensively covers all required sections: motivation (PR #7041 broke connectNulls), implementation details, testing (255 unit tests pass), and documentation updates.
Linked Issues check ✅ Passed The PR successfully addresses both linked issues: #6985 (stackId with connectNulls now handles null values correctly) and #7070 (overlap artifacts fixed by preserving !connectNulls guard and adding allStackedSeriesNull check).
Out of Scope Changes check ✅ Passed All changes are directly related to fixing connectNulls behavior with stacks: new selector, updated computeArea logic, and example updates demonstrating the fix.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/cartesian/Area.tsx (1)

1047-1047: Avoid duplicate getValueByDataKey lookup per datum.

Line 1047 recalculates rawValue, while non-stacked flow already computed it at Line 1035. Reusing one value avoids repeated accessor/function execution inside this loop.

Proposed change
-    if (hasStack) {
+    const rawValue = getValueByDataKey(entry, dataKey);
+    if (hasStack) {
       valueAsArray = stackedData[dataStartIndex + index];
     } else {
-      const rawValue = getValueByDataKey(entry, dataKey);
-
       if (!Array.isArray(rawValue)) {
         valueAsArray = [baseValue, rawValue];
       } else {
         valueAsArray = rawValue;
         isRange = true;
       }
     }
@@
-    const rawValue = getValueByDataKey(entry, dataKey);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cartesian/Area.tsx` at line 1047, The loop in Area.tsx is calling
getValueByDataKey twice for the same datum; reuse the previously computed
rawValue instead of recalculating it. Modify the loop so the rawValue computed
earlier (from getValueByDataKey(entry, dataKey)) is stored in a variable visible
to both the non-stacked and stacked branches and remove the second
getValueByDataKey call, ensuring you still use entry and dataKey where needed
and preserve any variable renaming (e.g., rawValue) used by the surrounding code
paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/state/selectors/areaSelectors.ts`:
- Line 151: The current expression in areaSelectors.ts that builds dataKeys —
group.graphicalItems.map(item => item.dataKey).filter(Boolean) — incorrectly
drops valid falsy keys like 0 or ''; update the filter to only remove
null/undefined (e.g., .filter(k => k !== undefined && k !== null)) so
allStackedSeriesNull and any logic using the dataKey list preserve numeric-zero
and empty-string keys while still excluding missing values.

---

Nitpick comments:
In `@src/cartesian/Area.tsx`:
- Line 1047: The loop in Area.tsx is calling getValueByDataKey twice for the
same datum; reuse the previously computed rawValue instead of recalculating it.
Modify the loop so the rawValue computed earlier (from getValueByDataKey(entry,
dataKey)) is stored in a variable visible to both the non-stacked and stacked
branches and remove the second getValueByDataKey call, ensuring you still use
entry and dataKey where needed and preserve any variable renaming (e.g.,
rawValue) used by the surrounding code paths.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b8cf58 and 9ead305.

📒 Files selected for processing (2)
  • src/cartesian/Area.tsx
  • src/state/selectors/areaSelectors.ts

Comment thread src/state/selectors/areaSelectors.ts Outdated
@codecov

codecov Bot commented Mar 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.65%. Comparing base (4b8cf58) to head (4db1417).
⚠️ Report is 49 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7085      +/-   ##
==========================================
- Coverage   89.81%   89.65%   -0.17%     
==========================================
  Files         529      536       +7     
  Lines       39956    40561     +605     
  Branches     5452     5538      +86     
==========================================
+ Hits        35888    36363     +475     
- Misses       4059     4190     +131     
+ Partials        9        8       -1     

☔ 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/state/selectors/areaSelectors.ts`:
- Around line 134-154: Add a unit test that exercises the "all-null
stacked-null" branch by creating area settings with stackId and
connectNulls={true}, a stack group (selectNumericalAxisStackGroups) whose
graphicalItems all have null values at the same index, and assert that
selectStackDataKeys flows into computeArea producing the expected all-null
handling; specifically, write a focused test under Area tests that constructs
the RechartsRootState slices used by selectSynchronisedAreaSettings and
selectNumericalAxisStackGroups, calls the selector/selectors
(selectStackDataKeys) and then computeArea (or the public component behavior
relying on it), and asserts the behavior for the all-null breakpoint so this new
production path is covered.

In `@www/src/docs/exampleComponents/AreaChart/AreaChartConnectNulls.tsx`:
- Around line 68-70: The sample data in the AreaChartConnectNulls component
contains a duplicated category label ("Page D") for the last two points; update
the data array in AreaChartConnectNulls.tsx by renaming the final object's name
field to a distinct label (e.g., change the last "Page D" to "Page E") so the
categorical axis and connectNulls behavior are clear and not confusing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f7b7cf8b-fee4-4a85-b870-ff48033933fc

📥 Commits

Reviewing files that changed from the base of the PR and between 9ead305 and 7d4e3c5.

⛔ Files ignored due to path filters (3)
  • test-vr/__snapshots__/tests/www/AreaChartApiExamples.spec-vr.tsx-snapshots/AreaChartConnectNulls-1-chromium-linux.png is excluded by !**/*.png
  • test-vr/__snapshots__/tests/www/AreaChartApiExamples.spec-vr.tsx-snapshots/AreaChartConnectNulls-1-firefox-linux.png is excluded by !**/*.png
  • test-vr/__snapshots__/tests/www/AreaChartApiExamples.spec-vr.tsx-snapshots/AreaChartConnectNulls-1-webkit-linux.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • src/state/selectors/areaSelectors.ts
  • www/src/docs/exampleComponents/AreaChart/AreaChartConnectNulls.tsx

Comment on lines +134 to +154
const selectStackDataKeys: (
state: RechartsRootState,
id: GraphicalItemId,
isPanorama: boolean,
) => ReadonlyArray<DataKey<any>> | undefined = createSelector(
[selectSynchronisedAreaSettings, selectNumericalAxisStackGroups],
(areaSettings: AreaSettings | undefined, stackGroups: Record<StackId, StackGroup> | undefined) => {
if (areaSettings == null || stackGroups == null) {
return undefined;
}
const { stackId } = areaSettings;
if (stackId == null) {
return undefined;
}
const group: StackGroup | undefined = stackGroups[stackId];
if (group == null) {
return undefined;
}
return group.graphicalItems.map(item => item.dataKey).filter(isNotNil);
},
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a unit test for the new all-null stacked-null branch.

This wires a new production path for connectNulls={true} when every sibling in the stack is null at the same index, but the PR context only mentions existing coverage for the partial-null case. Please add a focused Area test for the all-null breakpoint behavior so this selector-to-computeArea() path stays pinned.

As per coding guidelines, "Aim for 100% unit test code coverage when writing new code".

Also applies to: 172-225

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/state/selectors/areaSelectors.ts` around lines 134 - 154, Add a unit test
that exercises the "all-null stacked-null" branch by creating area settings with
stackId and connectNulls={true}, a stack group (selectNumericalAxisStackGroups)
whose graphicalItems all have null values at the same index, and assert that
selectStackDataKeys flows into computeArea producing the expected all-null
handling; specifically, write a focused test under Area tests that constructs
the RechartsRootState slices used by selectSynchronisedAreaSettings and
selectNumericalAxisStackGroups, calls the selector/selectors
(selectStackDataKeys) and then computeArea (or the public component behavior
relying on it), and asserts the behavior for the all-null breakpoint so this new
production path is covered.

Comment thread www/src/docs/exampleComponents/AreaChart/AreaChartConnectNulls.tsx Outdated
@codecov

codecov Bot commented Mar 7, 2026

Copy link
Copy Markdown

Bundle Report

Changes will increase total bundle size by 88.42kB (1.77%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
recharts/bundle-cjs 1.3MB 29.49kB (2.32%) ⬆️
recharts/bundle-es6 1.13MB 26.62kB (2.41%) ⬆️
recharts/bundle-umd 547.17kB 5.93kB (1.1%) ⬆️
recharts/bundle-treeshaking-polar 448.02kB 8.07kB (1.83%) ⬆️
recharts/bundle-treeshaking-treemap 354.73kB 9.78kB (2.84%) ⬆️
recharts/bundle-treeshaking-cartesian 644.4kB 8.53kB (1.34%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: recharts/bundle-treeshaking-polar

Assets Changed:

Asset Name Size Change Total Size Change (%)
bundle.js 8.07kB 448.02kB 1.83%
view changes for bundle: recharts/bundle-treeshaking-treemap

Assets Changed:

Asset Name Size Change Total Size Change (%)
bundle.js 9.78kB 354.73kB 2.84%
view changes for bundle: recharts/bundle-treeshaking-cartesian

Assets Changed:

Asset Name Size Change Total Size Change (%)
bundle.js 8.53kB 644.4kB 1.34%
view changes for bundle: recharts/bundle-cjs

Assets Changed:

Asset Name Size Change Total Size Change (%)
state/selectors/axisSelectors.js 3.49kB 69.27kB 5.31% ⚠️
cartesian/Area.js 264 bytes 29.44kB 0.9%
polar/Pie.js 673 bytes 28.25kB 2.44%
util/ChartUtils.js 114 bytes 19.98kB 0.57%
state/selectors/tooltipSelectors.js 309 bytes 18.22kB 1.73%
synchronisation/useChartSynchronisation.js 3.57kB 16.61kB 27.39% ⚠️
chart/RechartsWrapper.js 332 bytes 15.46kB 2.19%
index.js 774 bytes 14.83kB 5.51% ⚠️
polar/PolarRadiusAxis.js -99 bytes 11.69kB -0.84%
polar/PolarGrid.js -50 bytes 10.32kB -0.48%
util/types.js 14 bytes 9.63kB 0.15%
state/tooltipSlice.js 220 bytes 9.24kB 2.44%
state/keyboardEventsMiddleware.js 2.0kB 7.86kB 34.03% ⚠️
component/DefaultLegendContent.js 1 bytes 7.65kB 0.01%
component/DefaultTooltipContent.js 10 bytes 7.33kB 0.14%
util/createCartesianCharts.js (New) 7.04kB 7.04kB 100.0% 🚀
state/selectors/areaSelectors.js 604 bytes 6.42kB 10.38% ⚠️
util/createPolarCharts.js (New) 6.11kB 6.11kB 100.0% 🚀
zIndex/ZIndexLayer.js 2.24kB 5.38kB 71.33% ⚠️
state/selectors/polarSelectors.js 52 bytes 4.94kB 1.06%
state/selectors/dataSelectors.js 1.82kB 4.23kB 75.35% ⚠️
state/selectors/combiners/combineConfiguredScale.js -32 bytes 2.44kB -1.3%
state/selectors/combiners/combineTooltipPayloadConfigurations.js 45 bytes 2.36kB 1.95%
view changes for bundle: recharts/bundle-umd

Assets Changed:

Asset Name Size Change Total Size Change (%)
Recharts.js 5.93kB 547.17kB 1.1%
view changes for bundle: recharts/bundle-es6

Assets Changed:

Asset Name Size Change Total Size Change (%)
state/selectors/axisSelectors.js 3.35kB 59.24kB 6.0% ⚠️
cartesian/Area.js 247 bytes 27.59kB 0.9%
polar/Pie.js 640 bytes 26.43kB 2.48%
util/ChartUtils.js 114 bytes 17.97kB 0.64%
synchronisation/useChartSynchronisation.js 3.53kB 15.63kB 29.22% ⚠️
state/selectors/tooltipSelectors.js 300 bytes 14.72kB 2.08%
chart/RechartsWrapper.js 332 bytes 13.61kB 2.5%
polar/PolarRadiusAxis.js -99 bytes 10.24kB -0.96%
util/types.js 14 bytes 9.22kB 0.15%
polar/PolarGrid.js -50 bytes 9.18kB -0.54%
state/tooltipSlice.js 220 bytes 7.87kB 2.88%
state/keyboardEventsMiddleware.js 1.81kB 7.24kB 33.26% ⚠️
component/DefaultLegendContent.js 1 bytes 6.69kB 0.01%
util/createCartesianCharts.js (New) 6.3kB 6.3kB 100.0% 🚀
component/DefaultTooltipContent.js 10 bytes 6.19kB 0.16%
state/selectors/areaSelectors.js 577 bytes 5.84kB 10.95% ⚠️
util/createPolarCharts.js (New) 5.34kB 5.34kB 100.0% 🚀
zIndex/ZIndexLayer.js 2.19kB 5.13kB 74.5% ⚠️
state/selectors/polarSelectors.js 74 bytes 3.94kB 1.92%
index.js 173 bytes 3.87kB 4.68%
state/selectors/dataSelectors.js 1.52kB 3.32kB 84.9% ⚠️
state/selectors/combiners/combineTooltipPayloadConfigurations.js 45 bytes 2.15kB 2.14%
state/selectors/combiners/combineConfiguredScale.js -32 bytes 1.56kB -2.01%

@PavelVanecek

Copy link
Copy Markdown
Collaborator

Here is the chart before & after, is this how it's meant to look like? #6985 (comment)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@Harikrushn9118 this doesn't look correct

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for adding the example and the isNotNil cleanup! The approach here is to only break when all stacked series are null at a data point — partial nulls are still treated as 0 in the stack so stacking stays consistent.

…ent connectNulls on both areas, remove stale VR snapshots
@Harikrushn9118

Copy link
Copy Markdown
Contributor Author

@PavelVanecek Fixed! The 5th chart had a duplicate "Page D" label and only one area had connectNulls — that's why it looked off. Now both areas use connectNulls and the labels are unique. Deleted the VR snapshots so CI can regenerate them.

The core logic is same — partial nulls still treated as 0 in the stack, only all-null entries become breakpoints.

@PavelVanecek

Copy link
Copy Markdown
Collaborator

Our CI doesn't generate snapshots. You need to commit them.

PavelVanecek pushed a commit that referenced this pull request Jul 20, 2026
…ries is null (#7566)

Fixes #6985.

![Stacked AreaChart with connectNulls, dataWithGaps dataset. Before:
all-null point at Page C collapses to 0. After: Page C connects across,
and the partial-null uv at Page F still renders as
0.](https://raw.githubusercontent.com/kimlj/recharts/pr-6985-assets/6985-before-after.png)

Top chart is master, bottom is this PR. The all-null point (Page C)
connects across; the partial-null point (Page F, only `uv` missing)
still renders as 0, so the #7073 regression does not return.

## Problem

In a stacked AreaChart with `connectNulls`, a data point where every
series is null renders as a drop to 0 instead of connecting across the
gap. d3-stack defaults nulls to 0, so `value1` is never null for stacked
data, and the `!connectNulls` guard is the only thing controlling null
behavior there.

## Change

`computeArea` in `src/cartesian/Area.tsx` marks a point as a break point
when every dataKey in the stack group is null (`wholeStackIsNull`). The
stack dataKeys are supplied by a new `selectStackDataKeys` selector in
`src/state/selectors/areaSelectors.ts`.

The `!connectNulls && rawValue == null` guard is unchanged, so a point
where only some series are null still renders as 0 in the stack.

- Every series null at a point: connects across (new behavior).
- Some series null at a point: unchanged, renders as 0 to preserve stack
offsets.

## Prior art

This is the design proposed by @Harikrushn9118 in #7085: keep the
existing guard, add a separate all-null check, and pass the stack
dataKeys into `computeArea`. #7085 was closed by its author before
completion. This PR implements that design and commits the VR snapshots
#7085 was missing.

## History

#7041 removed the `!connectNulls` guard and was merged, then reverted in
#7073 because it made stacked charts with a single null series render
incorrectly. This PR keeps that guard and scopes the new behavior to the
all-null case, so the #7073 regression does not return.

## Tests

- `test/chart/AreaChart.spec.tsx`: two regression tests, "connects
across points where every stacked series is null if connectNulls is
true" and "breaks at points where every stacked series is null if
connectNulls is false". Both fail without the source change. The
existing "Renders null points as 0 if stacked and connectNulls is true"
test covers the partial-null case that must stay unchanged.
- `www` example `AreaChartConnectNulls.tsx`: adds a `dataWithGaps`
dataset with an all-null point at Page C and a partial-null point at
Page F.
- VR snapshots committed for chromium, firefox, and webkit.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved stacked area gap/break detection when an entire stacked point
has all series values missing, so gaps are handled correctly.
* `connectNulls` now reliably bridges fully missing stacked points,
while keeping breaks when `connectNulls` is disabled.
* Partial missing values still render with correct stacked
contributions.
* **Documentation**
* Added stacked area examples showing how gaps are rendered with and
without `connectNulls`.
* **Tests**
* Added coverage validating `connectNulls` behavior for all-missing
stacked points in area charts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Unreleased] Area connect nulls overlaps stackId and connectNulls don't work together for points with no data

2 participants