diff options
Diffstat (limited to 'room-schedule.rb')
-rw-r--r-- | room-schedule.rb | 248 |
1 files changed, 0 insertions, 248 deletions
diff --git a/room-schedule.rb b/room-schedule.rb deleted file mode 100644 index fd4e282..0000000 --- a/room-schedule.rb +++ /dev/null @@ -1,248 +0,0 @@ -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 <<EOL -/* default fill styles for multiple datasets (probably only use a single dataset on this graph though) */ -.key1,.fill1{ - fill: #ff0000; - fill-opacity: 0.5; - stroke: none; - stroke-width: 0.5px; -} -.key2,.fill2{ - fill: #0000ff; - fill-opacity: 0.5; - stroke: none; - stroke-width: 1px; -} -.key3,.fill3{ - fill: #00ff00; - fill-opacity: 0.5; - stroke: none; - stroke-width: 1px; -} -.key4,.fill4{ - fill: #ffcc00; - fill-opacity: 0.5; - stroke: none; - stroke-width: 1px; -} -.key5,.fill5{ - fill: #00ccff; - fill-opacity: 0.5; - stroke: none; - stroke-width: 1px; -} -.key6,.fill6{ - fill: #ff00ff; - fill-opacity: 0.5; - stroke: none; - stroke-width: 1px; -} -.key7,.fill7{ - fill: #00ffff; - fill-opacity: 0.5; - stroke: none; - stroke-width: 1px; -} -.key8,.fill8{ - fill: #ffff00; - fill-opacity: 0.5; - stroke: none; - stroke-width: 1px; -} -.key9,.fill9{ - fill: #cc6666; - fill-opacity: 0.5; - stroke: none; - stroke-width: 1px; -} -.key10,.fill10{ - fill: #663399; - fill-opacity: 0.5; - stroke: none; - stroke-width: 1px; -} -.key11,.fill11{ - fill: #339900; - fill-opacity: 0.5; - stroke: none; - stroke-width: 1px; -} -.key12,.fill12{ - fill: #9966FF; - fill-opacity: 0.5; - stroke: none; - stroke-width: 1px; -} -.event-title { - font-size: 80%; -} -EOL - end - - private - - def timescale_unit - if timescale_divisions - timescale_divisions =~ /(\d+) ?(days|weeks|hours|minutes|seconds)?/ - division_units = $2 ? $2 : "days" - amount = $1.to_i - unit = nil - case division_units - when "weeks" - unit = 7 - when "days" - unit = 1 - when "hours" - unit = (1.0 / 24) - when "minutes" - unit = (1.0 / 1440) - when "seconds" - unit = (1.0 / 86400) - end - end - [ amount, unit ] - end - - def x_range - max_value = @data.map {|room| room[:data].map {|e| e.end_time}.max}.max - min_value = @data.map {|room| room[:data].map {|e| e.start_time}.min}.min - - amount, unit = timescale_unit - max_value += unit * (amount - (max_value.min % amount)) - range = max_value - min_value - right_pad = 0 #range == 0 ? 10 : range / 20.0 - scale_range = (max_value + right_pad) - min_value - - scale_division = scale_x_divisions || (scale_range / 10.0) - - if scale_x_integers - scale_division = scale_division < 1 ? 1 : scale_division.round - end - - [min_value, max_value, scale_division] - end - - def get_x_values - rv = [] - min, max, scale_division = x_range - if timescale_divisions - amount, unit = timescale_unit - min.step( max, amount * unit) {|v| rv << v} if amount - return rv - end - min.step(max, scale_division) {|v| rv << v} - return rv - end - end - end -end |