コンテンツにスキップ

$p.events.on_gantt_load

概要

ガントチャートを読み込んだとき、もしくはフィルタ等で表示する内容が変わったときに実行するメソッドの指定方法を説明します。

制限事項

  1. 意図しないタイミングで処理が実行されてしまう等の影響がある場合を除き、出力先は「全て」を選択してください。
  2. 複数のスクリプトを作成し各スクリプトの内容に本関数を記述すると、スクリプトが上書きされるため、最新のもの以外は動作しません。回避策は以下FAQを参照してください。

構文

JavaScript
$p.events.on_gantt_load = function () {
    //処理内容
}

使用例

以下のサンプルコードをプリザンターのスクリプトへ設定すると、ガントチャート画面を読み込んだときに画面下部にメッセージを表示します。

JavaScript
$p.events.on_gantt_load = function () {
    $p.setMessage('#Message', JSON.stringify({
        Css: 'alert-success',
        Text: 'ガントチャートを読み込みました。'
        })
    );
}

サンプルコード

Note

コード内の【 ... 】は適宜修正してください。

1. ガントチャートに祝日・会社休日の帯を表示する

プロジェクトのタスクをガントチャートで見るとき、別テーブル「祝日カレンダー」に登録した祝日・会社休日を取得し、該当する日に土日と同じような縦の帯を描きます。帯にマウスを乗せると祝日の名称を表示します。$p.events.on_gantt_loadは、ガントチャートを開いたときに加えて、表示期間の移動や分類・並び替えの変更で描き直すたびに発火するので、そのたびに帯を描き直します。

実務での使いどころ

ガントチャートは土日に色が付きますが、祝日や会社の休日(創立記念日、夏季休業など)には色が付きません。そのため、祝日をまたぐタスクの期間が実際の稼働日より長く見積もられていても、画面からは気付きにくくなります。このサンプルを使うと、祝日・会社休日が土日と同じように帯で表示されるので、スケジュールを組むときや進み具合を確かめるときに、休みを見落とさずに済みます。

祝日カレンダーは、$p.events.on_calendar_loadのサンプル(カレンダーに祝日を表示する)と同じテーブルを使います。祝日を1か所で管理すれば、カレンダーとガントチャートの両方に反映されます。

事前準備

1:祝日カレンダーのテーブル(記録テーブル)を用意します。祝日を取り込むサンプル(items.Upsert・$p.apiUpsertに掲載)で作ったものをそのまま使えます。

項目コード 内容
日付A(DateA) 日付
分類A(ClassA) 名称(例:文化の日、創立記念日)
分類B(ClassB) 区分(「国民の祝日」または「会社休日」)。会社休日の色を分ける場合のみ使います

2:タスクのテーブル(期限付きテーブル)に、スクリプトを登録します。
 2-1:「テーブルの管理 > スクリプト」タブで「新規作成」を選択する。
 2-2:タイトル: 任意の名前(例:祝日の帯)
 2-3:スクリプト: 下記サンプルコードを貼り付け、【サイトID】を祝日カレンダーのサイトIDに置き換える
 2-4:出力先:「ガントチャート」と「一覧」にチェック

