Create a BioJS component that displays a barchart that visualizes de contribution of the bases of a biological sequence.
CAGTGCATGatACGTCAGTGCATGCTGGGGGGGGGgcatgcatgcatgCC
Not much!
There are only 3 requirements to be in the BioJS registry:
biojs
needs to be included in the package.jsonAnd a few conventions:
biojs-[io/rest/vis/algo/…]-[name]
But there are many common parts among BioJS components:
$ npm install -g slush
$ slush -v
[slush] 1.1.1
$ npm install -g slush-biojs
$ mkdir biojs-vis-example
$ cd biojs-vis-example
$ slush biojs
[slush] Using slushfile /usr/local/lib/node_modules/slush-biojs/slushfile.js
[16:53:59] Starting 'biojs:default'...
? Module name? (required) biojs-vis-example
? Description? Creating a basic example for biojs
? Module version? 0.1.0
? Author name? gsalazar
? Author email? gsalazar@ebi.ac.uk
? Github username? 4ndr01d3
? Keywords for npm (separate with comma) biojs,barchart,d3
? A visualization lib? Yes
? Unit tests: No
? Add a example css file? No
? Configure a build system? (Gulp) No
? Linting (Check code style with JSHint) No
? Choose your license type: Apache-2.0
? Is this correct? Yes
Available npm commands:
$ npm run build
$ npm run sniper
$ npm run test
$ npm run watch
$ npm run w
...
running: http://localhost:9090
...
Keep npm run w
running.
Open the example file biojs-vis-example/examples/simple.js
in your favourite editor:
// if you don't specify a html file, the sniper will generate a div with id "rootDiv"
var app = require("biojs-vis-example");
var instance = new app({el: rootDiv, text: 'biojs'});
Then try changing the text
option and refreshing your browser.
The npm run w
action, detects changes in your files, re-bundles the biojs-vis-example/build/example.js
file, and exposes the result on http://localhost:9090/examples/simple
Task: Add an style file.
Create a CSS file in this path: biojs-vis-example/css/main.css
.header {
font-weight: bold;
color: green;
}
Add the following line at the end of the biojsvisexample()
function, in the JavaScript file: biojs-vis-example/lib/index.js
this.el.setAttribute("class", "header");
Include the style file in the npm file: biojs-vis-example/package.json
"...
sniper": {
"js": [ "/build/example.js"],
"css": [ "/css/main.css"],
"snippets": ["examples"],
"first": "simple"
},
...
This requires to restart npm run w
for the sniper to consider the new file
https://nodejs.org/api/modules.html
Files and modules are in one-to-one correspondence.
Export 1 object per file, assigning it to module.exports
. For example the file biojs-vis-example/lib/example.js
:
module.exports = " - from another module";
And to import it in another file you can use the function require()
. For example in the file biojs-vis-example/lib/index.js
:
var example = require("./example.js");
console.log(example); // - from another module
Remove the functionality of displaying "Hello BioJS"
and make it show "BARCHART"
, but the code should be in a separate module.
biojs-vis-example/lib/barchart.js
:
var Barchart = function(opts) {
var container = opts.el;
container.textContent = "BARCHART";
container.setAttribute("class", "header");
}
module.exports = Barchart;
biojs-vis-example/lib/index.js
:
var biojsvisexample;
var Barchart = require("./barchart.js");
module.exports = biojsvisexample = function(opts){
var bc = new Barchart(opts);
};
Using npm is possible to install any module that is in the repository. For example:
$ npm i d3 --save
And then you can use it as a module in your files with:
var d3 = require('d3');
Refactor your code to use D3 to manipulate your DOM.
biojs-vis-example/lib/barchart.js
:
var d3 = require("d3");
var Barchart = function(opts) {
var container = opts.el;
d3.select(container)
.attr("class", "header")
.text("Space for a barchart with D3!");
}
module.exports = Barchart;
Given a sequence in your options, count how many times each base appears in it, and then display this values in the page.
biojs-vis-example/examples/simple.js
:
var app = require("biojs-vis-example");
var instance = new app({el: rootDiv, sequence: "CAGTGCATGatACGTCAGTGCATGCTGGGGGGGGGgcatgcatgcatg"});
biojs-vis-example/lib/barchart.js
:
var getBases = function(sequence) {
var s = sequence.toUpperCase();
var bases = {};
for (var i =0;i<s.length;i++){
if (typeof bases[s[i]] == "undefined")
bases[s[i]] = 1;
else
bases[s[i]]++;
}
return bases;
} // Object {C: 9, A: 9, G: 20, T: 10}
var Barchart = function(opts) {
var container = opts.el;
var bases = getBases(opts.sequence);
d3.select(container)
.attr("class", "header")
.text("Bases:")
.selectAll("p")
.data(d3.keys(bases)).enter()
.append("p")
.text(function(d){ return d +": "+bases[d]; });
}
Interested in d3?? Read about Thinking with Joins
Change the text representation for a barchart.
biojs-vis-example/lib/barchart.js
:
...
var Barchart = function(opts) {
var container = opts.el,
bases = getBases(opts.sequence),
keys = d3.keys(bases),
values = keys.map(function(e){return bases[e];});
var x = d3.scale.linear()
.domain([0, d3.max(values)])
.range([0, 420]);
d3.select(container)
.attr("class", "chart")
.selectAll("div")
.data(keys)
.enter().append("div")
.style("width", function(d) { return x(bases[d]) + "px"; })
.text(function(d) { return bases[d]+":"+d; });
}
biojs-vis-example/css/main.css
.chart div {
font: 10px sans-serif;
background-color: steelblue;
text-align: right;
padding: 3px;
margin: 1px;
color: white;
}
.chart div:hover {
background-color: cadetblue;
font-size: 12px;
}
$ npm adduser
package.json
file includes the biojs tag and points to the right github repo?Then simply:
$ npm publish
Here is the code in this page:
<div id='snippetDiv'></div>
<script>
var rootDiv = document.getElementById('snippetDiv');
// if you don't specify a html file, the sniper will generate a div with id "rootDiv"
var app = require("biojs-vis-example");
var instance = new app({el: rootDiv, sequence: "CAGTGCATGatACGTCAGTGCATGCTGGGGGGGGGgcatgcatgcatgCC"});
</script>
And here how it looks: