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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+