GridVar is a jQuery plugin that visualizes multi-dimensional datasets as layers organized in a row-column format. At each cell (i.e., rectangle at the intersection of a row and column), GridVar displays your data as a background color (like a color/heat map) and/or a glyph (shape). This enables different characteristics of your dataset to be layered on top of each other.
Please view our examples page to see GridVar in action.
- Display of multi-dimensional data through colors and/or glyphs.
- Animated transitions when reordering rows and columns.
- Histogram for aggregate data analysis.
- Tooltips for more information about the cell.
- Export visualization to SVG.
Download the javascript and css:
GridVar has a few dependencies that need to be included:
- d3 2.0+
- jQuery 1.8+
- jQuery UI 1.8+
- Underscore 1.0+
Additional functionality can be activated by including the following libraries:
- QTip: if this is not included, you don't get the qtip-styled tooltips
- Filesaver: if this is not included, export to SVG option will be disabled
- Blob.js: some older browser versions need Blob.js for FileSaver.js to function properly
Renderers come in two forms, Built-in Renderers and Custom Renderers.
Built-in renderers consist of two types, backgrounds and glyphs. You can specify a background renderer by providing a RGB hex color code preceded by a '#' like '#AAFFAA'. You can specify a built-in glyph render by providing renderer type (for example, 'xRenderer'). The built-in renderers provide default styles and attributes. Override these with values or functions of your own choosing by providing styles and/or attribute data. Provide a function for dynamically generated attributes and styles. The format for the styles and attributes take the following base form:
{ attrs : { d : 'builtInRendererName'}, styles : { stroke : '#0000ff' }}
Change the stroke color of the xRenderer render like so:
{ attrs : { d : 'xRenderer'}, styles : { stroke :'#0000ff' }}
This set of attributes and styles results in a blue xRenderer:
Style functions will be passed the data, width, and height of the cell. For example, if you wish to scale the stroke-width according to the size of the cell, define the following parameters:
{
attrs : {
d : 'xRenderer'
},
styles : {
'stroke-width' : function (data,width,height) {
return Math.floor(Math.sqrt( width * height) / 10);
}
}
}
This will result in the following dynamic stroke-width of the xRender defined by the the cell size for example:
There are two ways to provide a custom renderer to the GridVar plugin:
- Simple custom renderer: a function that returns an SVG path
- Complete custom renderer: a function and set of attributes and or styles
Simple custom renderers are functions which return the 'd' value for an SVG path. A function will be passed the data for the cell, the width of the cell, and the height of the cell. For example, to draw a simple diagonal line from the top left corner of the cell to the bottom right corner of the cell, provide the following simple custom renderer:
DataTypeValue: function(value,width,height) {return 'M0,0L' + width + ',' + height;}
This will result in the following custom renderer:
Simple custom renderers are created using a function that returns a SVG path. Using an SVG editor (e.g. Google's svg-edit) is an easy solution for editing an SVG path.
Copy the SVG path to the results of a function in the mappings object (see example below). This function will be passed three arguments, the data associated with the cell for the renderer data type, along with the width and height of the cell.
{
dataType: 'cloudy',
mappings: {
cloudy: function(data, width, height) {
return "m3.2863,7.40575c-0.72778,0 -1.31805,-0.68071 -1.31805,-1.52l0,0c ...";
}
}
}
Complete custom renderers provide additional functionality for customizing the styles and attributes of the glyph, such as stroke color, stroke width, opacity, etc. At a minimum, the complete custom renderer must provide the path function as part of the attributes object. For example, the complete form of the diagonal line from above becomes:
DataTypeValue: {
attrs : {
d: function(value,width,height) {
return 'M0,0L' + width + ',' + height;
}
}
}
To customize styles, such as stroke color, provide the styles object with the stroke value:
DataTypeValue: {
attrs : {
d : function (value, width, height) {
return 'M0,0L' + width + ',' + height;
}
},
styles : {
stroke : '#0000ff'
}
}
This results in the following custom glyph:
You can override any style attribute. For example, to adjust the stroke-width:
DataTypeValue: {
attrs: {
d: function (value, width, height) {
return 'M0,0L' + width + ',' + height;
}
},
styles: {
stroke: '#0000ff',
'stroke-width': 3
}
}
This results in the following custom glyph:
To dynamically generate glyphs, provide a function for attributes or styles. For example, to scale the stroke-width by the size of the cell:
DataTypeValue: {
attrs: {
d: function (value, width, height) {
return 'M0,0L' + width + ',' + height;
}
},
styles: {
stroke: '#0000ff',
'stroke-width': function (data, width, height) {
return Math.floor(Math.sqrt(width * height) / 10);
}
}
}
This results in the following scalable custom glyph:
Server-side scripts should handle SVG file uploads, use a tool such as Apache Batik or CairoSVG to rasterize them, and return a link where the new image can be retrieved. A simple PHP implementation:
< ?php
$fileName = $_FILES['data']['tmp_name'];
$batikPath = 'batik/batik-rasterizer.jar';
$downloadLink = 'retrieve.php?token=' . $fileName;
if (is_uploaded_file($fileName)) {
exec('java -jar ' . $batikPath . ' -d /tmp/' . $fileName . '.png ' . $fileName);
echo $downloadLink;
} else {
header('400 Bad Request', true, 400);
}
?>
...and:
< ?php
$fileName = '/tmp/' . $_GET['token'];
if (file_exists($fileName)) {
header('Content-Type: image/png');
header('Content-Disposition: attachment; filename=' . $fileName);
header('Pragma: no-cache');
readfile($fileName);
} else {
header('410 File Not Found', true, 410);
}
?>
GridVar built using the jQuery UI Widget Factory. The following options are provided for supplying data to and customizing GridVar.
- type: Number
- default: 12px
Height in pixels of each cell and height of the rows.
- type: Function
- default: undefined
Function that is called to fill in the 'title' field of each cell. This function will have one parameter, function(cellData), that contains a row of data as provided by the dataMapping option. For example, this may look like:
function(cellData) {
return ['<strong>',cellData.join(', '),'</strong>'].join('');
}
If qtip is available, then this is displayed as a tooltip when the user hovers over the cell.
- type: Number
- default: 12
Width in pixels of each cell and width of the columns.
- type: Object
- default: undefined
Object that maps column key to the column display name. If this isn't provided, the column key will be displayed.
var columnKeysToLabel = {
4235: 'This is a column label',
myKey: 'Column Label'
};
- type: Array of Strings
- default: undefined
Ordered array of the keys of the column data. These should be consistent across the dataset itself and the data mappings. Updating this option animates the reordering. Example:
$('#gridVar').gridVar('option', 'columnOrder',
['firstColumnKey', 'secondColumnKey', 'thirdColumnKey']);
- type: Object
- default: undefined
An array of objects that maps the data type to either a user-provided glyph drawing function, built-in glyph, or a color mapping--the visual encoding. Each of these objects has 3 fields: dataType
, mappings
, and labelMapping
.
The dataType
field corresponds to the dataIndex (see the dataMapping option) and this indicates for which data this mapping encodes.
The mappings
field translates the data value to either a color or a glyph. Colors are the hex encoding and start with a #. Glyphs defined by a string value, shown in the Renderers table below (ex. 'xRenderer'), or a user function that returns an SVG path given the value, cell width, and cell height. For example:
mappings: {
highValue: function(value, width, height){
return 'M0,0L' + width + ',' + height;
}
};
The 'labelMapping' is optional and is used for displaying text on the legend. If you find that the data value would be better displayed in a different format, you can specify the translation in a map from key to field. For example:
var labelMapping = {
low: 'Low Value',
high: 'High',
unknown: 'Unknown'
};
Altogether, this might look like:
var mappings = [{
dataType: 'mutation',
mappings: {
missense: '#FEC44F',
nonsense: '#ADDD8E',
unknown: '#b1b1b1'
},
labelMapping: {
missense: 'Missense Mutation',
nonsense: 'Nonsense Mutation',
unknown: 'Unknown'
}
},
{
dataType: 'copyNumber',
mappings: {
amplified: function(value, width, height){
return 'M0,0L' + width + ',' + height;
},
deleted: 'minusRenderer',
none: { attrs: {d : 'circleRenderer'} , styles : { stroke: 'black'}}
},
labelMapping: {
amplified: 'Amplified',
deleted: 'Deleted',
none: 'Unknown'
}
}
];
For more details see Renderers
- value: Object
- default: undefined
This object holds a data index mapping and the dataset. dataIndex
maps dataType
to the array position of the
arrays provided to data
. The data index must have rowKey
and columnKey
fields. For example:
var dataIndex = {
rowKey: 0, // position 0
columnKey: 1,
copyNumber: 2,
mutation: 3
};
The data
field points to an array of arrays of data. The innermost array corresponds to a row of data with row and
column keys along with the actual data fields that you, for example, paired with the 'dataIndex' above, the data might look like:
var data = [
['23123', 'TCGA-23123', ['amplified'], ['missense']],
['94982', 'TCGA-SAMPL', ['deleted'], ['nonsense']],
['55555', 'TCGA-DSJEN', ['neutral'], ['missense']]
];
The dataMapping
wraps the above variables into the fields dataIndex
and data
.
var dataMapping = {
data: data,
dataIndex: dataIndex
};
- type: Object
- default: undefined
Parameters that specify GridVar's internal SVG rendering and external PNG rasterizing capabilities. Supply a CSS stylesheet to enable SVG export and a server-side script to enable PNG transcoding in addition to the optional libraries in the panel to the right. Download links appear above the legend, if and only if the following options are defined.
exportOptions: {
style: 'GridVar/plugin/gridvar.css',
server: 'upload.php'
}
- type: Object
- default: undefined
Like the dataMapping
option, this option maps the optional histogram data to the rows. It also includes an
optional label
that will be displayed at the bottom of the histogram. The data
field maps a row key to a
percent value. For example:
var histogramMapping = {
data: {
myRowKey: 0.24, // 24%
anotherRowKey: 1.0 // 100%
},
label: 'Frequency'
};
- type: Object
- default: undefined
Object with two values: a boolean to determine if the legend will be split into multiple lines, one for each category, and an array of labels for each of those categories.
var multipleLegendLines = {
include: true,
labels: ['Temperature: ', 'Cloud Levels: ']
};
- type: Object
- default: undefined
Object that maps row key to the column display name. If this isn't provided, the row key will be displayed.
var rowKeysToLabel = {
4235: 'This is a row label',
myRowKey: 'Row Label'
};
- type: Array of Strings
- default: undefined
Ordered array of the keys of the row data. These should be consistent across the dataset itself and the data mappings. Updating this option animates the reordering. Example:
$('#gridVar').gridVar('option', 'rowOrder', ['firstRowKey', 'firstRowKey', 'firstRowKey']);
- parameters:
event
:Event,columnKey
:String
This is fired when a column label is clicked. event
is a jQuery Event. columnKey
is the key that identifies that column.
- parameters:
event
:Event,rowKey
:String
This is fired when a row label is clicked. event
is a jQuery Event. rowKey
is the key that identifies that row.
The following built-in renderers are available for displaying glyphs within cells.
If you find bugs or have feature requests, please create issues on GitHub.
Tests are written using QUnit. Open the test page (/src/tests/qunit-test.html) in a web browser to run the tests in the browser, or run $ grunt test
to run the test suite with PhantomJS. Visual tests can be inspected by opening the visual test page (/src/tests/visual-test.html) in a browser.
Before building and testing GridVar, install dependencies using $ npm install
. The following tasks can be run using Grunt:
grunt build
– Builds GridVar from source, generates a minified source, generates CSS using Compass, runs linting, and runs tests.grunt lint
– Runs source and test files through JSHint.grunt test
– Runs the test suite with PhantomJS.
Copyright 2014 Novartis Institutes for BioMedical Research, Inc..
Licensed under the BSD 3-Clause License.