DevExpress / devextreme-reactive

Business React components for Bootstrap and Material-UI
https://devexpress.github.io/devextreme-reactive/
Other
2.08k stars 379 forks source link

fix(grid-core): Make a virtual table's viewport calculation band-friendly (T1154239) #3643

Closed VasilyStrelyaev closed 1 year ago

VasilyStrelyaev commented 1 year ago

This PR fixes an issue where header bands that stretch across several fixed columns are split during scrolling: https://supportcenter.devexpress.com/ticket/details/t1154239/reactive-grid-fixed-columns-are-duplicated-if-virtualtable-is-used.

The reason is that when the virtual table calculates the viewport to determine which columns to render, and fixed columns are beyond the regularly calculated viewport, the virtual table adds fixed columns explicitly. However, fixed columns are not merged into a single range but rather added as multiple ranges:

Here is the code that did it: https://github.com/DevExpress/devextreme-reactive/blob/master/packages/dx-grid-core/src/utils/virtual-table.ts#L22

However, bands cannot stretch through multiple viewport ranges, so they get split.

It looks like there is no special reason why adjacent ranges of the viewport cannot be merged together. So, I modified the method that adds fixed columns to the viewport, so that it now merges adjacent indexes into ranges (see my new tests). I aimed not to increase the algorithm's computational complexity as it runs on scroll.

You may notice that the algorithm can now merge both fixed and unfixed columns in a single range. This does not seem to be a problem and it does not prevent a border to appear between fixed and unfixed columns. That's because when splitting the header bands, the grid relies not only on the viewport ranges but also on "column chains", which do break between fixed and unfixed columns.