はじめに
プロジェクトのスケジュール表示、機器の稼働履歴、イベントの年表——「時間軸に沿ってデータを並べるUI」が必要になった経験はありませんか?いざ自作しようとすると、時間軸の目盛り計算、ズーム時のスケール切り替え、アイテムの重なり回避など、考えることが山ほど出てきて途方に暮れてしまいます。
そんなときに頼りになるのが、今回紹介するvis-timelineです。ドラッグでの移動、ホイールでのズーム、アイテムの編集までが標準装備されたインタラクティブなタイムラインを、数行のコードで表示できるJavaScriptライブラリです。
vis-timelineとは
vis-timelineは、ネットワーク図で有名なvis.jsファミリーの一員で、時間軸上のデータ可視化に特化したライブラリです。ミリ秒単位から年単位まで幅広いスケールに対応し、ズーム操作に応じて目盛りが自動で切り替わります。2026年7月にv8.5.2がリリースされるなど現在も活発にメンテナンスされており、MITとApache-2.0のデュアルライセンスで商用利用も安心です。
主な特徴
- インタラクティブ操作が標準装備 - ドラッグでのスクロール、ホイールでのズーム、アイテムの選択・移動・編集までライブラリ側で面倒を見てくれます
- 柔軟な時間スケール - ミリ秒から数百年まで、ズームレベルに応じて時間軸の目盛りが自動調整されます
- 双方向データバインディング - 付属の
DataSetにデータを追加・更新するだけで、画面が即座に反映されます - 依存フレームワーク不要 - 素のJavaScriptで動くため、React・Vue・Svelteなどどんな環境にも組み込めます
インストール
npmを使う場合は、次のコマンドでインストールします。
npm install vis-timeline
ビルドツールを使わない場合は、CDNから読み込むこともできます。
<script src="https://unpkg.com/vis-timeline@latest/standalone/umd/vis-timeline-graph2d.min.js"></script>
<link
href="https://unpkg.com/vis-timeline@latest/styles/vis-timeline-graph2d.min.css"
rel="stylesheet"
/>
基本的な使い方
まずは最小構成のタイムラインを表示してみましょう。コンテナ要素とデータを渡すだけです。
<div id="visualization"></div>
import { Timeline, DataSet } from "vis-timeline/standalone";
import "vis-timeline/styles/vis-timeline-graph2d.min.css";
const container = document.getElementById("visualization");
// タイムラインに表示するアイテム
const items = new DataSet([
{ id: 1, content: "要件定義", start: "2026-07-01", end: "2026-07-10" },
{ id: 2, content: "設計レビュー", start: "2026-07-13" },
{ id: 3, content: "実装", start: "2026-07-14", end: "2026-07-31" },
{ id: 4, content: "リリース", start: "2026-08-03", type: "point" },
]);
const options = {
width: "100%",
height: "300px",
};
const timeline = new Timeline(container, items, options);
これだけで、ドラッグ移動もズームもできるタイムラインが完成します。startだけを指定すれば単一の時点、endも指定すれば期間として描画されます。
アイテムの4つの表示タイプ
アイテムはtypeプロパティで見た目を切り替えられます。
const items = new DataSet([
// box: 吹き出し型(単一時点のデフォルト)
{ id: 1, type: "box", content: "定例会議", start: "2026-07-15" },
// point: 時間軸上の点。マイルストーン表示に最適
{ id: 2, type: "point", content: "検収日", start: "2026-07-20" },
// range: 期間をバーで表現。ガントチャート風の表示に
{ id: 3, type: "range", content: "開発期間", start: "2026-07-10", end: "2026-07-24" },
// background: 背景の帯。営業時間や休暇期間の表現に
{ id: 4, type: "background", content: "夏季休暇", start: "2026-08-10", end: "2026-08-14" },
]);
DataSetでデータを動的に操作する
DataSetは双方向データバインディングを提供します。データを操作すると、タイムラインの再描画を自分で呼ぶことなく画面に反映されます。
// アイテムを追加
items.add({ id: 5, content: "追加タスク", start: new Date() });
// アイテムを更新
items.update({ id: 1, content: "定例会議(オンライン)" });
// アイテムを削除
items.remove(2);
実践的なユースケース
チーム別のスケジュールボードを作る
グループ機能を使うと、チームやリソースごとにレーンを分けた「ガントチャート風」の表示が作れます。さらにeditableオプションを有効にすると、ユーザーがドラッグでアイテムを動かせるようになります。
import { Timeline, DataSet } from "vis-timeline/standalone";
import "vis-timeline/styles/vis-timeline-graph2d.min.css";
const container = document.getElementById("visualization");
// レーン(グループ)の定義
const groups = new DataSet([
{ id: "frontend", content: "フロントエンド" },
{ id: "backend", content: "バックエンド" },
{ id: "infra", content: "インフラ" },
]);
// 各グループに属するタスク
const items = new DataSet([
{ id: 1, group: "frontend", content: "UI実装", start: "2026-07-13", end: "2026-07-22" },
{ id: 2, group: "frontend", content: "E2Eテスト", start: "2026-07-23", end: "2026-07-28" },
{ id: 3, group: "backend", content: "API開発", start: "2026-07-10", end: "2026-07-24" },
{ id: 4, group: "infra", content: "本番環境構築", start: "2026-07-20", end: "2026-07-27" },
]);
const options = {
stack: false,
editable: {
updateTime: true, // ドラッグで日程変更
updateGroup: true, // レーン間の移動
},
// 移動時のバリデーション
onMove: (item, callback) => {
if (item.start < new Date("2026-07-01")) {
alert("7月より前には移動できません");
callback(null); // 変更をキャンセル
} else {
callback(item); // 変更を確定
}
},
};
const timeline = new Timeline(container, items, groups, options);
onMoveのようなコールバックで変更内容を検証し、callback(null)を返せば操作をキャンセルできます。保存処理を挟みたい場合もこのフックが使えます。
イベントでユーザー操作を検知する
選択や表示範囲の変更はイベントとして購読できます。詳細画面との連動や、表示範囲に応じたデータの遅延読み込みに便利です。
// アイテムが選択されたら詳細を表示
timeline.on("select", (properties) => {
const selected = items.get(properties.items[0]);
if (selected) {
console.log("選択されたタスク:", selected.content);
}
});
// 表示範囲の変更が確定したタイミングで発火
timeline.on("rangechanged", (properties) => {
console.log("表示範囲:", properties.start, "〜", properties.end);
// ここで表示範囲内のデータだけをサーバーから取得する、といった実装が可能です
});
rangechange(ドラッグ中に連続発火)とrangechanged(操作完了時に1回発火)が分かれているため、重い処理はrangechanged側に置くのがポイントです。
まとめ
vis-timelineを使えば、自作すると骨の折れるインタラクティブなタイムラインUIを、驚くほど少ないコードで実現できます。ポイントを振り返りましょう。
- ドラッグ・ズーム・編集が標準装備で、時間軸の目盛り計算もすべてお任せ
box・point・range・backgroundの4タイプで多彩な表現が可能DataSetによる双方向バインディングで、動的なデータ更新も簡単- グループ機能とイベント処理を組み合わせれば、実用的なスケジュールボードが作れる
まずはCDN版をHTMLファイルに貼り付けて、ドラッグとズームの気持ちよさを体感してみてください。「これを自作しなくてよかった」と、きっと実感できるはずです。
