2012年9月2日日曜日

【Redmine】ガントチャートpdf出力拡張 vol.1.5 進捗度の描画ずれ修正

目的
前回、ガントチャートのpdf出力表示にて、
日付毎に縦線を引いたが、
バーのゲージや、端、マイルストンの位置がずれていた。
これを修正する。


作業手順
引き続き、
apps\redmine\backup\lib\redmine\helpers\gantt.rbを解析。

各項目毎の進捗は、
line_for_xxx(xxxはワイルドカード)メソッドにて行われているのは前回で分かった。
line_for_xxxメソッドの内部を見てみる。

coordinatesメソッドで座標を求め、
pdf_taskメソッドで描画を行っているようだ。

coordinatesメソッド内の最後の方にある、
以下の処理にて、floorメソッドを使用している。
coords.keys.each do |key|
  coords[key] = (coords[key] * zoom).floor
end
coords[key]もしくは、zoomが小数で、
かつpdf出力時は小数を許容する場合、
誤差が生じることになる。


まずは、
coords[key]もしくはzoomが小数かどうか調査する。

xの値を調べる場合、
ActiveRecord::Base.logger.info x
と記述することで、ログファイル(apps\redmine\htdocs\log内)に出力される。

coords[key]及び、zoomの値を出力してみたところ、
zoomの値は小数であった。(正確にはRational。)


次に、
pdf出力時は小数を許容するのか調査する。

描画する際に、gantt.rbでは、
pdf_taskメソッド内でRDMCellメソッドを呼び出している。

RDMCellメソッドは、
pdfオブジェクトを使用しているが、
これはto_pdfメソッド内の以下の処理にて生成されている。
pdf = ::Redmine::Export::PDF::ITCPDF.new(current_language)
ITCPDFクラスは、
apps\redmine\htdocs\lib\redmine\export\pdf.rbに記述されている。
RDMCellメソッドは、ITCPDFクラスのインスタンスメソッドであり、
Cellメソッドを呼び出しているだけである。
CellメソッドはITCPDFの親クラスである
TCPDFクラスのインスタンスメソッドである。

TCPDFクラスは、
apps\redmine\htdocs\lib\plugins\rfpdf\lib\tcpdf.rbに記述されている。
Cellメソッドのコメントを見ると、
第一、第二引数ともにfloatになっている。


これらからの調査結果から、
floorメソッドの呼び出しが原因である可能性が高い。
よって、pdf出力時にはfloorメソッドを呼ばないように変更をかける。


まずは、coordinatesメソッド内の最後にある、
floorメソッド呼び出し部分を以下のように変更する。
coords.keys.each do |key|
  coords[key] = coords[key] * zoom
  coords[key] = coords[key].floor unless format == :pdf
end
次に、coordinatesメソッドの引数にformatを追加する。
def coordinates(start_date, end_date, progress, zoom=nil, format=nil)
最後に、全てのcoordinatesメソッドの呼び出しに、
options[:format]を追加する。

以上で、作業完了ある。


変更後のソースコードは以下にアップされている。
『進捗度の描画ずれ修正 』のフォルダにある。
変更前のソースコードは『日付表示を見やすく 』のフォルダにある、
変更後のソースコードを参照してもらいたい。

ソースコード




結果
修正前:


修正後:


ずれはなくなっているようだ。