Class: Bio::Graphics::Panel

Inherits:
Object
  • Object
show all
Defined in:
lib/bio/graphics/panel.rb

Overview

The Bio::Graphics::Panel class describes the complete graph and contains all tracks. See Bio::Graphics documentation for explanation of interplay between different classes.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(length, opts = {}) ⇒ Panel

Create a new Bio::Graphics::Panel object

g = Bio::Graphics::Panel.new(456)

The height of the image is calculated automatically depending on how many tracks and features it contains. The width of the image defaults to 800 pt but can be set manually by using the width argument to the opts hash:

g = Bio::Graphics::Panel.new(456, :width => 1200)

See also: Bio::Graphics::Panel::Track, Bio::Graphics::Panel::Track::Feature


Arguments:

  • length

    length of the thing you want to visualize, e.g for

    visualizing a sequence that is 3.24 kb long, use 324. (required)

  • :width

    width of the resulting image in pixels. (default: 800)

  • :clickable

    whether the picture should have clickable glyphs or not

    (default: false) If set to true, a html file will be created with the map.

  • :display_start

    start coordinate to be displayed (default: 1)

  • :display_stop

    stop coordinate to be displayed (default: length of sequence)

  • :vertical

    Boolean: false = horizontal (= default)

  • :format

    File format of the picture. Can be :png, :svg, :pdf or :ps

    (default: :png)

Returns

Bio::Graphics::Panel object


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/bio/graphics/panel.rb', line 110

def initialize(length, opts = {})
  @length = length
  opts = {
    :width => DEFAULT_PANEL_WIDTH,
    :display_range => Range.new(0,@length),
    :vertical => false,
    :clickable => false,
    :format => :png
  }.merge(opts)
  
  @width = opts[:width].to_i

  @display_range = opts[:display_range]
  @display_start = [0, @display_range.lend].max
  @display_stop = [@length,@display_range.rend].min
  if @display_stop <= @display_start
    raise "[ERROR] Start coordinate to be displayed has to be smaller than stop coordinate."
  end
  @display_range = Range.new(@display_start,@display_stop)
  
  @vertical = opts[:vertical]
  @clickable = opts[:clickable]
  
  @format = opts[:format]
  if ! [:png, :svg, :pdf, :ps].include?(@format)
    raise "[ERROR] Format has to be one of :png, :svg, :pdf or :ps."
  end
  
  @tracks = Array.new
  @number_of_feature_rows = 0
  @image_map = ImageMap.new

  @rescale_factor = (@display_stop - @display_start).to_f / @width
  
  # To prevent that we do the whole drawing thing multiple times
  @final_panel_destination = nil
end

Instance Attribute Details

#clickableObject

Returns the value of attribute clickable


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def clickable
  @clickable
end

#display_rangeObject

Returns the value of attribute display_range


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def display_range
  @display_range
end

#display_startObject

Returns the value of attribute display_start


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def display_start
  @display_start
end

#display_stopObject

Returns the value of attribute display_stop


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def display_stop
  @display_stop
end

#final_panel_destinationObject

Returns the value of attribute final_panel_destination


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def final_panel_destination
  @final_panel_destination
end

#formatObject

Returns the value of attribute format


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def format
  @format
end

#heightObject

Returns the value of attribute height


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def height
  @height
end

#image_mapObject

Returns the value of attribute image_map


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def image_map
  @image_map
end

#lengthObject

Returns the value of attribute length


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def length
  @length
end

#number_of_feature_rowsObject

Returns the value of attribute number_of_feature_rows


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def number_of_feature_rows
  @number_of_feature_rows
end

#rescale_factorObject

Returns the value of attribute rescale_factor


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def rescale_factor
  @rescale_factor
end

#tracksObject

Returns the value of attribute tracks


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def tracks
  @tracks
end

#verticalObject

Returns the value of attribute vertical


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def vertical
  @vertical
end

#widthObject

Returns the value of attribute width


147
148
149
# File 'lib/bio/graphics/panel.rb', line 147

def width
  @width
end

Instance Method Details

#add_track(name, opts = {}) ⇒ Object

