SysMO-DB/seek

View on GitHub
app/helpers/i_s_a_helper.rb

Summary

Maintainability
B
6 hrs
Test Coverage
require 'tempfile'
require 'dot_generator'

module ISAHelper

  include DotGenerator

  FILL_COLOURS = {'Sop'=>"#7ac5cd", #cadetblue3
                  'Model'=>"#cdcd00", #yellow3
                  'DataFile'=>"#eec591", #burlywood2
                  'Investigation'=>"#C7E9C0",
                  'Study'=>"#91c98b",
                  'Assay'=> {'EXP'=>"#64b466",'MODEL'=>"#92CD00"},
                  'Publication'=>"#84B5FD",
                  'Presentation' => "#8ee5ee", #cadetblue2
                  'Sample' => "#ffa500", #orange
                  'Specimen' => "#ff0000", #red
                  'HiddenItem' => "#d3d3d3"} #lightgray

  BORDER_COLOURS = {'Sop'=>"#619da4",
                    'Model'=>"#a4a400",
                    'DataFile'=>"#be9d74",
                    'Investigation'=>"#9fba99",
                    'Study'=>"#74a06f",
                    'Assay'=> {'EXP'=>"#509051",'MODEL'=>"#74a400"},
                    'Publication'=>"#6990ca",
                    'Presentation' => "#71b7be", #cadetblue2
                    'Sample' => "#cc8400",
                    'Specimen' => "#cc0000",
                    'HiddenItem' => "#a8a8a8"}

  FILL_COLOURS.default = "#8ee5ee" #cadetblue2
  BORDER_COLOURS.default = "#71b7be"

  #the cytoscape elements are generated by parsing the elements from the dot format
  def cytoscape_elements root_item,deep=true,current_item=nil
    begin
      current_item||=root_item
      dot_graph = to_dot(root_item,deep,current_item)
      dot_elements = dot_graph.gsub('graph ISA_graph {','').gsub('}','')
      elements = dot_elements.split(';')
      edges = elements.select{|e| e.include?('--')}
      nodes = edges.collect{|edge| edge.split('--')}.flatten.uniq
      nodes = nodes.each{|n| n.strip!}
      cytoscape_elements = cytoscape_node_elements(nodes) + cytoscape_edge_elements(edges)
      cytoscape_elements
    rescue Exception=>e
      Rails.logger.error("Error generating nodes and edges for the graph - #{e.message}")
      {:error => 'error'}
    end
  end

  private

  def cytoscape_node_elements nodes
    cytoscape_node_elements = []
    nodes.each do |node|
      item_type, item_id = node.split('_')
      item = item_type.constantize.find_by_id(item_id)
      if item.can_view?
        description = item.description
        no_description_text = item.kind_of?(Publication) ? 'No abstract' : 'No description'
        tooltip = description.blank? ? no_description_text : truncate(h(description), :length => 500)
        #distinquish two assay classes
        if item.kind_of?(Assay)
          assay_class_title = item.assay_class.title
          assay_class_key = item.assay_class.key
          name = truncate(assay_class_title + ': ' + item.title)
          item_info = link_to("<b>#{assay_class_title}: </b>".html_safe +  h(item.title), polymorphic_path(item), :title => tooltip_title_attrib(tooltip))
          fave_color = FILL_COLOURS[item_type][assay_class_key] || FILL_COLOURS.default
          border_color = BORDER_COLOURS[item_type][assay_class_key] || BORDER_COLOURS.default
        else
          name = truncate(item_type.humanize + ': ' + item.title)
          item_info = link_to("<b>#{item_type.humanize}: </b>".html_safe +  h(item.title), polymorphic_path(item), :title => tooltip_title_attrib(tooltip))
          fave_color = FILL_COLOURS[item_type] || FILL_COLOURS.default
          border_color = BORDER_COLOURS[item_type] || BORDER_COLOURS.default
        end
        # give more space for title of isa elements
        if item.is_isa?
          name = truncate item.title
        end
      else
        name = 'Hidden item'
        item_info = hidden_items_html([item], 'Hidden item')
        fave_color = FILL_COLOURS['HiddenItem'] || FILL_COLOURS.default
        border_color = BORDER_COLOURS['HiddenItem'] || BORDER_COLOURS.default
      end
      cytoscape_node_elements << node_element(node, name, item_info, fave_color, border_color)
    end
    cytoscape_node_elements
  end

  def cytoscape_edge_elements edges
    cytoscape_edge_elements = []
    edges.each do |edge|
      source, target = edge.split('--')
      source.strip!
      target.strip!
      edge.strip!
      target_type,target_id = target.split('_')
      target_item = target_type.constantize.find_by_id(target_id)
      name = edge_label(source, target)
      if target_item.can_view?
        if target_item.kind_of?(Assay)
          fave_color = BORDER_COLOURS[target_type][target_item.assay_class.key] || BORDER_COLOURS.default
        else
          fave_color = BORDER_COLOURS[target_type] || BORDER_COLOURS.default
        end
      else
        fave_color = BORDER_COLOURS['HiddenItem'] || BORDER_COLOURS.default
      end
      cytoscape_edge_elements << edge_element(edge, name, source, target, fave_color)
    end
    cytoscape_edge_elements
  end

  def node_element id, name, item_info, fave_color, border_color
    {:group => 'nodes',
     :data => {:id => id,
               :name => name,
               :item_info => item_info,
               :faveColor => fave_color,
               :borderColor => border_color}
    }
  end

  def edge_element id, name, source, target, fave_color
    {:group => 'edges',
     :data => {:id => id,
               :name => name,
               :source => source,
               :target => target,
               :faveColor => fave_color}
    }
  end

  def edge_label source,target
    source_type,source_id = source.split('_')
    target_type,target_id = target.split('_')

    label = ''
    if source_type == 'Assay' && target_type == 'DataFile'
      assay_asset = AssayAsset.where(["assay_id=? AND asset_id=?",
                        source_id, target_id]).first
      label << assay_asset.try(:relationship_type).try(:title).to_s
    end
    label
  end
end