Permalink
Cannot retrieve contributors at this time
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?
VQI_GenomeBrowser/VQI_GenomeBrowser.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
executable file
1881 lines (1604 sloc)
65.2 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function VQI_GenomeBrowser(id, serviceURL) { | |
var divId = id; | |
var width = 1000; | |
var height = 20; | |
var margin = 50; | |
var bufferSpace = 20; | |
var trackHeight = 50; | |
var panExtent = [0, width]; | |
var trackList = []; | |
var genomeData = []; | |
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 zoomOnly = false; | |
var waitTime; | |
var trackInfo = []; | |
trackInfo[0] = {name: "HG19", type: "bed", fileHandle: "upload1436481988"}; | |
trackInfo[1] = {name: "Tile2 Content Snp", type: "bed", fileHandle: "upload1436411775"}; | |
trackInfo[2] = {name: "cpg", type: "cpg", fileHandle: "upload1437097194,upload1437098473,upload1437098556"}; | |
var serviceURL = serviceURL; | |
// $("#" + id).append("<div style='border : 1px solid; display : inline-block'>CPG:<input type='file' id='cpg'/>Shore:<input type='file' id='shore'/>Shelve:<input type='file' id='shelve'/><input id='submit' type='submit' /></div>"); | |
// d3.select("#" + id).append("div").text("Chromosome: ") | |
// var select = d3.select("#" + id) | |
// .append("div") | |
// .append("select") | |
// .on("change", function (d) { | |
// graph(select.property("value")); | |
// }); | |
// | |
// d3.select("#" + id).append("div").text("Start: ") | |
// var minNumber = d3.select("#" + id) | |
// .append("input") | |
// .attr("type", "number") | |
// .property("value", 0); | |
// | |
// d3.select("#" + id).append("div").text("End: ") | |
// var maxNumber = d3.select("#" + id) | |
// .append("input") | |
// .attr("type", "number") | |
// .property("value", 0); | |
// var graphButton = d3.select("#" + id) | |
// .append("input") | |
// .attr("type", "button") | |
// .attr("value", "Graph") | |
// .on("click", function () { | |
// graph(select.property("value"), minNumber.property("value"), maxNumber.property("value")) | |
// }); | |
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 | |
{ | |
graph(chrom, chrom_start, chrom_end); | |
} | |
} | |
else | |
{ | |
browseToGene(); | |
} | |
}; | |
var addRecentTrack = function(){ | |
console.log(trackInfo); | |
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.addOneTrackFromDatabase(trackInfo[i].fileHandle,track,trackInfo[i].type); | |
break; | |
} | |
} | |
} | |
/*this.makeNavigationForm = function () { | |
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'>" + navigateBox + navigateButton + "</form>"; | |
$("#" + divId).append(form); | |
$("#" + divId + " #navigatebutton").on("click", navigateToRegion.bind(this)); | |
}; | |
this.makeNavigationForm();*/ | |
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); | |
// objVQIResult.parseSNPAndSNP(data, true); | |
}).error(function (req, status, error) { | |
$("body").append(status + ": " + error); | |
}); | |
}; | |
this.makeNavigationForm = function () { | |
var navigateBox = "<input type='text' name='navigate' id='navigate' size='30'>"; | |
var navigateButton = "<input type='button' id='navigatebutton' value='Go To'>"; | |
//var geneText = "Gene: <input type='text' name='geneName' id='geneName'>"; | |
//var geneSearchButton = "<input type='button' id='genesearchbutton' value='Search'>"; | |
var form = "<form id='navigation_form'>" + navigateBox + navigateButton + "</form>"; | |
$("#" + divId).append(form); | |
//$("#" + divId + " #genesearchbutton").on("click", browseToGene.bind(this)); | |
$("#" + divId + " #navigatebutton").on("click", navigateToRegion.bind(this)); | |
}; | |
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); | |
// objVQIResult.parseSNPAndSNP(data, true); | |
}).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) { | |
console.log(data); | |
$("#pvalue_div").empty().append("p-value = " + data); | |
// alert("pvalue = " + data); | |
// objVQIResult.parseSNPAndSNP(data, true); | |
}).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).append(form); | |
$("#" + divId + " #colocalize").on("click", colocalize.bind(this)); | |
}; | |
this.makeFormForColocalization(); | |
var removeSelectedTracks = function () { | |
var tracknames = [] | |
for (var i in trackList) { | |
if (graphRegion.selectAll("g").data([trackList[i]['name']], function (d) { | |
return d; | |
}).select("#check").node().checked) | |
{ | |
tracknames.push(trackList[i]['name']); | |
} | |
} | |
for (var i in tracknames) { | |
removeTrack(tracknames[i]); | |
} | |
reorderTracks(); | |
} | |
var removeTrack = function (removedTrackName) { | |
//var removedTrackName = $("#" + divId + " #removeTrack").val(); | |
if (removedTrackName != null) | |
{ | |
for (var i in trackList) { | |
var thisTrack = trackList[i]; | |
if (thisTrack['name'] == removedTrackName) { | |
svg.selectAll("g").data([trackList[i]['name']], function (d) { | |
return d; | |
}).remove(); | |
trackList.splice(i, 1); | |
break; | |
} | |
} | |
} | |
updateAllTracksSelectBoxes(); | |
//graph(chrom_curr, xScale.domain()[0], xScale.domain()[1]); | |
}; | |
/*this.makeFormForRemoveTrack = function () { | |
var removeTrackSelect = "Remove: <select name='removeTrack' id='removeTrack'>"; | |
for (var i in trackList) { | |
var thisTrack = trackList[i]; | |
var text = thisTrack['name']; | |
var value = thisTrack['name']; | |
removeTrackSelect += "<option value='" + value + "'>" + text + "</option>"; | |
} | |
removeTrackSelect += "</select>"; | |
var removeButton = "<input type='button' id='removetrackbutton' value='Remove Track'>"; | |
var form = "<form id='removeTrack_form'>" + removeTrackSelect + removeButton + "</form>"; | |
$("#" + divId).append(form); | |
$("#" + divId + " #removetrackbutton").on("click", removeTrack.bind(this)); | |
}; | |
this.makeFormForRemoveTrack();*/ | |
this.getSelectedTrackNames = function(){ | |
var tracknames = [] | |
for (var i in trackList) { | |
if (graphRegion.selectAll("g").data([trackList[i]['name']], function (d) { | |
return d; | |
}).select("#check").node().checked) | |
{ | |
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 (graphRegion.selectAll("g").data([trackList[i]['name']], function (d) { | |
return d; | |
}).select("#check").node().checked) | |
{ | |
tracknames.push(trackList[i]['name']); | |
} | |
} | |
for (var i in tracknames) { | |
exportTrack(tracknames[i]); | |
} | |
} | |
var exportTrack = function (track_name) { | |
// alert("here"); | |
// var outputFile = window.prompt("What do you want to name your output file (Note: This won't have any effect on Safari)") || 'export'; | |
// outputFile = outputFile.replace('.csv','') + '.txt' | |
//var track_name = $("#" + divId + " #exportTrack").val(); | |
var track = thisObj.getTrackByName(track_name); | |
// console.log(track); | |
exportTrackToText(track, track_name); | |
} | |
/*this.makeFormForExportTrack = function () { | |
var exportTrackSelect = "Export: <select name='exportTrack' id='exportTrack'>"; | |
for (var i in trackList) { | |
var thisTrack = trackList[i]; | |
var text = thisTrack['name']; | |
var value = thisTrack['name']; | |
exportTrackSelect += "<option value='" + value + "'>" + text + "</option>"; | |
} | |
exportTrackSelect += "</select>"; | |
var exportButton = "<input type='button' id='exporttrackbutton' value='Export'>"; | |
var form = "<form id='exportTrack_form'>" + exportTrackSelect + exportButton + "</form>"; | |
$("#" + divId).append(form); | |
$("#" + divId + " #exporttrackbutton").on("click", exportTrack.bind(this)); | |
} | |
this.makeFormForExportTrack();*/ | |
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"); | |
f.innerHTML = "Add track by uploading file: "; | |
f.appendChild(fileInput); | |
$("#" + divId).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).append(form); | |
$("#" + divId + " #addTrackButton").on("click", addRecentTrack.bind(this)); | |
} | |
this.makeRecentTrackForm(); | |
this.makeSelectionForm = function () { | |
var removeButton = "<input type='button' id='removetrackbutton' value='Remove Track'>"; | |
var exportButton = "<input type='button' id='exporttrackbutton' value='Export'>"; | |
// var scoreButton = "<input type='button' id='scoreTracks' value='Score' onclick='VQI_ControlPanel.scoreButtonClicked()'>"; | |
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 form = "<form id='selectionForm'>" + removeButton + exportButton + mcScoreButton + entScoreButton + "</form>"; | |
$("#" + divId).append(form); | |
$("#" + 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 fullXScale = d3.scale.linear(); | |
var xScale = 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") | |
// .attr("transform", "translate(0," + (height + margin) + ")"); | |
var zoom = d3.behavior.zoom(); | |
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. | |
//set up tool tips | |
/*var tip = d3.tip() | |
.attr('class', 'd3-tip') | |
.offset([-20, 0]) | |
.html(function (d) { | |
// if(/) | |
// if | |
var strand = ""; | |
if (d.length > indexArray.strand) { | |
strand = " (" + d[indexArray.strand] + ")"; | |
} | |
return "<span style='color:white; font-size:10pt; display:block; text-align:center'>" + d[indexArray.name] + strand + "</span>" | |
+ "<span style='color:white; font-size:10pt; display:block'>(" + d[indexArray.chr] + " : " + d[indexArray.start] + " - " + d[indexArray.end] + ")" + "</span>"; | |
}); | |
svg.call(tip); | |
d3.selectAll(".d3-tip").style({ | |
"line-height": "1", | |
"font-weight": "bold", | |
"padding": "12px", | |
"background": "rgba(0, 0, 0, 0.8)", | |
"color": "#fff", | |
"border-radius": "2px" | |
});*/ | |
var zoomed = function () { | |
zoom.translate([panLimit(), 0]); | |
//console.log(d3.event.scale); | |
//svg.selectAll("g.scalable").attr("transform", "translate(" + d3.event.translate[0] + ",0)scale(" + d3.event.scale + ",1)"); | |
//fast, scales as a group, but doesn't draw at large zooms | |
svg.selectAll("g.scalable").attr("transform", "translate(" + zoom.translate()[0] + ",0)scale(" + zoom.scale() + ",1)"); | |
//slow, scales elements individually, draws at large zooms | |
//svg.selectAll("g.scalable").selectAll("*").attr("transform", "translate(" + zoom.translate()[0]+",0)scale(" + zoom.scale() + ",1)"); | |
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"}); | |
//console.log(zoom.scale()); | |
//optmizedTrack(); | |
if (! zoomOnly){ | |
if (waitTime != undefined) | |
{ | |
clearTimeout(waitTime); | |
} | |
waitTime = setTimeout(updateTrack, 100); } | |
//addOneTrack(testdata, "HG19", 'bed'); | |
$("#" + divId + " #navigate").val(chrom_curr + ":" + Math.round(xScale.domain()[0]) + "-" + Math.round(xScale.domain()[1])); | |
}; | |
var uploadFile = function(data){ | |
var rows = data.split("\n"); | |
headerArray = rows[0].split("\t"); | |
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; | |
console.log(CurrentFileHandle); | |
trackInfo.push({name: CurrentFileHandle, type: "bed", fileHandle: CurrentFileHandle}); | |
updateRecentTrackDropDown(); | |
self.addOneTrackFromDatabase(CurrentFileHandle,CurrentFileHandle,"bed"); | |
//self.loadData(CurrentFileHandle); | |
//setTimeout(function() { this.getCurrentData(); }, 1000); | |
}).error(function (req, status, error) { | |
$("body").append(status + ": " + error); | |
}); | |
} | |
var updateTrack = function(){ | |
if (isready){ | |
//console.log(trackList); | |
//setTimeout(testRemove(), 5000); | |
//testRemove(); | |
var start = (Math.round(xScale.domain()[0])).toString(); | |
var end = (Math.round(xScale.domain()[1])).toString(); | |
// var xScale = d3.scale.linear() | |
// .domain([-3953, 249241810]) | |
// .range([0,1000]); | |
var chrom = "chr1"; | |
var fileHandles = []; | |
var name = []; | |
for (i in trackList) { | |
for(j in trackInfo){ | |
if(trackInfo[j].name == trackList[i].name){ | |
fileHandles.push(trackInfo[j].fileHandle); | |
break; | |
} | |
} | |
name.push(trackList[i].name); | |
} | |
$.ajax({ | |
url: serviceURL, | |
type: 'POST', | |
dataType: "json", | |
data: { | |
"getTrackData": "", | |
"fileHandles": fileHandles, | |
"name": name, | |
"chrom": chrom, | |
"start": start, | |
"end": end | |
} | |
}).success(function (returnData) { | |
//console.log(returnData); | |
//console.log(trackList); | |
for (i in trackList){ | |
var name = trackList[i]['name']; | |
var type = trackList[i]['type']; | |
trackList[i] = returnData[name]; | |
trackList[i]['name'] = name; | |
trackList[i]['type'] = type; | |
if (name == "HG19"){ | |
addBEDTrack(returnData[name][0], name, returnData[name][1]); | |
} | |
else if (name == "cpg"){ | |
addCpgTrack(returnData[name], name); | |
} | |
else{ | |
addBEDTrack(returnData[name], name); | |
//console.log("hellow"); | |
} | |
} | |
// var i = getTrackIndexByName("HG19"); | |
// trackList[i] = returnData["HG19"]; | |
// trackList[i]['name'] = "HG19"; | |
// trackList[i]['type'] = "bed"; | |
// //console.log(trackList); | |
// addBEDTrack(returnData["HG19"][0], "HG19",returnData["HG19"][1]); | |
// var i = getTrackIndexByName("Tile2 Content Snp"); | |
// trackList[i] = returnData["Tile2 Content Snp"]; | |
// trackList[i]['name'] = "Tile2 Content Snp"; | |
// trackList[i]['type'] = "bed"; | |
// //console.log(trackList); | |
// addBEDTrack(returnData["Tile2 Content Snp"], "Tile2 Content Snp"); | |
// //console.log(trackList); | |
// var i = getTrackIndexByName("cpg"); | |
// trackList[i] = returnData["cpg"]; | |
// trackList[i]['name'] = "cpg"; | |
// trackList[i]['type'] = "cpg"; | |
// //console.log(trackList); | |
// addCpgTrack(returnData["cpg"], "cpg"); | |
zoomOnly = true; | |
zoomed(); | |
zoomOnly = false; | |
}).error(function (req, status, error) { | |
$("body").append(status + ": " + error); | |
}); | |
} | |
} | |
var testRemove = function(){ | |
removeTrack("HG191"); | |
reorderTracks(); | |
//console.log(trackList); | |
} | |
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) { | |
//console.log(Number(min) + " "+ Number(max)); | |
var xMin = Number(min) > panExtent[0] ? Number(min) : panExtent[0]; | |
var xMax = Number(max) < panExtent[1] ? Number(max) : panExtent[1]; | |
//console.log(xMin + " "+ xMax); | |
var initialZoom = 10000 //defines what will be considered a zoom scale of 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]); | |
zoom.x(xScale).on("zoom", zoomed); | |
svg.call(zoom).on("dblclick.zoom", null); | |
var scale = (panExtent[1] - panExtent[0]) / (xMax - xMin) / 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); | |
zoom.translate([zoomWidth, 0]) | |
.scale(scale); | |
zoomed(); | |
// minNumber.property("value", xMin); | |
// maxNumber.property("value", xMax); | |
} | |
var setPanExtent = function (min, max) { | |
var mins = []; | |
var maxs = []; | |
if (min != null && max != null) | |
{ | |
mins.push(Number(min)); | |
maxs.push(Number(max)); | |
} | |
for (var i in trackList) { | |
mins.push(d3.min(trackList[i], function (d) { | |
return Number(d[indexArray.start]) | |
})); | |
maxs.push(d3.max(trackList[i], function (d) { | |
return Number(d[indexArray.end]) | |
})); | |
} | |
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]) / 10000 | |
/*xScale.domain([0,distance]) | |
.range([0,width]);*/ | |
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)); | |
} | |
//console.log(trackList); | |
for (var i in trackList) { | |
addOneTrack(trackList[i], trackList[i]['name'], trackList[i]['type'], i); | |
} | |
//addOneTrack(trackList[2], trackList[2]['name'], trackList[2]['type'], 2); | |
} | |
var addOneTrack = function (data, name, type, i) { | |
i = Number(i); | |
var trackIndex; | |
if (!isNaN(i)) { | |
trackIndex = i; | |
} else { | |
trackIndex = trackList.length; | |
} | |
//check if min and max of whole graph needs to be readjusted | |
var min = d3.min(data, function (d) { | |
return Number(d[indexArray.start]) | |
}); | |
var max = d3.max(data, function (d) { | |
return Number(d[indexArray.start]) | |
}); | |
if (min < panExtent[0] || max > panExtent[1]) | |
{ | |
setPanExtent(min, max); | |
//console.log(trackList); | |
graph(chrom_curr); | |
} | |
var thisData = data.filter(function (d) { | |
return (d[indexArray.chr] === chrom_curr); | |
}); | |
//console.log(thisData); | |
var trackCount = trackIndex + 1; | |
//name of track | |
name = name || "track-" + (trackIndex + 1); | |
if (type == 'cpg') { | |
initTrack(name); | |
addCpgTrack(thisData, name); | |
data['type'] = 'cpg'; | |
} else { | |
// if (type == 'bed') { | |
initTrack(name); | |
addBEDTrack(thisData, name); | |
data['type'] = 'bed'; | |
} | |
data['name'] = name; | |
clipPath.attr("height", Number(svg.attr("height"))); | |
zoomOnly = true; | |
zoomed(); | |
zoomOnly = false; | |
return data; | |
} | |
var reorderTracks = function () { | |
svg.attr("height", height + 2 * margin + trackList.length * (trackHeight + bufferSpace)); | |
for (var i in trackList) { | |
graphRegion.selectAll("g").data([trackList[i]['name']], function (d) { | |
return d; | |
}) | |
.attr("transform", "translate(" + 0 + "," + (margin + bufferSpace + i * (trackHeight + bufferSpace)) + ")"); | |
} | |
} | |
var initTrack = function (name) { | |
graphRegion.selectAll("g").data([name], function (d) { | |
return d; | |
}).enter().append("g"); | |
var trackGroup = graphRegion.selectAll("g").data([name], function (d) { | |
return d; | |
}) | |
//.attr("transform", "translate(" + 0 + "," + thisY + ")"); | |
//Just a line | |
trackGroup.selectAll("line").data([name], function (d) { | |
return d; | |
}).enter().append("line") | |
.attr("x1", 0) | |
.attr("y1", 0) | |
.attr("x2", width) | |
.attr("y2", 0) | |
.style("stroke", "blue") | |
.style("stroke-opacity" , 0.5); | |
trackGroup.selectAll("text").data([name], function (d) { | |
return d; | |
}).enter().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); | |
/* if (trackGroup.select("rect.remove").empty()) | |
{ | |
trackGroup.append("rect") | |
.attr("height", 10) | |
.attr("width", 10) | |
.attr("x", width + 10) | |
.attr("y", -5) | |
.attr("class", "remove") | |
.on('click', function(){removeTrack(name);}); | |
} | |
if (trackGroup.select("rect.export").empty()) | |
{ | |
trackGroup.append("rect") | |
.attr("height", 10) | |
.attr("width", 10) | |
.attr("x", width + 30) | |
.attr("y", -5) | |
.attr("class", "export") | |
.on('click', function(){exportTrack(name);}); | |
}*/ | |
if (trackGroup.select(".checkbox").empty()) | |
{ | |
trackGroup.append("foreignObject") | |
.attr("width", 50) | |
.attr("height", 20) | |
.attr("x", width) | |
.attr("y", -10) | |
.attr("class", "checkbox") | |
.append("xhtml:div") | |
.html("<form><input type=checkbox id='check'/></form>") | |
.on("click", function () { | |
// console.log("clicked " + d + " -- " + i); | |
// console.log(trackGroup.select("#check").property('checked')); | |
xAxisSelection.call(xAxis);//I have no idea why it won't redraw the checkbox unless I call this | |
}); | |
} | |
if (trackGroup.select("path.up").empty()) | |
{ | |
trackGroup.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(); | |
}); | |
} | |
if (trackGroup.select("path.down").empty()) | |
{ | |
trackGroup.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(); | |
}); | |
} | |
/*if (trackGroup.select("rect.drag").empty()) | |
{ | |
var drag = d3.behavior.drag() | |
//.origin(function() { return {x: 0, y: d3.transform(trackGroup.attr("transform")).translate[1] }}) | |
.on("drag", function(){ | |
trackGroup = graphRegion.selectAll("g").data([name], function(d){return d;}) | |
.attr("transform", "translate(" + 0 + "," + Math.max(margin + trackHeight/2 - bufferSpace/2, Math.min(svg.attr("height") - 2* margin, d3.transform(trackGroup.attr("transform")).translate[1] + d3.event.y)) + ")"); | |
//console.log(thisY + " " +d3.event.y); | |
}); | |
trackGroup.append("rect") | |
.attr("height", trackHeight) | |
.attr("width", 10) | |
.attr("x", -20) | |
.attr("y", -trackHeight/2) | |
.attr("class", "drag") | |
.call(drag); | |
}*/ | |
if (trackGroup.select("g.scalable").empty()) | |
{ | |
trackGroup.append("g") | |
.attr("clip-path", "url(#clip)") | |
.append("g") | |
.attr("class", "scalable"); | |
} | |
} | |
var addCpgTrack = function (data, name) { | |
var trackScalableGroup = graphRegion.selectAll("g").data([name], function (d) { | |
return d; | |
}).select("g.scalable"); | |
trackScalableGroup.selectAll("rect") | |
.data(data, function (d) { | |
return d; | |
}) | |
.exit() | |
.remove(); | |
trackScalableGroup.selectAll("rect") | |
.data(data, function (d) { | |
return d; | |
}) | |
.enter() | |
.append("rect"); | |
trackScalableGroup.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 fullXScale(d[indexArray.end]) - fullXScale(d[indexArray.start]) | |
}) | |
.attr("x", function (d) { | |
return fullXScale(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 | |
}); | |
trackScalableGroup.selectAll('*').each(function(d){ | |
$(this).qtip({ | |
content: { | |
text: function(event, api) { | |
$.ajax({ | |
url: serviceURL, | |
type: 'POST', | |
dataType: "json", | |
data: { | |
"loadTooltip": "", | |
"trackName" : name, | |
"type" : d[indexArray.type], | |
"xCoordinate" : d[indexArray.start] | |
} | |
}) | |
.then(function(content) { | |
// Set the tooltip content upon successful retrieval | |
api.set('content.text', content); | |
}, function(xhr, status, error) { | |
// Upon failure... set the tooltip content to the status and error value | |
api.set('content.text', status + ': ' + error); | |
}); | |
return 'Loading...'; // Set some initial text | |
} | |
}, | |
position: { | |
my: 'top center', | |
at: 'top center', | |
target: 'mouse', | |
adjust: { | |
mouse: true, // Can be omitted (e.g. default behaviour) | |
y: 10 | |
} | |
} | |
}); | |
}) | |
} | |
var addBEDTrack = function (data, name, exons) { | |
testdata = data; | |
//console.log(data); | |
/** | |
* @author Pujan Joshi | |
* @since April 16, 2015 | |
* | |
* if data is empty, we do not need to proceed. Trying to check for | |
* some records in empty array was causing error in this method. | |
* | |
*/ | |
//console.log(data); | |
//console.log(name); | |
if (data.length === 0) { | |
return; | |
} | |
var trackHeight = 10; | |
var trackScalableGroup = graphRegion.selectAll("g").data([name], function (d) { | |
return d; | |
}).select("g.scalable"); | |
//console.log(data[142]); | |
trackScalableGroup.selectAll("rect") | |
.data(data, function (d) { | |
return d; | |
}) | |
.exit() | |
.remove(); | |
trackScalableGroup.selectAll("rect") | |
.data(data, function (d) { | |
return d; | |
}) | |
.enter() | |
.append("rect"); | |
// console.log(data[1]); | |
var tracks = trackScalableGroup.selectAll("rect") | |
.data(data, function (d) { | |
return d; | |
}) | |
.attr("x", function (d) { | |
return fullXScale(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 fullXScale(d[indexArray.end]) - fullXScale(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") | |
.attr("class", "scalable") | |
.each(function(d){ | |
$(this).qtip({ | |
content: { | |
text: function(event, api) { | |
$.ajax({ | |
url: serviceURL, | |
type: 'POST', | |
dataType: "json", | |
data: { | |
"loadTooltip": "", | |
"trackName" : name, | |
"type" : "gene", | |
"xCoordinate" : d[indexArray.start] | |
} | |
}) | |
.then(function(content) { | |
// Set the tooltip content upon successful retrieval | |
api.set('content.text', content); | |
}, function(xhr, status, error) { | |
// Upon failure... set the tooltip content to the status and error value | |
api.set('content.text', status + ': ' + error); | |
}); | |
return 'Loading...'; // Set some initial text | |
} | |
}, | |
position: { | |
my: 'top center', | |
at: 'top center', | |
target: 'mouse', | |
adjust: { | |
mouse: true, // Can be omitted (e.g. default behaviour) | |
y: 10 | |
} | |
} | |
}); | |
}) | |
/*.attr("x1", function (d) { | |
return fullXScale(d[indexArray.start]); | |
}) | |
.attr("y1", function (d) { | |
return 0; | |
}) | |
.attr("x2", function (d) { | |
return fullXScale(d[indexArray.end]); | |
}) | |
.attr("y2", function (d) { | |
return 0; | |
}) | |
.style("stroke", "black") | |
.style("stroke-width", "2px") | |
.attr("class", "scalable")*/ | |
if (exons) | |
{ | |
//console.log(exons[1]); | |
trackScalableGroup.selectAll("rect") | |
.data(data, function (d) { | |
return d; | |
}) | |
.exit() | |
.remove(); | |
trackScalableGroup.selectAll("rect") | |
.data(exons, function (d) { | |
return d; | |
}) | |
.enter() | |
.append("rect"); | |
trackScalableGroup.selectAll("rect") | |
.data(exons, function (d) { | |
return d; | |
}) | |
.attr("x", function (d) { | |
return fullXScale(d[0]); | |
}) | |
.attr("y", -10) | |
.attr("height", 20) | |
.attr("width", function (d) { | |
return fullXScale(d[1]) - fullXScale(d[0]); | |
}) | |
.style("fill-opacity", ".8") | |
.style("stroke", "black") | |
.style("fill", "black") | |
.style("vector-effect", "non-scaling-stroke") | |
.attr("class", "scalable") | |
.each(function(d){ | |
$(this).qtip({ | |
content: { | |
text: function(event, api) { | |
$.ajax({ | |
url: serviceURL, | |
type: 'POST', | |
dataType: "json", | |
data: { | |
"loadTooltip": "", | |
"trackName" : name, | |
"type" : "exon", | |
"xCoordinate" : d[indexArray.start] | |
} | |
}) | |
.then(function(content) { | |
// Set the tooltip content upon successful retrieval | |
api.set('content.text', content); | |
}, function(xhr, status, error) { | |
// Upon failure... set the tooltip content to the status and error value | |
api.set('content.text', status + ': ' + error); | |
}); | |
return 'Loading...'; // Set some initial text | |
} | |
}, | |
position: { | |
my: 'top center', | |
at: 'top center', | |
target: 'mouse', | |
adjust: { | |
mouse: true, // Can be omitted (e.g. default behaviour) | |
y: 10 | |
} | |
} | |
}); | |
}) | |
} | |
// //addHeightTrack(thisData, name); | |
} | |
/* var addHeightTrack = function (data, name) { | |
var bufferSpace = 10; | |
var trackHeight = 100; | |
var thisY = Number(svg.attr("height")) - margin + trackHeight / 2 + bufferSpace; | |
svg.attr("height", Number(svg.attr("height")) + trackHeight + bufferSpace); | |
var yScale = d3.scale.linear(); | |
var yMin = d3.min(data, function (d) { | |
return isNaN(d[indexArray.score]) ? 0 : Number(d[indexArray.score]) | |
}) - 1; | |
var yMax = d3.max(data, function (d) { | |
return isNaN(d[indexArray.score]) ? 0 : Number(d[indexArray.score]) | |
}) + 1; | |
yScale.domain([yMin, yMax]) | |
.range([thisY + trackHeight / 2, thisY - trackHeight / 2]); | |
var trackGroup = svg.select("g." + name); | |
var yAxis = d3.svg.axis() | |
.scale(yScale) | |
.orient("left") | |
.ticks(5); | |
var yAxisSelection = trackGroup.append("g") | |
.call(yAxis) | |
.attr("class", "axis " + name) | |
.attr("transform", "translate(" + margin + "," + 0 + ")"); | |
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"}); | |
var trackScalableGroup = trackGroup.select("g.scalable"); | |
if (trackScalableGroup.select("g.height").empty()) | |
{ | |
trackScalableGroup.append("g") | |
.attr("class", "height") | |
} | |
var trackHeightGroup = svg.select("g.height"); | |
var lines = data.filter(function (d) { | |
return d[indexArray.score] == ""; | |
}); | |
var rects = data.filter(function (d) { | |
return !isNaN(d[indexArray.score]) && d[indexArray.score] != ""; | |
}); | |
trackHeightGroup.selectAll("rect") | |
.data(rects, function (d) { | |
return d; | |
}) | |
.exit() | |
.remove(); | |
trackHeightGroup.selectAll("rect") | |
.data(rects, function (d) { | |
return d; | |
}) | |
.enter() | |
.append("rect"); | |
trackHeightGroup.selectAll("rect") | |
.data(rects, function (d) { | |
return d; | |
}) | |
.attr("x", function (d) { | |
return fullXScale(Number(d[indexArray.start])); | |
}) | |
.attr("y", function (d) { | |
return d < 0 ? yScale(0) : yScale(d[indexArray.score]); | |
}) | |
.attr("height", function (d) { | |
return Math.abs(yScale(d[indexArray.score]) - yScale(0)); | |
}) | |
.attr("width", function (d) { | |
return fullXScale(Number(d[indexArray.end])) - fullXScale(Number(d[indexArray.start])); | |
}) | |
.style("fill-opacity", ".8") | |
.style("stroke", "gray") | |
.style("fill", "gray") | |
trackHeightGroup.selectAll("line") | |
.data(lines, function (d) { | |
return d; | |
}) | |
.exit() | |
.remove(); | |
trackHeightGroup.selectAll("line") | |
.data(lines, function (d) { | |
return d; | |
}) | |
.enter() | |
.append("line"); | |
trackHeightGroup.selectAll("line") | |
.data(lines, function (d) { | |
return d; | |
}) | |
.attr("x1", function (d) { | |
return fullXScale(d[indexArray.start]); | |
}) | |
.attr("y1", yScale(0)) | |
.attr("x2", function (d) { | |
return fullXScale(d[indexArray.end]); | |
}) | |
.attr("y2", yScale(0)) | |
.style("stroke", "black") | |
.style("stroke-width", "2px") | |
}*/ | |
this.addTrackFromDatabase = function(){ | |
//console.log(trackList); | |
//setTimeout(testRemove(), 5000); | |
//testRemove(); | |
// var xScale = d3.scale.linear() | |
// .domain([-3953, 249241810]) | |
// .range([0,1000]); | |
var chrom = "chr1"; | |
var fileHandles = []; | |
var name = []; | |
for (i in trackInfo) { | |
fileHandles.push(trackInfo[i].fileHandle); | |
name.push(trackInfo[i].name); | |
} | |
$.ajax({ | |
url: serviceURL, | |
type: 'POST', | |
dataType: "json", | |
data: { | |
"getStartEndTrackData": "", | |
"fileHandles": fileHandles, | |
"name": name, | |
"chrom": chrom | |
} | |
}).success(function (returnData) { | |
//console.log(returnData); | |
for (i in trackInfo){ | |
thisObj.addTrack(returnData[i], trackInfo[i].name, trackInfo[i].type); | |
} | |
//console.log | |
// thisObj.addTrack(returnData[0], "HG19", "bed"); | |
// thisObj.addTrack(returnData[1], "Tile2 Content Snp", "bed"); | |
// thisObj.addTrack(returnData[2], "cpg", "cpg"); | |
isready = true; | |
updateTrack(); | |
}).error(function (req, status, error) { | |
$("body").append(status + ": " + error); | |
}); | |
} | |
this.addOneTrackFromDatabase = function(fileHandle,name,type){ | |
var chrom = "chr1"; | |
$.ajax({ | |
url: serviceURL, | |
type: 'POST', | |
dataType: "json", | |
data: { | |
"getStartEndTrackData": "", | |
"fileHandles": [fileHandle], | |
"name": [name], | |
"chrom": chrom | |
} | |
}).success(function (returnData) { | |
thisObj.addTrack(returnData[0], name, type); | |
//console.log(trackList); | |
isready = true; | |
updateTrack(); | |
}).error(function (req, status, error) { | |
$("body").append(status + ": " + error); | |
}); | |
} | |
this.addTrack = function (data, name, type) { | |
// data['name'] = name; | |
if(data[0][0] != "chrom") | |
{ | |
data.unshift(["chrom", "chrom_start", "chrom_end", "name", "score", "strand"]) | |
} | |
data = addOneTrack(data, name, type); | |
trackList.push(data); | |
reorderTracks(); | |
updateAllTracksSelectBoxes(); | |
} | |
this.addTrackFile = function (dataFile, name, type, header) { | |
$.get(dataFile, function (data) { | |
var dataRows = thisObj.parseTrackFile(data, header); | |
//console.log(dataRows); | |
//testdata = dataRows; | |
thisObj.addTrack(dataRows, name, type); | |
}); | |
} | |
this.setData = function (data) { | |
genomeData = data; | |
graph(chromosomes[0]); | |
} | |
this.getData = function () { | |
return genomeData; | |
} | |
/*var submitFile = function () { | |
genomeData = []; | |
chromosomes = []; | |
var file_dir = "./saved-data/"; | |
file_dir = "../../../saved-data/"; | |
var cpg = file_dir + "./CpG_site_hg19.txt"; | |
var shoer = file_dir + "./shoer_hg19.txt"; | |
var shelve = file_dir + "./shelve_hg19.txt"; | |
//Will read the 3 files and place all data into genomeData | |
//as objects with attributes 'chromosome', 'start', 'end', 'type' | |
$.get(cpg, function (data) { | |
var cpgData = data.trim().split("\n"); | |
$.each(cpgData, function (index, value) { | |
cpgData[index] = cpgData[index].trim().split("\t").map(function (item) { | |
return isNaN(Number(item)) ? item : Number(item); | |
}); | |
}); | |
//get all unique chromosomes | |
var currentChromosome = ""; | |
$.each(cpgData, function (index, value) { | |
if (value[0] != currentChromosome) | |
{ | |
chromosomes.push(value[0]); | |
currentChromosome = value[0]; | |
} | |
}); | |
cpgData = cpgData.map(function (data) { | |
// return {"chromosome": data[0], "start": data[1], "end": data[2], "type": "cpg"} | |
return [data[0], data[1], data[2], "cpg"]; | |
}); | |
genomeData = genomeData.concat(cpgData); | |
}); | |
$.get(shoer, function (data) { | |
var tempShoreData = data.trim().split("\n"); | |
$.each(tempShoreData, function (index, value) { | |
tempShoreData[index] = tempShoreData[index].trim().split("\t").map(function (item) { | |
return isNaN(Number(item)) ? item : Number(item); | |
}); | |
}); | |
var shoreData = []; | |
$.each(tempShoreData, function (index, value) { | |
// shoreData.push({"chromosome": value[0], "start": value[1], "end": value[2], "type": "shore"}); | |
shoreData.push([value[0], value[1], value[2], "shore"]); | |
shoreData.push([value[0], value[3], value[4], "shore"]); | |
// shoreData.push({"chromosome": value[0], "start": value[3], "end": value[4], "type": "shore"}); | |
}); | |
genomeData = genomeData.concat(shoreData); | |
}); | |
$.get(shelve, function (data) { | |
var tempShelveData = data.trim().split("\n"); | |
$.each(tempShelveData, function (index, value) { | |
tempShelveData[index] = tempShelveData[index].trim().split("\t").map(function (item) { | |
return isNaN(Number(item)) ? item : Number(item); | |
}); | |
}); | |
var shelveData = []; | |
$.each(tempShelveData, function (index, value) { | |
shelveData.push([value[0], value[1], value[2], "shelve"]); | |
// shelveData.push({"chromosome": value[0], "start": value[1], "end": value[2], "type": "shelve"}); | |
shelveData.push([value[0], value[3], value[4], "shelve"]); | |
// shelveData.push({"chromosome": value[0], "start": value[3], "end": value[4], "type": "shelve"}); | |
}); | |
genomeData = genomeData.concat(shelveData); | |
graph(chromosomes[0]); | |
}); | |
} | |
d3.select("#" + id + " #submit").on("click", submitFile.bind(this)); | |
// submitFile();*/ | |
this.loadCPGFiles = function (cpg, shoer, shelf) { | |
genomeData = []; | |
chromosomes = []; | |
//Will read the 3 files and place all data into genomeData | |
//as objects with attributes 'chromosome', 'start', 'end', 'type' | |
$.get(cpg, function (data) { | |
var cpgData = data.trim().split("\n"); | |
$.each(cpgData, function (index, value) { | |
cpgData[index] = cpgData[index].trim().split("\t").map(function (item) { | |
return isNaN(Number(item)) ? item : Number(item); | |
}); | |
}); | |
//get all unique chromosomes | |
var currentChromosome = ""; | |
$.each(cpgData, function (index, value) { | |
if (value[0] != currentChromosome) | |
{ | |
chromosomes.push(value[0]); | |
currentChromosome = value[0]; | |
} | |
}); | |
cpgData = cpgData.map(function (data) { | |
return [data[0], data[1], data[2], "cpg"]; | |
}); | |
genomeData = genomeData.concat(cpgData); | |
}); | |
$.get(shoer, function (data) { | |
var tempShoreData = data.trim().split("\n"); | |
$.each(tempShoreData, function (index, value) { | |
tempShoreData[index] = tempShoreData[index].trim().split("\t").map(function (item) { | |
return isNaN(Number(item)) ? item : Number(item); | |
}); | |
}); | |
var shoreData = []; | |
$.each(tempShoreData, function (index, value) { | |
// shoreData.push({"chromosome": value[0], "start": value[1], "end": value[2], "type": "shore"}); | |
shoreData.push([value[0], value[1], value[2], "shore"]); | |
shoreData.push([value[0], value[3], value[4], "shore"]); | |
// shoreData.push({"chromosome": value[0], "start": value[3], "end": value[4], "type": "shore"}); | |
}); | |
genomeData = genomeData.concat(shoreData); | |
}); | |
$.get(shelf, function (data) { | |
var tempShelveData = data.trim().split("\n"); | |
$.each(tempShelveData, function (index, value) { | |
tempShelveData[index] = tempShelveData[index].trim().split("\t").map(function (item) { | |
return isNaN(Number(item)) ? item : Number(item); | |
}); | |
}); | |
var shelveData = []; | |
$.each(tempShelveData, function (index, value) { | |
shelveData.push([value[0], value[1], value[2], "shelve"]); | |
// shelveData.push({"chromosome": value[0], "start": value[1], "end": value[2], "type": "shelve"}); | |
shelveData.push([value[0], value[3], value[4], "shelve"]); | |
// shelveData.push({"chromosome": value[0], "start": value[3], "end": value[4], "type": "shelve"}); | |
}); | |
genomeData = genomeData.concat(shelveData); | |
thisObj.addTrack(genomeData, "cpg", 'cpg'); | |
}); | |
} | |
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.makeFormForColocalization = function () { | |
// var track1Select = "<br>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 = "<br>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 colocalizeButton = "<br><input type='button' id='colocalize' value='colocalize'>"; | |
// var form = "<form id='colocalization_form'>" + track1Select + track2Select + colocalizeButton + "</form>"; | |
// $("#" + divId).append(form); | |
// $("#" + divId + " #colocalize").on("click", colocalize.bind(this)); | |
// }; | |
// | |
// var colocalize = function () { | |
// var track1Name = $("#" + divId + " #track1").val(); | |
// var track2Name = $("#" + divId + " #track2").val(); | |
// | |
// var data1 = this.getTrackByName(track1Name); | |
// var data2 = this.getTrackByName(track2Name); | |
// | |
// var dataToPost1 = [], dataToPost2 = []; | |
// dataToPost1 = JSON.stringify(data1); | |
// dataToPost2 = JSON.stringify(data2); | |
// | |
// $.ajax({ | |
// url: vqi_url + 'serverside/web/VQService.php?service=coloc-bed-and-bed', | |
// type: 'POST', | |
// dataType: "json", | |
// data: { | |
// "bed1": dataToPost1, | |
// "bed2": dataToPost2 | |
// }, | |
// async: false | |
// }).success(function (data) { | |
// var data1 = []; | |
// var data2 = [] | |
// data = data.slice(1); | |
// for (var i in data) { | |
// data1.push(data[i].slice(0, 3)); | |
// data2.push(data[i].slice(3)); | |
// } | |
// thisObj.addTrack(data1); | |
// thisObj.addTrack(data2); | |
// | |
//// objVQIResult.parseSNPAndSNP(data, true); | |
// }).error(function (req, status, error) { | |
// $("body").append(status + ": " + error); | |
// }); | |
// | |
// }; | |
this.getTrackByName = function (name) { | |
// console.log(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 removeTrackSelect = $("#" + divId + " #removeTrack"); | |
updateSelectBoxWithTracks(removeTrackSelect.get(0)); | |
var exportTrackSelect = $("#" + divId + " #exportTrack"); | |
updateSelectBoxWithTracks(exportTrackSelect.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 = []; | |
//console.log(data[1].join("\t")); | |
// var header = ["CHROM", "CHROM_START", "CHROM_END", "NAME", "SCORE", "STRAND"]; | |
// temp.push(header.join("\t")); | |
for (i in data) | |
{ | |
if (data[i].constructor === Array) | |
{ | |
var row = data[i].join("\t"); | |
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 optmizedTrack(){ | |
var myData; | |
var start = (Math.round(xScale.domain()[0])).toString(); | |
var end = (Math.round(xScale.domain()[1])).toString(); | |
// var xScale = d3.scale.linear() | |
// .domain([-3953, 249241810]) | |
// .range([0,1000]); | |
$.ajax({ | |
url: 'zoomAssist.php', | |
type: 'POST', | |
dataType: "json", | |
data: { | |
"start": start, | |
"end": end | |
} | |
}).success(function (data) { | |
myData = data; | |
//console.log(data); | |
d3.select(test2).select("svg") | |
.remove(); | |
var svg2 = d3.select(test2) | |
.append("svg") | |
.attr("width", width + 2 * margin) | |
.attr("height", height + 2 * margin); | |
var graphR = svg2.append("g").attr("transform", "translate(" + margin + "," + margin + ")"); | |
var tracks = graphR.selectAll("rect") | |
.data(myData) | |
.enter() | |
.append("rect") | |
.attr("fill", "gray") | |
.attr("x", function (d) { | |
return xScale(d.start); | |
}) | |
.attr("y", 5) | |
.attr("height", 10) | |
.attr("width", function (d) { | |
// if (xScale(d.end) - xScale(d.start) < 1){ | |
// return 1; | |
// } | |
// else return xScale(d.end) - xScale(d.start); | |
return Math.ceil(xScale(d.end) - xScale(d.start)); | |
}); | |
}).error(function (req, status, error) { | |
$("body").append(status + ": " + error); | |
}); | |
} | |
} |