LocusZoom is a Javascript/d3 embeddable plugin for interactively visualizing statistical genetic data from customizable sources.
See github.com/statgen/locuszoom/wiki for full documentation and API reference.
To see functional examples of plots generated with LocusZoom.js see statgen.github.io/locuszoom and statgen.github.io/locuszoom/#examples.
The page you build that embeds the LocusZoom plugin must include the following resources, found in the dist
directory:
-
locuszoom.vendor.min.js
This file contains the concatenated vendor libraries. You can alternatively include d3 and Q from other sources, so long as they are included before including LocusZoom files. -
locuszoom.app.js
ORlocuszoom.app.min.js
This is the primary application logic. It should only be included after the vendor dependencies have been included. -
locuszoom.css
This is the primary stylesheet. It is namespaced so as not to conflict with any other styles defined on the same page.
CDN links are available for these resources (see statgen.github.io/locuszoom/).
Data Sources is an object representing a collection of arbitrarily many sources from which data for the plot can be requested. When adding sources to the collection they must be namespaced so that retrieving specific fields can be done with respect to specific data sources.
Here's an example of defining a data sources object for a remote API:
var data_sources = new LocusZoom.DataSources();
data_sources.add("trait", ["AssociationLZ", { url: "http://server.com/api/" }]);
The above example adds an "AssociationLZ" data source (a predefined data source designed to make requests for association data) with a defined URL. The namespace for this data source is "trait".
Data sources can also be local files:
data_sources = new LocusZoom.DataSources();
data_sources.add("trait", ["AssociationLZ", { url: "file:///path/to/data.json" }]);
Refer to the Data Sources Documentation for more information on using predefined data sources or extending/creating custom data sources.
Layout is a serializable object that describes the configuration of the LocusZoom plot, including what data will be pulled from the data sources and displayed in what way, along with visual characteristics like color and geometry.
A layout definition may look something like this:
var layout = {
width: 500,
height: 500,
panels: [
{
id: "association",
data_layers: [
{
id: "association",
type: "scatter",
fields: ["trait:position", "trait:pvalue"],
x_axis: { field: "trait:position" },
y_axis: { field: "trait:pvalue" }
}
]
}
]
};
The above example defines a basic plot that is 500 pixels on a side and has one panel with one scatter plot data layer that pulls in position and pvalue from the "trait" data source, mapping position to the x axis and pvalue to the y axis.
The LocusZoom.js library provides several pre-defined layouts for entire plots and subdivisions of plots such as panels, data layers, tool tips, etc. Refer to the Layout Documentation for more information.
With includes included, data sources defined, and a layout defined, LocusZoom.populate()
will accept a CSS selector
string to populate the first matching element with a plot.
A basic example may then look like this:
<html>
<head>
<script src="locuszoom.vendor.min.js" type="text/javascript"></script>
<script src="locuszoom.app.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="locuszoom.css"/>
</head>
<body>
<div id="plot"></div>
<script type="text/javascript">
var data_sources = new LocusZoom.DataSources();
data_sources.add("trait", ["AssociationLZ", { url: "http://server.com/api/single/" }]);
var layout = {
width: 500,
height: 500,
panels: [
{
id : "association",
data_layers: [
{
id: "association",
type: "scatter",
fields: ["trait:position", "trait:pvalue"],
x_axis: { field: "trait:position" },
y_axis: { field: "trait:pvalue" }
}
]
}
]
};
var plot = LocusZoom.populate("#plot", data_sources, layout);
</script>
</body>
</html>
The core LocusZoom library comes equipped with several predefined layouts, organized by type ("plot", "panel",
"data_layer", and "dashboard"). You can see what layouts are predefined by reading the contents of
assets/js/app/Layouts.js
or in the browser by entering LocusZoom.Layouts.list()
(or to list one specific type:
LocusZoom.Layouts.list(type)
).
Get any predefined layout by type and name using LocusZoom.Layouts.get(type, name)
.
If no layout is passed to LocusZoom.populate()
the Standard GWAS plot layout is used (requiring appropriate data
sources to be configured).
LocusZoom.Layouts.get(type, name)
can also be used to pull predefined layouts of smaller pieces, like data layers or
dashboards, into a custom layout:
var layout = {
width: 1000,
height: 500,
panels: [
LocusZoom.Layouts.get("panel","gwas"),
{
id: "custom_panel",
...
},
LocusZoom.Layouts.get("panel","genes")
]
...
};
The get()
function also accepts a partial layout to be merged with the predefined layout as a third argument,
providing the ability to use predefined layouts as starting points for custom layouts with only minor differences. Example:
var changes = {
label_font_size: 20,
transition: false
};
LocusZoom.Layouts.get("data_layer", "genes", changes);
State is a serializable JSON object that describes orientation to specific data from data sources, and specific interactions with the layout. This can include a specific query against various data sources or pre-selecting specific elements. Essentially, the state object is what tracks these types of user input under the hood in LocusZoom, and it can be predefined at initialization as a top-level parameter in the layout. For example:
var layout = LocusZoom.Layouts.merge({ state: { chr: 6, start: 20379709, end: 20979709 } }, LocusZoom.StandardLayout);
You can also describe the locus query aspect of the State (chromosome, start, and end position) using a data-region
attribute of the containing element before populating it, like so:
<div id="foo" data-region="10:114550452-115067678"></div>
When LocusZoom.populate()
is executed on the element defined above it will automatically parse any data-region
parameter to convert those values into the initial state.
LocusZoom.populate()
will only populate the first matching HTML element for the provided selector string. To populate
all matching elements for a single selector string use LocusZoom.populateAll()
like so:
<div class="plot" id="plot_1"></div>
<div class="plot" id="plot_2"></div>
<div class="plot" id="plot_3"></div>
<script type="text/javascript">
var plots = LocusZoom.populateAll(".plot", data_source, layout);
</script>
LocusZoom is an entirely client-side application designed to plug into arbitrary data sets, be they local files, APIs, or something else entirely. It has the following vendor dependencies:
The application is built using Gulp. Gulp and all necessary dev dependencies can be installed for this project from the top-level directory using the following commands:
$ npm install
Once complete run npx gulp build
from the top of the application directory to run all tests and build the
following files (in the dist
folder):
locuszoom.app.js
- A concatenated app file suitable for use in developmentlocuszoom.app.min.js
- A concatenated and minified app file suitable for use in productionlocuszoom.vendor.min.js
- A concatenated vendor file suitable for use as a single vendor include in either development or production (contains d3 and Q)locuszoom.css
- A generated CSS file for all LocusZoom styles
This build process will also write sourcemaps, to help with debugging code even in production environments.
npx gulp build
- Build app and vendor js files (runs tests and aborts if tests fail)npx gulp watch
- Watch for any changes to app .js, .scss, or test source files to trigger another full buildnpx gulp test
- Just run the testsnpx gulp app_js
- Build app js files (does not run tests)npx gulp ext_js
- Build extensions (features that are not part of LocusZoom core)npx gulp vendor_js
- Build vendor js filenpx gulp css
- Build CSS file
Append --force
to the end of any gulp command that runs the automated testing suite to force the creation of
locuszoom.app.js
and locuszoom.app.min.js
even when the tests fail. This can be useful during active
development as sometimes debugging can be led from either the output of automated tests or inspection of
an active plugin.
This flag is particularly useful with the watch command:
$ npx gulp watch --force
The above command with enter forced-watch-mode, which will detect any changes to app .js or .scss files, as well as
test files, and run a new build. If errors are encountered in the tests they will be reported, but locuszoom.app.js
and locuszoom.app.min.js
will still be generated and gulp will not exit but return to watch mode. This is an
effective way to have automatic continuous builds while developing both the application and its tests.
LocusZoom uses Mocha for unit testing. Tests are located in the test
subdirectory, with
a one-to-one mapping of test files to app files.
Note that the build and test process requires Node.js version 6 LTS or higher.
All app-specific javascript files should be developed in strict mode. LocusZoom is also linted using
ESLint, the rules for which can be found in .eslintrc
.
Full documentation can be found here: github.com/statgen/locuszoom/wiki
A LocusZoom discussion forum is available here: groups.google.com/forum/#!forum/locuszoom. For the most effective help, please specify that your question is about "LocusZoom.js".
If you have questions or feedback please file an issue on the LocusZoom.js GitHub repository or post at the discussion forum referenced above.