Static | Dynamic | Interactive

Integrate an Interactive Plot

This demo shows how to create a plot which uses several features of the iCanPlot system.

Live example

HTML

The following commented HTML describes use of different elements for creating an interactive plot. For brevity, only the relevant divs are shown. To see an example of a layout, see live example.


<script src="/js/icanplot.js">
<script src="/js/data.js">










JavaScript

// set the names of the div in the HTML
var selectedDiv = '#selected-wrapper';
var selectedNavDiv = '#selected-nav';
var namesDiv = '#names-wrapper';
var enrichmentDiv = '#enrichment-wrapper';

var default_cols = [0, 1, -1, -1];

var showSelectedTable = true;
var showEnrichmentTable = true;

var selectedNavPos = -1;

// call the plotting functions when the DOM is ready
$(document).ready(function () {
	icp_init(default_cols);
});

// set canvas element, get default cols to plot and draw figure
function icp_init(_default_cols) {
	viz.init(document.getElementById('plot-area'));

	// setting this allows users to select points by defining an arbitrary polygon
	viz.selectionType = 'polygon';

	// hooking the function to be called when points are selected
	viz.processSelectedData = processSelectedData;

	if(_default_cols)
		default_cols = _default_cols;
	drawFig();
}

// when user changes the source of data, reload new data file and draw
function drawFig() {
	viz.clear();

	$("#param-columns").html("");

	var url = document.getElementById("url-select").value;
	
	data.loadData({
		url: url,
		filetype: 'GCT',
	});

	if (data.success) {
		createDropdowns(default_cols);
		startDrawing(default_cols[0], default_cols[1], default_cols[2], default_cols[3]);
	}
}

// get data vectors and draw the figure
function startDrawing(x_axs, y_axs, color, size){
	$(selectedDiv).css('display', 'none');

	// read all the data columns based on indices
	cols = data.getCols(x_axs, y_axs, color, size);

	// read the names to be highlighted, if any
	var str = document.getElementById('highlight-rows').value;
	var to_highlight = str.trim().split(/[\s,]+/);

	// loose the case, keep the unique ones
	var hHighlight = new Array();
	for(var j = 0; j < to_highlight.length; j++) {
		symbol = to_highlight[j].trim().toUpperCase();
		hHighlight[symbol] = true;
	}

	// set labels
	viz.xAxisLabel = data.colNames[x_axs];
	viz.yAxisLabel = data.colNames[y_axs];
	if(color != -1) {
		viz.colorLabel = data.colNames[color];
	}
	if(size != -1) {
		viz.sizeLabel = data.colNames[size];
	}

	// set the points to be highlighted
	viz.highlight = hHighlight;

	viz.plot({
		x: cols.x,
		y: cols.y,
		color: cols.color,
		size: cols.size,
		label: data.rowNames
	});
}

// when X axis, Y axis, color or size source is changed, redraw figure
function restartDrawing() {
	var x_axs = document.getElementById("x-select").value;
	var y_axs = document.getElementById("y-select").value;
	var color = document.getElementById("color-select").value;
	var size = document.getElementById("size-select").value;
	startDrawing(x_axs, y_axs, color, size);
}

// create dropdowns on the basis of name of columns
function createDropdowns(default_cols) {
	var str = ''

	str += '<table>';

	// x-axis drop down
	str += '<tr><th>X axis</th>';
	str += '<td><select id="x-select" onchange="restartDrawing()">';
	str += dropdownOptions(data.colNames, default_cols[0]);
	str += '</select></td></tr>';

	// y-axis drop down
	str += '<tr><th>Y axis</th>';
	str += '<td><select id="y-select" onchange="restartDrawing()">';
	str += dropdownOptions(data.colNames, default_cols[1]);
	str += '</select></td></tr>';

	// color drop down
	str += '<tr><th>Color by</th>';
	str += '<td><select id="color-select" onchange="restartDrawing()">';
	str += '<option value="-1">None';
	str += dropdownOptions(data.colNames, default_cols[2]);
	str += '</select></td></tr>';

	// size drop down
	str += '<tr><th>Size by</th>';
	str += '<td><select id="size-select" onchange="restartDrawing()">';
	str += '<option value="-1">None';
	str += dropdownOptions(data.colNames, default_cols[3]);
	str += '</select></td></tr>';

	str += '</table>';

	$("#param-columns").html(str);
}

function dropdownOptions(myArray, defaultVal) {
	var maxLen = 25;
	var str = ''
	for(var i = 0; i < myArray.length; i++) {
		var extra = (i == defaultVal ? ' selected' : '');
		var name = myArray[i];
		// long names break the layout, shorten name and add tool tip
		if (name.length > maxLen) {
			extra = extra + ' title="' + myArray[i] + '"';
			name = name.substr(0, maxLen);
		}
		str += '<option value="' + i + '"' + extra + '>' + name;
	}

	return str;
}

