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.
694 lines (584 sloc)
24 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) { | |
var divId = id; | |
var width = 1000; | |
var height = 100; | |
var margin = 50; | |
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}; | |
// $("#" + 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 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.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)); | |
}; | |
this.makeFormForColocalization(); | |
var self = this; | |
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")) | |
}); | |
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; | |
//set up scales and axis | |
var xScale = d3.scale.linear(); | |
var xAxis = d3.svg.axis() | |
.scale(xScale) | |
.orient("bottom") | |
.ticks(10); | |
//x-axis | |
var xAxisSelection = svg.append("g") | |
.call(xAxis) | |
.attr("class", "axis") | |
.attr("transform", "translate(0," + (0 + margin) + ")"); | |
// .attr("transform", "translate(0," + (height + margin) + ")"); | |
var zoom = d3.behavior.zoom(); | |
//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 () { | |
xAxisSelection.call(xAxis); | |
svg.selectAll("rect") | |
.attr("width", function (d) { | |
return xScale(d[indexArray.end]) - xScale(d[indexArray.start]) | |
}) | |
.attr("x", function (d) { | |
return xScale(d[indexArray.start]) | |
}) | |
minNumber.property("value", xScale.domain()[0]); | |
maxNumber.property("value", xScale.domain()[1]); | |
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 graph = function (chromosome, min, max) { | |
var indexList = indexArray; | |
//Graphs the current chromosome. If min and max are specified, graph only in that range. | |
//Otherwise, graphs the whole chromosome | |
var self = this; | |
var currentData; | |
var xMax = 0; | |
var xMin = 0; | |
//Populates drop down list with different chromosomes | |
select.selectAll("option") | |
.data(chromosomes) | |
.enter() | |
.append("option") | |
.attr("value", function (d) { | |
return d; | |
}) | |
.text(function (d) { | |
return d; | |
}) | |
chrom_curr = chromosome; | |
//Gets relevant data and calculates min/max if needed | |
if (min == null || max == null) { | |
currentData = genomeData.filter(function (d) { | |
return d[indexList.chr] == chromosome | |
}); | |
xMax = d3.max(currentData, function (d) { | |
return d[indexList.end] | |
}); | |
xMin = d3.min(currentData, function (d) { | |
return d[indexList.start] | |
}); | |
minNumber.property("value", xMin); | |
maxNumber.property("value", xMax); | |
} | |
else { | |
currentData = genomeData.filter(function (d) { | |
return d.chromosome == chromosome && d[indexList.start] >= min && d[indexList.end] <= max | |
}); | |
xMax = Number(max); | |
xMin = Number(min); | |
} | |
xScale.domain([xMin - (xMax - xMin) * 1 / 10, xMax + (xMax - xMin) * 1 / 10]) | |
.range([margin, width + margin]); | |
xAxisSelection.call(xAxis); | |
zoom.x(xScale) | |
.on("zoom", zoomed.bind(self)); | |
svg.call(zoom); | |
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"}); | |
//Just a line | |
svg.append("line") | |
.attr("x1", margin) | |
.attr("y1", height / 2 + margin + 20) | |
.attr("x2", width + margin) | |
.attr("y2", height / 2 + margin + 20) | |
.style("stroke", "blue"); | |
svg.selectAll("rect") | |
.data(currentData) | |
.exit() | |
.remove(); | |
svg.selectAll("rect") | |
.data(currentData) | |
.enter() | |
.append("rect"); | |
svg.selectAll("rect") | |
.style("fill-opacity", ".4") | |
.style("stroke", function (d) { | |
var type = d[indexList.type]; | |
return type == "cpg" ? "red" : type == "shore" ? "green" : "yellow" | |
}) | |
.style("fill", function (d) { | |
var type = d[indexList.type]; | |
return type == "cpg" ? "red" : type == "shore" ? "green" : "yellow" | |
}) | |
.attr("height", function (d) { | |
var type = d[indexList.type]; | |
return type == "cpg" ? 40 : type == "shore" ? 20 : 15 | |
}) | |
.attr("width", function (d) { | |
return xScale(d[indexList.end]) - xScale(d[indexList.start]) | |
}) | |
.attr("x", function (d) { | |
return xScale(d[indexList.start]) | |
}) | |
.attr("y", function (d) { | |
var type = d[indexList.type]; | |
var offset = type == "cpg" ? 0 : type == "shore" ? 10 : 12.5; | |
return height / 2 + margin + offset | |
}) | |
.on('mouseover', tip.show) | |
.on('mouseout', tip.hide); | |
for (var i in trackList) { | |
addOneTrack(trackList[i], trackList[i]['name'], i); | |
} | |
} | |
var addOneTrack = function (data, name, i) { | |
i = Number(i); | |
var trackIndex; | |
if (!isNaN(i)) { | |
trackIndex = i; | |
} else { | |
trackIndex = trackList.length; | |
} | |
var index = indexArray; | |
var thisData = data.filter(function (d) { | |
return (d[index.chr] === chrom_curr); | |
}); | |
//Just another line | |
var trackCount = trackIndex + 1; | |
//name of track | |
name = name || "track-" + (trackIndex + 1); | |
var ySpace = 50 * trackCount; | |
var fHeight = 10; | |
svg.attr("height", height + 2 * margin + ySpace); | |
var thisY = height / 2 + margin + 20 + ySpace; | |
if (!i) { | |
svg.append("line") | |
.attr("x1", margin) | |
.attr("y1", height / 2 + margin + 20 + ySpace) | |
.attr("x2", width + margin) | |
.attr("y2", height / 2 + margin + 20 + ySpace) | |
.style("stroke-width", 1) | |
.style("stroke", "black"); | |
svg.append("text") | |
.attr("x", 0) | |
.attr("y", thisY - 10) | |
.attr("font-family", "sans-serif") | |
.attr("font-size", "12px") | |
.attr("fill", "red") | |
.text(name); | |
} | |
// test.addTrack({start:20000000, end:20000100}) | |
var tracks = svg.selectAll("track") | |
.data(thisData) | |
.enter() | |
.append("rect"); | |
var rectAttributes = tracks | |
.attr("x", function (d) { | |
return xScale(d[index.start]); | |
}) | |
.attr("y", function (d) { | |
return thisY - fHeight / 2; | |
}) | |
.attr("height", function (d) { | |
return fHeight; | |
}) | |
.attr("width", function (d) { | |
// return 50; | |
return xScale(d[index.end]) - xScale(d[index.start]); | |
}) | |
.style("fill-opacity", ".4") | |
.style("stroke", "blue") | |
.style("fill", "green") | |
.on('mouseover', tip.show) | |
.on('mouseout', tip.hide); | |
// .tipsy({ | |
// gravity: 'w', | |
// html: true, | |
// title: function (d) { | |
// return d[indexArray.name] + " (" + d[indexArray.chr] + " : " + d[indexArray.start] + " - " + d[indexArray.end] + ")"; | |
// } | |
// }); | |
// | |
$('svg rect').tipsy({ | |
gravity: 'n', | |
html: true, | |
title: function () { | |
var d = this.__data__; | |
// , c = colors(d.i); | |
return d[indexArray.name] + " (" + d[indexArray.chr] + " : " + d[indexArray.start] + " - " + d[indexArray.end] + ")"; | |
} | |
}); | |
// .text(function (d) { | |
// return d[indexArray.name] + " (" + d[indexArray.chr] + " : " + d[indexArray.start] + " - " + d[indexArray.end] + ")"; | |
// }); | |
// | |
data['name'] = name; | |
return data; | |
} | |
this.addTrack = function (data, name) { | |
// data['name'] = name; | |
data = addOneTrack(data, name); | |
trackList.push(data); | |
updateAllTracksSelectBoxes(); | |
} | |
this.addTrackFile = function (dataFile, name, header) { | |
$.get(dataFile, function (data) { | |
var dataRows = thisObj.parseTrackFile(data, header); | |
thisObj.addTrack(dataRows, name); | |
}); | |
} | |
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); | |
graph(chromosomes[0]); | |
}); | |
} | |
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) { | |
for (var i in trackList) { | |
var thisTrack = trackList[i]; | |
if (thisTrack['name'] === name) { | |
return thisTrack; | |
} | |
} | |
}; | |
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); | |
} | |
}; | |
this.makeFormForColocalization(); | |
} | |
VQI_GenomeBrowser.prototype = new VQI_Publisher(); |