diff --git a/bin/prepare-refseqs.pl b/bin/prepare-refseqs.pl index dd4b904dc4..55bc6b13b3 100755 --- a/bin/prepare-refseqs.pl +++ b/bin/prepare-refseqs.pl @@ -247,11 +247,8 @@ =head1 OPTIONS 'label' => $seqTrackName, 'key' => $seqTrackName, 'type' => "SequenceTrack", - 'config' => - { - 'chunkSize' => $chunkSize, - 'urlTemplate' => "$seqRel/{refseq}/", - } + 'chunkSize' => $chunkSize, + 'urlTemplate' => "$seqRel/{refseq}/", }; return $trackList; }); diff --git a/compat_121.html b/compat_121.html new file mode 100644 index 0000000000..8caf0e4fd1 --- /dev/null +++ b/compat_121.html @@ -0,0 +1,80 @@ + + + + + + JBrowse + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/index.html b/index.html index b3386629d4..1945911350 100644 --- a/index.html +++ b/index.html @@ -17,6 +17,8 @@ + + @@ -25,6 +27,13 @@ + + + + + + + @@ -46,15 +55,15 @@ var dataRoot = queryParams.data || 'data'; var b = new Browser({ containerID: "GenomeBrowser", - refSeqs: {url: dataRoot + "/seq/refSeqs.json"}, - tracklists: [ - {url: dataRoot + "/trackList.json"} + refSeqs: dataRoot + "/seq/refSeqs.json", + include: [ + dataRoot + "/trackList.json", ], nameUrl: dataRoot + "/names/root.json", defaultTracks: "DNA,gene,mRNA,noncodingRNA", queryParams: queryParams, location: queryParams.loc, - tracks: queryParams.tracks, + forceTracks: queryParams.tracks, show_nav: queryParams.nav, show_tracklist: queryParams.tracklist, show_overview: queryParams.overview diff --git a/js/ArrayRepr.js b/js/ArrayRepr.js index e33351d747..c34f128704 100644 --- a/js/ArrayRepr.js +++ b/js/ArrayRepr.js @@ -1,19 +1,34 @@ -/* - class for operating on indexed representations of objects +// MODEL + +/** + @class + @constructor + + @description + + Class for operating on indexed array representations of objects. + + For example, if we have a lot of objects with similar attrbutes, e.g.: - For example, if we have a lot of objects with similar attributes, e.g.: +
         [
             {start: 1, end: 2, strand: -1},
             {start: 5, end: 6, strand: 1},
             ...
         ]
+    
+ + @description we can represent them more compactly (e.g., in JSON) something like this: + +
         class = ["start", "end", "strand"]
         [
             [1, 2, -1],
             [5, 6, 1],
             ...
         ]
+    
If we want to represent a few different kinds of objects in our big list, we can have multiple "class" arrays, and tag each object to identify @@ -21,6 +36,8 @@ For example, if we have a lot of instances of a few types of objects, like this: + +
         [
             {start: 1, end: 2, strand: 1, id: 1},
             {start: 5, end: 6, strand: 1, id: 2},
@@ -29,8 +46,12 @@
             {start: 30, end: 40, chunk: 2},
             ...
         ]
+    
+ We could use the first array position to indicate the "class" for the object, like this: + +
         classes = [["start", "end", "strand", "id"], ["start", "end", "chunk"]]
         [
             [0, 1, 2, 1, 1],
@@ -39,13 +60,18 @@
             [1, 10, 20, 1],
             [1, 30, 40, 1]
         ]
+    
+ Also, if we occasionally want to add an ad-hoc attribute, we could just stick an optional dictionary onto the end: + +
         classes = [["start", "end", "strand", "id"], ["start", "end", "chunk"]]
         [
             [0, 1, 2, 1, 1],
             [0, 5, 6, 1, 2, {foo: 1}]
         ]
+    
Given that individual objects are being represented by arrays, generic code needs some way to differentiate arrays that are meant to be objects @@ -59,15 +85,15 @@ In the end, we get something like this: +
         classes=[
             {'attributes': ['Start', 'End', 'Subfeatures'],
              'proto': {'Chrom': 'chr1'},
              'isArrayAttr': {Subfeatures: true}}
             ]
+    
That's what this class facilitates. - """ - */ function ArrayRepr (classes) { this.classes = classes; @@ -84,6 +110,9 @@ function ArrayRepr (classes) { } } +/** + * @private + */ ArrayRepr.prototype.attrIndices = function(attr) { return this.classes.map( function(x) { @@ -107,12 +136,6 @@ ArrayRepr.prototype.get = function(obj, attr) { } }; -ArrayRepr.prototype.fastGet = function(obj, attr) { - // can be used only if attr is guaranteed to be in - // the "classes" array for this object - return obj[self.fields[obj[0]][attr]]; -}; - ArrayRepr.prototype.set = function(obj, attr, val) { if (attr in this.fields[obj[0]]) { obj[this.fields[obj[0]][attr]] = val; @@ -124,12 +147,6 @@ ArrayRepr.prototype.set = function(obj, attr, val) { } }; -ArrayRepr.prototype.fastSet = function(obj, attr, val) { - // can be used only if attr is guaranteed to be in - // the "classes" array for this object - obj[this.fields[obj[0]][attr]] = val; -}; - ArrayRepr.prototype.makeSetter = function(attr) { var self = this; return function(obj, val) { self.set(obj, attr, val); }; @@ -170,6 +187,91 @@ ArrayRepr.prototype.construct = function(self, obj, klass) { return result; }; + +/** + +Returns fast pre-compiled getter and setter functions for use with +Arrays that use this representation. + +When the returned get and set functions are +added as methods to an Array that contains data in this +representation, they provide fast access by name to the data. + +@returns {Object} { get: function() {...}, set: function(val) {...} } + +@example +var accessors = attrs.accessors(); +var feature = get_feature_from_someplace(); +feature.get = accessors.get; +// print out the feature start and end +console.log( feature.get('start') + ',' + feature.get('end') ); + +*/ +ArrayRepr.prototype.accessors = function () { + return this._accessors = this._accessors || this._makeAccessors(); +}; + +/** + * @private + */ +ArrayRepr.prototype._makeAccessors = function() { + var that = this, + accessors = { + get: function(field) { + var f = this.get.field_accessors[field]; + if( f ) + return f.call(this); + else + return undefined; + }, + set: function(field,val) { + var f = this.set.field_accessors[field]; + if( f ) + return f.call(this,val); + else + return undefined; + } + }; + accessors.get.field_accessors = {}; + accessors.set.field_accessors = {}; + + // make a data structure as: { attr_name: [offset,offset,offset], } + // that will be convenient for finding the location of the attr + // for a given class like: indexForAttr{attrname}[classnum] + var indices = {}; + dojo.forEach( this.classes, function(cdef,classnum) { + dojo.forEach( cdef.attributes || [], function(attrname,offset) { + attrname = attrname.toLowerCase(); + indices[attrname] = indices[attrname] || []; + indices[attrname][classnum] = offset + 1; + }); + }); + + // use that to make precalculated get and set accessors for each field + for( var attrname in indices ) { + if( ! indices.hasOwnProperty(attrname) ) continue; + + // get + accessors.get.field_accessors[ attrname ] = (function() { + var attr_indices = indices[attrname]; + return !attr_indices ? function() { return undefined; } : function() { + return this[ attr_indices[ this[0] ] ]; + }; + })(); + + // set + accessors.set.field_accessors[ attrname ] = (function() { + var attr_indices = indices[attrname]; + return !attr_indices ? function() { return undefined; } : function(v) { + return ( this[ attr_indices[ this[0] ] ] = v ); + }; + })(); + } + + + return accessors; +}; + /* Copyright (c) 2007-2010 The Evolutionary Software Foundation diff --git a/js/Browser.js b/js/Browser.js index 4ede46b126..aadaa54b0c 100644 --- a/js/Browser.js +++ b/js/Browser.js @@ -1,12 +1,14 @@ +// CONTROLLER + /** * Construct a new Browser object. * @class This class is the main interface between JBrowse and embedders * @constructor * @param params an object with the following properties:
*