SpreadJSのガントシートでタスクバースタイルをカスタマイズする

JavaScriptスプレッドシートライブラリ「SpreadJS(スプレッドJS)」ではプロジェクト管理や生産管理などで使用される工程管理表(ガントチャート)をExcelライクなUIで作成できる「ガントシート」機能が利用可能です。

ガントシートでタスクバースタイルをカスタマイズ

今回はこのガントシートのタスクバーの外観をカスタマイズする方法を解説します。

開発環境

今回は開発環境として以下を使用します。

事前準備

以下の4つのファイルを用意してWebページにガントシートを組み込みます。

index.htmlページ本体。このページの要素としてガントシートを組み込みます
app.jsガントシートの初期化など各種設定を行うためのコードを記載します
data.jsガントシートに表示するタスクのデータの定義を記載します
styles.cssガントシートや各種要素のスタイル設定を行うためのコードを記載します

ガントシートの使用にはSpreadJSのモジュールを環境に配置する必要があります。npmなどから入手する方法もありますが、今回は環境に直接SpreadJSのモジュールを配置していきます。あらかじめSpreadJSの製品版かトライアル版をご用意ください。トライアル版は以下より無償で入手可能です。

製品版、またはトライアル版をダウンロードしたら、ZIPファイルを解凍し、以下のファイルを環境にコピーします。CSSファイルは7種類あるのでお好みのテーマのものを選択してください。

  • scripts/gc.spread.sheets.all.17.1.10.min.js
  • scripts/plugins/gc.spread.sheets.tablesheet.17.1.10.min.js
  • scripts/plugins/gc.spread.sheets.ganttsheet.17.1.10.min.js
  • scripts/resources/ja/gc.spread.sheets.resources.ja.17.1.10.min.js
  • css/gc.spread.sheets.excel2013white.17.1.10.css

ガントシートの作成

ガントシートの基本的な作成方法については、以下の記事もご一読いただければと思います。

最初に、SpreadJSライブラリの参照設定をHTMLファイルに追加します。SpreadJSのモジュールに加えて、上記の「app.js」、「data.js」、「styles.css」への参照も追加します。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />

    <!-- ローカルのライブラリを参照する場合 -->
    <link href="css/gc.spread.sheets.excel2013white.17.1.10.css" rel="stylesheet"/>
    <script src="scripts/gc.spread.sheets.all.17.1.10.min.js"></script>
    <script src="scripts/gc.spread.sheets.tablesheet.17.1.10.min.js"></script>
    <script src="scripts/gc.spread.sheets.ganttsheet.17.1.10.min.js"></script>
    <script src="scripts/gc.spread.sheets.resources.ja.17.1.10.min.js"></script>

    <link href="css/styles.css" rel="stylesheet"/>
    <script src="scripts/data.js"></script>
    <script src="scripts/app.js"></script>
</head>
<body>
    <div class="settings">
        <label for="styleRule">ルール:</label>
        <select id="styleRule" onchange="ruleChange();">
            <optgroup label="Summary"></optgroup>
            <option value="projectSummary">projectSummary</option>
            <option value="summary">summary</option>
            <option value="manualSummary">manualSummary</option>
            <optgroup label="Task"></optgroup>
            <option value="task">task</option>
            <option value="progress">progress</option>
            <option value="manualTask">manualTask</option>
            <option value="startOnly">startOnly</option>
            <option value="durationOnly">durationOnly</option>
            <option value="finishOnly">finishOnly</option>
            <option value="manualProgress">manualProgress</option>
            <optgroup label="Milestone"></optgroup>
            <option value="milestone">milestone</option>
            <option value="manualMilestone">manualMilestone</option>
            <option value="startOnlyMilestone">startOnlyMilestone</option>
            <option value="durationOnlyMilestone">durationOnlyMilestone</option>
            <option value="finishOnlyMilestone">finishOnlyMilestone</option>
        </select>
        <label for="styleColor">色:</label>
        <select id="styleColor" onchange="colorChange();">
            <option value="magenta">magenta</option>
            <option value="royalblue">royalblue</option>
            <option value="gold">gold</option>
        </select>
        <input type="button" value="設定内容の反映" onclick="setColor();">
    </div>
    <div id="ss"></div>
</body>
</html>

ガントシートの初期化

続いて「app.js」と「data.js」および「styles.css」を次のように作成します。

※ ライセンスキーを設定しない場合、トライアル版を示すメッセージが表示されます。ライセンスキーの設定方法についてはこちらをご覧ください。

