BlueGenes is built in Clojure and ClojureScript, but we don't want to re-write all existing browser data vis and analysis tools, so we've built a way to integrate JavaScript tools into our pages.
You can take existing JavaScript biology applications and provide a wrapper for them, allowing them to interact with BlueGenes.
This document provides reference for the API specifications, but there is also a tutorial to walk you through creating a wrapper for your tool.
.
+-- myapp/
| +-- dist/
| +-- style.css (optional)
| +-- bundle.js (required)
| +-- src/
| +-- style.less (optional, could be some other preprocessor too.)
| +-- index.js (optional but recommended)
| +-- config.json (required)
| +-- package.json (required)
| +-- demo.html (optional)
| +-- preview.png (optional)
You may optionally also have additional folders, including node_modules, if needed. They won't interfere.
Put all of your prod-ready bundled files in here. Ideally this should be no more than two things:
Where do the bundled files come from? Probably the src directory. This is the folder you'll be doing most of your work in.
This is the preferred entry point to build dist/bundle.js. May import external libraries or node modules if needed. See bluegenesProtVista example. Make sure to export an object that matches your tool name and has a main method - e.g. for bluegenesProtVista, there is an exposed method called bluegenesProtvista.main()
.
The signature of the main method should look have the following signature:
var myApp.main = function(el, service, imEntity, state, config, navigate) {
// code to initialise your app here
}
el - The id of a dom element where the tool will render
service - An object representing an intermine service, like the following:
{
"root": "www.flymine.org/query",
"token": "bananacakes"
}
imEntity
An object representing the data passed to the app, e.g.:
{
"Gene": {
"class": "Gene",
"format": "id",
"value": 456
}
}
If your tool accepts ids
and takes multiple classes, (see config.json) it might receive more than one class if they are present on the list or query results page.
{
"Gene": {
"class": "Gene",
"format": "ids",
"value": [1, 2]
},
"Protein": {
"class": "Protein",
"format": "ids",
"value": [3, 4]
}
}
It is up to you which class you want to use in your tool, and you can even use multiple.
Currently, it is not possible to receive multiple classes on the report page with accepts id
. However, the Tool API allows for this should it be an option in the future.
navigate
A function you can call to make BlueGenes navigate to a specific page.
// Navigate to a report page.
navigate("report", {type: "Gene", id: 1018204});
// Run a query and open the page showing the results.
navigate("query", myQueryObj);
You can optionally specify a third argument with the namespace of a mine (e.g. "humanmine"
).
This is the preferred entry point to build dist/styles.css. If your tool has a stylesheet already, make sure to import the styles and wrap them in a parent class to ensure the styles are sandboxed and don't leak into another file. See bluegenesProtVista's less file for an example and the css it compiled to.
This file provides bluegenes-specific config info. Some further config info is drawn from package.json as well.
{
"accepts": ["id", "ids", "records", "rows"],
"classes": ["Gene", "Protein", "*"],
"columnMapping": {"Protein": {"id" : "primaryAccession"}},
"depends": ["AtlasExpression", "ProteinAtlasExpression"],
"files": {
"css": "dist/style.css",
"js": "dist/bundle.js"
},
"toolName": {
"human": "Protein Features",
"cljs": "proteinFeatures"
},
"version": 2
}
Plurality (i.e. id vs ids) will help to determine which context a tool can appear (report page, list analysis page)
classes default to *
if this tool isn't class / objectType specific. otherwise your tool might be specific to a certain class, e.g. a gene displayer.
columnMapping is an important way to specify (or override) which columns should be passed to the tool by BlueGenes. As an example, for a gene tool, you might want to pass a symbol, OR a primaryIdentifier, or even secondaryIdentifier - and this might change depending in the InterMine that is fuelling the BlueGenes. Set a default likely value here, and in the future individual bluegenes administrators can override it if needed.
depends lets you specify any class names in the InterMine instance's model that your tool depends on. This is useful if you're querying for a non-standard path that is only present in a specific InterMine instance. Any instances which don't have the class name in their model, will not attempt to run your tool, and will instead list it as unsupported.
files - one file each for css and js, please. This should be the file bundled/built with all dependencies except/ imjs if needed. CSS is optional if the tool has no styles.
toolName is an object with a human-readable name, as well as an internal name. The human name would be what you want to see as a header for this tool (e.g. ProtVista might be called "Protein Features"). The internal cljs
name needs to be unique among tools and identical to the global JS variable which your tool's bundle initialises.
version is a whole number indicating which major version of the Tool API your tool adheres to. When creating a tool, you should always specify the latest version presented here. If your tool's version does not match the Tool API version of the BlueGenes using your tool, a warning will be shown and your tool will be disabled from displaying. In this case, you will have to update your tool to support the Tool API version of the BlueGenes using your tool, update the version key in your config.json and publish a new version of your tool. See the Changelog for details on each version.
Optional preview image for the "app store" dashboard (when admins are selecting tools, this is the way to impress them!)
Credits: Thanks to Josh and Vivek for early work on the Tool API proposal.
We aim to keep all changes to the Tool API as backwards compatible as possible, but in some cases breaking changes are necessary. The Tool API major version number will increment on breaking changes and additional details on the rationale and upgrading process will be included.
Changes imEntity
from an object to a nested object with keys corresponding to each object's class.
{"class": "Gene", "format": "id", "value": 1}
--> {"Gene": {"class": "Gene", "format": "id", "value": 1}}
Rationale: It's possible for a list or query results page to have multiple classes, depending on the columns present. This meant a tool needed to be able to receive multiple imEntity's, which the previous Tool API didn't allow.
Upgrading: You will need to grab the value you wish to work on out from the nested object in imEntity
. As an example for a tool that works on the "Gene" class, you would change imEntity.value
to imEntity.Gene.value
. If your tool takes multiple classes, you can decide whether to always default to one if available, or present a different behaviour when multiple classes are present.
Adds a version
key to config.json.
Rationale: To accomodate the first breaking change in the Tool API, we have added versioning of the tools. If your tool's version does not match the Tool API version of the BlueGenes using it, a warning will be displayed and your tool won't be shown on the respective pages. To make your tool work again, you will have to update it to support the changes to the Tool API, as well as update the version
key in config.json. Note that a missing version
key will be interpreted as version 1.
Upgrading: Make sure your tool adheres to Tool API version 2 as described here, then add "version": 2
to your config.json.
Can you improve this documentation? These fine people already did:
uosl, Herald & Leandro DoctorsEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close