From d589b564cb653b46446c3056b16e323a99774e47 Mon Sep 17 00:00:00 2001 From: corywang Date: Mon, 2 Mar 2015 01:49:56 -0500 Subject: [PATCH] Added js file and demo --- VQI_GenomeBrowser.js | 273 +++++++++++++++++++++++++++++++++++++ VQI_GenomeBrowserDemo.html | 21 +++ 2 files changed, 294 insertions(+) create mode 100644 VQI_GenomeBrowser.js create mode 100644 VQI_GenomeBrowserDemo.html diff --git a/VQI_GenomeBrowser.js b/VQI_GenomeBrowser.js new file mode 100644 index 0000000..0fd3164 --- /dev/null +++ b/VQI_GenomeBrowser.js @@ -0,0 +1,273 @@ +function VQI_GenomeBrowser(id){ + this.div_id = id; + + this.width = 1000; + + this.height = 100; + + this.margin = 50; + + this.genomeData = []; + + this.chromosomes = []; + + $("#" + id).append("
CPG:Shore:Shelve:
"); + d3.select("#" + id + " #submit").on("click", this.submitFile.bind(this)); + + d3.select("#" + id).append("div").text("Chromosome: ") + this.select = d3.select("#" + id) + .append("div") + .append("select") + .on("change", function(d) { + self.graph(self.select.property("value")); + }); + + d3.select("#" + id).append("div").text("Start: ") + this.minNumber = d3.select("#" + id) + .append("input") + .attr("type","number") + .property("value",0); + + d3.select("#" + id).append("div").text("End: ") + this.maxNumber = d3.select("#" + id) + .append("input") + .attr("type","number") + .property("value",0); + + var self = this; + + this.graphButton = d3.select("#" + id) + .append("input") + .attr("type","button") + .attr("value","Graph") + .on("click", function(){ + self.graph(self.select.property("value"),self.minNumber.property("value"),self.maxNumber.property("value")) + }); + + this.svg = d3.select("#" + id) + .append("svg") + .attr("width", this.width + 2 * this.margin) + .attr("height", this.height + 2 * this.margin); + + //set up scales and axis + + this.xScale = d3.scale.linear(); + + this.xAxis = d3.svg.axis() + .scale(this.xScale) + .orient("bottom") + .ticks(10); + + this.xAxisSelection = this.svg.append("g") + .call(this.xAxis) + .attr("class", "axis") + .attr("transform", "translate(0,"+ (this.height + this.margin) + ")"); + + this.zoom = d3.behavior.zoom(); + + //set up tool tips + + this.tip = d3.tip() + .attr('class', 'd3-tip') + .offset([-20, 0]) + .html(function(d) { + return "" + d.chromosome + " " + d.type + "" + + "(" + d.start + " - " + d.end + ")"+ ""; + }); + + this.svg.call(this.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" + }); +} + +VQI_GenomeBrowser.prototype = new VQI_Publisher(); + + +VQI_GenomeBrowser.prototype.zoomed = function() { + var self = this; + + self.xAxisSelection.call(self.xAxis); + + self.svg.selectAll("rect") + .attr("width", function (d) {return self.xScale(d.end) - self.xScale(d.start)}) + .attr("x", function(d) {return self.xScale(d.start)}) + + self.minNumber.property("value", self.xScale.domain()[0]); + self.maxNumber.property("value", self.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"}); +} + + +VQI_GenomeBrowser.prototype.graph = function(chromosome , min , max){ + //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 + self.select.selectAll("option") + .data(self.chromosomes) + .enter() + .append("option") + .attr("value", function (d) { return d; }) + .text(function (d) { return d; }) + + //Gets relevant data and calculates min/max if needed + if(min == null || max == null) + { + currentData = self.genomeData.filter(function(d) {return d.chromosome == chromosome}); + + xMax = d3.max(currentData, function(d) {return d.end}); + xMin = d3.min(currentData, function(d) {return d.start}); + self.minNumber.property("value", xMin); + self.maxNumber.property("value", xMax); + } + else + { + currentData = self.genomeData.filter(function(d) {return d.chromosome == chromosome && d.start >= min && d.end <= max}); + xMax = Number(max); + xMin = Number(min); + } + + self.xScale.domain([xMin - (xMax - xMin) * 1/10, xMax + (xMax - xMin) * 1/10]) + .range([self.margin, self.width + self.margin]); + + self.xAxisSelection.call(self.xAxis); + + self.zoom.x(self.xScale) + .on("zoom", self.zoomed.bind(self)); + + self.svg.call(self.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 + self.svg.append("line") + .attr("x1",self.margin) + .attr("y1",self.height/2 + self.margin + 20) + .attr("x2",self.width+self.margin) + .attr("y2",self.height/2 + self.margin + 20) + .style("stroke", "blue"); + + self.svg.selectAll("rect") + .data(currentData) + .exit() + .remove(); + + self.svg.selectAll("rect") + .data(currentData) + .enter() + .append("rect"); + + self.svg.selectAll("rect") + .style("fill-opacity", ".4") + .style("stroke", function (d) { return d.type == "cpg" ? "red" : d.type == "shore" ? "green" : "yellow"}) + .style("fill", function (d) { return d.type == "cpg" ? "red" : d.type == "shore" ? "green" : "yellow"}) + .attr("height", function (d) { return d.type == "cpg" ? 40 : d.type == "shore" ? 20 : 15}) + .attr("width", function (d) {return self.xScale(d.end) - self.xScale(d.start)}) + .attr("x", function(d) {return self.xScale(d.start)}) + .attr("y", function (d) { var offset = d.type == "cpg" ? 0 : d.type == "shore" ? 10 : 12.5; + return self.height/2 + self.margin + offset}) + .on('mouseover', self.tip.show) + .on('mouseout', self.tip.hide); +} + +VQI_GenomeBrowser.prototype.setData = function(data){ + this.genomeData = data; + this.graph(); +} + +VQI_GenomeBrowser.prototype.getData = function(){ + return this.genomeData; +} + +VQI_GenomeBrowser.prototype.submitFile = function(){ + var self = this; + self.genomeData = []; + self.chromosomes = []; + + //Will read the 3 files and place all data into genomeData + //as objects with attributes 'chromosome', 'start', 'end', 'type' + + $.get($("#" + self.div_id + " #cpg").val().split('\\').pop(), 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) + { + self.chromosomes.push(value[0]); + currentChromosome = value[0]; + } + }); + + + cpgData = cpgData.map(function(data){ + return {"chromosome" : data[0], "start" : data[1], "end" : data[2], "type" : "cpg"} + }); + self.genomeData = self.genomeData.concat(cpgData); + }); + + $.get($("#" + self.div_id + " #shore").val().split('\\').pop(), 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({"chromosome" : value[0], "start" : value[3], "end" : value[4], "type" : "shore"}); + }); + self.genomeData = self.genomeData.concat(shoreData); + }); + + $.get($("#" + self.div_id + " #shelve").val().split('\\').pop(), 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({"chromosome" : value[0], "start" : value[1], "end" : value[2], "type" : "shelve"}); + shelveData.push({"chromosome" : value[0], "start" : value[3], "end" : value[4], "type" : "shelve"}); + }); + self.genomeData = self.genomeData.concat(shelveData); + self.graph(self.chromosomes[0]); + }); +} diff --git a/VQI_GenomeBrowserDemo.html b/VQI_GenomeBrowserDemo.html new file mode 100644 index 0000000..5c46ca2 --- /dev/null +++ b/VQI_GenomeBrowserDemo.html @@ -0,0 +1,21 @@ + + + +
+
+
+
+ + + + + + + + + + + +