fix(dataZoom): keep boundary neighbors for line series so partial segments and null gaps survive#21636
Open
JamesGoslings wants to merge 1 commit into
Open
Conversation
|
Thanks for your contribution! Please DO NOT commit the files in dist, i18n, and ssr/client/dist folders in a non-release pull request. These folders are for release use only. |
…al segments and null gaps survive. close apache#21564, close apache#21565 When dataZoom uses the default filterMode 'filter', AxisProxy calls selectRange() on the series store, which physically drops every row whose value falls outside the window. For line / area series this corrupts the rendering in two ways: - A line segment that crosses the window boundary loses one of its endpoints, so the visible portion of the segment vanishes entirely (apache#21564). - A null data point that interrupts the line gets dropped if its own value sits outside the window, so the line view no longer sees the gap and connects across it as a ghost line (apache#21565). This is most visible when data is non-monotonic in the filter dimension and the null is the only signal that two adjacent rows belong to different segments. Replace selectRange with a boundary-aware filter for line subType only: keep row i when row i, row i-1 or row i+1 is in the window. A single Uint8Array pre-scan computes inWindow status; filterSelf then applies the keep predicate. Other series types and other filter modes are untouched. Adds unit coverage for the partial-segment case, the null-gap case, the bar-series no-op, the filterMode: 'none' no-op, and the all-in-window short-circuit. Adds a visual reproducer at test/line-dataZoom-boundary.html.
4cc086f to
5d8e7cd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brief Information
This pull request is in the type of:
What does this PR do?
When
dataZoomfilters a line series with the defaultfilterMode: 'filter', keep one neighboring data row on each side of the in-window range so partial line segments at the boundary can still be drawn andnullgap markers outside the window still interrupt the line.Fixed issues
Details
Before: What was the problem?
Both bugs share one root cause.
AxisProxy.filterData()callsseriesData.selectRange(), which physically drops every row whose value falls outside the data zoom window. For line / area series this corrupts the rendering in two ways:#21564 — partial line segments vanish at the boundary.
When a segment connects an in-window point with an out-of-window point, the out-of-window endpoint is removed and the line view loses the entire segment instead of clipping it. The result is that any line crossing the visible edge disappears completely.
#21565 — null gap markers stop interrupting the line.
When a
nullrow's value sits outside the window, the row is dropped from the filtered store and the line view never sees the gap marker. With non-monotonic data, the line view then connects two rows that should remain interrupted, drawing a "ghost line".After: How does it behave after the fixing?
For line / area series only (
subType === 'line') and only whenfilterMode === 'filter', swapselectRange()for a boundary-aware filter:A single
Uint8Arraypre-scan computes inWindow status;filterSelfthen applies the keep predicate in one pass. Other series types (bar, scatter, ...) and other filter modes (none,empty,weakFilter) are completely untouched, so the fastselectRangepath remains the default for everything that does not need this.With the fix:
nullrow whose raw-order neighbor is in the window is retained, so it still breaks the line and prevents ghost connections.The visible-y extent on auto-fit Y axes may extend slightly to include the boundary points' Y values; this is necessary because the partial segment's clipping line can reach those Y values, and without the wider extent the segment would be clipped along the Y dimension as well.
Tests
test/ut/spec/component/dataZoom/lineBoundary.test.tsadds five unit tests covering:#21564: window[3, 13]against[(0,5), (2,6), (8,5), (12,5), (16,6)]→ kept raw indices[1, 2, 3, 4](the two boundary neighbors are now retained).#21565: window[3, 10]against[(4,5), (7,5), (11,5), (11,null), (6,6), (9,6)]→ all six rows retained, so the null still breaks the line.barseries: behavior unchanged (no boundary keeping).filterMode: 'none': behavior unchanged.test/line-dataZoom-boundary.htmlis a visual reproducer for both issues so reviewers can pan the chart and verify the rendering directly.Full unit suite: 26 suites, 197 tests, all green.
Document Info
Misc
Security Checking
ZRender Changes
Related test cases or examples to use the new APIs
test/ut/spec/component/dataZoom/lineBoundary.test.ts— unit teststest/line-dataZoom-boundary.html— visual reproducerMerging options
Other information
A few related rendering features were not exhaustively visually verified and are worth a reviewer's eye:
endLabelon a line series with dataZoom: with the fix, the last filtered row may be a boundary point sitting just outside the window. The label would either be clipped or rendered just past the chart edge depending on howendLabelis positioned. If this turns out to need adjusting, it can be a follow-up.markPointwithtype: 'max'/'min': same caveat — these may now match a boundary point.For the bugs as reported, both reproductions render correctly with the fix applied.