GC.Spread.Sheets.LicenseKey = 'ここにSpreadJSのライセンスキーを設定します';
GC.Spread.Common.CultureManager.culture('ja-jp');

var spread;
var ganttTable;
var ganttSheet;

window.onload = function () {
  spread = new GC.Spread.Sheets.Workbook("ss", { sheetCount: 0 });
  spread.options.scrollbarMaxAlign = true;
  initSpread(spread);
};

function initSpread(spread) {
  spread.suspendPaint();
  initGanttSheet(spread);
  spread.resumePaint();
}

function initGanttSheet(spread) {
  // データマネージャーの初期化
  const dataManager = spread.dataManager();
  ganttTable = dataManager.addTable('ganttTable', {
    data: getData(),
    batch: true,
    schema: {
      hierarchy: {
        type: 'Parent',
        column: 'parentId',
      },
      columns: {
        taskNumber: { isPrimaryKey: true, dataType: 'rowOrder' },
      },
    },
  });

  // ガントシートの生成と設定
  ganttSheet = spread.addSheetTab(
    0,
    'projectSummary',
    GC.Spread.Sheets.SheetType.ganttSheet
  );
  ganttSheet.project.startDate = new Date('2025/03/03');
  ganttSheet.project.timescale.minDate = new Date('2025/03/01');
  ganttSheet.project.timescale.maxDate = new Date('2025/03/22');

  // 組み込みのタスクスタイルルールの確認
  console.log(ganttSheet.project.taskStyleRules.inner);

  // ビューの生成と設定
  var view = ganttTable.addView('ganttView', [
    { value: 'taskNumber', width: 125 },
    { value: 'name', width: 170 },
    { value: 'duration', width: 75 },
    { value: 'predecessors', width: 105 },
    { value: 'mode', width: 60 },
    { value: 'start', width: 105 },
    { value: 'finish', width: 105 },
    { value: 'complete', width: 85 },
    { value: 'isMilestone', width: 95 }
  ]);
  view.fetch().then(()=> {
    ganttSheet.bindGanttView(view);
  }).then(()=>{
    // タスクバー(taskNumber=11)のスタイル変更
    ・・・ 中略 ・・・
  });

  // 先頭行の選択
  setTimeout(() => { ruleChange(); }, 0);
}

function setColor(){
  ・・・ 中略 ・・・
}

// 選択された項目に対応する行へ移動
function ruleChange() {
  ・・・ 中略 ・・・
}

