npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@canvas-components/gantt-table

v0.1.5

Published

Framework-agnostic Canvas Gantt chart core engine.

Downloads

102

Readme

@canvas-components/gantt-table

纯原生 Canvas 甘特图核心,目录组织参考 @canvas-components/list-table:配置位于 schema,布局与日期计算位于 domain,绘制位于 rendering,命中测试位于 interaction。

首版支持时间轴、任务条、进度、依赖线、横纵滚动、固定时间表头与任务列、任务选中、拖拽平移日期和任务条宽度调整。开启 editable 后,可在未排期任务行中拖拽添加任务条,移动或缩放已有任务条,并用 Delete/Backspace 删除选中任务条(清除 start / end,保留任务行)。选中任务后还可以从左右连接锚点拖到另一任务条,新建或修改依赖;依赖线可独立选中并用 Delete/Backspace 删除。通过 snapToColumn 可让移动与缩放吸附到最小日维度,拖拽结果始终限制在时间轴范围内;开启 rowDraggable 后可在固定任务列中拖拽调整行顺序,相邻行会以动画让出目标位置,并通过 onTaskReorder 返回新顺序。weekendBackground 可控制是否显示周末底色,颜色可通过 theme.weekendBackgroundColor 调整。滚动位置会根据内容和视口尺寸自动约束,也可以通过实例的 scrollTo(left, top) 方法定位。React 接入位于独立的 @canvas-components/react-gantt-table 适配包中。

React 配置示例

import { useState } from "react";
import { ReactGanttTable } from "@canvas-components/react-gantt-table";
import type { GanttTask } from "@canvas-components/gantt-table";

const taskContent = {
  render: (task: GanttTask) => `${task.title} · ${task.progress ?? 0}%`,
  style: { color: "#ffffff", fontWeight: 600, textAlign: "center" },
} satisfies Pick<GanttTask, "render" | "style">;

export function ProjectPlan() {
  const [tasks, setTasks] = useState<GanttTask[]>([
    {
      id: "research",
      title: "需求调研",
      start: "2026-09-01",
      end: "2026-09-04",
      progress: 100,
      ...taskContent,
    },
    {
      id: "design",
      title: "交互设计",
      start: "2026-09-04",
      end: "2026-09-09",
      progress: 60,
      ...taskContent,
    },
  ]);
  const [dependencies, setDependencies] = useState([
    { from: "research", to: "design", type: "finish-to-start" as const },
  ]);

  return (
    <ReactGanttTable
      tasks={tasks}
      dependencies={dependencies}
      startDate="2026-08-31"
      endDate="2026-10-01"
      scale="day"
      taskColumnWidth={180}
      editable
      taskColumnResizable
      taskResizable
      snapToColumn
      rowDraggable
      weekendBackground
      theme={{ weekendBackgroundColor: "#fafafa" }}
      onTaskChange={(changedTask) => {
        setTasks((current) =>
          current.map((task) =>
            task.id === changedTask.id ? { ...changedTask } : task,
          ),
        );
      }}
      onTaskReorder={(reorderedTasks) => {
        setTasks(reorderedTasks.map((task) => ({ ...task })));
      }}
      onDependenciesChange={(nextDependencies) => {
        setDependencies(nextDependencies.map((item) => ({ ...item })));
      }}
      style={{ height: 360 }}
    />
  );
}

原生配置示例

import { Gantt } from "@canvas-components/gantt-table";

const tasksWithContent = tasks.map((task) => ({
  ...task,
  render: (currentTask) =>
    `${currentTask.title} · ${currentTask.progress ?? 0}%`,
  style: { color: "#ffffff", fontWeight: 600, textAlign: "center" },
}));

const gantt = new Gantt(container, {
  tasks: tasksWithContent,
  dependencies,
  startDate: "2026-08-31",
  endDate: "2026-10-01",
  scale: "week",
  editable: true,
  taskColumnResizable: true,
  taskResizable: true,
  snapToColumn: true,
  rowDraggable: true,
  weekendBackground: true,
  onTaskChange: (task) => console.log(task),
  onTaskReorder: (nextTasks) => console.log(nextTasks),
  onDependenciesChange: (nextDependencies) => console.log(nextDependencies),
});

gantt.mount();
gantt.scrollTo(320, 0);
// gantt.destroy();

常用配置

