JSだけで ガントチャートを 担当者ごとに表示する方法

2020.09.17
REDMINE JAPAN前夜祭 LT
発表者：山崎進（株式会社アンコウソフト）

LT発表のきっかけ
イベント二日前の朝に来た一通のメールを受信したのが今回の発表のきっかけです。
ーー＞突貫でLTのテーマとJSの実装を決定（3時間ぐらいでJSの開発と動作検証行いました。）

弊社では、Redmineのガントチャートを強化した「ANKOガントチャート」という製品を販売しています。

http://www.ankosoft.co.jp/anko_gantt_chart/弊社では、Redmineのガントチャートを強化した「ANKOガントチャート」という製品を販売しています。

http://www.ankosoft.co.jp/anko_gantt_chart/弊社では、Redmineのガントチャートを強化した「ANKOガントチャート」という製品を販売しています。

http://www.ankosoft.co.jp/anko_gantt_chart/弊社では、Redmineのガントチャートを強化した「ANKOガントチャート」という製品を販売しています。

http://www.ankosoft.co.jp/anko_gantt_chart/Redmineのガントチャートでは、右側の図のように、「担当者ごとのガントチャートを表示する」機能は提供されていません。

本来であればRails側の開発が必要ですが、JSだけでも、それなりのもどきが作れました。
あくまでもどきです。 。 。

動作の原理と作り方
１．各担当者のクエリを作ってガントチャートを表示させる
２．該当のページを呼び出すことができるURLを確認をする
３．ajaxを使って２のページを読み込み、ガントチャートに追加をする
４．マウスクリックイベントで担当者別のガントチャートを「展開/閉じる」
を行う

動作の原理と作り方
１．各担当者のクエリを作ってガントチャートを表示させる
２．該当のページを呼び出すことができるURLを確認をする
３．ajaxを使って２のページを読み込み、ガントチャートに追加をする
４．マウスクリックイベントで担当者別のガントチャートを「展開/閉じる」
を行うhttp://localhost/redmine/projects/ankosoft/issues/gantt

http://localhost/redmine/projects/ankosoft/issues/gantt?query_id=1

動作の原理と作り方
１．各担当者のクエリを作ってガントチャートを表示させる
２．該当のページを呼び出すことができるURLを確認をする
３．ajaxを使って２のページを読み込み、ガントチャートに追加をする
４．マウスクリックイベントで担当者別のガントチャートを「展開/閉じる」を行う

該当のページを開く部分のソース（一番肝になる部分）$.ajax({url: location.href + "?query_id=" + queryId,type: "get"})http://localhost/redmine/projects/ankosoft/issues/gantt?query_id=1
開きたいURLを3つの部分に分けて、変数として表現↑↑↑たったこれだけで非同期で該当urlのページ情報を取得できます。

正しく取得できるかの動作確認

取得したページを任意に編集$.ajax({url: location.href + "?query_id=" + query_id,
type: "get",contenttype: "application/json; charset=utf-8"}).done(function (data) {$(data).appendTo("#queryId" + query_id);$queryIdElem = $("#queryId" + query_id);$queryIdElem.find(".contextual").remove();$queryIdElem.find("#query_form").remove();$queryIdElem.find(".pagination").remove();$queryIdElem.find(".other-formats").remove();$queryIdElem.find("h2").append("<span class='open-gantt'>を展開</span>").append("<span > / </span>").append("<span class='all-open-gantt'>全てを展開</span>");$queryIdElem.find("#gantt-export").hide();});<---ajaxで読み取ったページを現在のページに追加<---不必要な要素を「がりがり」と削除<---必要な要素を追加<--非表示処理

var queryIds = '1,2,3,4';
queryIds.split(',').forEach( function( value ) {eachQueryGantt(value);})<---複数のクエリIDに対応するため、カンマ区切りの変数に代入

function eachQueryGantt(queryId) {$("<div/>", { id: "queryId" + queryId }).appendTo("#gantt-export");<---一連の処理を関数化<---各クエリIDを引数にして、ガントチャート表示関数を呼び出し$.ajax({url: location.href + "?query_id=" + queryId,type: "get"}).done(function (data) {$(data).appendTo("#queryId" + queryId);$queryIdElem = $("#queryId" + queryId);$queryIdElem.find("link").remove();$queryIdElem.find("script").remove();$queryIdElem.find(".contextual").remove();$queryIdElem.find("#query_form").remove();$queryIdElem.find(".pagination").remove();$queryIdElem.find(".other-formats").remove();$queryIdElem.find("h2").append("<span class='open-gantt'>を展開</span>").append("<span > / </span>").append("<span class='all-open-gantt'>全てを展開</span>");$queryIdElem.find("#gantt-export").hide();});

使いやすくするために抽象化、関数化}

動作の原理と作り方
１．各担当者のクエリを作ってガントチャートを表示させる
２．該当のページを呼び出すことができるURLを確認をする
３．ajaxを使って２のページを読み込み、ガントチャートに追加をする
４．マウスクリックイベントで担当者別のガントチャートを「展開/閉じる」を行う

基本画面

折りたたんだ状態で表示

展開が可能//閉じるをクリックすると展開になる<---マウスのイベントを登録する$(document).on("click", ".close-gantt", function () {基本は閉じた状態で表示$(this).text("を展開").removeClass("close-gantt").addClass("open-gantt");
マウスクリックで個別ガントチャートを表示$(this).parent().next().hide();クラス名を付与することにより、現在の状態を認識});//展開をクリックすると閉じるになる$(document).on("click", ".open-gantt", function () {$(this).text("を閉じる").removeClass("open-gantt").addClass("close-gantt");$(this).parent().next().show();});//全て閉じるをクリックすると全て展開になる$(document).on("click", ".all-close-gantt", function () {$(".all-close-gantt").each(function (i, elem) {$(elem).text("全てを展開").removeClass("all-close-gantt").addClass("all-open-gantt");$(elem).parent().next().hide();});$(".close-gantt").each(function (i, elem) {$(elem).text("を展開").removeClass("close-gantt").addClass("open-gantt");$(elem).parent().next().hide();});});//全て展開をクリックすると全て閉じるになる$(document).on("click", ".all-open-gantt", function () {$(".all-open-gantt").each(function (i, elem) {$(elem).text("全てを閉じる").removeClass("all-open-gantt").addClass("all-close-gantt");$(elem).parent().next().show();});$(".open-gantt").each(function (i, elem) {$(elem).text("を閉じる").removeClass("open-gantt").addClass("close-gantt");$(elem).parent().next().show();});});

作ったJSコードをRedmineに適用する方法

明日のB07（13:30〜13:55）で紹介される「View customizeplugin」を使う方法など、色々あり得ます。
第17回redmine.tokyo勉強会 LT07
「The world of Redmine as seen from JavaScript 」にもJSをRedmineに適用する方法が紹介されています。

メリット• JSだけで担当者別のスケジュールを簡単に把握可能（Redmine本体を修正する必要がない）

デメリット• 事前にユーザーごとのクエリを作成する必要がある• ユーザーが多くなるとそれだけ通信の回数が増え、サーバーに負荷がかかるご清聴ありがとうございました

株式会社Ankosoft〒111-0041 東京都台東区元浅草2-6-4上野コアビル3F
http://www.ankosoft.co.jp
info@ankosoft.co.jp
山崎進