Skip to content
Permalink
4f2077935a
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
executable file 2017 lines (1739 sloc) 69 KB
function VQI_GenomeBrowser(id) {
var resourceFolder = 'js/modules/VQI_GenomeBrowser/';
var serviceURL = resourceFolder + 'dynamic_loading.php';
var deleteImage = resourceFolder + 'DeleteTrack.png';
var exportImage = resourceFolder + 'ExportTrack.png';
var divId = id;
var width = 1000;
var height = 20;
var margin = 50;
var bufferSpace = 20;
var trackHeight = 50;
var panExtent = [0, width];
var initialZoom = 1 //defines what will be considered a zoom scale of 1
var trackList = [];
var genomes = {};
var chromosomes = [];
var thisObj = this;
var chrom_curr = "chr1";
var indexArray = {chr: 0, start: 1, end: 2, name: 3, type: 3, score: 4, strand: 5, options: 6, exonStarts: 9, exonEnds: 10};
var testdata;
var isready = false;
var waitTime;
var loadCount = 0;
var trackInfo = [];
var serviceURL = serviceURL;
// var trackDiv;
// var trackNavContainer;
// var recentTrackContainer;
// var dataDiv;
// var otherDiv;
var navigateToRegion = function () {
var navigate = $("#" + divId + " #navigate").val();
navigate = navigate.split(/[:-]/);
if (navigate.length == 3) {
var chrom = navigate[0].trim();
var chrom_start = Number(navigate[1].trim());
var chrom_end = Number(navigate[2].trim());
//Only need to set bounds if current chromosome is already graphed
if (chrom == chrom_curr)
{
setBounds(chrom_start, chrom_end);
}
else
{
setPanExtent();
graph(chrom, chrom_start, chrom_end);
}
}
else
{
browseToGene();
}
};
var addRecentTrack = function () {
var track = $("#" + divId + " #RecentTracks").val();
for (i in trackList) {
if (trackList[i].name == track) {
return;
}
}
for (i in trackInfo) {
if (trackInfo[i].name == track) {
self.addTrack(trackInfo[i].name, trackInfo[i].type, trackInfo[i].args);
break;
}
}
}
var browseToGene = function () {
var geneName = $("#" + divId + " #navigate").val();
var genes = [geneName];
dataToPost = JSON.stringify(genes);
$.ajax({
url: vqi_url + 'serverside/web/VQService.php?service=gene-info-for-gene-symbol',
type: 'POST',
dataType: "json",
data: {
"genes": dataToPost
},
async: false
}).success(function (data) {
var thisGene = data.slice(1)[0];
var gene_chrom = thisGene[2];
var gene_start = thisGene[3];
var gene_end = thisGene[4];
thisObj.navigate(gene_chrom, gene_start, gene_end);
}).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
};
this.makeNavMenu = function () {
var menu = "<ul class='nav nav-tabs' style='font-size: 16'>" +
//"<li class='active'><a data-toggle='tab' href='#home'>Home</a></li>"+
"<li class='active'><a data-toggle='tab' href='#traks'>Track</a></li>" +
"<li><a data-toggle='tab' href='#analysis'>Analysis</a></li>" +
"<li><a data-toggle='tab' href='#other'>Other</a></li>" +
"</ul>"
var homeTable = "<table cellpadding='5'; style='margin: 0px 20px;font-size: 14'>" +
"<tr> <td id='trackNavContainer'> </td></tr>" +
"<tr> <td id=''> </td></tr>" +
"<tr> <td id=''> </td></tr>" +
"</table>"
var tackMenuTable = "<table cellpadding='5'; style='margin: 0px 20px;font-size: 14'>" +
"<tr> <td id='uploadDataContainer'> </td></tr>" +
"<tr> <td id='recentTrackContainer'> </td></tr>" +
"<tr> <td id='exportRemoveContainer'> </td></tr>" +
"</table>"
var analysisMenuTable = "<table cellpadding='5'; style='margin: 0px 20px;font-size: 14'>" +
"<tr> <td id='colocalizeContainer'> </td></tr>" +
"<tr> <td id='mcEntContainer'> </td></tr>" +
"</table>"
var menuContent = "<div class='tab-content'>" +
//"<div id='home' class='tab-pane fade in active' style='height: 130px; width: 800px; background-color:#F0F0F0'>"+homeTable+"</div>"+
"<div id='traks' class='tab-pane fade in active ' >" + tackMenuTable + "</div>" +
"<div id='analysis' class='tab-pane fade' >" + analysisMenuTable + "</div>" +
"<div id='other' class='tab-pane fade'></div>" +
"</div>"
var menuContainer = "<div class='container-fluid' >" + menu + menuContent + "</div>";
$("#" + divId).append(menuContainer);
};
this.makeNavMenu();
this.makeNavigationForm = function () {
var genomeDropdown = "<select name='genomes' id='genomes'>";
var navigateBox = "<input type='text' name='navigate' id='navigate' size='30'>";
var navigateButton = "<input type='button' id='navigatebutton' value='Go To'>";
var form = "<form id='navigation_form' style='margin: 10px 0px;'>" + genomeDropdown + navigateBox + navigateButton + "</form>";
$("#" + divId).append(form);
$("#" + divId + " #navigatebutton").on("click", navigateToRegion.bind(this));
$("#" + divId + " #genomes").on("change", function () {
self.setGenome($("#" + divId + " #genomes").val())
});
};
this.makeNavigationForm();
var colocalize = function () {
var track1Name = $("#" + divId + " #track1").val();
var track2Name = $("#" + divId + " #track2").val();
var coloc_dist = $("#" + divId + " #coloc_dist").val();
if (track1Name === track2Name) {
alert("Track1 and Track2 cannot be same for colocalization.");
return;
}
var data1 = this.getTrackByName(track1Name);
var data2 = this.getTrackByName(track2Name);
var dataToPost1 = [], dataToPost2 = [];
dataToPost1 = JSON.stringify(data1);
dataToPost2 = JSON.stringify(data2);
var data1Length = data1.length;
var data2Length = data2.length;
$.ajax({
url: vqi_url + 'serverside/web/VQService.php?service=coloc-bed-and-bed',
type: 'POST',
dataType: "json",
data: {
"bed1": dataToPost1,
"bed2": dataToPost2,
"coloc_dist": coloc_dist
},
async: false
}).success(function (data) {
var data1 = [];
var data2 = []
data = data.slice(1);
for (var i in data) {
data1.push(data[i].slice(0, 6));
data2.push(data[i].slice(6));
}
thisObj.addTrack(data1);
thisObj.addTrack(data2);
thisObj.getPValue(data1Length, data2Length, data1.length);
}).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
};
/**
*
* @author Pujan Joshi
* @since April 16, 2015
* @param {type} k1
* @param {type} k2
* @param {type} ob
* @returns {p-value}
*
* This method calls Yue's pvalue program and returns p-value result.
*/
this.getPValue = function (k1, k2, ob) {
$.ajax({
url: vqi_url + 'serverside/web/VQService.php?service=coloc-pvalue',
type: 'GET',
dataType: "text",
data: {
"K1": k1,
"K2": k2,
"OB": ob
},
async: true
}).success(function (data) {
$("#pvalue_div").empty().append("p-value = " + data);
}).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
}
this.makeFormForColocalization = function () {
var track1Select = "Track1: <select name='track1' id='track1'>";
for (var i in trackList) {
var thisTrack = trackList[i];
var text = thisTrack.name;
var value = thisTrack.name;
track1Select += "<option value='" + value + "'>" + text + "</option>";
}
track1Select += "</select>";
var track2Select = " Track2: <select name='track2' id='track2'>";
for (var i in trackList) {
var thisTrack = trackList[i];
var text = thisTrack.name;
var value = thisTrack.name;
track2Select += "<option value='" + value + "'>" + text + "</option>";
}
track2Select += "</select>";
var distanceTextBox = "<input type=text name='coloc_dist' id='coloc_dist' value='100'>";
var colocalizeButton = "<input type='button' id='colocalize' value='colocalize'>";
var pValueDiv = "<div id='pvalue_div'></div>"
var form = "<form id='colocalization_form'>" + track1Select + track2Select + distanceTextBox + colocalizeButton + pValueDiv + "</form>";
$("#" + divId + " #colocalizeContainer").append(form);
$("#" + divId + " #colocalize").on("click", colocalize.bind(this));
};
this.makeFormForColocalization();
/*var removeSelectedTracks = function () {
for (var i = trackList.length - 1; i >= 0; i--) {
if (trackList[i].isSelected())
{
trackList[i].group.remove();
trackList.splice(i, 1);
}
}
reorderTracks();
updateAllTracksSelectBoxes();
}*/
var removeTrack = function (track_name) {
for (var i = trackList.length - 1; i >= 0; i--) {
if (trackList[i].name == track_name)
{
trackList[i].group.remove();
trackList.splice(i, 1);
}
}
//setPanExtent();
//graph(chrom_curr, xScale.domain()[0], xScale.domain()[1]);
reorderTracks();
updateAllTracksSelectBoxes();
}
var removeAllTracks = function () {
for (var i = trackList.length - 1; i >= 0; i--) {
trackList[i].group.remove();
trackList.splice(i, 1);
}
reorderTracks();
updateAllTracksSelectBoxes();
}
/* this.getSelectedTrackNames = function(){
var tracknames = []
for (var i in trackList) {
if (trackList[i].isSelected())
{
tracknames.push(trackList[i].name);
}
}
return tracknames;
}
this.getSelectedTracks = function(){
tracknames = thisObj.getSelectedTrackNames();
tracks = [];
for (var i in tracknames) {
tracks.push(thisObj.getTrackByName(tracknames[i]));
}
return tracks;
}
var exportSelectedTracks = function () {
var tracknames = []
for (var i in trackList) {
if (trackList[i].isSelected())
{
tracknames.push(trackList[i].name);
}
}
for (var i in tracknames) {
exportTrack(tracknames[i]);
}
}*/
var exportTrack = function (track_name) {
var track = thisObj.getTrackByName(track_name);
exportTrackToText(track.getData(), track_name);
}
this.makeUploadForm = function () {
var fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.addEventListener('change', function (e) {
var file = fileInput.files[0];
var textType = /text.*/;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.onload = function (e) {
var Data = reader.result;
uploadFile(Data);
}
reader.readAsText(file);
} else {
alert("File not supported!");
}
});
var f = document.createElement("form");
fileInput.style.display = "inline";
f.innerHTML = "Add track by uploading file: ";
f.appendChild(fileInput);
$("#" + divId + " #uploadDataContainer").append(f);
}
this.makeUploadForm();
this.makeRecentTrackForm = function () {
var trackSelect = "Recent tracks: <select name='RecentTracks' id='RecentTracks'>";
for (var i in trackInfo) {
var thisTrack = trackInfo[i];
var text = thisTrack.name;
var value = thisTrack.name;
trackSelect += "<option value='" + value + "'>" + text + "</option>";
}
trackSelect += "</select>";
var addTrackButton = "<input type='button' id='addTrackButton' value='Add Track'>";
var form = "<form id='colocalization_form'>" + trackSelect + addTrackButton + "</form>";
$("#" + divId + " #recentTrackContainer").append(form);
$("#" + divId + " #addTrackButton").on("click", addRecentTrack.bind(this));
}
this.makeRecentTrackForm();
this.makeSelectionForm = function () {
var removeButton = "<input type='button' id='removetrackbutton' value='Remove Selected Track'>";
var exportButton = "<input type='button' id='exporttrackbutton' value='Export Selected Track'>";
var mcScoreButton = "<input type='button' id='mcscoreTracks' value='MC System' onclick='VQI_ControlPanel.scoreButtonClicked()'>";
var entScoreButton = "<input type='button' id='entscoreTracks' value='EMT Score' onclick='VQI_ControlPanel.EMTScoreButtonClicked()'>";
//var removeExportform = "<form id='removeExportForm'>" + removeButton + "&nbsp&nbsp&nbsp"+exportButton +"</form>";
var mcEntForm = "<form id='mcEntForm'>" + mcScoreButton + "&nbsp&nbsp&nbsp" + entScoreButton + "</form>";
//$("#" + divId +" #exportRemoveContainer").append(removeExportform);
$("#" + divId + " #mcEntContainer").append(mcEntForm);
//$("#" + divId + " #removetrackbutton").on("click", removeSelectedTracks.bind(this));
//$("#" + divId + " #exporttrackbutton").on("click", exportSelectedTracks.bind(this));
};
this.makeSelectionForm();
var self = this;
this.svg = d3.select("#" + id)
.append("svg")
.attr("width", width + 2 * margin)
.attr("height", height + 2 * margin)
.style("border", "1px solid black")
var svg = this.svg;
var graphRegion = svg.append("g").attr("transform", "translate(" + margin + "," + margin + ")");
//set up scales and axis
var xScale = d3.scale.linear();
var fullXScale = d3.scale.linear();
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(10);
//x-axis
var xAxisSelection = graphRegion.append("g")
.call(xAxis)
.attr("class", "axis")
var zoom = d3.behavior.zoom();
var rubberbanding = false;
var rubberbandingX;
svg.on("mousedown", function () {
svg.selectAll("rect.selection").remove();
if (d3.event.shiftKey) {
d3.event.preventDefault();
zoom.on("zoom", null);
svg.call(zoom);
rubberbanding = true;
var p = d3.mouse(this);
// create rubber band selector
if (p[0] > margin && p[0] < margin + width)
{
svg.append("rect")
.attr({
class: "selection",
x: p[0],
y: 0,
width: 0,
height: height + 2 * margin + trackList.length * (trackHeight + bufferSpace)
})
.style("fill-opacity", ".2")
.on("mousedown", navigateToRegion);
}
rubberbandingX = p[0];
}
})
.on("mousemove", function () {
// rubber band selector
var s = svg.select("rect.selection");
if (!s.empty() && rubberbanding) {
d3.event.preventDefault();
// get cursor coordinate
var p = d3.mouse(this);
// get rubber band selector coordinate and size
newX = Math.min(Math.max(p[0], margin), width + margin);
var c = {
x: Math.min(newX, rubberbandingX),
width: Math.abs(newX - rubberbandingX)
};
s.attr(c);
}
})
.on("mouseup", function () {
// remove rubber band selector
zoom.on("zoom", zoomed);
svg.call(zoom).on("dblclick.zoom", null);
rubberbanding = false;
var s = svg.select("rect.selection");
if (!s.empty()) {
$("#" + divId + " #navigate").val(chrom_curr + ":"
+ Math.round(xScale.invert(parseInt(s.attr("x")) - margin)) + "-"
+ Math.round(xScale.invert(parseInt(s.attr("x")) + parseInt(s.attr("width")) - margin)));
}
});
var clipPath = graphRegion.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height)
.attr("y", -margin); //to make this work with all the transformations.
var zoomed = function () {
svg.selectAll("rect.selection").remove();
zoom.translate([panLimit(), 0]);
for (i in trackList)
{
trackList[i].zoomed();
}
xAxisSelection.call(xAxis);
d3.selectAll(".axis path, .axis line").style({
"fill": "none",
"stroke": "black",
"shape-rendering": "crispEdges"});
d3.selectAll(".axis text").style({
"font-family": "sans-serif",
"font-size": "11px"});
if (waitTime != undefined)
{
clearTimeout(waitTime);
}
waitTime = setTimeout(updateTrack, 100);
$("#" + divId + " #navigate").val(chrom_curr + ":" + Math.round(xScale.domain()[0]) + "-" + Math.round(xScale.domain()[1]));
};
var uploadFile = function (data, name, genome) {
//console.log(data);
headerArray = ["CHROM", "CHROM_START", "CHROM_END", "GENESYMBOL", "SCORE", "STRAND"];
for (i in headerArray) {
indexArray[headerArray[i]] = i;
}
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
data: {
"header": headerArray,
"indexArray": indexArray,
"upload": data
}
}).success(function (data) {
var CurrentFileHandle = data;
var trackName = CurrentFileHandle;
if (name !== undefined) {
var trackName = name;
}
self.addTrack(trackName, "custom", {table_name: CurrentFileHandle});
}).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
}
this.uploadFileFromServer = function (data, name, genome) {
var temp = [];
for (i in data) {
temp.push(data[i].join('\t'));
}
trackData = temp.join('\n');
uploadFile(trackData, name, genome);
}
var updateTrack = function () {
for (i in trackList) {
trackList[i].updateTrack();
}
}
var testRemove = function () {
removeTrack("HG191");
reorderTracks();
}
var panLimit = function () {
var divisor = (width) / ((xScale.domain()[1] - xScale.domain()[0]) * zoom.scale());
minX = -(((xScale.domain()[0] - xScale.domain()[1]) * zoom.scale()) + (panExtent[1] - (panExtent[1] - (width / divisor)))),
maxX = -(((xScale.domain()[0] - xScale.domain()[1])) + (panExtent[1] - panExtent[0])) * divisor * zoom.scale();
tx = xScale.domain()[0] < panExtent[0] ?
minX :
xScale.domain()[1] > panExtent[1] ?
maxX :
zoom.translate()[0];
return tx;
}
this.navigate = function (chrom, chrom_start, chrom_end) {
graph(chrom, chrom_start, chrom_end);
};
var setBounds = function (min, max) {
var xMin = Number(min) > panExtent[0] ? Number(min) : panExtent[0];
var xMax = Number(max) < panExtent[1] ? Number(max) : panExtent[1];
var range = (panExtent[1] - panExtent[0]) / initialZoom
xScale.domain([panExtent[0], panExtent[0] + range])
.range([0, width]);
zoom.scaleExtent([1 / initialZoom, (panExtent[1] - panExtent[0]) / 50 / initialZoom]);
var prevTranslate = zoom.translate();
var prevScale = zoom.scale();
zoom.x(xScale).on("zoom", zoomed);
svg.call(zoom).on("dblclick.zoom", null);
var scale = (panExtent[1] - panExtent[0]) / (xMax - xMin) / initialZoom;
if (scale > (panExtent[1] - panExtent[0]) / 50 / initialZoom)
scale = (panExtent[1] - panExtent[0]) / 50 / initialZoom;
if (scale < 1 / initialZoom)
scale = 1 / initialZoom;
zoom.scale(scale)
//translates scale with regards to the middle of xMin and xMax
var divisor = (width) / ((xScale.domain()[1] - xScale.domain()[0]) * scale);
var minX = -(((xScale.domain()[0] - xScale.domain()[1]) * scale) + (panExtent[1] - (panExtent[1] - (width / divisor))));
var maxX = -(((xScale.domain()[0] - xScale.domain()[1])) + (panExtent[1] - panExtent[0])) * divisor * scale;
var midScale = d3.scale.linear()
.domain([panExtent[0] + (xMax - xMin) / 2, panExtent[1] - (xMax - xMin) / 2])
.range([minX, maxX]);
var zoomWidth = midScale((xMax + xMin) / 2);
//transitions start from the previous transition, so I make a transition that first zooms
//to the current view in no time, then another transition that zooms to the desired view
svg.transition()
.duration(0)
.call(zoom.translate(prevTranslate).scale(prevScale).event)
.each("end", function () {
svg.transition()
.duration(1000)
.call(zoom.scale(scale).translate([zoomWidth, 0]).event)
})
zoomed();
}
var setPanExtent = function () {
var mins = [];
var maxs = [];
for (var i in trackList) {
range = trackList[i].getRange();
mins.push(Number(range[0]));
maxs.push(Number(range[1]));
}
min = d3.min(mins);
max = d3.max(maxs);
panExtent[0] = isNaN(min) ? 0 : min;
panExtent[1] = isNaN(max) ? width : max;
var distance = (panExtent[1] - panExtent[0]) / initialZoom;
fullXScale = d3.scale.linear()
.domain([panExtent[0], panExtent[0] + distance])
.range([0, width]);
}
var graph = function (chromosome, min, max) {
var self = this;
chrom_curr = chromosome;
if (min == null || max == null) {
setBounds(panExtent[0], panExtent[1]);
}
else {
setBounds(Number(min), Number(max));
}
for (var i in trackList) {
trackList[i].updateTrack();
}
}
var reorderTracks = function () {
svg.transition().attr("height", height + 2 * margin + trackList.length * (trackHeight + bufferSpace));
for (var i in trackList) {
trackList[i].group.transition().attr("transform", "translate(" + 0 + "," + (margin + bufferSpace + i * (trackHeight + bufferSpace)) + ")");
}
}
this.loadGenomes = function (genomesData) {
genomes = genomesData;
selectBox = $("#" + divId + " #genomes").get(0);
selectBox.options.length = 0;
var optionIndex = 0;
for (var key in genomes) {
var text = key;
var value = key;
selectBox.options[optionIndex++] = new Option(text, value);
for (var key2 in genomes[key])
{
if (key2 === 'custom' || key2 === 'genes')
{
checkTableUpload(genomes[key][key2].table_name, genomes[key][key2].file)
}
if (key2 === 'cpg')
{
var tempHandles = genomes[key][key2].table_name.split(",");
var fileHandles = genomes[key][key2].file.split(",");
for (var i in tempHandles)
{
checkTableUpload(tempHandles[i].trim(), fileHandles[i].trim())
}
}
}
}
selectBox = $("#" + divId + " #genomes").get(0);
selectBox.options.length = 0;
var optionIndex = 0;
for (var key in genomes) {
var text = key;
var value = key;
selectBox.options[optionIndex++] = new Option(text, value);
}
}
this.setGenome = function (genome) {
removeAllTracks();
$("#" + divId + " #genomes").val(genome);
if (genomes.hasOwnProperty(genome)) {
for (var key in genomes[genome])
{
this.addTrack(genome + "_" + key, key, genomes[genome][key])
}
}
}
var checkTableUpload = function (tableName, filePath) {
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
data: {
"checkTable": "",
"tableName": tableName,
"filePath": filePath
}
}).success(function (returnData) {
}
).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
}
this.addTrack = function (name, type, args, fromServer) {
if (fromServer) {
var temp = [];
for (i in args) {
temp.push(args[i].join('\t'));
}
trackData = temp.join('\n');
uploadFile(trackData, name);
}
else {
var trackIndex = trackList.length;
var trackCount = trackIndex + 1;
//name of track
name = name || "track-" + (trackIndex + 1);
if (type == "cpg") {
trackList.push(new CpgTrack(name, graphRegion.append("g"), args));
}
else if (type == "genes") {
trackList.push(new BedTrack(name, graphRegion.append("g"), args));
}
else if (type == "fasta") {
trackList.push(new FastaTrack(name, graphRegion.append("g"), args));
}
else
{
args.exportable = true;
trackList.push(new CustomTrack(name, graphRegion.append("g"), args));
}
var inTrackInfo = false;
for(var i in trackInfo)
{
if (trackInfo[i].name == name)
{
inTrackInfo = true;
break;
}
}
if(!inTrackInfo)
{
trackInfo.push({name: name, type: type, args: args});
updateRecentTrackDropDown();
}
setPanExtent();
graph(chrom_curr);
clipPath.attr("height", Number(svg.attr("height")));
zoomOnly = true;
zoomed();
zoomOnly = false;
reorderTracks();
updateAllTracksSelectBoxes();
}
}
/*this.addTrackFile = function (dataFile, name, type, header) {
$.get(dataFile, function (data) {
var dataRows = thisObj.parseTrackFile(data, header);
thisObj.addTrack(dataRows, name, type);
});
}
this.parseTrackFile = function (data, header) {
var delimeter = "\t";
var thisData = new Array();
var txtContent = data.split(/\r\n|\r|\n/g);
var startRow = 0;
if (header) {
startRow = 1;
}
for (var i = startRow; i < txtContent.length; i++) {
var thisRow = txtContent[i].split(delimeter);
var thisObject = {};
thisObject = thisRow;
if (thisRow[0].indexOf("##") === 0) {
continue;
}
thisData.push(thisObject);
}
return thisData;
};*/
this.getTrackByName = function (name) {
for (var i in trackList) {
var thisTrack = trackList[i];
if (thisTrack.name === name) {
return thisTrack;
}
}
};
var getTrackIndexByName = function (name) {
for (var i in trackList) {
var thisTrack = trackList[i];
if (thisTrack.name === name) {
return i;
}
}
};
var updateAllTracksSelectBoxes = function () {
var track1Select = $("#" + divId + " #track1");
updateSelectBoxWithTracks(track1Select.get(0));
var track2Select = $("#" + divId + " #track2");
updateSelectBoxWithTracks(track2Select.get(0));
}
var updateSelectBoxWithTracks = function (selectBox) {
selectBox = selectBox;
selectBox.options.length = 0;
var optionIndex = 0;
for (var i in trackList) {
var text = trackList[i].name;
var value = text;
selectBox.options[optionIndex++] = new Option(text, value);
}
};
var updateRecentTrackDropDown = function () {
var trackSelect = $("#" + divId + " #RecentTracks");
selectBox = trackSelect.get(0);
selectBox.options.length = 0;
var optionIndex = 0;
for (var i in trackInfo) {
var text = trackInfo[i].name;
var value = text;
selectBox.options[optionIndex++] = new Option(text, value);
}
};
var exportTrackToText = function (data, filename) {
temp = [];
for (i in data)
{
if (data[i].constructor === Array)
{
var row = data[i].join("\t");
row = row.trim();
temp.push(row);
}
}
var txt = temp.join("\r\n");
var blob = new Blob([txt], {type: "text/csv;charset=utf-8"});
saveAs(blob, filename + ".txt");
}
function Track(name, group, args) {
this.group = group;
this.name = name;
group.append("line")
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", width)
.attr("y2", 0)
.style("stroke", "blue")
.style("stroke-opacity", 0.5);
group.append("text")
.attr("x", 0)
.attr("y", -trackHeight / 2 - bufferSpace / 2)
.attr("font-family", "sans-serif")
.attr("font-size", "12px")
.attr("fill", "red")
.text(name);
group.append("foreignObject")
.attr("width", 20)
.attr("height", 20)
.attr("x", width + 5)
.attr("y", -15)
.append("xhtml:div")
.html("<form><input type=image src=" + deleteImage + " width=15 height=15 onclick='return false;'></form>")
.on("click", function () {
deleteConfirm.style("visibility", "visible");
});
if (args.exportable)
{
group.append("foreignObject")
.attr("width", 20)
.attr("height", 20)
.attr("x", width + 5)
.attr("y", 0)
.append("xhtml:div")
.html("<form><input type=image src=" + exportImage + " width=15 height=15 onclick='return false;'></form>")
.on("click", function () {
exportTrack(name);
});
}
group.append("foreignObject")
.attr("width", 20)
.attr("height", 20)
.attr("x", width + 25)
.attr("y", -10)
.attr("class", "checkbox")
.append("xhtml:div")
.html("<form><input type=checkbox id='check'/></form>")
.on("click", function () {
xAxisSelection.call(xAxis)
});//I have no idea why it won't redraw the checkbox unless I call this
var deleteConfirm = group.append("g")
.style("visibility", "hidden");
deleteConfirm.append("rect")
.attr("width", 40)
.attr("height", 50)
.attr("x", width + 5)
.attr("y", -25)
.style("fill", "white")
deleteConfirm.append("text")
.attr("x", width + 5)
.attr("y", -25)
.text("Delete?")
deleteConfirm.append("foreignObject")
.attr("width", 40)
.attr("height", 20)
.attr("x", width + 5)
.attr("y", -20)
.append("xhtml:div")
.html("<form><input type=button value='Yes' onclick='return false;'></form>")
.on("click", function () {
removeTrack(name);
});
deleteConfirm.append("foreignObject")
.attr("width", 40)
.attr("height", 20)
.attr("x", width + 5)
.attr("y", 0)
.append("xhtml:div")
.html("<form><input type=button value='No' onclick='return false;'></form>")
.on("click", function () {
deleteConfirm.style("visibility", "hidden");
});
group.append("path")
.attr("transform", function (d) {
return "translate(" + -20 + "," + -10 + ")"
})
.attr("d", d3.svg.symbol().type(["triangle-up"]))
.attr("class", "up")
.on('click', function () {
var i = Number(getTrackIndexByName(name));
if (i > 0)
{
var temp = trackList[i];
trackList[i] = trackList[i - 1];
trackList[i - 1] = temp;
}
reorderTracks();
});
group.append("path")
.attr("transform", function (d) {
return "translate(" + -20 + "," + 10 + ")"
})
.attr("d", d3.svg.symbol().type(["triangle-down"]))
.attr("class", "down")
.on('click', function () {
var i = Number(getTrackIndexByName(name));
if (i < trackList.length - 1)
{
var temp = trackList[i];
trackList[i] = trackList[i + 1];
trackList[i + 1] = temp;
}
reorderTracks();
});
this.trackGroup = group.append("g")
.attr("clip-path", "url(#clip)")
.append("g");
this.isSelected = function () {
return group.select("#check").node().checked;
}
//Updates currently loaded objects whenever zooming or scrolling
this.zoomed = function () {
};
//Pull in new data from database if neccessary when zooming/scrolling stops
this.updateTrack = function () {
};
this.getData = function () {
};
this.getRange = function () {
};
}
function CpgTrack(name, group, args) {
Track.call(this, name, group, args);
var trackGroup = this.trackGroup;
var fileHandle = args.table_name;
var tempHandles = fileHandle.split(",");
var cpgFileHandle = tempHandles[0];
var shelveFileHandle = tempHandles[1];
var shoreFileHandle = tempHandles[2];
var data;
var redrawCutoff = 1000; //Scale at which rectangles will be drawn individually
var getScale = function () {
if (zoom.scale() < redrawCutoff)
return fullXScale;
else
return xScale;
}
var drawTrack = function (data)
{
var thisScale = getScale();
trackGroup.selectAll("rect")
.data(data, function (d) {
return d;
})
.exit()
.remove();
trackGroup.selectAll("rect")
.data(data, function (d) {
return d;
})
.enter()
.append("rect");
trackGroup.selectAll("rect")
.style("fill-opacity", ".4")
.style("stroke", function (d) {
var type = d[indexArray.type];
return type == "cpg" ? "red" : type == "shore" ? "green" : "yellow"
})
.style("fill", function (d) {
var type = d[indexArray.type];
return type == "cpg" ? "red" : type == "shore" ? "green" : "yellow"
})
.style("vector-effect", "non-scaling-stroke")
//.attr("class", "scalable")
.attr("height", function (d) {
var type = d[indexArray.type];
return type == "cpg" ? 40 : type == "shore" ? 20 : 15
})
.attr("width", function (d) {
return thisScale(d[indexArray.end]) - thisScale(d[indexArray.start])
})
.attr("x", function (d) {
return thisScale(d[indexArray.start])
})
.attr("y", function (d) {
var type = d[indexArray.type];
var offset = type == "cpg" ? -20 : type == "shore" ? -10 : -7.5;
return offset;//height / 2 + margin + offset
})
addTooltip(trackGroup.selectAll("rect")
.filter(function (d) {
return d[indexArray.type] == "cpg";
}), "cpg", cpgFileHandle);
addTooltip(trackGroup.selectAll("rect")
.filter(function (d) {
return d[indexArray.type] == "shore";
}), "shore", shoreFileHandle);
addTooltip(trackGroup.selectAll("rect")
.filter(function (d) {
return d[indexArray.type] == "shelve";
}), "shelve", shelveFileHandle);
}
var addTooltip = function (selection, type, fileHandle)
{
var start = (Math.round(xScale.domain()[0])).toString();
var end = (Math.round(xScale.domain()[1])).toString();
var scale = (end - start) / 1000;
selection.each(
function (d) {
$(this).qtip({
content: {
text: "Loading..."
},
position: {
my: 'top center',
at: 'top center',
target: 'mouse',
adjust: {
mouse: true, // Can be omitted (e.g. default behaviour)
y: 10
}
}
})
});
selection.each(function () {
var selected = $(this);
var hoverTimeout = 0;
$(this).mousemove(function (event) {
clearTimeout(hoverTimeout);
hoverTimeout = setTimeout(function () {
var pixelWidth = (xScale.domain()[1] - xScale.domain()[0]) / 1000
var min = (event.pageX - 60) * pixelWidth + xScale.domain()[0];
var max = (event.pageX - 58) * pixelWidth + xScale.domain()[0];
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
data: {
"loadTooltip": "",
"chrom": chrom_curr,
"type": type,
"min": min,
"max": max,
'fileHandle': fileHandle
}
})
.then(function (content) {
// Set the tooltip content upon successful retrieval
selected.qtip('option', 'content.text', content);
selected.qtip('reposition', event);
}, function (xhr, status, error) {
// Upon failure... set the tooltip content to the status and error value
selected.qtip('option', 'content.text', status + ': ' + error);
});
}, 200);
});
});
}
this.updateTrack = function () {
var start = (Math.round(xScale.domain()[0])).toString();
var end = (Math.round(xScale.domain()[1])).toString();
var chrom = chrom_curr;
//var fileHandles = [fileHandle];
var name = this.name;
var LoadingText = group.append("g")
LoadingText.append("rect")
.attr("x", 450)
.attr("width", 100)
.attr("y", -10)
.attr("height", 20)
.attr("rx", 6)
.attr("ry", 6)
.style("fill-opacity", .6)
.style("fill", "white")
LoadingText.append("text")
.text("Loading...")
.attr("x", 475)
.attr("y", 5);
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
data: {
"getTrackData": "",
"fileHandle": fileHandle,
"type": "cpg",
"chrom": chrom,
"start": start,
"end": end
}
}).success(function (returnData) {
drawTrack(returnData);
LoadingText.remove();
}
).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
}
var previousScale = 1;
this.zoomed = function () {
var thisScale = getScale();
if (zoom.scale() < redrawCutoff)
{
if (previousScale > redrawCutoff)
{
trackGroup.selectAll("rect")
.attr("width", function (d) {
return thisScale(d[indexArray.end]) - thisScale(d[indexArray.start])
})
.attr("x", function (d) {
return thisScale(d[indexArray.start])
});
}
trackGroup.attr("transform", "translate(" + zoom.translate()[0] + ",0)scale(" + zoom.scale() + ",1)");
}
else
{
trackGroup.attr("transform", null);
trackGroup.selectAll("rect")
.attr("width", function (d) {
return thisScale(d[indexArray.end]) - thisScale(d[indexArray.start])
})
.attr("x", function (d) {
return thisScale(d[indexArray.start])
});
}
previousScale = zoom.scale();
}
this.getData = function () {
return data;
}
this.getRange = function () {
var range;
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
async: false,
data: {
"getRange": "",
"fileHandle": fileHandle,
"type": "cpg",
"chrom": chrom_curr
}
}).success(function (returnData) {
range = returnData;
}).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
return range;
}
}
function BedTrack(name, group, args) {
Track.call(this, name, group, args)
var trackGroup = this.trackGroup;
var fileHandle = args.table_name;
var data;
var redrawCutoff = 1000; //Scale at which rectangles will be drawn individually
var getScale = function () {
if (zoom.scale() < redrawCutoff)
return fullXScale;
else
return xScale;
}
var drawTrack = function (data, exons)
{
if (data.length === 0) {
return;
}
var thisScale = getScale();
var trackHeight = 10;
trackGroup.selectAll("rect")
.data(data, function (d) {
return d;
})
.exit()
.remove();
trackGroup.selectAll("rect")
.data(data, function (d) {
return d;
})
.enter()
.append("rect");
trackGroup.selectAll("rect")
.data(data, function (d) {
return d;
})
.attr("x", function (d) {
return thisScale(d[indexArray.start]);
})
.attr("y", function (d) {
return d[indexArray.score] > 0 ? -10 : d[indexArray.score] < 0 ? 0 : -5;
})
.attr("height", 10)
.attr("width", function (d) {
return thisScale(d[indexArray.end]) - thisScale(d[indexArray.start]);
})
.style("fill-opacity", "1")
.style("stroke", function (d) {
return d[indexArray.score] > 0 ? "red" : d[indexArray.score] < 0 ? "green" : "grey";
})
.style("fill", function (d) {
return d[indexArray.score] > 0 ? "red" : d[indexArray.score] < 0 ? "green" : "grey";
})
.style("vector-effect", "non-scaling-stroke")
addTooltip(trackGroup.selectAll("rect")
.data(data, function (d) {
return d;
}), "gene")
if (exons)
{
trackGroup.selectAll("rect")
.data(exons, function (d) {
return d;
})
.enter()
.append("rect");
trackGroup.selectAll("rect")
.data(exons, function (d) {
return d;
})
.attr("x", function (d) {
return thisScale(d[indexArray.start]);
})
.attr("y", -10)
.attr("height", 20)
.attr("width", function (d) {
return thisScale(d[indexArray.end]) - thisScale(d[indexArray.start]);
})
.style("fill-opacity", ".8")
.style("stroke", "black")
.style("fill", "black")
.style("vector-effect", "non-scaling-stroke")
addTooltip(trackGroup.selectAll("rect")
.data(exons, function (d) {
return d;
}), "exon")
}
}
var addTooltip = function (selection, type)
{
var start = (Math.round(xScale.domain()[0])).toString();
var end = (Math.round(xScale.domain()[1])).toString();
var scale = (end - start) / 1000;
selection.each(
function (d) {
$(this).qtip({
content: {
text: "Loading..."
},
position: {
my: 'top center',
at: 'top center',
target: 'mouse',
adjust: {
mouse: true, // Can be omitted (e.g. default behaviour)
y: 10
}
}
})
});
selection.each(function () {
var selected = $(this);
var hoverTimeout = 0;
$(this).mousemove(function (event) {
clearTimeout(hoverTimeout);
hoverTimeout = setTimeout(function () {
var pixelWidth = (xScale.domain()[1] - xScale.domain()[0]) / 1000
var min = (event.pageX - 60) * pixelWidth + xScale.domain()[0];
var max = (event.pageX - 58) * pixelWidth + xScale.domain()[0];
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
data: {
"loadTooltip": "",
"chrom": chrom_curr,
"type": type,
"min": min,
"max": max,
'fileHandle': fileHandle
}
})
.then(function (content) {
// Set the tooltip content upon successful retrieval
selected.qtip('option', 'content.text', content);
selected.qtip('reposition', event);
}, function (xhr, status, error) {
// Upon failure... set the tooltip content to the status and error value
selected.qtip('option', 'content.text', status + ': ' + error);
});
}, 200);
});
});
}
this.updateTrack = function () {
var start = (Math.round(xScale.domain()[0])).toString();
var end = (Math.round(xScale.domain()[1])).toString();
var chrom = chrom_curr;
var LoadingText = group.append("g")
LoadingText.append("rect")
.attr("x", 450)
.attr("width", 100)
.attr("y", -10)
.attr("height", 20)
.attr("rx", 6)
.attr("ry", 6)
.style("fill-opacity", .6)
.style("fill", "white")
LoadingText.append("text")
.text("Loading...")
.attr("x", 475)
.attr("y", 5);
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
data: {
"getTrackData": "",
"fileHandle": fileHandle,
"type": "gene",
"chrom": chrom,
"start": start,
"end": end
}
}).success(function (returnData) {
if (returnData.length == 2) {//exons exist
drawTrack(returnData[0], returnData[1]);
}
else {
drawTrack(returnData);
}
LoadingText.remove();
}
).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
this.zoomed();
}
var previousScale = 1;
this.zoomed = function () {
var thisScale = getScale();
if (zoom.scale() < redrawCutoff)
{
if (previousScale > redrawCutoff)
{
trackGroup.selectAll("rect")
.attr("width", function (d) {
return thisScale(d[indexArray.end]) - thisScale(d[indexArray.start])
})
.attr("x", function (d) {
return thisScale(d[indexArray.start])
});
}
trackGroup.attr("transform", "translate(" + zoom.translate()[0] + ",0)scale(" + zoom.scale() + ",1)");
}
else
{
trackGroup.attr("transform", null);
trackGroup.selectAll("rect")
.attr("width", function (d) {
return thisScale(d[indexArray.end]) - thisScale(d[indexArray.start])
})
.attr("x", function (d) {
return thisScale(d[indexArray.start])
});
}
previousScale = zoom.scale();
}
this.getData = function () {
var data;
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
async: false,
data: {
"getFullTrackData": "",
"fileHandle": fileHandle
}
}).success(function (returnData) {
data = returnData;
data.unshift(["CHROM", "CHROM_START", "CHROM_END", "GENESYMBOL", "SCORE", "STRAND"]);
}).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
return data;
}
this.getRange = function () {
var range;
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
async: false,
data: {
"getRange": "",
"fileHandle": fileHandle,
"type": "gene",
"chrom": chrom_curr
}
}).success(function (returnData) {
range = returnData;
}).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
return range;
}
}
function CustomTrack(name, group, args) {
Track.call(this, name, group, args)
var trackGroup = this.trackGroup;
var fileHandle = args.table_name;
var data;
var redrawCutoff = 1000; //Scale at which rectangles will be drawn individually
var getScale = function () {
if (zoom.scale() < redrawCutoff)
return fullXScale;
else
return xScale;
}
var drawTrack = function (data, exons)
{
if (data.length === 0) {
return;
}
var thisScale = getScale();
var trackHeight = 10;
trackGroup.selectAll("rect")
.data(data, function (d) {
return d;
})
.exit()
.remove();
trackGroup.selectAll("rect")
.data(data, function (d) {
return d;
})
.enter()
.append("rect");
trackGroup.selectAll("rect")
.data(data, function (d) {
return d;
})
.attr("x", function (d) {
return thisScale(d[indexArray.start]);
})
.attr("y", function (d) {
return d[indexArray.score] > 0 ? -10 : d[indexArray.score] < 0 ? 0 : -5;
})
.attr("height", 10)
.attr("width", function (d) {
return thisScale(d[indexArray.end]) - thisScale(d[indexArray.start]);
})
.style("fill-opacity", "1")
.style("stroke", function (d) {
return d[indexArray.score] > 0 ? "red" : d[indexArray.score] < 0 ? "green" : "grey";
})
.style("fill", function (d) {
return d[indexArray.score] > 0 ? "red" : d[indexArray.score] < 0 ? "green" : "grey";
})
.style("vector-effect", "non-scaling-stroke")
addTooltip(trackGroup.selectAll("rect")
.data(data, function (d) {
return d;
}), "custom")
}
var addTooltip = function (selection, type)
{
var start = (Math.round(xScale.domain()[0])).toString();
var end = (Math.round(xScale.domain()[1])).toString();
var scale = (end - start) / 1000;
selection.each(
function (d) {
$(this).qtip({
content: {
text: "Loading..."
},
position: {
my: 'top center',
at: 'top center',
target: 'mouse',
adjust: {
mouse: true, // Can be omitted (e.g. default behaviour)
y: 10
}
}
})
});
selection.each(function () {
var selected = $(this);
var hoverTimeout = 0;
$(this).mousemove(function (event) {
clearTimeout(hoverTimeout);
hoverTimeout = setTimeout(function () {
var pixelWidth = (xScale.domain()[1] - xScale.domain()[0]) / 1000
var min = (event.pageX - 60) * pixelWidth + xScale.domain()[0];
var max = (event.pageX - 58) * pixelWidth + xScale.domain()[0];
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
data: {
"loadTooltip": "",
"chrom": chrom_curr,
"type": "custom",
"min": min,
"max": max,
'fileHandle': fileHandle
}
})
.then(function (content) {
// Set the tooltip content upon successful retrieval
selected.qtip('option', 'content.text', content);
selected.qtip('reposition', event);
}, function (xhr, status, error) {
// Upon failure... set the tooltip content to the status and error value
selected.qtip('option', 'content.text', status + ': ' + error);
});
}, 200);
});
});
}
this.updateTrack = function () {
var start = (Math.round(xScale.domain()[0])).toString();
var end = (Math.round(xScale.domain()[1])).toString();
var chrom = chrom_curr;
var LoadingText = group.append("g")
LoadingText.append("rect")
.attr("x", 450)
.attr("width", 100)
.attr("y", -10)
.attr("height", 20)
.attr("rx", 6)
.attr("ry", 6)
.style("fill-opacity", .6)
.style("fill", "white")
LoadingText.append("text")
.text("Loading...")
.attr("x", 475)
.attr("y", 5);
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
data: {
"getTrackData": "",
"fileHandle": fileHandle,
"type": "custom",
"chrom": chrom,
"start": start,
"end": end
}
}).success(function (returnData) {
if (returnData.length == 2) {//exons exist
drawTrack(returnData[0], returnData[1]);
}
else {
drawTrack(returnData);
}
LoadingText.remove();
}
).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
this.zoomed();
}
var previousScale = 1;
this.zoomed = function () {
var thisScale = getScale();
if (zoom.scale() < redrawCutoff)
{
if (previousScale > redrawCutoff)
{
trackGroup.selectAll("rect")
.attr("width", function (d) {
return thisScale(d[indexArray.end]) - thisScale(d[indexArray.start])
})
.attr("x", function (d) {
return thisScale(d[indexArray.start])
});
}
trackGroup.attr("transform", "translate(" + zoom.translate()[0] + ",0)scale(" + zoom.scale() + ",1)");
}
else
{
trackGroup.attr("transform", null);
trackGroup.selectAll("rect")
.attr("width", function (d) {
return thisScale(d[indexArray.end]) - thisScale(d[indexArray.start])
})
.attr("x", function (d) {
return thisScale(d[indexArray.start])
});
}
previousScale = zoom.scale();
}
this.getData = function () {
var data;
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
async: false,
data: {
"getFullTrackData": "",
"fileHandle": fileHandle
}
}).success(function (returnData) {
data = returnData;
data.unshift(["CHROM", "CHROM_START", "CHROM_END", "GENESYMBOL", "SCORE", "STRAND"]);
}).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
return data;
}
this.getRange = function () {
var range;
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
async: false,
data: {
"getRange": "",
"fileHandle": fileHandle,
"type": "custom",
"chrom": chrom_curr
}
}).success(function (returnData) {
range = returnData;
}).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
return range;
}
}
function FastaTrack(name, group, args) {
Track.call(this, name, group, args);
var trackGroup = this.trackGroup;
var file = args.fasta;
var indexFile = args.index
var drawTrack = function (data) {
trackGroup.selectAll("text")
.data(data, function (d) {
return d;
})
.exit()
.remove();
trackGroup.selectAll("text")
.data(data, function (d) {
return d;
})
.enter()
.append("text")
trackGroup.selectAll("text")
.data(data, function (d) {
return d;
})
.text(function (d) {
return d[0]
})
.attr("x", function (d) {
return xScale(d[1]) - 2; //-2 to center text
})
addTooltip(trackGroup.selectAll("text"))
}
var clearTrack = function () {
trackGroup.selectAll("text").remove();
}
var addTooltip = function (selection) {
var start = (Math.round(xScale.domain()[0])).toString();
var end = (Math.round(xScale.domain()[1])).toString();
var scale = (end - start) / 1000;
selection.each(
function (d) {
$(this).qtip({
content: {
text: d[1]
},
position: {
my: 'top center',
at: 'top center',
target: 'mouse',
adjust: {
mouse: true, // Can be omitted (e.g. default behaviour)
y: 10
}
}
})
});
}
this.zoomed = function () {
trackGroup.selectAll("text")
.attr("x", function (d) {
return xScale(d[1]) - 2;
})
}
this.updateTrack = function () {
if (zoom.scale() >= (panExtent[1] - panExtent[0]) / 100 / initialZoom)
{
var LoadingText = group.append("g")
LoadingText.append("rect")
.attr("x", 450)
.attr("width", 100)
.attr("y", -10)
.attr("height", 20)
.attr("rx", 6)
.attr("ry", 6)
.style("fill-opacity", .6)
.style("fill", "white")
LoadingText.append("text")
.text("Loading...")
.attr("x", 475)
.attr("y", 5);
var xStart = Math.floor(xScale.domain()[0]);
var length = Math.ceil(xScale.domain()[1]) - xStart;
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
data: {
"loadFastaData": "",
"chrom": chrom_curr,
"start": xStart,
"length": length,
"file": file,
"indexFile": indexFile
}
}).success(function (returnData) {
var data = returnData.split("");
for (var i = 0; i < returnData.length; i++)
{
data[i] = [data[i], xStart + i]
}
drawTrack(data);
LoadingText.remove();
}).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
}
else {
clearTrack();
}
}
this.getRange = function () {
var range;
$.ajax({
url: serviceURL,
type: 'POST',
dataType: "json",
async: false,
data: {
"getFastaRange": "",
"chrom": chrom_curr,
"indexFile": indexFile
}
}).success(function (returnData) {
range = returnData;
}).error(function (req, status, error) {
$("body").append(status + ": " + error);
});
return range;
}
}
}