T
TanStack10mo ago
rare-sapphire

How to create a Virtualized Pivot Table?

I want to create a pivot table like this https://js.devexpress.com/React/Demos/WidgetsGallery/Demo/PivotGrid/VirtualScrolling/MaterialBlueLight/ using tanstack. There are row/column headers and cells. Row/column headers are virtualized vertically/horizontally, and cells are virtualized in both directions. I'm aware of the grid example in https://tanstack.com/virtual/latest/docs/framework/react/examples/fixed But there are no headers in this example. A tricky part is to stay all 3 of them synced in position. Some pointers/ideas would be appreciated!
TanStack | High Quality Open-Source Software for Web Developers
Headless, type-safe, powerful utilities for complex workflows like Data Management, Data Visualization, Charts, Tables, and UI Components.
From An unknown user
From An unknown user
1 Reply
rare-sapphire
rare-sapphireOP10mo ago
Resolved by using this
function useSyncScroll({ horizontal, ref1, ref2 } = {}) {
const field = horizontal ? "scrollLeft" : "scrollTop";

useEffect(() => {
const handleScroll = (sourceRef, targetRef) => {
if (sourceRef.current && targetRef.current) {
targetRef.current[field] = sourceRef.current[field];
}
};

const div1 = ref1.current;
const div2 = ref2.current;

if (div1 && div2) {
const onScrollDiv1 = () => handleScroll(ref1, ref2);
const onScrollDiv2 = () => handleScroll(ref2, ref1);

div1.addEventListener("scroll", onScrollDiv1);
div2.addEventListener("scroll", onScrollDiv2);

return () => {
div1.removeEventListener("scroll", onScrollDiv1);
div2.removeEventListener("scroll", onScrollDiv2);
};
}
}, []);

return [ref1, ref2];
}

export default useSyncScroll;
function useSyncScroll({ horizontal, ref1, ref2 } = {}) {
const field = horizontal ? "scrollLeft" : "scrollTop";

useEffect(() => {
const handleScroll = (sourceRef, targetRef) => {
if (sourceRef.current && targetRef.current) {
targetRef.current[field] = sourceRef.current[field];
}
};

const div1 = ref1.current;
const div2 = ref2.current;

if (div1 && div2) {
const onScrollDiv1 = () => handleScroll(ref1, ref2);
const onScrollDiv2 = () => handleScroll(ref2, ref1);

div1.addEventListener("scroll", onScrollDiv1);
div2.addEventListener("scroll", onScrollDiv2);

return () => {
div1.removeEventListener("scroll", onScrollDiv1);
div2.removeEventListener("scroll", onScrollDiv2);
};
}
}, []);

return [ref1, ref2];
}

export default useSyncScroll;

Did you find this page helpful?