JavaScript
/**
 * ================================================================
 * サンプル  ガントチャートに祝日・会社休日の帯を表示する
 * ================================================================
 *
 * 【概要】
 *   プロジェクトのタスクをガントチャートで見るとき、別サイト「祝日カレンダー」に
 *   登録した祝日・会社休日を $p.apiGet で取得し、該当する日に土日と同じような
 *   縦の帯を描きます。帯にマウスを乗せると祝日の名称を表示します。
 *   $p.events.on_gantt_load は、ガントチャートを開いたときだけでなく、
 *   表示期間の移動や分類・並び替えの変更で描き直すたびに発火します。
 *   描き直すと帯は消えるため、発火のたびに描き直します。
 *
 * 【前提】
 *   祝日カレンダーは、カレンダーに祝日を表示するサンプル
 *   (show-holidays-on-calendar.js)と同じテーブルを使います。
 *     ・DateA : 日付
 *     ・ClassA: 名称(例:文化の日、創立記念日)
 *     ・ClassB: 区分(国民の祝日/会社休日)。会社休日の色を分ける場合だけ追加
 *   ガントチャートを見る人は、祝日カレンダーの閲覧権限が必要です。
 *
 * 【スクリプトの出力先】
 *   「ガントチャート」と「一覧」にチェックしてください。一覧画面からビューの
 *   切り替えでガントチャートにした場合、画面は読み込み直されず、一覧画面で
 *   読み込んだスクリプトのまま動くためです。
 *
 * 【帯の位置の求め方】
 *   ガントチャートは svg#Gantt に描かれ、土日は rect.saturday / rect.sunday の
 *   帯になっています。帯の幅が1日分の幅です。表示の先頭の日(隠し項目
 *   GanttMinDate)と、最初の土日の帯の位置から左端の位置を逆算し、
 *   「左端+先頭の日からの日数×1日の幅」に祝日の帯を描きます。
 *   左端の値(20 など)を直接書かないのは、表示の設定で変わる可能性があるためです。
 *   なお、隠し項目 GanttFirstDay は「次へ」などで表示期間を移動しても変わらないため、
 *   表示の先頭の日には使えません。
 *
 * コード内の【 ... 】は適宜修正してください。
 * ================================================================
 */

// ===== 設定 =====
// 祝日カレンダーのサイトID
const HOLIDAY_SITE_ID = 【サイトID】;
// 祝日カレンダーの項目
const HOLIDAY_DATE_COLUMN = 'DateA'; // 日付
const HOLIDAY_NAME_COLUMN = 'ClassA'; // 名称
const HOLIDAY_KIND_COLUMN = 'ClassB'; // 区分(使わない場合は '' にする)
// 区分がこの値のときは会社休日の色にする
const COMPANY_HOLIDAY_KIND = '会社休日';
// 帯の色
const HOLIDAY_COLOR = '#ffe4e4'; // 国民の祝日
const COMPANY_HOLIDAY_COLOR = '#e4ecff'; // 会社休日

const DAY_MS = 24 * 60 * 60 * 1000;

// ===== 処理 =====
// 「2026/11/03」の形の文字列を、その日の0時の Date にする
function parseDate(text) {
    const [y, m, d] = String(text).slice(0, 10).split('/').map(Number);
    return new Date(y, m - 1, d);
}

// Date を「2026/11/03」の形にする
function formatDate(date) {
    const pad = (n) => String(n).padStart(2, '0');
    return `${date.getFullYear()}/${pad(date.getMonth() + 1)}/${pad(date.getDate())}`;
}

// 2つの日付の間の日数(time の差を日数にし、夏時間などの端数は丸める)
function daysBetween(from, to) {
    return Math.round((to - from) / DAY_MS);
}

// 土日の帯から、帯を描くための寸法(左端・1日の幅・y・高さ)と表示期間を求める
function getLayout() {
    // 表示の先頭の日。期間を移動すると GanttMinDate が変わる(GanttFirstDay は変わらない)
    const firstDayText = $('#GanttMinDate').val();
    const weekend = $('#Gantt rect.saturday, #Gantt rect.sunday').first();
    if (!firstDayText || weekend.length === 0) {
        // 表示期間が短く土日が入らない場合は、帯の寸法が分からないので描かない
        return null;
    }
    const firstDay = parseDate(firstDayText);
    const dayWidth = Number(weekend.attr('width'));
    // 最初の土日の帯が、先頭の日から何日目かを曜日から求めて、左端を逆算する
    const weekendDay = weekend.hasClass('saturday') ? 6 : 0;
    const offset = (weekendDay - firstDay.getDay() + 7) % 7;
    const left = Number(weekend.attr('x')) - offset * dayWidth;
    // 表示されている日数は、svg の幅から求める
    const svgWidth = Number($('#Gantt').attr('width')) || $('#Gantt')[0].getBoundingClientRect().width;
    const days = Math.max(1, Math.ceil((svgWidth - left) / dayWidth));
    const lastDay = new Date(firstDay.getTime() + (days - 1) * DAY_MS);
    return {
        firstDay: firstDay,
        lastDay: lastDay,
        left: left,
        dayWidth: dayWidth,
        y: weekend.attr('y'),
        height: weekend.attr('height'),
        // 帯は最後の土日の帯の直後に入れる(タスクの棒より奥に描くため)
        $insertAfter: $('#Gantt rect.saturday, #Gantt rect.sunday').last(),
    };
}

