一日のチャート
Railsのアップデートをしたので、カテゴリを変更しておこう。
さて相変わらずのRadRailsの魔改造ネタなんだけど「日付単位ではなくて時間単位で表示させたい」という欲望に駆られたので試してみた。
すんげー苦労したさ。時間のプロットが。
コントローラ
#1日のサポートのガントチャートを作ってみる def daygantt @day_gantt = find_search #requestがゲットなら、パラメータをセットする。 if request.get? if params[:page].nil? @day_gantt.empty_daygantt! @day_gantt.select_day = Date.parse(params[:select_day]) unless params[:select_day].nil? end else @day_gantt.set_daygantt_params(params) end params[:page] = 1 if params[:page].nil? @year_from = @day_gantt.select_day.to_date.year @month_from = @day_gantt.select_day.to_date.month @day_from = @day_gantt.select_day.to_date.day @page_title = @year_from.to_s + "年" + @month_from.to_s + "月" + @day_from.to_s + "日のチャート" #時間範囲を指定、8:00から22:00まで @time_from = Time.mktime(@year_from,@month_from,@day_from,8,0) @time_to = Time.mktime(@year_from,@month_from,@day_from,22,0) @events = [] @events += Request.find(:all, :conditions =>["started >= ? AND responded <= ?", @time_from, @time_to], :order=>'requested DESC' ) @events.sort! {|x,y| x.responded <=> y.responded} end private def find_search session[:patrol_cond] ||= PatrolCond.new end
Zoomは面倒だったので止めた。簡単に追加できると思うけど。
テーブルには「start」が始まり、「responded」が終わりといった感じです。
モデル
class PatrolCond < Cond #daygantt attr_accessor :select_day #daygantt用 def empty_daygantt! @select_day = Date.today end #daygantt用 def set_daygantt_params(params) @select_day = params[:day_gantt][:select_day] end
初期化と検索後にテキストボックスにパラメータを残す為のおまじない。
ビュー
最初は年月日なセレクトボックスを作ってみたけど、操作性が悪かったのでcalendar date selectを使うことにした。
<%- content_for :html_header do -%> <%= stylesheet_link_tag 'patrol_calendar' %> <%= calendar_date_select_includes %> <script type="text/javascript"> _translations = { "OK": "OK", "Now": "現在", "Today": "今日" } Date.weekdays = $w("日 月 火 水 木 金 土"); Date.months = $w("1 2 3 4 5 6 7 8 9 10 11 12" ); </script> <%- end -%> <% subject_width = 200 header_heigth = 18 headers_height = header_heigth*3 time_to_from = (@time_to - @time_from)/36 chk_hour = @time_to.hour - @time_from.hour + 1 chk_min = ((@time_to - @time_from)/600).to_i g_width = time_to_from/10 * chk_hour + chk_min g_height = [(20 * @events.length + 6)+50, 206].max t_height = g_height + headers_height %> <h2><%= @page_title %></h2> <% form_tag do %> <table width="100%"> <tr> <td align="left"> <%= calendar_date_select(:day_gantt, :select_day) %> <%= submit_tag "変更", :class => "button-small" %> </td> <td><%= @time_from.to_s(:jp_date) %></td> </tr> </table> <% end %> <table width="100%" style="border:1; border-collapse: collapse;"> <tr> <td style="width:<%= subject_width %>px;"> <div style="position:relative; height:<%= t_height + 24 %>px;width:<%= subject_width + 1 %>px;"> <div style="right:-2px;width:<%= subject_width %>px; height:<%= headers_height %>px;background: #eee;" class="gantt_hdr"></div> <div style="right:-2px;width:<%= subject_width %>px; height:<%= t_height %>px;border-left: 1px solid #c0c0c0;overflow:hidden;" class="gantt_hdr"></div> <% # # Tasks subjects # top = headers_height + 8 @events.each do |i| %> <div style="position: absolute;line-height:1.2em; height:16px;top:<%= top %>px;left:4px;overflow:hidden;"><small> <%= link_to h(truncate(i.member_name, 20)), :controller => 'support/response', :action=>'new', :id=>i.sup_request_id %> </small></div> <% top = top + 20 end %> </div> </td> <td> <div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;"> <div style="width:<%= g_width-1 %>px;height:<%= headers_height %>px; background: #eee;" class="gantt_hdr"> </div> <% # # Months headers # left = 0 height = header_heigth width = time_to_from - 1 %> <div style="left:<%= left %>px;width:<%= g_width %>px;height:<%= height %>px;" class="gantt_hdr"> <%= @time_from.to_s(:jp_simple) %> から <%= @time_to.to_s(:jp_simple) %>まで</div> <% left = left + width + 1 %> <% # # Weeks headers && houres # left = 5 height = header_heigth-1 count_time = @time_from width = time_to_from/10 while count_time <= @time_to %> <div style="left:<%= left %>px;top:19px;width:<%= width %>px; height:<%= height %>px;" class="gantt_hdr"> <%= count_time.hour %></div> <% count_time += 60.minutes left=left+width+6 end %> <% # # Times header && minitues # left = 0 height = g_height + header_heigth - 1 count_time = @time_from width = time_to_from/60 while count_time <= @time_to %> <div style="left:<%= left %>px;top:37px;width:<%= width %>px; height:<%= height %>px;font-size:0.7em;<%= "background:#f1f1f1;" if count_time.min == 0 %>" class="gantt_hdr"> <%= count_time.min %> </div> <% count_time += 10.minutes left = left + width + 1 end %> <% # # Tasks # top = headers_height + 10 @events.each do |i| i_start_time = (i.started >= @time_from ? i.started : @time_from) i_end_time = (i.responded <= @time_to ? i.responded : @time_to) chk_min = ((i_start_time - @time_from)/600).to_i i_left = (i_start_time - @time_from)*time_to_from/36000 + chk_min i_width = (i_end_time - i_start_time)*time_to_from/36000 %> <div style="top:<%= top %>px;left:<%= i_left %>px;width:<%= i_width %>px;" class="task task_todo"> </div> <% # === tooltip === %> <div class="tooltip" style="position: absolute;top:<%= top %>px;left:<%= i_left %>px;width:<%= i_width %>px;height:12px;"> <span class="tip"> <%= i.staff_name %><br /> <%= h(i.member_name) %> : <%= i.status %><br /> <%= i.started.to_s(:jp_noyear) %><br /> <%= i.responded.to_s(:jp_noyear) %><br /> <%= h(truncate(i.content, 256)) %> </span></div> <% top = top + 20 end %> </div> </td> </tr> </table>
- 時間軸は決めウチなんですが、Zoomパラメータと絡めるとできるはず
- 時間軸を縮小すると短い期間のtooltipが表示できなくなる
- tooltipはIE6では表示されない・・・しょぼーん
改造なので厳密な検証とかしていませんし、なんかしらの不具合があると思います。