@context-action/chunk-grid
v0.5.0
Published
Headless vanilla TypeScript library for infinite scroll data visualization with chunk-based rendering
Maintainers
Readme
@context-action/chunk-grid
Headless vanilla TypeScript library for infinite scroll data visualization with chunk-based rendering.
Features
- Chunk-based rendering: Efficient viewport rendering with configurable buffer zones
- Infinite scroll: Seamless scrolling with camera-based coordinate system
- Variable cell sizes: Support for dynamic cell widths/heights per axis
- Hierarchical data: Collapsible rows with parent-child relationships
- Multi-layer cells: Background, content, and overlay layers with z-ordering
- Hit testing: Convert mouse coordinates to cell/chunk coordinates
- Zero dependencies: Pure vanilla TypeScript, no framework required
Installation
npm install @context-action/chunk-grid
# or
pnpm add @context-action/chunk-grid
# or
yarn add @context-action/chunk-gridQuick Start
import { ChunkGridSystem, AxisManager } from '@context-action/chunk-grid'
// Create axis managers
const xAxis = new AxisManager(
Array.from({ length: 100 }, (_, i) => ({
id: `col-${i}`,
index: i,
size: 100,
visible: true,
data: { label: `Column ${i}` }
}))
)
const yAxis = new AxisManager(
Array.from({ length: 100 }, (_, i) => ({
id: `row-${i}`,
index: i,
size: 40,
visible: true,
data: { label: `Row ${i}` }
}))
)
// Create grid system
const grid = new ChunkGridSystem({
container: document.getElementById('grid-container')!,
viewportWidth: 900,
viewportHeight: 600,
xAxisManager: xAxis,
yAxisManager: yAxis,
dataProvider: {
async getCellData(xRange, yRange) {
const cells = []
for (let y = yRange.start; y <= yRange.end; y++) {
for (let x = xRange.start; x <= xRange.end; x++) {
cells.push({
x, y,
content: { text: `${x},${y}` }
})
}
}
return cells
}
},
cellRenderer: (cell) => {
const el = document.createElement('div')
el.className = 'cell'
el.textContent = cell.content.text
return el
}
})
grid.initialize()CDN Usage
<script src="https://unpkg.com/@context-action/chunk-grid"></script>
<script>
const { ChunkGridSystem, AxisManager } = DataViewer
// ... use as above
</script>Core Concepts
Viewport → Content Area → Chunks → Cells
- Viewport: Container DOM element with fixed size
- Content Area: Buffered chunk grid that renders content
- Chunk: Render unit = viewport ÷ 3 (loads/unloads based on camera position)
- Cell: Data placement unit with x,y coordinates
Camera System
The grid uses a camera-based coordinate system:
- Camera stays in center chunk
- Crossing chunk boundary triggers DOM update and snap-back
- Configurable buffer size (0-3) around visible area
- Optional predictive buffer for scroll direction
Hierarchical Axis
import { CollapsibleAxisManager } from '@context-action/chunk-grid'
const yAxis = new CollapsibleAxisManager([
{ id: 'team-1', index: 0, size: 40, visible: true, collapsible: true, data: {} },
{ id: 'member-1', index: 1, size: 40, visible: true, parentId: 'team-1', data: {} },
{ id: 'member-2', index: 2, size: 40, visible: true, parentId: 'team-1', data: {} },
])
// Collapse/expand
yAxis.collapse('team-1') // Hides member-1, member-2
yAxis.expand('team-1') // Shows them again
yAxis.toggle('team-1') // Toggle stateComponents
GridScrollbar
import { GridScrollbar } from '@context-action/chunk-grid'
const scrollbar = new GridScrollbar(
{
container: viewport,
horizontalHeight: 12,
verticalWidth: 12,
},
{ onScroll: (x, y) => grid.scrollToPixel(x, y) },
{
viewportSize: grid.getViewportSize(),
totalSize: grid.getTotalSize(),
position: grid.getPixelPosition(),
}
)GridAxisRenderer
import { GridAxisRenderer } from '@context-action/chunk-grid'
const header = new GridAxisRenderer({
container: headerElement,
axis: 'x',
axisManager: xAxis,
cellRenderer: (cell) => {
const el = document.createElement('div')
el.textContent = cell.data.label
return el
}
})API Reference
Main Classes
| Class | Description |
|-------|-------------|
| ChunkGridSystem | Main entry point for grid rendering |
| AxisManager | Manages axis cells with O(log n) position lookup |
| CollapsibleAxisManager | Extends AxisManager with hierarchy support |
| GridScrollbar | Scrollbar component with drag support |
| GridAxisRenderer | Header/sidebar rendering component |
Key Methods
// Navigation
grid.scrollToPixel(x, y)
grid.scrollToCell(cellX, cellY)
grid.getPixelPosition()
// Hit testing
grid.hitTest(clientX, clientY) // Returns { pixel, cell, chunk, viewport }
// Bounds
grid.setPixelBounds(bounds)
grid.applyPixelBoundsFromAxis()
// Buffer configuration
grid.updateBufferConfig({ bufferSize: 2, predictiveBuffer: true })
// Events
grid.on('scroll', (state) => {})
grid.on('chunkTransition', (from, to) => {})Browser Support
- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
License
MIT
