/ LIVE

huy123456
2024.10.03

個人開発でガントチャートライブラリを作ってみた

Posted at 

react-gantt-flow

個人開発でガントチャートライブラリを作成しており、先日ベータ版をリリースしました🎉
良きタイミングでアウトプットしたいな〜と思っていたので、いくつか記事を分けてまとめていければと思います

どんな機能があるの?

現状まだまだ機能不足ですが、最低限の機能は用意できました👏
詳細は前述の Storybook を参照ください🙇

機能 ひとことで
ドラッグ & リサイズ タスクの開始・終了日をマウス操作で更新
進捗バー(スライダー) 0 ~ 100 % をリアルタイム編集
依存矢印 タスク間を自動で S 字曲線で接続
Today ライン / 計画↔実績差分 boolean でオン・オフ切り替え
Type-safe API 全プロップに厳密な TS 型を付与

なんでガントチャート?

今回ガントチャートを作成した理由は、"今後作りたいシステムの 1 機能としてガントチャートの機能が欲しかったから" というシンプルな理由です

既存の OSS (Frappe Gantt など) でも正直よかったのですが、私が調べた限り、スケジュールと現在進捗との乖離が一目でわかる機能(いわゆる稲妻線表示機能)を持ったライブラリが無かった為、「じゃあ作ってみよう」と作成を始めました🏃‍♀️

技術選定

技術選定を以下にまとめます
至ってシンプルな構成です

項目 選定内容
UI React 19 + TypeScript
チャート描画 SVG
日付計算 date-fns
ビルド Vite
パッケージマネージャー pnpm
品質 Vitest / React Testing Library / Chromatic(VRT)
静的解析・フォーマッター Biome
ドキュメンテーション Storybook
CI/CD GitHub Actions

実装方針

react-gantt-flow はチャート部分の描画は全て svg で作成しています

なぜ全て svg なのか

以下のポイントと比較表の内容に基づき svg での実装を選びました
あと、自分で svg をろくに書いたことがなかったので、この際に学びたいなという個人的な気持ちもありました👀

ポイント どう効くか
解像度フリー/ズームに強い ・ガントは時間軸を拡大縮小する UI
・SVG はベクタなので 1 px 単位のスナップや Hi-DPI でも線がにじまない
・Canvas だと再描画が必須、DOM‐div だとサブピクセル誤差が残る
DOM ノードを極小化できる <svg> 内にバー・グリッド・矢印をすべて <g> でまとめれば “1 行 ≒ 数ノード”
・HTML で <div> を行列配置すると千~万単位のノードが増えレイアウト/スタイル計算が激重
1 レイヤ描画で GPU 合成が効く ・まとまった SVG はブラウザで 単一のコンポジットレイヤ になる。
・水平方向のスクロールや transform はレイヤを動かすだけで再ペイント不要の為、60 fps を維持しやすい
ベジェ曲線・パスが 標準装備 ・依存矢印の S 字やプロジェクト線など、Path API ひとつで表現可能
・Canvas も描けるが毎フレーム座標計算と再描画が必要、HTML だと不可能

svg / Canvas / Html + CSS 比較表

特性 SVG Canvas HTML + CSS
解像度依存 なし あり なし (だがサブピクセル誤差)
ノード数 1 枚
インタラクション DOM イベント 手動ヒットテスト DOM イベント
描画コスト 初回のみ 逐次 レイアウト+ペイント

蛇足

SVG のチュートリアルページです
ここの内容を一通り学習するだけでも、かなり勉強になりました📝

ブランチ戦略

作成したライブラリを公開するにあたり、以下のブランチ戦略を採用しました
今回初めてライブラリ開発をしてみて、通常のシステム開発とブランチ戦略が異なる部分に難しさを感じてます😖

こちらのモデルでは以下の 3 つの特徴を意識しています

  • main でメジャーバージョン向けに高速開発
  • 複数の安定ブランチを長期保守
  • 緊急修正をタイムリーに横展開

スクリーンショット 2025-06-14 22.01.11.png