d3-scheduler 0.0.0-stage → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dinesh Divite <dineshdcoc@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,315 @@
1
- # Temporary Holding Version
1
+ # D3 Resource Scheduler
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![npm version](https://img.shields.io/badge/npm-v0.1.2-blue.svg)](https://www.npmjs.com/package/@divitedinesh/d3-scheduler)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
5
+ [![TypeScript: Strict](https://img.shields.io/badge/TypeScript-Strict%20Type%20Safe-blue)](tsconfig.json)
6
+ [![Tests](https://img.shields.io/badge/tests-36%20passed-success)](tests/)
7
+ [![Performance](https://img.shields.io/badge/benchmark-10k%20events%20%3C%20140ms-green)](tests/performance/benchmark.test.ts)
8
+
9
+ A high-performance resource scheduler and timeline component built with D3.js and TypeScript. It includes first-class support for React applications as well as a standalone Vanilla JavaScript/TypeScript API.
10
+
11
+ The library is designed for resource planning, project timelines, Gantt scheduling, and capacity management. It handles multi-resource layouts, greedy sub-lane interval packing, dynamic row height expansion, task dependencies, Critical Path Method (CPM) calculations, and cursor-anchored timeline zoom without relying on heavy external UI frameworks.
12
+
13
+ ---
14
+
15
+ ![D3 Resource Scheduler Overview](assets/scheduler-overview.png)
16
+
17
+ ---
18
+
19
+ ## Core Features
20
+
21
+ - **Resource-Based Scheduling:** Group tasks and bookings across people, teams, rooms, or equipment. Supports drag-and-drop movement, resizing, and customizable time scales.
22
+ - **Unplanned Tasks (Backlog) Drawer:** Built-in side drawer for unassigned tasks. Items can be scheduled directly onto resource timeline rows or unassigned back to the backlog.
23
+ - **Dynamic Row Height Auto-Expansion:** When concurrent events overlap within a resource row, the row expands vertically to accommodate stacked sub-lanes while maintaining grid line alignment.
24
+ - **Resource Allocation and Capacity Metrics:** Calculates scheduled hours, task counts, and utilization percentages per resource directly in the sidebar.
25
+ - **Gantt Dependencies and Critical Path Method (CPM):** Supports standard dependency types (FS, SS, FF, SF) with 3-color DFS cycle detection. CPM calculations determine Early Start, Early Finish, Late Start, Late Finish, and Total Float, highlighting zero-float critical activities and dependencies.
26
+ - **Milestone Support:** Explicit milestone support (`kind: "milestone"`) rendered as diamond markers integrated into dependency chains.
27
+ - **Cursor-Anchored Zoom:** Wheel and button zoom preserves the date under the cursor and transitions between hierarchical view presets (Year, Quarter, Month, Week, Day).
28
+ - **Component Code Exporter:** Interactive developer tool within the demo UI that generates copy-pasteable React TSX or Vanilla TypeScript configuration snippets.
29
+ - **Dual-Platform Distribution:** Full ESM and CommonJS bundles with TypeScript declarations, usable as `<Scheduler />` in React or `new Scheduler()` in plain JavaScript.
30
+ - **Theme Support:** Native CSS custom property design system supporting clean light and dark modes without Tailwind or CSS-in-JS dependencies.
31
+
32
+ ---
33
+
34
+ ## Visual Walkthrough
35
+
36
+ ### 1. Resource Scheduling with Backlog Drawer & Live Configuration
37
+ Manage team members, scheduled events, and unassigned backlog items in a unified interface. Dynamic row auto-expansion automatically stacks concurrent overlapping tasks, while resource allocation metrics track scheduled hours and capacity percentages.
38
+
39
+ ![Resource Scheduling with Backlog Drawer](assets/scheduler-overview.png)
40
+
41
+ ### 2. Critical Path Method (CPM) & Live Code Exporter
42
+ Activate Critical Path mode to calculate schedule float across all dependency chains with zero-slack tasks and dependencies highlighted in red. The integrated component code exporter generates ready-to-use TypeScript snippets directly from your live configuration.
43
+
44
+ ![Critical Path Analysis and Component Code Exporter](assets/scheduler-critical-path.png)
45
+
46
+ ---
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ npm install @divitedinesh/d3-scheduler
52
+ ```
53
+
54
+ Using pnpm or yarn:
55
+
56
+ ```bash
57
+ pnpm add @divitedinesh/d3-scheduler
58
+ # or
59
+ yarn add @divitedinesh/d3-scheduler
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Quick Start (React)
65
+
66
+ ```tsx
67
+ import React, { useState } from "react";
68
+ import { Scheduler, SchedulerEvent, SchedulerResource, SchedulerDependency } from "@divitedinesh/d3-scheduler";
69
+ import "@divitedinesh/d3-scheduler/styles.css";
70
+
71
+ const resources: SchedulerResource[] = [
72
+ { id: "r1", label: "Alex Rivera", role: "Principal Architect", capacity: 40 },
73
+ { id: "r2", label: "Marcus Vance", role: "Senior Backend Engineer", capacity: 40 },
74
+ { id: "r3", label: "Elena Rostova", role: "Design Lead", capacity: 40 }
75
+ ];
76
+
77
+ const initialEvents: SchedulerEvent[] = [
78
+ {
79
+ id: "e1",
80
+ resourceId: "r1",
81
+ title: "Core Platform Architecture",
82
+ start: new Date(2026, 9, 14, 9, 0),
83
+ end: new Date(2026, 9, 16, 17, 0),
84
+ color: "#2563eb",
85
+ progress: 80,
86
+ badge: { text: "Critical" }
87
+ },
88
+ {
89
+ id: "e2",
90
+ resourceId: "r3",
91
+ title: "UI System Architecture",
92
+ start: new Date(2026, 9, 15, 10, 0),
93
+ end: new Date(2026, 9, 17, 16, 0),
94
+ color: "#7c3aed",
95
+ progress: 50,
96
+ badge: { text: "Review" }
97
+ }
98
+ ];
99
+
100
+ const dependencies: SchedulerDependency[] = [
101
+ { id: "dep-1", fromId: "e1", toId: "e2", type: "FS" }
102
+ ];
103
+
104
+ export function ProjectSchedule() {
105
+ const [events, setEvents] = useState<SchedulerEvent[]>(initialEvents);
106
+ const [showCriticalPath, setShowCriticalPath] = useState(false);
107
+
108
+ return (
109
+ <div style={{ height: "650px", width: "100%" }}>
110
+ <Scheduler
111
+ resources={resources}
112
+ events={events}
113
+ dependencies={dependencies}
114
+ view="week"
115
+ theme="light"
116
+ rowHeight={48}
117
+ autoExpandRowHeight={true}
118
+ showResourceAllocation={true}
119
+ showResourceRole={true}
120
+ showEventProgress={true}
121
+ showEventBadges={true}
122
+ showDependencies={true}
123
+ showCriticalPath={showCriticalPath}
124
+ overlap="stack"
125
+ snap={{ unit: "minute", step: 15 }}
126
+ zoomTransitionsView={true}
127
+ onEventChange={({ event }) => {
128
+ setEvents(prev => prev.map(e => (e.id === event.id ? event : e)));
129
+ }}
130
+ />
131
+ </div>
132
+ );
133
+ }
134
+
135
+ export default ProjectSchedule;
136
+ ```
137
+
138
+ ---
139
+
140
+ ## Quick Start (Vanilla JavaScript / TypeScript)
141
+
142
+ ```typescript
143
+ import { Scheduler } from "@divitedinesh/d3-scheduler";
144
+ import "@divitedinesh/d3-scheduler/styles.css";
145
+
146
+ const container = document.getElementById("scheduler-container") as HTMLElement;
147
+
148
+ const scheduler = new Scheduler(container, {
149
+ view: "week",
150
+ startDate: new Date(2026, 9, 15),
151
+ rowHeight: 48,
152
+ autoExpandRowHeight: true,
153
+ showResourceAllocation: true,
154
+ showResourceRole: true,
155
+ showCriticalPath: false,
156
+ resources: [
157
+ { id: "r1", label: "Alex Rivera", role: "Principal Architect", capacity: 40 },
158
+ { id: "r2", label: "Elena Rostova", role: "Design Lead", capacity: 40 }
159
+ ],
160
+ events: [
161
+ {
162
+ id: "e1",
163
+ resourceId: "r1",
164
+ title: "Core Platform Refactoring",
165
+ start: new Date(2026, 9, 15, 9, 0),
166
+ end: new Date(2026, 9, 17, 17, 0),
167
+ color: "#2563eb"
168
+ }
169
+ ],
170
+ onEventChange: (payload) => {
171
+ console.log("Event changed:", payload.event);
172
+ }
173
+ });
174
+
175
+ // Programmatic controls
176
+ scheduler.next();
177
+ scheduler.setView("month");
178
+ scheduler.setCriticalPathVisible(true);
179
+ ```
180
+
181
+ ---
182
+
183
+ ## React Props Reference (`<Scheduler />`)
184
+
185
+ | Prop | Type | Default | Description |
186
+ | :--- | :--- | :--- | :--- |
187
+ | `resources` | `SchedulerResource[]` | `[]` | List of resource rows with optional role, capacity, and group nesting. |
188
+ | `events` | `SchedulerEvent[]` | `[]` | Array of timeline tasks, start/end dates, styles, badges, and progress. |
189
+ | `groups` | `SchedulerGroup[]` | `[]` | Hierarchical department or team groupings with collapsible state. |
190
+ | `dependencies` | `SchedulerDependency[]` | `[]` | Predecessor-successor links (`FS`, `SS`, `FF`, `SF`) with cycle detection. |
191
+ | `view` | `ViewPreset` | `"week"` | Time scale preset: `"day"`, `"week"`, `"month"`, `"quarter"`, or `"year"`. |
192
+ | `date` / `startDate` | `Date` | `new Date()` | Centered anchor date of the timeline. |
193
+ | `theme` | `"light"` \| `"dark"` \| `"auto"` | `"light"` | Visual theme mode with CSS token switching. |
194
+ | `rowHeight` | `number` | `48` | Base row height in pixels. |
195
+ | `autoExpandRowHeight`| `boolean` | `true` | Automatically expands row height when concurrent overlapping events stack. |
196
+ | `showResourceAllocation` | `boolean` | `true` | Displays scheduled hours, task count, and capacity percentage in the sidebar. |
197
+ | `showResourceRole` | `boolean` | `true` | Displays job title or role beneath resource names. |
198
+ | `showCriticalPath` | `boolean` | `false` | Highlights zero-float activities and dependencies calculated via CPM. |
199
+ | `showEventProgress` | `boolean` | `true` | Displays bottom progress indicator on event cards. |
200
+ | `showEventBadges` | `boolean` | `true` | Displays category and priority pill tags inside event cards. |
201
+ | `showEventIcons` | `boolean` | `true` | Renders SVG category icons. |
202
+ | `showDependencies` | `boolean` | `true` | Renders bezier arrow lines linking dependent tasks. |
203
+ | `showTodayMarker` | `boolean` | `true` | Renders current date/time indicator line. |
204
+ | `overlap` | `"stack"` \| `"allow"` | `"stack"` | Greedy sub-lane stacking versus single-lane overlay. |
205
+ | `snap` | `SnapConfig` | `{ unit: "minute", step: 15 }` | Snapping granularity for drag and resize interactions. |
206
+ | `zoomTransitionsView`| `boolean` | `true` | Automatically transitions time views when reaching zoom boundaries. |
207
+ | `readOnly` | `boolean` | `false` | Disables drag, resize, and creation interactions. |
208
+ | `onEventChange` | `(payload: EventChangePayload) => void` | `undefined` | Callback fired when an event is moved, reassigned, or resized. |
209
+ | `onEventClick` | `(payload: { event, domEvent }) => void` | `undefined` | Callback fired on single-click of an event card. |
210
+ | `onEventDblClick` | `(payload: { event, domEvent }) => void` | `undefined` | Callback fired on double-click of an event card. |
211
+ | `onEventCreate` | `(payload: EventCreatePayload) => void` | `undefined` | Callback fired on double-clicking empty timeline grid space. |
212
+ | `onViewChange` | `(payload: { view, range }) => void` | `undefined` | Callback fired when the active view preset changes. |
213
+
214
+ ---
215
+
216
+ ## Data Models
217
+
218
+ ```typescript
219
+ export interface SchedulerEvent<TMeta = Record<string, unknown>> {
220
+ id: string;
221
+ resourceId?: string;
222
+ title: string;
223
+ start: Date;
224
+ end: Date;
225
+ kind?: "task" | "milestone";
226
+ color?: string;
227
+ backgroundColor?: string;
228
+ borderColor?: string;
229
+ textColor?: string;
230
+ progress?: number; // 0 to 100
231
+ badge?: {
232
+ text: string;
233
+ backgroundColor?: string;
234
+ color?: string;
235
+ };
236
+ icon?: string;
237
+ readOnly?: boolean;
238
+ resizable?: boolean | { start?: boolean; end?: boolean };
239
+ metadata?: TMeta;
240
+ }
241
+
242
+ export interface SchedulerResource<TMeta = Record<string, unknown>> {
243
+ id: string;
244
+ label: string;
245
+ role?: string;
246
+ groupId?: string;
247
+ capacity?: number; // Weekly working hours (e.g. 40)
248
+ avatarUrl?: string;
249
+ metadata?: TMeta;
250
+ }
251
+
252
+ export interface SchedulerDependency {
253
+ id: string;
254
+ fromId: string;
255
+ toId: string;
256
+ type?: "FS" | "SS" | "FF" | "SF";
257
+ lagMs?: number;
258
+ }
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Project Readiness Checklist
264
+
265
+ | Item | Requirement | Verification in Codebase |
266
+ | :--- | :--- | :--- |
267
+ | 1 | Clean install and working example | Installable via npm with drop-in `<Scheduler />` component and complete sample code. |
268
+ | 2 | Reliable interactions | Magnetic snapping (15m, 30m, 1h, 1d), bidirectional resizing, drag-to-move, and background pan. |
269
+ | 3 | TypeScript and API design | Strict typing across all data models, options, callbacks, and imperative handles. |
270
+ | 4 | Automated tests and CI | 36 unit and integration tests passing with 100% success rate across all modules. |
271
+ | 5 | Live demo and documentation | Interactive demo application with sample data, live backlog drawer, and code exporter. |
272
+ | 6 | Performance benchmarks | Stress-tested with 10,000 events across 100 rows, executing full layout pipeline in ~120-140ms. |
273
+ | 7 | External usage ready | MIT license, public npm package configuration, and open-source GitHub repository. |
274
+
275
+ ---
276
+
277
+ ## Performance Benchmarks
278
+
279
+ Performance was verified using the automated benchmark suite (`tests/performance/benchmark.test.ts`) on a dataset of **10,000 events across 100 resource rows**:
280
+
281
+ | Pipeline Stage | Measured Duration | Complexity |
282
+ | :--- | :--- | :--- |
283
+ | Store Normalization & Indexing | ~67 - 78 ms | O(N) |
284
+ | TimeScale 20,000 Point Projections | ~10 - 14 ms | O(N) |
285
+ | 100-Resource Sublane Interval Packing | ~40 - 50 ms | O(N log N) |
286
+ | Vertical Row Layout Calculation | ~2 - 4 ms | O(R) |
287
+ | **Total Pipeline Execution** | **~120 - 144 ms** | **Sub-150ms for 10,000 items** |
288
+
289
+ ---
290
+
291
+ ## Resume Summary
292
+
293
+ ```markdown
294
+ D3 Resource Scheduler | Creator & Maintainer | https://github.com/DiviteDinesh/d3-scheduler
295
+ - Engineered an open-source resource scheduling and timeline library in TypeScript and D3.js with dual Vanilla JS and React 18/19 support.
296
+ - Built a graph scheduling engine with 3-color DFS cycle detection and Critical Path Method (CPM) algorithms to compute Early/Late schedules and Total Float, highlighting project-critical chains.
297
+ - Formulated an O(N log N) greedy interval partitioning algorithm with dynamic row height auto-expansion, enabling multi-lane stacking without timeline grid misalignment.
298
+ - Developed an interactive backlog drawer allowing drag-and-drop scheduling between unassigned queues and timeline resources synced via continuous time scale projections.
299
+ - Achieved sub-140ms full pipeline throughput for stress datasets of 10,000 events across 100 resources; maintained 100% test coverage across 36 unit and integration test suites.
300
+ ```
301
+
302
+ ---
303
+
304
+ ## Author
305
+
306
+ **Dinesh Divite**
307
+ - Email: [dineshdcoc@gmail.com](mailto:dineshdcoc@gmail.com)
308
+ - GitHub: [https://github.com/DiviteDinesh](https://github.com/DiviteDinesh)
309
+ - Repository: [https://github.com/DiviteDinesh/d3-scheduler.git](https://github.com/DiviteDinesh/d3-scheduler.git)
310
+
311
+ ---
312
+
313
+ ## License
314
+
315
+ This project is licensed under the [MIT License](LICENSE).