Combining changesets for tracks (lots of noise and not a lot of signal). This is a rough prototype of the tracks extension to Galaxy.

This commit is contained in:
Ian Schenck
2009-03-04 23:55:51 +00:00
parent 9dc5b4f5b8
commit b5f93ebc12
39 changed files with 14315 additions and 2433 deletions
+1
View File
@@ -29,6 +29,7 @@
<datatype extension="html" type="galaxy.datatypes.images:Html" mimetype="text/html"/>
<datatype extension="interval" type="galaxy.datatypes.interval:Interval" display_in_upload="true">
<converter file="interval_to_bed_converter.xml" target_datatype="bed"/>
<indexer file="interval.xml" />
</datatype>
<datatype extension="jpg" type="galaxy.datatypes.images:Image" mimetype="image/jpeg"/>
<datatype extension="laj" type="galaxy.datatypes.images:Laj"/>
+8 -1
View File
@@ -18,6 +18,7 @@ import tempfile
from bisect import bisect
def divide( intervals, out_path ):
manifest = {}
current_file = None
lastchrom = ""
for line in intervals:
@@ -25,6 +26,7 @@ def divide( intervals, out_path ):
chrom = line.chrom
except AttributeError, e:
continue
manifest[chrom] = max(manifest.get(chrom,0),line.end)
if not lastchrom == chrom:
if current_file:
current_file.flush()
@@ -34,6 +36,7 @@ def divide( intervals, out_path ):
lastchrom = chrom
current_file.flush()
current_file.close()
return manifest
if __name__ == "__main__":
options, args = doc_optparse.parse( __doc__ )
@@ -56,5 +59,9 @@ if __name__ == "__main__":
end_col=end_col_1,
strand_col=strand_col_1,
fix_strand=True )
divide( interval, out_path )
manifest = divide( interval, out_path )
manifest_file = open( os.path.join( out_path, "manifest.tab" ),"w" )
for key, value in manifest.items():
print >> manifest_file, "%s\t%s" % (key, value)
manifest_file.close()
temp_file.close()
+2 -2
View File
@@ -298,10 +298,10 @@ class Interval( Tabular ):
record_start = int(fields[dataset.metadata.startCol-1])
record_end = int(fields[dataset.metadata.endCol-1])
if record_start < end and record_end > start:
window.append( fields ) #Yes I did want to use a generator here, but it doesn't work downstream
window.append( (record_start, record_end) ) #Yes I did want to use a generator here, but it doesn't work downstream
return window
def get_track_resolution( self, dataset, data, start, end):
def get_track_resolution( self, dataset, start, end):
return None
class Bed( Interval ):
+2
View File
@@ -0,0 +1,2 @@
1 2
3 4
+15
View File
@@ -18,9 +18,24 @@ class TrackStoreManager( object ):
return TrackStore( path=s.substitute(TemplateSubber(dataset)) )
class TrackStore( object ):
MANIFEST_NAME = "manifest.tab"
def __init__(self, path=""):
self.path = path
def get_manifest( self ):
if not self.exists: raise self.DoesNotExist("TrackStore at %s does not exist." % self.path)
manifest_path = os.path.join( self.path, self.MANIFEST_NAME )
if os.path.exists( manifest_path ):
manifest = {}
for line in open( manifest_path ):
line = line.rstrip("\n\r")
fields = line.split("\t")
manifest[fields[0]] = fields[1:]
return manifest
else:
raise self.DoesNotExist( "Manifest for TrackStore object could not be found." )
def get(self, chrom="chr1", resolution=None, **kwargs):
if not self.exists: raise self.DoesNotExist("TrackStore at %s does not exist." % self.path)
object_path = self._get_object_path( chrom, resolution )
+140
View File
@@ -0,0 +1,140 @@
from mako import exceptions
from mako.template import Template
from mako.lookup import TemplateLookup
from galaxy.web.base.controller import *
from galaxy.web.framework import simplejson
from galaxy import web
from galaxy.tracks import messages
import mimeparse
from galaxy.util.json import to_json_string
class MultiResponse(object):
"""
Shamelessly ripped off of a django snippet.
"""
def __init__(self, handlers):
self.handlers = handlers
def __call__(self, view_func):
def wrapper(that, trans, *args, **kwargs):
data_resource = view_func(that, trans, *args, **kwargs)
content_type = mimeparse.best_match(self.handlers.keys(),
trans.request.environ['HTTP_ACCEPT'])
response = self.handlers[content_type](data_resource, trans)
trans.response.headers['Content-Type'] = "%s" % content_type
return response
return wrapper
@classmethod
def JSON( cls, data_resource, trans ):
return simplejson.dumps( data_resource )
class XML( object ):
def __call__(self, data_resource, trans ):
raise NotImplementedError( "XML MultiResponse handler is not implemented." )
class AMF( object ):
def __call__(self, data_resource, trans ):
raise NotImplementedError( "XML MultiResponse handler is not implemented." )
class HTML( object ):
def __init__(self, template ):
self.template = template
def __call__(self, data_resource, trans ):
return trans.fill_template( self.template, **data_resource )
class DEBUG( HTML ):
def __call__(self, data_resource, trans ):
return trans.fill_template( self.template, data_resource=data_resource)
class WebRoot( BaseController ):
@web.expose
@MultiResponse( {'text/html':MultiResponse.JSON,
'text/javascript':MultiResponse.JSON} )
def dbkeys(self, trans ):
return list(set([x.metadata.dbkey for x in trans.get_history().datasets if not x.deleted]))
@web.expose
@MultiResponse( {'text/html':MultiResponse.JSON,
'text/javascript':MultiResponse.JSON} )
def chroms(self, trans, dbkey ):
db_manifest = os.path.join( trans.app.config.tool_data_path, 'shared','ucsc','chrom', "%s.len" % dbkey )
manifest = {}
if os.path.exists( db_manifest ):
for line in open( db_manifest ):
line = line.rstrip("\r\n")
fields = line.split("\t")
manifest[fields[0]] = int(fields[1])
else:
# try to fake a manifest by reading track stores
datasets = trans.app.model.HistoryDatasetAssociation.filter_by(deleted=False, history_id=trans.history.id).all()
for dataset in datasets:
if not dataset.metadata.dbkey == dbkey: continue
track_store = trans.app.track_store.get( dataset )
if track_store.exists:
try:
for chrom, fields in track_store.get_manifest().items():
manifest[chrom] = max(manifest.get(chrom, 0), int(fields[0]))
except track_store.DoesNotExist:
pass
return manifest
@web.expose
@MultiResponse( {'text/html':MultiResponse.JSON,
'text/javascript':MultiResponse.JSON} )
def list(self, trans, dbkey ):
datasets = trans.app.model.HistoryDatasetAssociation.filter_by(deleted=False, history_id=trans.history.id).all()
dataset_list = {}
for dataset in datasets:
if dataset.metadata.dbkey == dbkey and trans.app.datatypes_registry.get_indexers_by_datatype( dataset.extension ):
dataset_list[dataset.id] = dataset.name
return dataset_list
@web.expose
@MultiResponse( {'text/html':MultiResponse.JSON,
'text/javascript':MultiResponse.JSON} )
def data(self, trans, dataset_id, chrom="", start="", end=""):
dataset = trans.app.model.HistoryDatasetAssociation.get( dataset_id )
if not dataset: return messages.NO_DATA
if dataset.state == trans.app.model.Job.states.ERROR:
return messages.NO_DATA
if not dataset.state == trans.app.model.Job.states.OK:
return messages.PENDING
track_store = trans.app.track_store.get( dataset )
if not track_store.exists:
# Test if we can make a track
indexers = trans.app.datatypes_registry.get_indexers_by_datatype( dataset.extension )
if indexers:
tool = indexers[0] # They are sorted by class chain so use the top one
# If we can, return pending and launch job
job = trans.app.model.Job()
job.session_id = trans.get_galaxy_session().id
job.history_id = trans.history.id
job.tool_id = tool.id
job.tool_version = "1.0.0"
job.add_input_dataset( "input_dataset", dataset )
job.add_parameter( "input_dataset", to_json_string( dataset.id ) )
# This is odd
job.add_output_dataset( "input_dataset", dataset )
# create store path, this is rather unclear?
track_store.set()
job.add_parameter( "store_path", to_json_string( track_store.path ) )
job.flush()
trans.app.job_manager.job_queue.put( job.id, tool )
return messages.PENDING
else:
return messages.NO_DATA
else:
if chrom and start and end:
resolution = dataset.datatype.get_track_resolution( dataset, int(start), int(end ) )
data = track_store.get( chrom, resolution )
window = dataset.datatype.get_track_window( dataset, data, int(start), int(end) )
return window
else:
return messages.DATA
@web.expose
def index(self, trans, **kwargs):
return trans.fill_template( '/tracks/index.mako' )
+181
View File
@@ -0,0 +1,181 @@
"""MIME-Type Parser
This module provides basic functions for handling mime-types. It can handle
matching mime-types against a list of media-ranges. See section 14.1 of
the HTTP specification [RFC 2616] for a complete explanation.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
Contents:
- parse_mime_type(): Parses a mime-type into its component parts.
- parse_media_range(): Media-ranges are mime-types with wild-cards and a 'q' quality parameter.
- quality(): Determines the quality ('q') of a mime-type when compared against a list of media-ranges.
- quality_parsed(): Just like quality() except the second parameter must be pre-parsed.
- best_match(): Choose the mime-type with the highest quality ('q') from a list of candidates.
"""
__version__ = "0.1.2"
__author__ = 'Joe Gregorio'
__email__ = "joe@bitworking.org"
__credits__ = ""
def parse_mime_type(mime_type):
"""Carves up a mime-type and returns a tuple of the
(type, subtype, params) where 'params' is a dictionary
of all the parameters for the media range.
For example, the media range 'application/xhtml;q=0.5' would
get parsed into:
('application', 'xhtml', {'q', '0.5'})
"""
parts = mime_type.split(";")
params = dict([tuple([s.strip() for s in param.split("=")])\
for param in parts[1:] ])
full_type = parts[0].strip()
# Java URLConnection class sends an Accept header that includes a single "*"
# Turn it into a legal wildcard.
if full_type == '*': full_type = '*/*'
(type, subtype) = full_type.split("/")
return (type.strip(), subtype.strip(), params)
def parse_media_range(range):
"""Carves up a media range and returns a tuple of the
(type, subtype, params) where 'params' is a dictionary
of all the parameters for the media range.
For example, the media range 'application/*;q=0.5' would
get parsed into:
('application', '*', {'q', '0.5'})
In addition this function also guarantees that there
is a value for 'q' in the params dictionary, filling it
in with a proper default if necessary.
"""
(type, subtype, params) = parse_mime_type(range)
if not params.has_key('q') or not params['q'] or \
not float(params['q']) or float(params['q']) > 1\
or float(params['q']) < 0:
params['q'] = '1'
return (type, subtype, params)
def fitness_and_quality_parsed(mime_type, parsed_ranges):
"""Find the best match for a given mime-type against
a list of media_ranges that have already been
parsed by parse_media_range(). Returns a tuple of
the fitness value and the value of the 'q' quality
parameter of the best match, or (-1, 0) if no match
was found. Just as for quality_parsed(), 'parsed_ranges'
must be a list of parsed media ranges. """
best_fitness = -1
best_fit_q = 0
(target_type, target_subtype, target_params) =\
parse_media_range(mime_type)
for (type, subtype, params) in parsed_ranges:
if (type == target_type or type == '*' or target_type == '*') and \
(subtype == target_subtype or subtype == '*' or target_subtype == '*'):
param_matches = reduce(lambda x, y: x+y, [1 for (key, value) in \
target_params.iteritems() if key != 'q' and \
params.has_key(key) and value == params[key]], 0)
fitness = (type == target_type) and 100 or 0
fitness += (subtype == target_subtype) and 10 or 0
fitness += param_matches
if fitness > best_fitness:
best_fitness = fitness
best_fit_q = params['q']
return best_fitness, float(best_fit_q)
def quality_parsed(mime_type, parsed_ranges):
"""Find the best match for a given mime-type against
a list of media_ranges that have already been
parsed by parse_media_range(). Returns the
'q' quality parameter of the best match, 0 if no
match was found. This function bahaves the same as quality()
except that 'parsed_ranges' must be a list of
parsed media ranges. """
return fitness_and_quality_parsed(mime_type, parsed_ranges)[1]
def quality(mime_type, ranges):
"""Returns the quality 'q' of a mime-type when compared
against the media-ranges in ranges. For example:
>>> quality('text/html','text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5')
0.7
"""
parsed_ranges = [parse_media_range(r) for r in ranges.split(",")]
return quality_parsed(mime_type, parsed_ranges)
def best_match(supported, header):
"""Takes a list of supported mime-types and finds the best
match for all the media-ranges listed in header. The value of
header must be a string that conforms to the format of the
HTTP Accept: header. The value of 'supported' is a list of
mime-types.
>>> best_match(['application/xbel+xml', 'text/xml'], 'text/*;q=0.5,*/*; q=0.1')
'text/xml'
"""
parsed_header = [parse_media_range(r) for r in header.split(",")]
weighted_matches = [(fitness_and_quality_parsed(mime_type, parsed_header), mime_type)\
for mime_type in supported]
weighted_matches.sort()
return weighted_matches[-1][0][1] and weighted_matches[-1][1] or ''
if __name__ == "__main__":
import unittest
class TestMimeParsing(unittest.TestCase):
def test_parse_media_range(self):
self.assert_(('application', 'xml', {'q': '1'}) == parse_media_range('application/xml;q=1'))
self.assertEqual(('application', 'xml', {'q': '1'}), parse_media_range('application/xml'))
self.assertEqual(('application', 'xml', {'q': '1'}), parse_media_range('application/xml;q='))
self.assertEqual(('application', 'xml', {'q': '1'}), parse_media_range('application/xml ; q='))
self.assertEqual(('application', 'xml', {'q': '1', 'b': 'other'}), parse_media_range('application/xml ; q=1;b=other'))
self.assertEqual(('application', 'xml', {'q': '1', 'b': 'other'}), parse_media_range('application/xml ; q=2;b=other'))
# Java URLConnection class sends an Accept header that includes a single *
self.assertEqual(('*', '*', {'q': '.2'}), parse_media_range(" *; q=.2"))
def test_rfc_2616_example(self):
accept = "text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5"
self.assertEqual(1, quality("text/html;level=1", accept))
self.assertEqual(0.7, quality("text/html", accept))
self.assertEqual(0.3, quality("text/plain", accept))
self.assertEqual(0.5, quality("image/jpeg", accept))
self.assertEqual(0.4, quality("text/html;level=2", accept))
self.assertEqual(0.7, quality("text/html;level=3", accept))
def test_best_match(self):
mime_types_supported = ['application/xbel+xml', 'application/xml']
# direct match
self.assertEqual(best_match(mime_types_supported, 'application/xbel+xml'), 'application/xbel+xml')
# direct match with a q parameter
self.assertEqual(best_match(mime_types_supported, 'application/xbel+xml; q=1'), 'application/xbel+xml')
# direct match of our second choice with a q parameter
self.assertEqual(best_match(mime_types_supported, 'application/xml; q=1'), 'application/xml')
# match using a subtype wildcard
self.assertEqual(best_match(mime_types_supported, 'application/*; q=1'), 'application/xml')
# match using a type wildcard
self.assertEqual(best_match(mime_types_supported, '*/*'), 'application/xml')
mime_types_supported = ['application/xbel+xml', 'text/xml']
# match using a type versus a lower weighted subtype
self.assertEqual(best_match(mime_types_supported, 'text/*;q=0.5,*/*; q=0.1'), 'text/xml')
# fail to match anything
self.assertEqual(best_match(mime_types_supported, 'text/html,application/atom+xml; q=0.9'), '')
# common AJAX scenario
mime_types_supported = ['application/json', 'text/html']
self.assertEqual(best_match(mime_types_supported, 'application/json, text/javascript, */*'), 'application/json')
# verify fitness ordering
self.assertEqual(best_match(mime_types_supported, 'application/json, text/html;q=0.9'), 'application/json')
def test_support_wildcards(self):
mime_types_supported = ['image/*', 'application/xml']
# match using a type wildcard
self.assertEqual(best_match(mime_types_supported, 'image/png'), 'image/*')
# match using a wildcard for both requested and supported
self.assertEqual(best_match(mime_types_supported, 'image/*'), 'image/*')
unittest.main()
Regular → Executable
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/sh
cd `dirname $0`
python -ES ./scripts/paster.py serve universe_wsgi.ini $@
python2.52.5 -ES ./scripts/paster.py serve universe_wsgi.ini $@
Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