| 配置 | 说明 | 默认值 | | ------------------------------------------- | ------------------------------------ | ------------- | | scale | 时间轴维度:day、week、month | day | | headerLevels | 时间轴多层表头配置 | 当前 scale | | headerHeight | 每层表头的默认高度 | 56 | | editable | 开启任务条新增、移动、缩放与键盘删除 | false | | taskResizable | 编辑模式下允许移动及拖拽两端调整日期 | true | | snapToColumn | 鼠标释放后吸附到最小日维度 | false | | rowDraggable | 在固定任务列中拖拽改变任务顺序 | false | | multiTask | 开启一行多个任务条模式 | false | | debug | Canvas 调试叠层、日志和性能埋点配置 | undefined | | taskColumnResizable | 允许拖拽改变固定任务列宽度 | true | | taskColumnMinWidth / taskColumnMaxWidth | 固定任务列宽度限制 | 120 / 480 | | weekendBackground | 是否显示周末底色 | true | | theme.weekendBackgroundColor | 周末背景颜色 | #fafafa | | GanttTask.render | 自定义当前任务条内部内容 | - | | GanttTask.style | 当前任务条内部文字样式 | - | | onTaskChange | 任务条新增、移动、缩放或删除完成回调 | - | | onTaskReorder | 行拖拽排序完成回调 | - | | onDependenciesChange | 依赖连线新增、修改或删除回调 | - |

调试模式

通过 debug.enabled 开启与 list-table 一致的 Canvas 调试叠层。默认显示多层表头、表体行、任务条、固定列分隔线、视口和鼠标命中单元格;绘制节点详情统一使用公共调试 popup。各部分可通过 showHeaderBounds、showBodyBounds、showTaskBounds、showFixedSplitLines、showViewportBounds、showHitTarget 和 showNodeInspector 独立关闭。

const ganttRef = useRef<ReactGanttTableRef>(null);

<ReactGanttTable
  ref={ganttRef}
  debug={{
    enabled: true,
    logDrawCalls: true,
    onPerformance: (metric) => console.log(metric),
  }}
/>;

const snapshot = ganttRef.current?.getDebugSnapshot();

getDebugSnapshot() 返回最近一帧的布局、视口、滚动位置、可见行范围、任务与依赖数量、选中态、交互态和布局/渲染耗时。logStateChanges 可输出配置与滚动变化,logDrawCalls 可输出每帧快照;两项默认关闭。

任务可通过 color 单独设置未完成区域颜色,通过 progressColor 设置已完成区域颜色,progress 接受 0 到 100 的进度百分比。未配置任务级颜色时,分别回退到 theme.taskColor 与 theme.taskProgressColor。

每个任务可通过同级的 render(task, rowIndex) 与 style 分别配置内部内容和文字样式。render 返回字符串、数字或空值;style 支持 color、fontSize、fontWeight、fontFamily 和 textAlign。内容会裁剪在任务条的圆角范围内,空间不足时自动显示省略号。

默认每个顶层 GanttTask 对应一行和一个任务条。开启 multiTask 后,顶层任务作为行定义,固定列显示其 title,并通过 tasks 配置同一行内的多个任务条:

<ReactGanttTable
  multiTask
  tasks={[
    {
      id: "development-row",
      title: "核心开发",
      tasks: [
        {
          id: "api",
          title: "接口开发",
          start: "2026-09-09",
          end: "2026-09-13",
        },
        {
          id: "ui",
          title: "界面开发",
          start: "2026-09-13",
          end: "2026-09-17",
        },
      ],
    },
  ]}
/>

多任务模式下,选择、移动、缩放、删除、onTaskChange 和依赖连线均以行内任务为单位;固定列拖拽仍以顶层行为单位。若需要在空白区域拖拽创建任务条,可在行内预先提供未设置 start / end 的任务。

通过 headerLevels 可由上至下配置多层时间表头。支持 year、quarter、month、week 和 day,每层可单独设置 height 或通过 formatter(start, end) 自定义文案。未配置时保持当前 scale 对应的单层表头:

<ReactGanttTable
  headerHeight={36}
  headerLevels={[
    { unit: "month", height: 42 },
    { unit: "week" },
    {
      unit: "day",
      formatter: (start) => String(start.getDate()),
    },
  ]}
/>

左侧任务列表头会自动纵向合并并覆盖全部时间表头层级;横向滚动时,各层表头与时间网格保持同步固定。

任务的 start 和 end 可省略,用于展示尚未排期的空白行。编辑模式下在该行时间轴区域按住并水平拖拽即可创建任务条;选中后按 Delete 或 Backspace 会再次清除这两个字段。请在 onTaskChange 中同步受控数据。

依赖关系的 type 支持 finish-to-start、start-to-start、finish-to-finish,默认使用 finish-to-start。每条依赖可以通过 color 单独设置连线颜色;未配置时回退到 theme.milestoneColor。

编辑模式下先选中任务,任务条两侧会显示连接锚点。拖动左锚点到另一任务的开始端会创建 start-to-start;拖动右锚点到目标开始端会创建 finish-to-start,拖到目标完成端会创建 finish-to-finish。同一对任务重复连接时会更新原连线类型并保留其自定义颜色。