Introduction

A headless schedule engine that exposes numbers, not pixels.

schedgrid builds resource schedulers, timelines, calendars and Gantt charts — anything that is a grid of things against time, at a size where rendering every cell is not an option.

At its core it is a matrix of rows × columns, virtualised on both axes, that exposes numbers only: which rows and columns are in view, where each one starts, how big it is, and where every item lands, split into lanes when items overlap. It never touches a DOM, a canvas or a Date. You feed it a viewport and a scroll offset and draw the frame it gives you with whatever you like.

import { createGrid } from 'schedgrid/core';

const grid = createGrid({
  rows: { count: 500, size: 48, pinned: 1 },
  columns: { count: 96, size: 30, pinned: 1 },
  items: [{ id: 'a', rows: [3, 4], columns: [38.5, 42] }],
});

grid.setViewport({ width: 1200, height: 800 });
grid.setScroll({ x: 0, y: 0 });

const frame = grid.getFrame();
frame.rows; // [{ index, start, size, pinned }, ...]
frame.columns; // same shape
frame.items; // [{ id, x, y, width, height, lane, lanes, item }, ...]
frame.total; // { width, height }

grid.subscribe(() => draw(grid.getFrame()));

Positions are indices; a fraction is a position inside a cell, so 38.5 is halfway through column 38. schedgrid/time maps moments onto those indices, schedgrid/dom binds a scroll container, and schedgrid/react wraps the same thing in hooks.

Entry points

importwhat it is
schedgrid/corecreateGrid, the engine, plus assignLanes, itemsIntersect, rangesIntersect, createStore.
schedgrid/timetimeAxis: a time range ↔ fractional indices, plus ticks.
schedgrid/dombindScrollElement, viewportPoint.
schedgrid/reactuseGrid, useFrame, useScrollContainer.

Each entry point is its own bundle. A consumer that only imports schedgrid/core never pays for React.

Where to go next

  • Getting started installs the package and renders a first grid.
  • Concepts explains the two coordinate systems, pinned bands, lanes and the frame contract.
  • Examples drives one 10,000-row grid through a DOM renderer and a canvas renderer at the same time.
  • The entry point pages document every option and every value the engine hands back.