File diff suppressed because it is too large Load Diff
+126
View File
@@ -0,0 +1,126 @@
/*!
jquery.event.drag.js ~ v1.4 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
Liscensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
*/
;(function($){ // secure $ jQuery alias
/*******************************************************************************************/
// Created: 2008-06-04 | Updated: 2009-01-26
/*******************************************************************************************/
// Events: drag, dragstart, dragend
/*******************************************************************************************/
// jquery method
$.fn.drag = function( fn1, fn2, fn3 ){
if ( fn2 ) this.bind('dragstart', fn1 ); // 2+ args
if ( fn3 ) this.bind('dragend', fn3 ); // 3 args
return !fn1 ? this.trigger('drag') // 0 args
: this.bind('drag', fn2 ? fn2 : fn1 ); // 1+ args
};
// local refs
var $event = $.event, $special = $event.special,
// special event configuration
drag = $special.drag = {
not: ':input', // don't begin to drag on event.targets that match this selector
distance: 0, // distance dragged before dragstart
which: 1, // mouse button pressed to start drag sequence
setup: function( data ){
data = $.extend({
distance: drag.distance,
which: drag.which,
not: drag.not
}, data || {});
data.distance = squared( data.distance ); // x² + y² = distance²
$event.add( this, "mousedown", handler, data );
},
teardown: function(){
$event.remove( this, "mousedown", handler );
if ( this === drag.dragging ) drag.dragging = drag.proxy = null; // deactivate element
selectable( this, true ); // enable text selection
}
};
// handle drag-releatd DOM events
function handler ( event ){
var elem = this, returned, data = event.data || {};
// mousemove or mouseup
if ( data.elem ){
// update event properties...
elem = event.dragTarget = data.elem; // drag source element
event.dragProxy = drag.proxy || elem; // proxy element or source
event.cursorOffsetX = data.pageX - data.left; // mousedown offset
event.cursorOffsetY = data.pageY - data.top; // mousedown offset
event.offsetX = event.pageX - event.cursorOffsetX; // element offset
event.offsetY = event.pageY - event.cursorOffsetY; // element offset
}
// mousedown, check some initial props to avoid the switch statement
else if ( drag.dragging || ( data.which>0 && event.which!=data.which ) ||
$( event.target ).is( data.not ) ) return;
// handle various events
switch ( event.type ){
// mousedown, left click, event.target is not restricted, init dragging
case 'mousedown':
$.extend( data, $( elem ).offset(), {
elem: elem, target: event.target,
pageX: event.pageX, pageY: event.pageY
}); // store some initial attributes
$event.add( document, "mousemove mouseup", handler, data );
selectable( elem, false ); // disable text selection
return false; // prevents text selection in safari
// mousemove, check distance, start dragging
case !drag.dragging && 'mousemove':
if ( squared( event.pageX-data.pageX )
+ squared( event.pageY-data.pageY ) // x² + y² = distance²
< data.distance ) break; // distance tolerance not reached
event.target = data.target; // force target from "mousedown" event (fix distance issue)
returned = hijack( event, "dragstart", elem ); // trigger "dragstart", return proxy element
if ( returned !== false ){ // "dragstart" not rejected
drag.dragging = elem; // activate element
drag.proxy = event.dragProxy = $( returned || elem )[0]; // set proxy
}
// mousemove, dragging
case 'mousemove':
if ( drag.dragging ){
returned = hijack( event, "drag", elem ); // trigger "drag"
if ( $special.drop ){ // manage drop events
$special.drop.allowed = ( returned !== false ); // prevent drop
$special.drop.handler( event ); // "dropstart", "dropend"
}
if ( returned !== false ) break; // "drag" not rejected, stop
event.type = "mouseup"; // helps "drop" handler behave
}
// mouseup, stop dragging
case 'mouseup':
$event.remove( document, "mousemove mouseup", handler ); // remove page events
if ( drag.dragging ){
if ( $special.drop ) $special.drop.handler( event ); // "drop"
hijack( event, "dragend", elem ); // trigger "dragend"
}
selectable( elem, true ); // enable text selection
drag.dragging = drag.proxy = data.elem = null; // deactivate element
break;
}
};
// set event type to custom value, and handle it
function hijack ( event, type, elem ){
event.type = type; // force the event type
var result = $event.handle.call( elem, event );
return result===false ? false : result || event.result;
};
// return the value squared
function squared ( value ){ return Math.pow( value, 2 ); };
// toggles text selection attributes
function selectable ( elem, bool ){
if ( !elem ) return; // maybe element was removed ?
elem.unselectable = bool ? "off" : "on"; // IE
elem.onselectstart = function(){ return bool; }; // IE
if ( document.selection && document.selection.empty ) document.selection.empty(); // IE
if ( elem.style ) elem.style.MozUserSelect = bool ? "" : "none"; // FF
};
/*******************************************************************************************/
})( jQuery ); // confine scope
+1979 -1287
View File
File diff suppressed because it is too large Load Diff
Regular → Executable
+8970 -1140
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,5 @@
/*
jquery.event.drag.js ~ v1.4 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
Liscensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
*/
(function(H){H.fn.drag=function(K,J,I){if(J){this.bind("dragstart",K)}if(I){this.bind("dragend",I)}return !K?this.trigger("drag"):this.bind("drag",J?J:K)};var D=H.event,B=D.special,F=B.drag={not:":input",distance:0,which:1,setup:function(I){I=H.extend({distance:F.distance,which:F.which,not:F.not},I||{});I.distance=G(I.distance);D.add(this,"mousedown",E,I)},teardown:function(){D.remove(this,"mousedown",E);if(this===F.dragging){F.dragging=F.proxy=null}C(this,true)}};function E(K){var J=this,I,L=K.data||{};if(L.elem){J=K.dragTarget=L.elem;K.dragProxy=F.proxy||J;K.cursorOffsetX=L.pageX-L.left;K.cursorOffsetY=L.pageY-L.top;K.offsetX=K.pageX-K.cursorOffsetX;K.offsetY=K.pageY-K.cursorOffsetY}else{if(F.dragging||(L.which>0&&K.which!=L.which)||H(K.target).is(L.not)){return }}switch(K.type){case"mousedown":H.extend(L,H(J).offset(),{elem:J,target:K.target,pageX:K.pageX,pageY:K.pageY});D.add(document,"mousemove mouseup",E,L);C(J,false);return false;case !F.dragging&&"mousemove":if(G(K.pageX-L.pageX)+G(K.pageY-L.pageY)<L.distance){break}K.target=L.target;I=A(K,"dragstart",J);if(I!==false){F.dragging=J;F.proxy=K.dragProxy=H(I||J)[0]}case"mousemove":if(F.dragging){I=A(K,"drag",J);if(B.drop){B.drop.allowed=(I!==false);B.drop.handler(K)}if(I!==false){break}K.type="mouseup"}case"mouseup":D.remove(document,"mousemove mouseup",E);if(F.dragging){if(B.drop){B.drop.handler(K)}A(K,"dragend",J)}C(J,true);F.dragging=F.proxy=L.elem=null;break}}function A(L,J,K){L.type=J;var I=D.handle.call(K,L);return I===false?false:I||L.result}function G(I){return Math.pow(I,2)}function C(J,I){if(!J){return }J.unselectable=I?"off":"on";J.onselectstart=function(){return I};if(document.selection&&document.selection.empty){document.selection.empty()}if(J.style){J.style.MozUserSelect=I?"":"none"}}})(jQuery);
+19 -1
View File
File diff suppressed because one or more lines are too long
+273 -1
View File
File diff suppressed because one or more lines are too long
+47
View File
@@ -0,0 +1,47 @@
/* tracks browser - Galaxy Project - PSU */
body { font-family:"Lucida Grande MS"; }
ul { margin:0; padding:0; }
ul li { list-style:none; float:left; }
.block { display:block; }
.float-left { float:left; }
.float-right { float:right; }
.padding-zero { padding:0; }
.margin-zero { margin:0; }
.overflow { overflow:visible; }
.no-overflow { overflow:hidden; }
.width-hundred-percent { margin:0; width:100%; }
.width-eighty-percent { margin:0; width:80%; }
.width-sixty-percent { margin:0; width:60%; }
.width-fifty-percent { margin:0; width:50%; }
.width-forty-percent { margin:0; width:40%; }
.width-twenty-percent { margin:0; width:20%; }
.track, .track-label, .track-canvas { height: 8em; }
.track-label { background:#e6e7e8; }
.track-canvas { background:#f9f9f9; }
.history-item { background: #CCFFCC; border: 1px solid #888888; border-left: 5px solid #888888;
border-right: none; margin:5px -5px 5px 0; padding: 5px 11px; width:85%; height:3em; }
#viewport { min-height:20em; border:1px solid #c6c7c8; margin-right:.4em;}
#viewport-top { height: 9em; }
#db-tools { height:4em; }
#history-tools { height:4em; }
#window-macro { height: 4em; }
#window-micro { height: 4em; }
#macro-slider { height: 1em; }
#x-axis { height: 4em; background:#E2F1F5;}
#tracks-sortable { min-height:15em; }
#drag-history { border:1px solid #c6c7c8; width: 0%; min-height:20em; position:relative; top:0; }
#history-control-bar { height:3em; }
#dock { position:absolute; bottom:0; left:20%; background: #FFFDF2; border:1px solid #919396;}
#dock ul li { margin:0 .4em; }
+39
View File
@@ -0,0 +1,39 @@
/* SVN FILE: $Id: jamal.js 18 2007-06-13 09:07:32Z teemow $ */
/**
* To quote Dave Cardwell:
* Built on the shoulders of giants:
* * John Resig - http://jquery.com/
*
* Jamal : Javascript MVC Assembly Layout <http://jamal-mvc.com/>
* Copyright (c) 2007, Timo Derstappen <http://teemow.com/>
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright (c) 2007, Timo Derstappen
* @link
* @package jamal
* @subpackage jamal.controller
* @since Jamal v 0.4
* @version $Revision: 40 $
* @modifiedby $LastChangedBy: teemow $
* @lastmodified $Date: 2007-08-20 18:24:35 +0200 (Mo, 20. Aug 2007) $
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Jamal app controller
*
* @public
* @cat controller
*/
jamal.extend(jamal.fn.c.prototype, {
components: ['session', 'modal'],
beforeAction: function() {
},
afterAction: function() {
}
});
+32
View File
@@ -0,0 +1,32 @@
/* SVN FILE: $Id: jamal.js 18 2007-06-13 09:07:32Z teemow $ */
/**
* To quote Dave Cardwell:
* Built on the shoulders of giants:
* * John Resig - http://jquery.com/
*
* Jamal : Javascript MVC Assembly Layout <http://jamal-mvc.com/>
* Copyright (c) 2007, Timo Derstappen <http://teemow.com/>
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright (c) 2007, Timo Derstappen
* @link
* @package jamal
* @subpackage jamal.model
* @since Jamal v 0.4
* @version $Revision: 40 $
* @modifiedby $LastChangedBy: teemow $
* @lastmodified $Date: 2007-08-20 18:24:35 +0200 (Mo, 20. Aug 2007) $
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Jamal app model
*
* @public
* @cat model
*/
jamal.extend(jamal.fn.m.prototype, {
});
+32
View File
@@ -0,0 +1,32 @@
/* SVN FILE: $Id: jamal.js 18 2007-06-13 09:07:32Z teemow $ */
/**
* To quote Dave Cardwell:
* Built on the shoulders of giants:
* * John Resig - http://jquery.com/
*
* Jamal : Javascript MVC Assembly Layout <http://jamal-mvc.com/>
* Copyright (c) 2007, Timo Derstappen <http://teemow.com/>
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright (c) 2007, Timo Derstappen
* @link
* @package jamal
* @subpackage jamal.view
* @since Jamal v 0.4
* @version $Revision: 40 $
* @modifiedby $LastChangedBy: teemow $
* @lastmodified $Date: 2007-08-20 18:24:35 +0200 (Mo, 20. Aug 2007) $
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Jamal app view
*
* @public
* @cat view
*/
jamal.extend(jamal.fn.v.prototype, {
});
+123
View File
@@ -0,0 +1,123 @@
$j.c( {
/**
* Viewport controller
*
**/
Viewport: {
index: function () {
this.loadDBKeys();
$j.v.Viewport.initTemplates();
$j.v.Viewport.initWindow();
$j.v.Viewport.initTracks();
$j.v.Viewport.initHistoryPanel();
this._registerListeners();
// initialize axis
$j.m.xAxis = new Axis();
},
/**
* Register Listeners
* @access private
**/
_registerListeners: function() {
$("a#show-history").bind("click", $j.v.Viewport.showHistory);
$("a#hide-history").bind("click", $j.v.Viewport.hideHistory);
$("select#dbkey").bind( "change", this.setDBKey );
$("select#chrom").bind( "change", this.setChrom );
$(window).bind("resize", this.redrawTracks );
},
loadDBKeys: function() {
$j.m.Data.getDBKeys( function() {
$j.v.Viewport.showDBKeys();
});
},
setDBKey: function(e) {
$j.m.Viewport.dbkey = e.target.value;
$j.m.Data.getDatasets( function() {
// Setup history
$j.v.Viewport.showDatasets();
});
$j.c.Viewport.getChroms();
},
getChroms: function() {
$j.m.Data.getChroms( $j.m.Viewport.dbkey, function() {
$j.v.Viewport.showChroms();
});
},
setChrom: function(e) {
chrom = $j.m.Viewport.chrom = e.target.value;
if( $j.m.Data.dbkeys[$j.m.Viewport.dbkey].chroms[chrom]) {
$j.m.Viewport.start = 0;
$j.m.Viewport.end = $j.m.Data.dbkeys[$j.m.Viewport.dbkey].chroms[chrom].len;
} else {
$j.m.Viewport.start = NaN;
$j.m.Viewport.end = NaN;
}
// Update data shown
for( track in $j.m.Viewport.tracks ) {
var trackObj = $j.m.Viewport.tracks[track];
$j.m.Data.getData(trackObj.datasetId, $j.m.Viewport.chrom, $j.m.Viewport.start, $j.m.Viewport.end, function(response) {
$j.m.Viewport.tracks[track].redraw();
});
}
$j.m.xAxis.redraw();
},
addTrack: function(datasetId) {
// Add a dataset track to the MVC
// Drop->receive->initTrack->this->$j.v.Viewport.addTrack
var newTrack = new Track(datasetId);
$j.log(datasetId);
var loadTrack = function () {
$j.m.Data.getDataset( datasetId, function(response) {
if( response=="data" ) {
if( $j.m.Viewport.chrom=="" ) $j.v.Viewport.getChroms();
else $j.m.Data.getData( datasetId,
$j.m.Viewport.chrom,
$j.m.Viewport.start,
$j.m.Viewport.end, function(t) {
return function() {
t.redraw();
}
}(newTrack));
} else if (response=="pending") {
setTimeout(loadTrack, 8000);
}
});
}
loadTrack();
$j.m.Viewport.tracks.push( newTrack );
$j.v.Viewport.addTrack( newTrack );
newTrack.redraw();
},
removeDataset: function(e) {
// TODO: Remove a dataset from the MVC
},
panTo: function(e) {
// TODO: Pan.
},
panBy: function(delta) {
$j.m.Viewport.start += delta;
$j.m.Viewport.end += delta;
$j.c.Viewport.redrawTracks();
},
zoomIn: function(e) {
var range = $j.m.Viewport.end - $j.m.Viewport.start;
$j.m.Viewport.end -= range / 4;
$j.m.Viewport.start += range / 4;
$j.c.Viewport.redrawTracks();
},
zoomTo: function(e) {
// TODO: zoom
},
redrawTracks: function(e) {
for( track in $j.m.Viewport.tracks ) {
$j.m.Viewport.tracks[track].redraw();
}
$j.m.xAxis.redraw();
}
}
}
);
+68
View File
@@ -0,0 +1,68 @@
$j.m( {
Viewport: {
start: NaN,
end: NaN,
dbkey: "",
chrom: "",
template: {},
tracks: []
},
Data: {
getDBKeys: function (callback) {
$j.m.Data.json("/tracks/dbkeys", function (response) {
for(item in response)
$j.m.Data.dbkeys[response[item]] = {chroms: {}};
if($j.m.Viewport.dbkey == "")
$j.m.Viewport.dbkey = response[0];
if(callback) callback(response);
});
},
getDatasets: function (callback) {
$j.m.Data.json("/tracks/list?dbkey="+$j.m.Viewport.dbkey, function (response) {
$j.m.Data.datasets = response;
if(callback) callback(response);
});
},
getChroms: function (dbkey, callback) {
$j.m.Data.json("/tracks/chroms?dbkey="+dbkey, function (response) {
for( key in response) {
if($j.m.Data.dbkeys[dbkey].chroms[key] == undefined) {
$j.m.Data.dbkeys[dbkey].chroms[key] = new Object();
}
$j.m.Data.dbkeys[dbkey].chroms[key].len = response[key];
}
if(callback) callback(response);
});
},
getData: function(dataset, chrom, start, end, callback) {
var qs = "/tracks/data";
qs += "?dataset_id=" + dataset.toString();
if(chrom != undefined) qs += "&chrom=" + chrom;
if(start != undefined) qs += "&start=" + start.toString();
if(end != undefined) qs += "&end=" + end.toString();
$j.m.Data.json(qs,
function (response) {
if($j.m.Data.dbkeys[$j.m.Viewport.dbkey].chroms[chrom] == undefined)
$j.m.Data.dbkeys[$j.m.Viewport.dbkey].chroms[chrom] = new Object();
if(response.resolution) {
if($j.m.Data.dbkeys[$j.m.Viewport.dbkey].chroms[chrom][dataset] == undefined)
$j.m.Data.dbkeys[$j.m.Viewport.dbkey].chroms[chrom][dataset] = new Object();
$j.m.Data.dbkeys[$j.m.Viewport.dbkey].chroms[chrom][dataset][response.resolution] = response;
} else {
$j.m.Data.dbkeys[$j.m.Viewport.dbkey].chroms[chrom][dataset] = response;
}
if(callback) callback(response);
});
},
getDataset: function(dataset, callback) {
var qs = "/tracks/data";
qs += "?dataset_id=" + dataset.toString();
$j.m.Data.json(qs,
function(response) {
if(callback) callback(response);
});
},
dbkeys: {},
datasets: {}
}
});
+72
View File
@@ -0,0 +1,72 @@
/*
* Requires jQuery
* testing a change for mercurial
*/
var Track = function (datasetId) {
this.elem = $($j.v.Viewport.trackTemplate).clone();
this.datasetId = datasetId;
this.titleElem = this.elem.find(".track-title");
this.titleElem.html($j.m.Data.datasets[datasetId]);
this.canvasElem = this.elem.find(".track-canvas");
console.log(this.canvasElem);
this.renderer = new FeatureRenderer(this.canvasElem.get(0), $j.m.Viewport);
// Bindings
this.canvasElem.bind( "dragstart", function (l_track) {
return function (e){
this.original_low = $j.m.Viewport.start;
};
}(this));
this.canvasElem.bind( "drag", function( l_track ) {
return function(e) {
var move_amount = ( e.offsetX - this.offsetLeft ) / this.offsetWidth;
var range = $j.m.Viewport.end - $j.m.Viewport.start;
var move_bases = Math.round( range * move_amount );
var new_low = this.original_low - move_bases;
/*if ( new_low < 0 ) {
new_low = 0;
}*/
var new_high = new_low + range;
/*if ( new_high > view.length ) {
new_high = view.length;
new_low = new_high - range;
}*/
$j.c.Viewport.panBy(new_low-$j.m.Viewport.start);
};
}(this));
this.canvasElem.bind( "dblclick", function( l_track ) {
return function(e) {
$j.c.Viewport.zoomIn();
};
}(this));
};
$.extend( Track.prototype, {
redraw: function () {
this.renderer.start = $j.m.Viewport.start;
this.renderer.end = $j.m.Viewport.end;
this.renderer.clear();
this.renderer.updateSize();
// tickDistance = Math.floor( Math.pow( 10, Math.floor( Math.log( range ) / Math.log( 10 ) ) ) )
this.renderer.xGridLines = Math.floor( Math.pow(10, Math.floor( Math.log( this.renderer.end - this.renderer.start ) / Math.log(10) ) ) );
this.renderer.drawGridLines();
this.renderer.plot( $j.m.Data.dbkeys[$j.m.Viewport.dbkey].chroms[chrom][this.datasetId] );
}
});
var Axis = function() {
this.canvasElem = $("#x-axis")[0];
this.renderer = new Renderer( this.canvasElem, $j.m.Viewport );
this.redraw = function () {
this.renderer.start = $j.m.Viewport.start;
this.renderer.end = $j.m.Viewport.end;
this.renderer.clear();
this.renderer.updateSize();
this.renderer.xGridLines = Math.floor( Math.pow(10, Math.floor( Math.log( this.renderer.end - this.renderer.start ) / Math.log(10) ) ) );
this.renderer.drawGridLines();
};
};
+79
View File
@@ -0,0 +1,79 @@
var Renderer = function (canvas, config) {
this.ctx = canvas.getContext("2d");
this.canvas = canvas;
this.updateSize();
this.start = config.start || 0;
this.end = config.end || 0;
this.yMin = config.yMin || 0;
this.yMax = config.yMax || this._height;
this.scaleX = this._width / (this.end - this.start);
this.scaleY = this._height /(this.yMax - this.yMin);
this.xGridLines = config.xGridLines || 100000;
this.xGridOffset = config.xGridOffset || 0;
};
$.extend( Renderer.prototype, {
tX: function (x) {
return ( x - this.start ) * this.scaleX;
},
tY: function (y) {
return ( y - this.yMin ) * this.scaleY;
},
drawGridLines: function() {
var lastX = this.end - (this.end % this.xGridLines) + this.xGridOffset;
this.ctx.beginPath();
this.ctx.setLineWidth(0.1);
for(i=lastX; i>this.start; i-= this.xGridLines ) {
this.ctx.moveTo( this.tX(i), 0);
this.ctx.lineTo( this.tX(i), this._height );
}
this.ctx.closePath();
this.ctx.stroke();
return true;
},
updateSize: function() {
this._width = this.ctx.canvas.width = $(this.canvas).width();
this._height = this.ctx.canvas.height = $(this.canvas).height();
this.scaleX = this._width / (this.end - this.start);
this.scaleY = this._height /(this.yMax - this.yMin);
},
clear: function() {
this.ctx.clearRect(0,0,this.ctx.canvas.width, this.ctx.canvas.height);
}
});
var PositionRenderer = function(canvas, config) {
Renderer.call( this, canvas, config );
};
var FeatureRenderer = function(canvas, config) {
Renderer.call( this, canvas, config );
this.lanes = [];
this.featureHeight = 8;
this.featurePadding = 2;
};
$.extend( FeatureRenderer.prototype, Renderer.prototype, {
drawRect: function(x1,y1,x2,y2) {
x1 = (x1 - this.start) * this.scaleX; //this.tX(x1);
x2 = (x2 - this.start) * this.scaleX; //this.tX(x2);
this.ctx.fillRect( x1, y1, Math.max(1,x2-x1), y2-y1 );
},
plot: function(features) {
var laneHeight = this.featureHeight + this.featurePadding;
this.ctx.setFillColor("#000000");
for( idx in features ) {
var feature = features[idx];
var lane = 0;
while( feature[0] < this.lanes[lane] && this.lanes[lane] != undefined ){
if( this.lanes && feature[0] < this.lanes[lane] )
lane++;
}
this.lanes[lane] = feature[1];
var yOffset = laneHeight * lane;
this.drawRect( feature[0], yOffset, feature[1], yOffset+this.featureHeight );
}
this.lanes = [];
}
});
+16
View File
@@ -0,0 +1,16 @@
$j.v({
/**
* Class Track
* Track in contianer
**/
Tracks: {
children:[],
init: function(curAddition) {
var curTemplate = $j.v.Viewport.trackTemplate.clone();
$(curTemplate).attr("id", "item_" + $("#tracks-sortable > li").length);
$(curTemplate).find(".track-title").html(curAddition.find(".history-item-title > b").html());
return curTemplate;
}
} // end class Track
});
+136
View File
@@ -0,0 +1,136 @@
$j.v({
Viewport: {
addView: function(dataset_id) {
// $("#viewport").append($j.m.Viewport.TrackTemplate.clone());
// $("div.track:last").attr("id", this.get_tid(dataset_id));
},
renderView: function(dataset_id) {
if (!$(this.get_selector(dataset_id)).length)
this.addView(dataset_id);
},
get_selector: function(dataset_id) {
return "div.track[@id=" + this.get_tid(dataset_id) + "]";
},
get_tid: function(dataset_id) {
return "t" + dataset_id.toString();
},
showDBKeys: function() {
options = '';
for( key in $j.m.Data.dbkeys ) {
options += '<option value="'+key+'">'+key+'</option>';
}
$("select#dbkey").html(options);
$("select#dbkey option:first").change();
},
showChroms: function() {
options = '';
for( key in $j.m.Data.dbkeys[$j.m.Viewport.dbkey].chroms ) {
options += '<option value="'+key+'">'+key+"</option>";
}
$("select#chrom").html(options);
$("select#chrom option:first").change();
},
showDatasets: function() {
options = '';
for( key in $j.m.Data.datasets ) {
options += '<option value="'+$j.m.Data.datasets[key]+'">'+key+"</option>";
}
$("select#datasets").html(options);
},
initTracks: function() {
$("#tracks-sortable").sortable({
handle: ".track-label",
items: 'li',
receive: function( event, ui ) {
currentAddition = $(".track-history-item"); // only one history added at one time.
$j.v.Viewport.addTrack(currentAddition);
// on recieve of item from history list
}
});
return false;
},
addTrack: function(curAddition) {
var curTemplate = $j.m.Viewport.template.clone();
$(curTemplate).attr("id", "item_" + $("#tracks-sortable > li").length);
$(curTemplate).find(".track-title").html(curAddition.find(".history-item-title > b").html());
$("#tracks-sortable .track-history-item:last").remove();
$("#tracks-sortable").append(curTemplate);
},
removeTrack:function() {
},
populateTrack: function() {
},
initHistoryPanel: function() {
//$("#drag-history").css("display", "none");
$("#tracks-history-sortable").sortable({
handle: ".history-item",
connectWith: $("#tracks-sortable"),
items: 'li',
remove: function( event, ui ) {
// on remove from history list
}
});
},
initOdometer: function() {
$("#macro-slider").slider({
range:true,
min: 0,
max: 100,
orientation: 'horizontal',
values:[20, 80],
start: function( event, ui ) {
// do blur tracks, odometers
},
slide: function( event, ui ) {
$j.log( "slide range: " + $(this).slider("values", 0) + " :: " + $(this).slider("values", 1) );
},
stop: function( event, ui ) {
// $j.log( "range: " + $(this).slider("values", 0) + " :: " + $(this).slider("values", 1) );
// $("#micro-scroll-bar").trigger("scroll");
}
});
// $("#macro-slider").bind("mousedown", function( event ) {
// if(e.pageX > $("#macro-slider").slider("values", 0) && e.pageX > $("#macro-slider").slider("values", 1) ) {
// $j.log("mouse down");
// }
// });
// $( "#micro-scroll-bar" ).bind("scroll", function( event ) {
// num = Math.floor ( Math.random() * 100 );
// $( "#micro-scroll-bar" ).slider('option', 'value', num);
// $( "#micro-scroll-content" ).css("margin-left", $("#micro-scroll-content").width() * -(num/100));
// });
//
// $( "#micro-scroll-bar" ).slider({
// orientation: 'horizontal',
// start: function( event, ui ) {
// // do blur tracks, odometers
// },
// slide: function( event, ui ) {
// scrollContent = $("#micro-scroll-content");
// scrollPane = $("#micro-scroll-pane");
// if( scrollContent.width() > scrollPane.width() ) {
// scrollContent.css('margin-left', Math.round( ui.value / 100 * ( scrollPane.width() - scrollContent.width() )) + 'px');
// }
// else {
// scrollContent.css('margin-left', 0);
// }
// },
// change: function( event, ui ) {
// // set new positions
// $j.log("end: " + ui.value);
// }
// });
this.updateOdometer();
},
updateOdometer: function() {
$j.log("updating odoemeter");
}
}
});
+107
View File
@@ -0,0 +1,107 @@
$j.v({
/**
* Class Viewport
* Entire container
**/
Viewport: {
addView: function(dataset_id) {
// $("#viewport").append($j.m.Viewport.TrackTemplate.clone());
// $("div.track:last").attr("id", this.get_tid(dataset_id));
},
initTemplates: function () {
this.historyTemplate = $(".track-history-item").remove();
this.trackTemplate = $(".track-list-item").remove();
},
showDBKeys: function() {
var options = '';
for( key in $j.m.Data.dbkeys ) {
options += '<option value="'+key+'">'+key+'</option>';
}
$("select#dbkey").html(options);
$("select#dbkey option:first").change();
},
showChroms: function() {
var options = '';
for( key in $j.m.Data.dbkeys[$j.m.Viewport.dbkey].chroms ) {
options += '<option value="'+key+'">'+key+"</option>";
}
$("select#chrom").html(options);
$("select#chrom option:first").change();
},
showDatasets: function() {
for( dataset in $j.m.Data.datasets ) {
var newDataset = $(this.historyTemplate).clone();
$("#tracks-history-sortable").append(newDataset);
var title = dataset.toString()+": "+$j.m.Data.datasets[dataset];
newDataset.find(".history-item-title > b").html(title);
newDataset.bind("initTrack", function (d) {
return function() {
$("#tracks-sortable .track-history-item:last").remove();
$j.c.Viewport.addTrack(d);
return false;
};
}(dataset));
}
},
initTracks: function() {
$j.log("initializing tracks");
$("#tracks-sortable").sortable({
handle: ".track-label",
items: 'li',
over: function( event, ui ) {
$("#tracks-sortable").css("border", "2px solid #FFee44");
},
receive: function( event, ui ) {
$("#tracks-sortable").css("border", "none");
$("#tracks-sortable .track-history-item:last").trigger("initTrack");
},
stop: function( event, ui ) {
$("#tracks-sortable").css("border", "none");
}
});
return false;
},
showHistory: function() {
$("#viewport").css("width", "80%");
$("#drag-history").css("width", "19%");
$("#drag-history").css("visibility", "visible");
},
hideHistory: function() {
$("#viewport").css("width", "100%");
$("#drag-history").css("visibility", "hidden");
},
addTrack: function(curAddition) {
//var newTrack = $j.v.Tracks.init(curAddition);
$("#tracks-sortable").append(curAddition.elem);
},
removeTrack:function(curRemoval) {
curRemoval.remove();
},
populateTrack: function() {
},
initHistoryPanel: function() {
$("#tracks-history-sortable").sortable({
handle: ".history-item",
connectWith: $("#tracks-sortable"),
items: 'li',
remove: function( event, ui ) {
// on remove from history list
}
});
this.hideHistory();
},
initWindow: function() {
$("#macro-slider").css("background", "#e6e7e8");
$("#macro-slider").append("<div id='macro-handle'></div>");
$("#macro-handle").css("width", "20%");
$("#macro-handle").css("height", "100%");
$("#macro-handle").css("background", "#cc0000");
},
updateOdometer: function() {
$j.log("updating odoemeter");
}
} // end class Viewport
});
+1
View File
@@ -0,0 +1 @@
${data_resource}
+104
View File
@@ -0,0 +1,104 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>
Galaxy
</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="${h.url_for('/static/style/base.css')}" rel="stylesheet" type="text/css" />
<script type='text/javascript' src="${h.url_for('/static/scripts/jquery.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/scripts/jquery.ui.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/scripts/jquery.event.drag.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/scripts/jquery.hoverIntent.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/scripts/jamal.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/tracks/app_model.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/tracks/app_controller.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/tracks/app_view.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/tracks/models/tracks.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/tracks/views/viewport.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/tracks/views/drawing_api.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/tracks/controllers/tracks.js')}"> </script>
<script type='text/javascript' src="${h.url_for('/static/tracks/views/components.js')}"> </script>
<link type="text/css" rel="stylesheet" href="http://ui.jquery.com/testing/themes/base/ui.all.css" />
<link href="${h.url_for('/static/tracks/app.css')}" rel="stylesheet" type="text/css" />
</head>
<body class="jamal {controller:'Viewport',action:'index',debug:true}">
<div id="viewport" class="float-left">
<div id="viewport-top" class="width-hundred-percent block overflow">
<div class="float-left width-twenty-percent">
<div id="db-tools" class="width-hundred-percent block">
<h2 class="margin-zero">db: </h2>
<select name="dbkey" id="dbkey"> </select>
<select name="chrom" id="chrom"> </select>
</div>
<div id="history-tools" class="width-hundred-percent block">
<a href="#" id="show-history" class="float-left margin-zero padding-zero">
<img src="${h.url_for('/static/images/tracks/show_history.gif')}">
</a>
</div>
</div>
<div class="float-left width-eighty-percent">
<div id="window-macro" class="width-hundred-percent block">
<div id="macro-slider"> </div>
</div>
<div id="window-micro" class="width-hundred-percent block">
<canvas id="x-axis" class="axis width-hundred-percent float-left"></canvas>
</div>
</div>
</div>
<div id="viewport-inner" class="width-hundred-percent block">
<ul id="tracks-sortable" class="width-hundred-percent padding-zero margin-zero">
<li class="track-list-item width-hundred-percent" id="item_1">
<div id="t11" class="track width-hundred-percent no-overflow margin-zero">
<div class="track-label margin-zero float-left width-twenty-percent">
<h5 class="track-title">mRNA</h5>
</div>
<div class="track-track margin-zero float-left width-eighty-percent">
<div id="track-graphics">
<canvas class="track-canvas width-hundred-percent"> </canvas>
</div>
</div>
</div>
</li>
</ul>
</div>
<div id="dock" class="padding-zero width-sixty-percent">
<ul>
<li><select name="chrom" id="chrom-select"> </select></li>
<li><input type="text" id="position-window" /></li>
<li><a id="go-btn" href="#"><img src="${h.url_for('/static/images/tracks/go_btn.gif')}"/></a></li>
<li><a id="pan-left" href="#"><img src="${h.url_for('/static/images/tracks/pan_left.gif')}"/></a></li>
<li><a id="pan-right" href="#"><img src="${h.url_for('/static/images/tracks/pan_right.gif')}"/></a></li>
<li><a id="zoom-out-full" href="#"><img src="${h.url_for('/static/images/tracks/zoom_out_full.gif')}"/></a></li>
<li><a id="zoom-out" href="#"><img src="${h.url_for('/static/images/tracks/zoom_out.gif')}"/></a></li>
<li><a id="zoom-in" href="#"><img src="${h.url_for('/static/images/tracks/zoom_in.gif')}"/></a></li>
<li><a id="zoom-in-full" href="#"><img src="${h.url_for('/static/images/tracks/zoom_in_full.gif')}"/></a></li>
</ul>
</div>
</div>
<div id="drag-history" class="float-left margin-zero">
<div id="history-control-bar" class="width-hundred-percent">
<div class="width-sixty-percent float-left">
<h3 class="margin-zero">History</h3>
</div>
<div class="width-forty-percent float-left">
<a id="hide-history" href="#">
<img src="${h.url_for('/static/images/tracks/close_btn.gif')}"/>
</a>
</div>
</div>
<ul id="tracks-history-sortable">
<li class="track-history-item" id="item_1">
<div class="history-item" id="history-item-1">
<div class="history-edit-panel"> </div>
<span class="history-item-title">
<b>3: UCSC Main on Human: knownGene (genome)</b>
<span>
</div>
</li>
</ul>
</div>
</body>
</html>
+3
View File
@@ -40,6 +40,9 @@ tool_data_path = tool-data
datatype_converters_config_file = datatype_converters_conf.xml
datatype_converters_path = %(here)s/lib/galaxy/datatypes/converters
# Datatype indexers
datatype_indexers_path = %(here)s/lib/galaxy/datatypes/indexers
# Session support (beaker)
use_beaker_session = True
session_type = file