Customizing feature colors
Set a track's color in displayDefaults as a plain CSS color, an object that
paints each value of a field with a key, or a jexl: expression. When the logic
outgrows one jexl line, add a function to the jexl language with a small plugin
and call it from your callback.
The object forms (a color per type, chosen colors, a threshold, a gradient)
are in the cookbook. Past those, a plugin file
registers a function and the callback calls it:
{
"plugins": [
{
"name": "MyPlugin",
"esmLoc": { "uri": "myplugin.js" }
}
],
"tracks": [
{
"type": "FeatureTrack",
"trackId": "my_track",
"name": "my track",
"assemblyNames": ["hg19"],
"adapter": {
"type": "Gff3Adapter",
"uri": "volvox.filtered.gff"
},
"displayDefaults": { "color": "jexl:customColor(feature)" }
}
]
}The
no-build plugin tutorial
is the myplugin.js that defines customColor: a single file beside the
config, no build step. In a jexl expression the feature's attributes are plain
properties (feature.type); in the plugin's JavaScript the same feature is a
SimpleFeature, read with feature.get('type')
(property access vs get()).
Named BED columns past name/score/strand (itemRgb, thickStart, ...)
are only guaranteed for BED12 or a track with an autoSql/columnNames. For a
BED7-BED11 file JBrowse cannot know what the extra columns mean, so it exposes
them generically as field6, field7, ... and feature.itemRgb reads as
undefined in a jexl callback. Set columnNames to refer to them by name.
An unset color paints each
feature from the colors a BED has, under whichever of those names they land, so
a callback is only needed to override that.
Reading the type list off the file
A color object with chosen colors per type is only as good as its domain,
so read the types off the file. The /^##FASTA/{exit} stops before any inline
sequence, whose lines have no # and would otherwise count as types:
awk -F'\t' '/^##FASTA/{exit} !/^#/{print $3}' annotations.gff |
sort | uniq -c | sort -rnA type the domain does not list takes the next palette color and a separate
row in the key, so an unexpected row there is the signal to go back to that
list. A worked case: the
EBI mobilome annotation pipeline
writes a GFF whose column 3 holds mobile element types (published per genome
under MGnify's
mgnify_genomes
as <accession>_mobilome.gff), so with no color the whole mobilome paints one
color. One color object separates the element classes and greys the passenger
CDSs back:
Goes in the tracks array of config.json. See Tracks.
{
"trackId": "mobilome",
"name": "Mobilome",
"uri": "MGYG000000001_mobilome.gff",
"assemblyNames": ["MGYG000000001"],
"displayDefaults": {
"color": {
"field": "type",
"domain": [
"prophage",
"viral_sequence",
"plasmid",
"insertion_sequence",
"terminal_inverted_repeat_element",
"inverted_repeat_element",
"integron",
"conjugative_integron",
"attC_site",
"compositional_outlier",
"direct_repeat",
"CDS"
],
"range": [
"#8e44ad",
"#9b59b6",
"#2980b9",
"#e67e22",
"#d35400",
"#d35400",
"#16a085",
"#1abc9c",
"#0e6655",
"#c0392b",
"#7f8c8d",
"#bdc3c7"
]
}
}
}jbrowse add-track MGYG000000001_mobilome.gff \
--trackId mobilome \
--name Mobilome \
--assemblyNames MGYG000000001 \
--displayDefaults '{"color":{"field":"type","domain":["prophage","viral_sequence","plasmid","insertion_sequence","terminal_inverted_repeat_element","inverted_repeat_element","integron","conjugative_integron","attC_site","compositional_outlier","direct_repeat","CDS"],"range":["#8e44ad","#9b59b6","#2980b9","#e67e22","#d35400","#d35400","#16a085","#1abc9c","#0e6655","#c0392b","#7f8c8d","#bdc3c7"]}}' \
--load copyIn JBrowse Desktop, or in any running JBrowse Web session, open a view on this track’s assembly, then File → Open track..., choose Add track from pasted JSON, and paste:
{
"trackId": "mobilome",
"name": "Mobilome",
"uri": "MGYG000000001_mobilome.gff",
"assemblyNames": ["MGYG000000001"],
"displayDefaults": {
"color": {
"field": "type",
"domain": [
"prophage",
"viral_sequence",
"plasmid",
"insertion_sequence",
"terminal_inverted_repeat_element",
"inverted_repeat_element",
"integron",
"conjugative_integron",
"attC_site",
"compositional_outlier",
"direct_repeat",
"CDS"
],
"range": [
"#8e44ad",
"#9b59b6",
"#2980b9",
"#e67e22",
"#d35400",
"#d35400",
"#16a085",
"#1abc9c",
"#0e6655",
"#c0392b",
"#7f8c8d",
"#bdc3c7"
]
}
}
}MGYG000000001_mobilome.gff is relative to a config.json. Replace it with its URL or its path on this computer.
unknowngreys the rest in one go."unknown": "#bdc3c7"in place of theCDSentry paints every type thedomainleaves out that grey, and the key names them one row, Other. An unexpected type then gets no separate row, so the key no longer signals that the type list needs checking.- Two names for the repeat flanks because the pipeline renamed the type across releases, and a file uses whichever name its release used. A renamed type is the usual reason a key is missing.
- The sequence is inline after
##FASTA.Gff3Adapterstops at that marker, so the whole file loads as-is. For abgzip/tabixtrack, cut the file there first: the sequence lines are not tab-delimited and tabix cannot skip them.
See also
- Config guide: Using jexl callbacks
- Config guide: Customizing feature details
- Developer guide: No-build plugin tutorial