require 'date' require 'time' require 'SVG/Graph/Plot' module SVG module Graph class RoomSchedule < Graph # In addition to the defaults set by Graph::initialize and # Plot::set_defaults, sets: # [x_label_format] '%Y-%m-%d %H:%M:%S' # [popup_format] '%Y-%m-%d %H:%M:%S' def set_defaults init_with( :x_label_format => '%Y-%m-%d %H:%M:%S', :popup_format => '%Y-%m-%d %H:%M:%S', :scale_x_divisions => false, :scale_x_integers => false, :bar_gap => true ) end # The format string use do format the X axis labels. # See Time::strformat attr_accessor :x_label_format # Use this to set the spacing between dates on the axis. The value # must be of the form # "\d+ ?(days|weeks|months|years|hours|minutes|seconds)?" # # EG: # # graph.timescale_divisions = "2 weeks" # # will cause the chart to try to divide the X axis up into segments of # two week periods. attr_accessor :timescale_divisions # The formatting used for the popups. See x_label_format attr_accessor :popup_format attr_accessor :scale_x_divisions attr_accessor :scale_x_integers attr_accessor :bar_gap protected def format x, y Time.at( x ).strftime( popup_format ) end def get_x_labels rv = get_x_values.collect { |v| v.strftime( x_label_format ) } end def y_label_offset( height ) height / -2.0 end def get_y_labels @data.map {|room| room[:title] } end def draw_data bargap = bar_gap ? (field_height < 10 ? field_height / 2 : 10) : 0 subbar_height = field_height - bargap field_count = 1 y_mod = (subbar_height / 2) + (font_size / 2) min,max,div = x_range scale = (@graph_width) / (max - min).to_f @data.each do |room| room[:data].each do |entry| x_start = (entry.start_time - min).to_f x_end = (entry.end_time - min).to_f y = @graph_height - (field_height * field_count) bar_width = (x_end - x_start) * scale bar_start = x_start * scale event = @graph.add_element( "rect", { "x" => bar_start.to_s, "y" => y.to_s, "width" => bar_width.to_s, "height" => subbar_height.to_s, "class" => "fill#{field_count+1}" }) switch = @graph.add_element("switch") fo = switch.add_element("foreignObject", { "x" => (bar_start + @font_size / 2).to_s, "y" => y.to_s, "width" => bar_width.to_s, "height" => subbar_height.to_s, "requiredExtensions" => "http://www.w3.org/1999/xhtml", }) body = fo.add_element("body", { "xmlns" => "http://www.w3.org/1999/xhtml", }) p = body.add_element("p", { "class" => "event-title", }) if entry.link p = p.add_element("a", { "href" => entry.link }) end p.add_text(entry.title) t = switch.add_element("text", { "x" => (bar_start + @font_size / 2).to_s, "y" => (y + 2 * @font_size).to_s, }) t.add_text(entry.title) end field_count += 1 end end def get_css return <