Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/GMOD/jbrowse
Browse files Browse the repository at this point in the history
  • Loading branch information
Erik Derohanian committed Sep 28, 2012
2 parents 8f90c3f + 59c5d29 commit b41065b
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 501 deletions.
4 changes: 4 additions & 0 deletions bin/add-track-json.pl
Expand Up @@ -2,6 +2,10 @@
use strict;
use warnings;

use FindBin qw($RealBin);
use lib "$RealBin/../src/perl5";
use JBlibs;

use Pod::Usage;

use JSON 2;
Expand Down
9 changes: 9 additions & 0 deletions main.css
Expand Up @@ -11,6 +11,10 @@ html, body {
color: #aaa;
}

.dijitDialogPaneActionBar {
text-align: right;
}

.nav {
vertical-align: middle;
z-index: 10;
Expand Down Expand Up @@ -268,6 +272,11 @@ div.track-label, div.tracklist-label {
/* NOTE: browsers that don't support rgba colors will fall back to all
track labels being #bcbcbc */

.notfound-dialog .message {
margin: 1em;
text-align: center;
}

div.track-label {
color: black;
margin: 5px 0 0 3px;
Expand Down
19 changes: 19 additions & 0 deletions release-notes.txt
@@ -1,5 +1,24 @@
{{$NEXT}}

* Fixed "Can't locate JSON.pm" errors with add-track-json.pl.

* Added a reference-sequence-selection dropdown box, similar to the
old one, that is on by default if fewer than 30 reference
sequences, otherwise it's off unless `refSeqDropdown: true` is set
in the configuration (issue #138).

* Fixed bug in which popup dialog boxes showing other websites showed
the website in only the top portion of the dialog box. Only
present in some browsers (issue #149).

* Fix coordinate display bug in feature detail popups. The feature's
position was being displayed in interbase coordinates, but should
be displayed in 1-based coordinates. Thanks to Steffi Geisen for
pointing this out.

* Added a `style.height` option to Wiggle tracks to control the
track's height in pixels (issue #131). (Erik Derohanian)

* Added support for a `style.trackLabelCss` configuration variable to
allow customizing the appearance of the label for a particular
track (issue #4).
Expand Down
46 changes: 45 additions & 1 deletion src/JBrowse/Browser.js
Expand Up @@ -3,11 +3,14 @@ var _gaq = _gaq || []; // global task queue for Google Analytics
define( [
'dojo/_base/lang',
'dojo/topic',
'dojo/aspect',
'dojo/_base/array',
'dijit/layout/ContentPane',
'dijit/layout/BorderContainer',
'dijit/Dialog',
'dijit/form/ComboBox',
'dijit/form/Button',
'dijit/form/Select',
'JBrowse/Util',
'JBrowse/Store/LazyTrie',
'JBrowse/Store/Autocomplete',
Expand All @@ -18,11 +21,14 @@ define( [
function(
lang,
topic,
aspect,
array,
dijitContentPane,
dijitBorderContainer,
dijitDialog,
dijitComboBox,
dijitButton,
dijitSelectBox,
Util,
LazyTrie,
AutocompleteStore,
Expand Down Expand Up @@ -729,9 +735,11 @@ Browser.prototype.navigateTo = function(loc) {
} catch (x) {}
if( oldLoc ) {
this.navigateToLocation( oldLoc );
return;
} else {
// if we don't just go to the middle 80% of that refseq
this.navigateToLocation({ref: ref.name, start: ref.end*0.1, end: ref.end*0.9 });
return;
}
}

Expand Down Expand Up @@ -816,7 +824,27 @@ Browser.prototype.searchNames = function( /**String*/ loc ) {
+ ":" + (startbp - flank)
+ ".." + (endbp + flank));
brwsr.showTracks(brwsr.names.extra[nameMatches[0][ post1_4 ? 1 : 0 ]]);
});
},
// if no match for the name is found, show a popup dialog saying this.
function() {
var d = dijitDialog({ title: 'Not found', className: 'notfound-dialog' });

var content = dojo.create('div', {
className: 'message',
innerHTML: 'Not found: <span class="locString">'+loc+'</span>'
});

var actionBar = dojo.create( 'div', { className: 'dijitDialogPaneActionBar' });
new dijitButton({label: 'OK', onClick: dojo.hitch(d,'hide')}).placeAt(actionBar);

d.set('content',[content,actionBar]);

// clean up this dialog completely when it's hidden
aspect.after(d, 'hide', function() { d.destroyRecursive(); });

d.show();
}
);
};


Expand Down Expand Up @@ -1299,6 +1327,22 @@ Browser.prototype.createNavBox = function( parent, locLength ) {

navbox.appendChild(document.createTextNode( four_nbsp ));

// if we have fewer than 30 ref seqs, or `refSeqDropdown: true` is
// set in the config, then put in a dropdown box for selecting
// reference sequences
if( this.refSeqOrder.length && this.refSeqOrder.length < 30 || this.config.refSeqDropdown ) {
this.refSeqSelectBox = new dijitSelectBox({
name: 'refseq',
options: array.map( this.refSeqOrder || [],
function( refseqName ) {
return { label: refseqName, value: refseqName };
}),
onChange: dojo.hitch(this, function( newRefName ) {
this.navigateToLocation({ ref: newRefName });
})
}).placeAt( navbox );
}

// make the location box
this.locationBox = new dijitComboBox(
{
Expand Down
39 changes: 27 additions & 12 deletions src/JBrowse/Store/LazyTrie.js
Expand Up @@ -138,26 +138,36 @@ return declare('JBrowse.Store.LazyTrie', null,
return results;
},

exactMatch: function(key, callback) {
exactMatch: function(key, callback, notfoundCallback ) {
notfoundCallback = notfoundCallback || function() {};

var trie = this;
this.findNode(key, function(prefix, node) {
this.findNode(key,
function(prefix, node) {
if ((prefix.toLowerCase() == key.toLowerCase()) && node[1])
callback(node[1]);
});
},
notfoundCallback
);
},

findNode: function(query, callback) {
findNode: function(query, foundCallback, notfoundCallback ) {
notfoundCallback = notfoundCallback || function() {};

var trie = this;
this.findPath(query, function(path) {
var node = trie.root;
for (i = 0; i < path.length; i++)
for (var i = 0; i < path.length; i++)
node = node[path[i]];
var foundPrefix = trie.pathToPrefix(path);
callback(foundPrefix, node);
});
foundCallback(foundPrefix, node);
}, notfoundCallback);
},

findPath: function(query, callback) {
findPath: function(query, foundCallback, notfoundCallback) {

notfoundCallback = notfoundCallback || function() {};

if (!this.root) {
this.deferred = arguments;
return;
Expand All @@ -171,7 +181,10 @@ return declare('JBrowse.Store.LazyTrie', null,

while(true) {
childIndex = this.binarySearch(node, query.charAt(qStart));
if (childIndex < 0) return;
if (childIndex < 0) {
notfoundCallback();
return;
}
path.push(childIndex);

if ("number" == typeof node[childIndex][0]) {
Expand All @@ -181,7 +194,7 @@ return declare('JBrowse.Store.LazyTrie', null,
handleAs: "json",
load: function(o) {
node[childIndex] = o;
trie.findPath(query, callback);
trie.findPath(query, foundCallback);
}
});
return;
Expand All @@ -194,14 +207,16 @@ return declare('JBrowse.Store.LazyTrie', null,
// match
if (query.substr(qStart, node[0].length)
!= node[0].substr(0, Math.min(node[0].length,
query.length - qStart)))
query.length - qStart))) {
notfoundCallback();
return;
}

qStart += node[0].length;
if (qStart >= query.length) {
// we've reached the end of the query string, and we
// have some matches
callback(path);
foundCallback(path);
return;
}
}
Expand Down
24 changes: 13 additions & 11 deletions src/JBrowse/View/Track/HTMLFeatures.js
Expand Up @@ -144,7 +144,7 @@ var HTMLFeatures = declare( BlockBased,
container.innerHTML += fmt( 'Name', f.get('name') );
container.innerHTML += fmt( 'Type', f.get('type') );
container.innerHTML += fmt( 'Description', f.get('note') );
container.innerHTML += fmt( 'Position', this.refSeq.name+':'+f.get('start')+'..'+f.get('end') );
container.innerHTML += fmt( 'Position', Util.assembleLocString({ start: f.get('start'), end: f.get('end'), ref: this.refSeq.name }));
container.innerHTML += fmt( 'Strand', {'1':'+', '-1': '-', 0: undefined }[f.get('strand')] || f.get('strand') );

var additionalTags = array.filter( f.tags(), function(t) { return ! {name:1,start:1,end:1,strand:1,note:1,subfeatures:1,type:1}[t.toLowerCase()]; });
Expand Down Expand Up @@ -972,16 +972,18 @@ var HTMLFeatures = declare( BlockBased,
onclick: dojo.hitch(dialog,'hide'),
innerHTML: spec.url
}, dialog.titleBar );
aspect.after( dialog, 'layout', function() {
// hitch a ride on the dialog box's
// layout function, which is called on
// initial display, and when the window
// is resized, to keep the iframe
// sized to fit exactly in it.
var cDims = domGeom.getMarginBox( dialog.domNode );
iframe.width = cDims.w;
iframe.height = iframe.height = cDims.h - domGeom.getMarginBox(dialog.titleBar).h - 2;
});
var updateIframeSize = function() {
// hitch a ride on the dialog box's
// layout function, which is called on
// initial display, and when the window
// is resized, to keep the iframe
// sized to fit exactly in it.
var cDims = domGeom.getMarginBox( dialog.domNode );
iframe.width = cDims.w;
iframe.height = cDims.h - domGeom.getMarginBox(dialog.titleBar).h - 2;
};
aspect.after( dialog, 'layout', updateIframeSize );
aspect.after( dialog, 'show', updateIframeSize );
}

aspect.after( dialog, 'hide', function() { dialog.destroyRecursive(); });
Expand Down
15 changes: 11 additions & 4 deletions src/perl5/Bio/JBrowse/Cmd/FormatSequences.pm
Expand Up @@ -18,7 +18,8 @@ use File::Path 'mkpath';

use POSIX;

use JsonGenerator;
use JSON 2;
use JsonFileStorage;
use FastaDatabase;

sub option_defaults {(
Expand Down Expand Up @@ -46,6 +47,8 @@ sub run {
my $refs = $self->opt('refs');
my $compress = $self->opt('compress');

$self->{storage} = JsonFileStorage->new( $self->opt('out'), $self->opt('compress'), { pretty => 0 } );

pod2usage( 'must provide either a --fasta, --gff, or --conf option' )
unless defined $self->opt('gff') || $self->opt('conf') || $self->opt('fasta');

Expand Down Expand Up @@ -102,7 +105,11 @@ sub run {
$refs = join (",", $db->seq_ids);
}
} elsif ( $self->opt('conf') ) {
my $config = JsonGenerator::readJSON( $self->opt('conf') );
my $config = decode_json( do {
local $/;
open my $f, '<', $self->opt('conf') or die "$! reading ".$self->opt('conf');
scalar <$f>
});

eval "require $config->{db_adaptor}; 1" or die $@;

Expand Down Expand Up @@ -189,7 +196,7 @@ sub run {
exit;
}

JsonGenerator::modifyJsonFile( catfile( $self->opt('out'), 'seq', 'refSeqs.json' ),
$self->{storage}->modify( 'seq/refSeqs.json',
sub {
#add new ref seqs while keeping the order
#of the existing ref seqs
Expand Down Expand Up @@ -219,7 +226,7 @@ sub run {
}

unless( $self->opt('noseq') ) {
JsonGenerator::modifyJsonFile( catfile( $self->opt('out'), "trackList.json" ),
$self->{storage}->modify( 'trackList.json',
sub {
my $trackList = shift;
unless (defined($trackList)) {
Expand Down
4 changes: 3 additions & 1 deletion src/perl5/JsonFileStorage.pm
Expand Up @@ -30,6 +30,8 @@ use IO::File;
use Fcntl ":flock";
use PerlIO::gzip;

use constant DEFAULT_MAX_JSON_DEPTH => 2048;

=head2 new( $outDir, $compress, \%opts )
Constructor. Takes the directory to work with, boolean flag of
Expand All @@ -44,7 +46,7 @@ sub new {
my ($class, $outDir, $compress, $opts) = @_;

# create JSON object
my $json = JSON->new->relaxed;
my $json = JSON->new->relaxed->max_depth( DEFAULT_MAX_JSON_DEPTH );
# set opts
if (defined($opts) and ref($opts) eq 'HASH') {
for my $method (keys %$opts) {
Expand Down

0 comments on commit b41065b

Please sign in to comment.