-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Coloring BAM reads by strand with mismatch highlights #72
Merged
Merged
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
3701d7e
Add option to show only mismatches.
7af149e
Show dots instead of matches.
37b00b3
Distinguish between feature orientation.
3044c5c
color strands, change del to # char
d077cfc
changed drawing for svg export
ec1f870
change color scheme, show quality for non-ref bases
5823cf0
changed strand colors to match igv
82ebd69
Merge pull request #1 from dev/color_strands_differently
69e758e
Bug fix for uncollapsing super groups
cd13c6b
Merge pull request #2 from dev/fix_uncollapsing_supergroup
54afe9d
first pass at making read drawing faster
f91be2c
color change, retain ref qual at max zoom
025fa21
add option to change strand color dynamically
1e8df3d
consolidate SVG drawing and colors
12d1e8b
change typo in colors
0c04cce
Merge branch 'master' into counsyl
ab42444
change hardcoding for bases in drawing
d265bf9
merging master to branch after resolving conflicts
5317ed2
bug fix related to merge conflict
e9f08b0
Merge branch 'opensource_master' into opensource_color_strands
635177e
Merge branch 'opensource_master' into opensource_color_strands
fbde313
tighten tier edit options
495e05d
Merge branch 'opensource_master' into opensource_color_strands
cf11be6
style cleanup
43ddec0
style cleanup
f2f2b30
tighten color edit options
1ba54c9
style cleanup
3251907
adjust args to SequenceGlyph constructor
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1015,15 +1015,22 @@ TextGlyph.prototype.toSVG = function() { | |
|
||
var isRetina = window.devicePixelRatio > 1; | ||
var __dalliance_SequenceGlyphCache = {}; | ||
var altPattern = new RegExp('^[ACGT-]$'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, the deletion character |
||
var isCloseUp = function(scale) { | ||
return scale >= 8; | ||
} | ||
|
||
function SequenceGlyph(baseColors, min, max, height, seq, ref, scheme, quals) { | ||
this.baseColors = baseColors; | ||
function SequenceGlyph(colorStyle, min, max, height, seq, ref, orientation, scheme, quals) { | ||
this.baseColors = colorStyle.baseColors; | ||
this.plusColor = colorStyle.plusColor || "lightsalmon"; | ||
this.minusColor = colorStyle.minusColor || "lightskyblue"; | ||
this._min = min; | ||
this._max = max; | ||
this._height = height; | ||
this._seq = seq; | ||
this._ref = ref; | ||
this._scheme = scheme; | ||
this._orientation = orientation; | ||
this._quals = quals; | ||
} | ||
|
||
|
@@ -1038,35 +1045,48 @@ SequenceGlyph.prototype.alphaForQual = function(qual) { | |
|
||
SequenceGlyph.prototype.draw = function(gc) { | ||
var seq = this._seq; | ||
|
||
var ref = this._ref; | ||
|
||
var seqLength = seq ? seq.length : (this._max - this._min + 1); | ||
var scale = (this._max - this._min + 1) / seqLength; | ||
|
||
if (this._scheme === 'mismatch' && !isCloseUp(scale)) { | ||
var readColor = this._orientation === '+' ? this.plusColor : this.minusColor; | ||
gc.fillStyle = readColor; | ||
gc.fillRect(this._min, this._height/4, this._max-this._min, this._height/2); | ||
} | ||
|
||
for (var p = 0; p < seqLength; ++p) { | ||
var base = seq ? seq.substr(p, 1).toUpperCase() : 'N'; | ||
|
||
if (!altPattern.test(base) && !isCloseUp(scale)) | ||
continue; | ||
|
||
var color = this.baseColors[base]; | ||
if (!color) { | ||
color = 'gray'; | ||
} | ||
|
||
if (this._scheme === 'mismatch' && this._ref) { | ||
var refbase = this._ref.substr(p, 1).toUpperCase(); | ||
if (refbase === 'N') { | ||
color = 'gray'; | ||
} else if (refbase === base) { | ||
color = 'black'; | ||
} else { | ||
color = 'red'; | ||
} | ||
} | ||
|
||
if (this._quals) { | ||
var qc = this._quals.charCodeAt(p) - 33; | ||
var oldAlpha = gc.globalAlpha; // NB hoisted! | ||
gc.globalAlpha = this.alphaForQual(qc); | ||
} | ||
|
||
if (scale >= 8) { | ||
if (!color) { | ||
var refBase = ref ? ref.substr(p, 1).toUpperCase() : 'N'; | ||
if (base == 'N' || refBase == 'N') | ||
color = 'gray'; | ||
else if (this._orientation == '+') | ||
color = this.plusColor; | ||
else if (this._orientation == '-') | ||
color = this.minusColor; | ||
else | ||
color = 'white'; | ||
} | ||
|
||
gc.fillStyle = color; | ||
|
||
gc.fillRect(this._min + p*scale, 0, scale, this._height); | ||
|
||
if (isCloseUp(scale) && altPattern.test(base)) { | ||
var key = color + '_' + base | ||
var img = __dalliance_SequenceGlyphCache[key]; | ||
if (!img) { | ||
|
@@ -1082,18 +1102,15 @@ SequenceGlyph.prototype.draw = function(gc) { | |
if (isRetina) { | ||
imgGc.scale(2, 2); | ||
} | ||
imgGc.fillStyle = color; | ||
imgGc.fillStyle = 'black'; | ||
imgGc.fillText(base, 0, 8); | ||
__dalliance_SequenceGlyphCache[key] = img; | ||
} | ||
if (isRetina) | ||
gc.drawImage(img, this._min + p*scale, 0, 8, 10); | ||
else | ||
gc.drawImage(img, this._min + p*scale, 0); | ||
} else { | ||
gc.fillStyle = color; | ||
gc.fillRect(this._min + p*scale, 0, scale, this._height); | ||
} | ||
} | ||
|
||
if (this._quals) { | ||
gc.globalAlpha = oldAlpha; | ||
|
@@ -1103,25 +1120,24 @@ SequenceGlyph.prototype.draw = function(gc) { | |
|
||
SequenceGlyph.prototype.toSVG = function() { | ||
var seq = this._seq; | ||
var ref = this._ref; | ||
var scale = (this._max - this._min + 1) / this._seq.length; | ||
var g = makeElementNS(NS_SVG, 'g'); | ||
|
||
for (var p = 0; p < seq.length; ++p) { | ||
var base = seq.substr(p, 1).toUpperCase(); | ||
var color = baseColors[base]; | ||
if (!color) { | ||
color = 'gray'; | ||
} | ||
var base = seq ? seq.substr(p, 1).toUpperCase() : 'N'; | ||
var color = this.baseColors[base]; | ||
|
||
if (this._scheme === 'mismatch' && this._ref) { | ||
var refbase = this._ref.substr(p, 1).toUpperCase(); | ||
if (refbase === 'N') { | ||
if (!color) { | ||
var refBase = ref ? ref.substr(p, 1).toUpperCase() : 'N'; | ||
if (base == 'N' || refBase == 'N') | ||
color = 'gray'; | ||
} else if (refbase === base) { | ||
color = 'black'; | ||
} else { | ||
color = 'red'; | ||
} | ||
else if (this._orientation == '+') | ||
color = this.plusColor; | ||
else if (this._orientation == '-') | ||
color = this.minusColor; | ||
else | ||
color = 'white'; | ||
} | ||
|
||
var alpha = 1.0; | ||
|
@@ -1130,23 +1146,22 @@ SequenceGlyph.prototype.toSVG = function() { | |
alpha = this.alphaForQual(qc); | ||
} | ||
|
||
if (scale >= 8) { | ||
g.appendChild( | ||
makeElementNS(NS_SVG, 'text', base, { | ||
x: this._min + p*scale, | ||
y: 8, | ||
fill: color, | ||
fillOpacity: alpha})); | ||
} else { | ||
g.appendChild( | ||
makeElementNS(NS_SVG, 'rect', null, { | ||
x:this._min + p*scale, | ||
y: 0, | ||
width: scale, | ||
height: this._height, | ||
fill: color, | ||
fillOpacity: alpha})); | ||
g.appendChild( | ||
makeElementNS(NS_SVG, 'rect', null, { | ||
x:this._min + p*scale, | ||
y: 0, | ||
width: scale, | ||
height: this._height, | ||
fill: color, | ||
fillOpacity: alpha})); | ||
|
||
if (isCloseUp(scale) && altPattern.test(base)) { | ||
g.appendChild( | ||
makeElementNS(NS_SVG, 'text', base, { | ||
x: this._min + p*scale, | ||
y: 8, | ||
fill: 'black', | ||
fillOpacity: alpha})); | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps there could be an option to customize these colors.
Also, the
'-'
character denoting deletion is currently just hardcoded here, which is probably not ideal.