// select要素の背景色と文字色の切替
function colorChange(){
  ・・・ 中略 ・・・
}
function getData() {
  return [
    {
      "taskNumber": 1,
      "name": "summary",
      "parentId": null,
      "predecessors": null,
      "mode": null,
      "duration": null,
      "start": null,
      "finish": null,
      "complete": null,
      "isMilestone": null
     },
     {
      "taskNumber": 2,
      "name": "progress",
      "parentId": 1,
      "predecessors": null,
      "mode": null,
      "duration": "2 days",
      "start": null,
      "finish": null,
      "complete": 1,
      "isMilestone": null
     },
     {
      "taskNumber": 3,
      "name": "milestone",
      "parentId": 1,
      "predecessors": "2",
      "mode": null,
      "duration": null,
      "start": null,
      "finish": null,
      "complete": null,
      "isMilestone": "true"
     },
     {
      "taskNumber": 4,
      "name": "manualProgress",
      "parentId": 1,
      "predecessors": "3",
      "mode": "Manual",
      "duration": null,
      "start": new Date('2025/03/06 08:00'),
      "finish": new Date('2025/03/07 08:00'),
      "complete": 1,
      "isMilestone": null
     },
     {
      "taskNumber": 5,
      "name": "manualMilestone",
      "parentId": 1,
      "predecessors": "4",
      "mode": "Manual",
      "duration": null,
      "start": new Date('2025/03/10 08:00'),
      "finish": new Date('2025/03/10 08:00'),
      "complete": null,
      "isMilestone": "true"
     },
     {
      "taskNumber": 6,
      "name": "startOnly",
      "parentId": 1,
      "predecessors": "5",
      "mode": "Manual",
      "duration": null,
      "start": new Date('2025/03/11 08:00'),
      "finish": null,
      "complete": null,
      "isMilestone": null
     },
     {
      "taskNumber": 7,
      "name": "durationOnly",
      "parentId": 1,
      "predecessors": "6",
      "mode": "Manual",
      "duration": "2 day",
      "start": null,
      "finish": null,
      "complete": null,
      "isMilestone": null
     },
     {
      "taskNumber": 8,
      "name": "finishOnly",
      "parentId": 1,
      "predecessors": "7",
      "mode": "Manual",
      "duration": null,
      "start": null,
      "finish": new Date('2025/03/14 8:00'),
      "complete": null,
      "isMilestone": null
     },
     {
      "taskNumber": 9,
      "name": "startOnlyMilestone",
      "parentId": null,
      "predecessors": null,
      "mode": "Manual",
      "duration": null,
      "start": new Date('2025/03/5 08:00'),
      "finish": null,
      "complete": null,
      "isMilestone": "true"
     },
     {
      "taskNumber": 10,
      "name": "manualSummary",
      "parentId": null,
      "predecessors": "9",
      "mode": "Manual",
      "duration": null,
      "start": new Date('2025/03/5 08:00'),
      "finish": new Date('2025/03/18 08:00'),
      "complete": null,
      "isMilestone": null
     },
     {
      "taskNumber": 11,
      "name": "task",
      "parentId": 10,
      "predecessors": null,
      "mode": null,
      "duration": "2 day",
      "start": null,
      "finish": null,
      "complete": null,
      "isMilestone": null
     },
     {
      "taskNumber": 12,
      "name": "durationOnlyMilestone",
      "parentId": 10,
      "predecessors": "11",
      "mode": "Manual",
      "duration": "1 day",
      "start": null,
      "finish": null,
      "complete": null,
      "isMilestone": "true"
     },
     {
      "taskNumber": 13,
      "name": "manualTask",
      "parentId": 10,
      "predecessors": "12",
      "mode": "Manual",
      "duration": null,
      "start": new Date('2025/03/11 08:00'),
      "finish": new Date('2025/03/14 08:00'),
      "complete": null,
      "isMilestone": null
     },
     {
      "taskNumber": 14,
      "name": "finishOnlyMilestone",
      "parentId": 10,
      "predecessors": 13,
      "mode": "Manual",
      "duration": null,
      "start": null,
      "finish": new Date('2025/03/18 08:00'),
      "complete": null,
      "isMilestone": "true"
     },
  ];
}
/* SpreadJSのスタイル */
#ss {
   width: 1530px;
   height: 600px;
}

/* SpreadJS以外のスタイル */
.settings{
   margin-top: 20px;
   margin-bottom: 20px;
}
input {
   margin-left: 20px;
}
label {
   margin-left: 20px;
}
optgroup {
   background-color: #D3A96D;
}
#styleColor {
   background-color: magenta;
   color: white;
}
select option {
   background-color: white;
   color: black;
}

組み込みスタイルルール

ガントシートで表示できるタスクの種類に応じて、次の組み込みスタイルルールが用意されています。

タスクの種類スタイルルール
サマリーprojectSummary
summary
manualSummary
タスクtask
progress
manualTask
startOnly
durationOnly
finishOnly
manualProgress
マイルストーンmilestone
manualMilestone
startOnlyMilestone
durationOnlyMilestone
finishOnlyMilestone

これらのスタイルルールは、ガントシートに連結されたデータの内容に従ってデータマネージャーが自動的に設定します。

データの内容とタスクバーのスタイルルールの関係は、下記のヘルプやデモおよびSpreadJSデザイナで確認することができます。

SpreadJSデザイナでは、「挿入」タブ-「シート」グループ-「ガントシート」で表示される「書式設定」タブで「バーのスタイル」グループ-「書式」-「バーのスタイル」を選択すると、下記の「バーのスタイル」ダイアログが表示されるので、それを操作することでスタイルルールと既定のスタイルを確認/変更できます。

SpreadJSデザイナでスタイルルールの設定

なお、今回作成するアプリケーションでは、スタイルルールとそれに対応するデータとタスクバースタイルを確認できるようになっています。

タスクバースタイルのカスタマイズ

各種タスクバーのスタイルを変更する方法について、下記のヘルプとデモで詳しく解説していますので、ご一読いただければと思います。

上記のドキュメントに記載しているように、タスクバーのスタイルを変更する方法として次の3つが用意されています。

  1. スタイルルールのタスクバースタイルを変更する方法
  2. スタイルルールの新規インスタンスを特定のタスクに設定する方法
  3. 組み込みのスタイルルールを継承したスタイルルールを作成する方法

ここでは1.と2.について紹介します。3.については割愛するので、上記のドキュメントをご参照いただければと思います。

スタイルルールのタスクバースタイルを変更する