// function is called when genes are selected
// a) show them in a table, b) do enrichment, c) scroll page down to show it 
// col1, col2, col3 contain name, x and y axis value of selected points
function processSelectedData(col1, col2, col3) {
	if(col1.length < 2) {
		return;
	}

	// clear from last time
	$(namesDiv).html("");
	$(enrichmentDiv).html("");
		
	saveSelectedSymbols(col1);

	$(selectedDiv).css('display', 'block');

	var navCode = '
    '; if(showSelectedTable) { navCode += '
  • Selected genes
  • '; writeSelectedTable(col1, col2, col3); } if(showEnrichmentTable) { navCode += '
  • Geneset enrichment
  • '; writeEnrichmentTable(col1); } navCode += '
  • Back to plot
  • '; navCode += '
'; $(selectedNavDiv).html(navCode); // remember position of div for fixing it in place on scroll down selectedNavPos = $(selectedNavDiv).offset().top; // move page to show selected genes, lest the user misses it $('html').scrollTop(selectedNavPos - 250); } // scroll the navigation links for selected div $(window).scroll(function () { var buffer = 10; var newPos = $('html').scrollTop() + buffer; // this gets called if there is any scrolling, even before nav is shown if (newPos > selectedNavPos && $(selectedDiv).css('display') != 'none') { $(selectedNavDiv).css("position", "fixed"); $(selectedNavDiv).css("top", buffer); } else { $(selectedNavDiv).css("position", "static"); } }); // save selected symbols in a hidden div function saveSelectedSymbols(arr) { symbols = arr.slice(1); jQuery.unique(symbols); symbols.sort(); str = symbols.join('\n'); $("#selected-symbols").html(str); } // trim a long name. if trim required, add full name as title function trimLongName(str, maxLen) { var name = ''; if (str.length > maxLen) { name = '' + str.substr(0, maxLen) + '' } else { name = str; } return name; } // write a table showing selected genes function writeSelectedTable(col1, col2, col3) { var html = '' html += '<h2>Selected Genes</h2>'; html += '<div id="names-link">'; html += '<a href="#" onclick="selected2highlight();return false;">^ To highlight</a>'; html += '</div>'; var maxLen = 100; var name1 = trimLongName(col1[0], maxLen); var name2 = trimLongName(col2[0], maxLen); var name3 = trimLongName(col3[0], maxLen); html += '<table id="names-table" class="results">'; html += '<thead>'; html += '<tr>'; html += '<th>' + name1 + '</th>'; html += '<th>' + name2 + '</th>'; html += '<th>' + name3 + '</th>'; html += "</tr>"; html += "</thead>"; html += "<tbody>"; for(var i = 1; i < col1.length; i++) { html += '<tr>'; html += '<td>' + col1[i] + '</td>'; html += '<td class="num">' + col2[i] + '</td>'; html += '<td class="num">' + col3[i] + '</td>'; html += '</tr>'; } html += '</tbody>'; html += '</table>'; $(namesDiv).html(html); $("#names-table").tablesorter({ sortList: [[0,0]]}); } // find enrichment of selected genes in geneset database function writeEnrichmentTable(col1) { var genes = new Array(); var uniqueSymbols = new Array(); for(var i = 1; i < col1.length; i++) { var name = col1[i]; if(name in uniqueSymbols) continue; uniqueSymbols[name] = true; genes.push(name); } var query = 'genes=' + genes.join(','); $.ajax({ type: "POST", url: "/goa", data: query, dataType: "jsonp", cache: false, error: function(){ alert('Error in geneset overlap analysis'); }, success: function(){ }, complete: function(){ }, }); } // parses the output of the AJAX call in enrichment function parseEnrichmentResults(msg) { if(msg['sig_genesets'].length == 0) return; var str = ""; str += '

Geneset Overlap Analysis

'; str += genesetTable(msg['sig_genesets']); $(enrichmentDiv).html(str); } // write a table of enriched genesets function genesetTable(jsonstr) { if (jsonstr.length == 0) return ''; var str = ''; str += '<table class="results">'; str += '<tr><th>Geneset name</th><th class="num">Size</th>' str += '<th class="num">Expected</th><th class="num">Observed</th><th>Pval</th></tr>'; var len = jsonstr.length; for (var i = 0; i < len; i++) { var item = jsonstr[i]; var name = item["name"]; if (name.length > 50) name = name.substr(0, 50) + '...'; var parts = item["pval"].split("^"); var pval = parts[0] + "<sup><b>" + parts[1] + "</b></sup>"; str += '<tr>'; str += '<td>' + name + '</td>'; str += '<td class="num">' + item["size"] + '</td>'; str += '<td class="num">' + item["num_expected"] + '</td>'; str += '<td class="num">' + item["num_common"] + '</td>'; str += '<td>' + pval + '</td>'; str += '</tr>'; } str += '</table>'; return str; } // send the selected genes to the highlight box function selected2highlight(names) { var symbols = $("#selected-symbols").html(); $("#highlight-rows").html(symbols); restartDrawing(); }