// 祝日1件分の帯を描く
function drawHoliday(layout, holiday) {
    const date = parseDate(holiday[HOLIDAY_DATE_COLUMN]);
    const index = daysBetween(layout.firstDay, date);
    if (index < 0 || date > layout.lastDay) {
        return;
    }
    const isCompanyHoliday =
        HOLIDAY_KIND_COLUMN !== '' && holiday[HOLIDAY_KIND_COLUMN] === COMPANY_HOLIDAY_KIND;

    const ns = 'http://www.w3.org/2000/svg';
    const rect = document.createElementNS(ns, 'rect');
    rect.setAttribute('class', 'holiday');
    rect.setAttribute('x', layout.left + index * layout.dayWidth);
    rect.setAttribute('y', layout.y);
    rect.setAttribute('width', layout.dayWidth);
    rect.setAttribute('height', layout.height);
    rect.setAttribute('fill', isCompanyHoliday ? COMPANY_HOLIDAY_COLOR : HOLIDAY_COLOR);
    // SVG のツールチップは、子要素の title で出す
    const title = document.createElementNS(ns, 'title');
    title.textContent = holiday[HOLIDAY_NAME_COLUMN] || '';
    rect.appendChild(title);
    layout.$insertAfter.after(rect);
}

// ガントチャートを開いたとき、表示期間の移動や設定の変更で描き直すたびに呼ばれる
$p.events.on_gantt_load = function () {
    const layout = getLayout();
    if (!layout) {
        return;
    }

    // 取得する項目(区分を使わない場合は除く)
    const columns = [HOLIDAY_DATE_COLUMN, HOLIDAY_NAME_COLUMN];
    if (HOLIDAY_KIND_COLUMN !== '') {
        columns.push(HOLIDAY_KIND_COLUMN);
    }

    $p.apiGet({
        id: HOLIDAY_SITE_ID,
        data: {
            View: {
                // 項目名をキーにした形式で受け取る(DateA は「2026/11/03」の文字列になる)。
                // この2つは View の中に書く(View の外に書くと既定の形式で返る)
                ApiDataType: 'KeyValues',
                ApiColumnKeyDisplayType: 'ColumnName',
                GridColumns: columns,
                // 日付の範囲は配列形式の文字列で、開始と終了をカンマで区切る
                ColumnFilterHash: {
                    [HOLIDAY_DATE_COLUMN]: JSON.stringify([
                        `${formatDate(layout.firstDay)},${formatDate(layout.lastDay)}`,
                    ]),
                },
            },
        },
        done: function (data) {
            try {
                (data.Response.Data || []).forEach(function (holiday) {
                    drawHoliday(layout, holiday);
                });
            } catch (e) {
                // 帯の描画に失敗してもガントチャート自体は止めない
                console.log(`祝日の表示に失敗しました: ${e}`);
            }
        },
        fail: function (data) {
            // 取得に失敗してもガントチャートの表示は止めず、コンソールに記録するだけにする
            console.log('祝日カレンダーの取得に失敗しました', data);
        },
    });
};

注意点

  • スクリプトの出力先は「ガントチャート」と「一覧」の両方にしてください。一覧画面からビューの切り替えでガントチャートにした場合、画面は読み込み直されず、一覧画面で読み込んだスクリプトのまま動きます。
  • 帯の位置は、表示の先頭の日(隠し項目GanttMinDate)と土日の帯の位置・幅から求めています。隠し項目GanttFirstDayは「次へ」などで表示期間を移動しても変わらないため、表示の先頭の日には使えません。
  • 帯は土日の帯の直後に追加するので、タスクの棒より奥に表示されます。
  • 表示期間に土日が1日も含まれない場合は、帯の幅が分からないため描きません。
  • ガントチャートを見る人には、祝日カレンダーの閲覧権限が必要です。取得に失敗してもガントチャートの表示は止めず、ブラウザの開発者ツールのコンソールに記録します。