Sheets.GanttSheet.ProjectクラスのtaskStyleRulesプロパティで参照できるコレクションのgetRuleメソッドを使って特定の組み込みスタイルルールを取得できます。そして、取得したSheets.GanttSheet.TaskbarStyleRuleのstyle.taskbarStyleを設定することで指定したスタイルルールのスタイルを変更します。

タスクバーのスタイルは、次の部分から構成されています。各部分ごとに形状や種類/パターンおよび色を変更することが可能です。

始点中部終点
形状形状形状
種類パターン種類

変更可能なスタイルについては、APIリファレンスのTaskbarStyleと前述のSpreadJSデザイナで確認できます

最初に提示した「app.js」ファイルのコードで省略していたsetColor関数は次のようになっています。この関数は、指定された名称(rule)に対応したスタイルルール(taskRule)を取得し、そのtaskbarStyleのstartColor、middleColor、およびendColorを変更します。

・・・(中略)・・・
function setColor(){
  ganttSheet.suspendPaint();

  // 指定したタスクルールの色を変更
  const rule = document.querySelector('#styleRule').value;
  const color = document.querySelector('#styleColor').value;
  const taskRule = ganttSheet.project.taskStyleRules.getRule(rule);
  const taskStyle = taskRule.style.taskbarStyle;
  taskStyle.startColor = color;
  taskStyle.middleColor = color;
  taskStyle.endColor = color;
  taskRule.style.taskbarStyle = taskStyle;

  // タスクバー(taskNumber=11)の色を再変更
  if(rule == "task"){
    const task = ganttSheet.project.getTask(11);
    const styles = task.style;
    if(styles != undefined){
      styles["task"].taskbarStyle.startColor = color;
      styles["task"].taskbarStyle.middleColor = color;
      styles["task"].taskbarStyle.endColor = color;
      task.style = styles;
    }
  }

  ganttSheet.resumePaint();
}
・・・(中略)・・・

また、上記の関数では、次の項目で解説する方法でタスクバーのスタイルを変更した「taskNumber=11」のタスクバーの色を変更するコードも記述しています。

この関数を実行して「manualTask」ルールのタスクバーのスタイルを変更したときの画像を以下に示します。この例では「taskNumber=4」(manualTask+manualProgress)と「taskNumber=13」(manualTask)のタスクバーの色が変更されています。

スタイルルールのタスクバースタイルを変更

スタイルルールの新規インスタンスを特定のタスクに設定する

ガントシート上の特定の行にあるタスクのスタイルを変更する方法についてこちらのデモで解説しています。以下では、その手法を使って「taskNumber=11」のタスクバーのスタイルを変更する例をご紹介します。

Sheets.GanttSheet.ProjectクラスのgetTaskメソッドで対象となるタスク(Task)のstyleプロパティに新たに生成したタスクルールのオブジェクトを設定します。このオブジェクトのtaskbarStyleプロパティに任意のスタイルを設定することで、指定したタスクのタスクバースタイルを変更します。

function initGanttSheet(spread) {
  ・・・ 中略 ・・・
  // ビューの生成と設定
  ・・・ 中略 ・・・
  view.fetch().then(()=> {
    ganttSheet.bindGanttView(view);
  }).then(()=>{
    // タスクバー(taskNumber=11)のスタイル変更
    const task = ganttSheet.project.getTask(11);
    const taskBarStyles = {};
    taskBarStyles["task"] = {
      taskbarStyle: {
        startShape: "lineShape",
        startType: "solid",
        startColor: "blue",
        middlePattern: "diagonalLeft",
        middleShape: "rectangleBar",
        middleColor: "red",
        endShape: "lineShape",
        endType: "solid",
        endColor: "blue",
      }
    }
    task.style = taskBarStyles;
  });
  ・・・ 中略 ・・・
}

下の図のように、初期表示の「taskNumber=11」のタスクバーが既定のスタイルから変更されています。

スタイルルールのタスクバースタイルを変更

作成したサンプルをStackBlitzで公開しているので、こちらもご覧ください。

なお、今回ご紹介したガントシートの機能はほんの一部です。ガントシートの詳細な機能については製品ヘルプやデモもご確認ください。

さいごに

今回の記事では、「SpreadJS」のガントシートで作成したガントチャート上のタスクバーのスタイルをカスタマイズする方法について解説しました。

製品サイトでは、SpreadJSの機能を手軽に体験できるデモアプリケーションやトライアル版も公開しておりますので、こちらもご確認ください。

また、ご導入前の製品に関するご相談、ご導入後の各種サービスに関するご質問など、お気軽にお問合せください。

\  この記事をシェアする  /