Adds a Bio::Graphics::Track container to this panel. A panel contains a logical grouping of features, e.g. (for sequence annotation:) genes, polymorphisms, ESTs, etc.

est_track = g.add_track('ESTs', :label => false, :glyph => :directed_generic)
gene_track = g.add_track('genes', :label => true)

Arguments:

  • name

    Name to be displayed at the top of the track. (Required)

  • :label

    boolean. Whether or not to display the labels for the features.

    (Default = true)

  • :glyph

    Default glyph for features in this track. For more info, see

    the lib/bio/graphics/glyph directory. (Default = :generic)

  • :colour

    Default colour for features in this track, in RGB

    (Default = [0,0,1])

Returns

Bio::Graphics::Track object that has just been created


166
167
168
169
170
# File 'lib/bio/graphics/panel.rb', line 166

def add_track(name, opts = {})
  track = Bio::Graphics::Track.new(self, name, opts)
  @tracks.push(track)
  return track
end

#draw(file_name) ⇒ Object

Create the drawing – The fact that display_start and display_stop can be set has two consequences:

1. not all features are drawn
2. the x-coordinate of all glyphs has to be corrected

++


179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/bio/graphics/panel.rb', line 179

def draw(file_name)
  if @final_panel_drawing.nil?
    # Create a panel that is huge vertically
    huge_height = 2000

    huge_panel_destination = nil
    huge_panel_destination = Cairo::ImageSurface.new(1, @width, huge_height)

    background = Cairo::Context.new(huge_panel_destination)
    background.set_source_rgb(1,1,1)
    background.rectangle(0,0,@width,huge_height).fill

    # Add ruler
    vertical_offset = 0
    ruler = Ruler.new(self)
    ruler.draw(huge_panel_destination)
    vertical_offset += ruler.height

    # Add tracks
    @tracks.each do |track|
      track.vertical_offset = vertical_offset
      track.draw(huge_panel_destination)
      @number_of_feature_rows += track.number_of_feature_rows
      vertical_offset += ( track.number_of_feature_rows*(FEATURE_HEIGHT+FEATURE_V_DISTANCE+5)) + 10 # '10' is for the header
    end

    # And create a smaller version of the panel
    @height = ruler.height
    @height += 20*@number_of_feature_rows
    @height += 10*@tracks.length #To correct for the track headers

    if @vertical
      @image_map.flip_orientation(@width)
      
      max_size = [@height, @width].max
      rotated_destination = Cairo::ImageSurface.new(1, max_size, max_size)
      rotated_context = Cairo::Context.new(rotated_destination)
      rotated_context.rotate(3*PI/2)
      rotated_context.translate(-@width, 0)
      rotated_context.set_source(huge_panel_destination, 0, 0)
      rotated_context.rectangle(0,0,max_size, max_size).fill

      @width, @height = @height, @width
      huge_panel_destination = rotated_destination
    end

    @final_panel_destination = Cairo::ImageSurface.new(1, @width, @height)
    resized_context = Cairo::Context.new(@final_panel_destination)
    resized_context.set_source(huge_panel_destination, 0, 0)
    resized_context.rectangle(0,0,@width, @height).fill
  end
  
  # And print to file
  if @format == :png
    @final_panel_destination.write_to_png(file_name)
  else
    case @format
    when :pdf
      output_destination = Cairo::PDFSurface.new(file_name, @width, @height)
    when :ps
      output_destination = Cairo::PSSurface.new(file_name, @width, @height)
    when :svg
      output_destination = Cairo::SVGSurface.new(file_name, @width, @height)
    end
    
    output_context = Cairo::Context.new(output_destination)
    output_context.set_source(@final_panel_destination, 0, 0)
    output_context.rectangle(0,0,@width, @height).fill
  end
  

  if @clickable # create png and map
    html_filename = file_name.sub(/\.[^.]+$/, '.html')
    html = File.open(html_filename,'w')
    html.puts "<html>"
    html.puts "<body>"
    html.puts @image_map.to_s
    html.puts "<img border='1' src='" + file_name + "' usemap='#image_map' />"
    html.puts "</body>"
    html.puts "</html>"
    html.close
  end
end