Final Genome Browser
This visualization presents a comparative genome browser for three bacteriophages—D29, U2, and L5—using data loaded from a JSON file. Each phage is displayed as a horizontal track with genes drawn as arrows, oriented forward or reverse based on their direction. The genes are color-coded by pham family, and hovering over a gene triggers a tooltip showing its details. The bottom panel includes an axis for genomic position, and the layout supports side-by-side comparison of genome structure across phages. The visualization is built with D3.js and rendered as an SVG, with a modal popup for additional information and a gradient background for visual appeal. It incorporates animation and is designed as an interactive genome browser for phamerator.org.# Final Genome Browser
**Author:** Wanagram | **Type:** Interactive SVG visualization | **Rendering:** SVG with animation
## Overview
Final Genome Browser is an interactive comparative genomics tool that visualizes phage genome structures across multiple organisms simultaneously. Built with D3.js and jQuery, it displays gene organization, orientation, and pham (phage family) groupings for three bacteriophage genomes (D29, U2, and L5) in a single aligned view.
## Visual Design
The visualization presents each genome as a horizontal track, with genes rendered as rectangular blocks along a shared coordinate axis. Forward-strand genes appear above the baseline, while reverse-strand genes appear below, using a diverging layout that clearly communicates directionality. The tool uses a clean aesthetic with steelblue gene paths, a light gradient background, and an interactive tooltip that reveals gene details (name, pham, start/stop positions, direction, and sequence) on hover. A modal dialog provides additional information on demand.
## Interaction
Users can hover over individual genes to view detailed information in a tooltip, click to open a modal with the gene's pham and other attributes, and select among different phage genomes (D29, U2, L5) via dropdown menus. The browser also includes a scrollable genome track and visual feedback for gene orientation.
## Data
The underlying data describes bacteriophage genomes as JSON objects with fields including phagename, genes, and genomelength. Each gene has a name, pham, start, stop, direction, phage, and sequence. The data is loaded asynchronously from genes.json.txt using jQuery.
## Design
The visualization uses a genomic coordinate axis with genes drawn as arrow shapes on a horizontal track. Genes above the axis are forward-oriented, genes below the axis are reverse-oriented. The tooltip system is supported by jQuery and Bootstrap's modal plugin for showing information about individual genes. The color scheme is light and airy with a soft gradient background, steelblue gene paths, and a clean axis.
## Improvements
This block builds on prior work by adding animations and a cleaner design.
</script>
<script>
var width = 960,
height = 250,
margin = {top: 50, right: 50, bottom: 50, left: 50},
minW = 60,
w = 10;
var xScale = d3.scale.linear()
.domain([0, 100])
.range([0, 100]);
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scale.linear()
.domain([0, 50000])
.range([0, 900]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(15);
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
//Add the svg canvas
var svg = d3.select("body")
.append("svg")
.attr("width", 1000)
.attr("height", 500);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, 450)")
.call(xAxis);
function drawGenome(data, phageName) {
console.log("drawGenome", data)
//find index that matches phageName in the array of genomes
function findGenome(data, phageName) {
for (i = 0; i < data.length; i++) {
if (data[i].phagename == phageName) {
return data[i];
}
}
}
var genome = findGenome(data, phageName);
// genome = data[0];
console.log(genome.genomelength)
var genomeLength = genome.genomelength;
var genes = genome.genes;
var svg = d3.select("body")
.append("div")
.append("svg")
.attr("width", 1500)
.attr("height", 400);
var w = 1500,
h = 400;
var padding = 40;
var seqpos = 100;
var color = d3.scale.category10();
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var x = d3.scale.linear()
.domain([0, data[0].genomelength])
.range([0, 1500]);
var y = d3.scale.linear()
.domain([0, 100])
.range([100, 0]);
var line = d3.svg.line()
.x(function(d) {
return x(d[0]);
})
.y(function(d) {
return y(d[1]);
})
.interpolate("basis");
//axes
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 800)
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10)
.tickFormat(function(d) {
return d / 1000 + "kb";
})
.tickSize(0.5)
function drawGenome(data, color) {
var name = data["phagename"];
var gLength = data["genomelength"];
var x = d3.scale.linear()
.domain([0, gLength])
.range([0, 930]);
var y = d3.scale.linear()
.domain([0, 22])
.range([0, 330]);
var chart = d3.select(".genome")
.append("svg")
.attr("width", 1200)
.attr("height", 300)
.append("g")
.attr("transform", "translate(70,30)");
//Function to draw the genomes
chart.selectAll("line")
.data([{ x: 0, y: 50 }])
.enter()
.append("line")
.attr("x1", function(d) { return d.x; })
.attr("y1", function(d) { return d.y; })
.attr("x2", 1000)
.attr("y2", function(d) { return d.y; })
.attr("stroke", "black")
.attr("stroke-width", 2)
// Add the scatterplot
chart.selectAll("path")
.data(function() {
return data;
})
.enter()
.append("path")
.attr("d", function(d) { return lineFunction(d); })
.attr("transform", "translate(50,10)");
// data
var lineFunction = d3.svg.line()
.x(function(d) { return d.start; })
.y(function(d) { return d.stop; })
.interpolate("linear");
var counter = 0;
var check = false;
data.forEach(function(phage) {
var temp = 0;
check = false;
for(i = 0; i < phage.genes.length; i++){
if(phage.genes[i].direction == "forward") {
if(phage.genes[i].pham == "a2" && check == false){
check = true;
var phagename = phage.phagename;
var stop = phage.genes[i].stop;
console.log(phage.phagename);
}
else if (check == false) {
temp += phage.genes[i].stop - phage.genes[i].start;
}
if (check && phage.genes[i].pham != "a2") {
temp += phage.genes[i].stop - phage.genes[i].start;
}
}
var numgenes = 0
var totalgenome = 0
for(i=0;i<data.length;i++){
if(data[i].phagename==phage){
numgenes = data[i].genes.length;
totalgenome = data[i].genomelength;
}
}
console.log("numgenes: " + numgenes + " totalgenome:" + totalgenome)
// build visual object
var offset = 0.04*numgenes;
var visual = {
phage: phage,
totalgenome: totalgenome,
objpos: objpos,
offset: offset
};
return visual;
}
//MODAL for datainfo
$(".modal-body").html("<h4>"+ "data[0]"+"</h4>");
var margins = {top: 100, right: 20, bottom: 50, left: 40};
//Width and height of "phageName" text in viewport
var w = 1000,
h = 500;
var width = w - margins.right - margins.left,
height = h - margins.top - margins.bottom;
//function called for each phages
function drawGenome(data, genomeLength) {
var phageScale = d3.scale.linear()
.domain([0, genomeLength])
.range([0, width]);
var svg = d3.select("body").append("svg")
.attr("width", width + margins.left + margins.right)
.attr("height", height + margins.top + margins.bottom)
.append("g")
.attr("transform", "translate(" + margins.left + "," + margins.top + ")");
svg.append("defs")
.append("marker")
.attr("id", "arrowhead")
.attr("refX", 7)
.attr("refY", 2)
.attr("markerWidth", 10)
.attr("markerHeight", 10)
.attr("orient", "auto")
.append("path")
.attr("d", "M 0 0 L 10 5 L 0 10 z");
// add the y axis
var yScale = d3.scale.linear()
.domain([0, 90])
.range([400, 0]);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(10);
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 500)
.attr("class", "y axis")
.append("g")
.attr("transform", "translate(0,0)");
svg.append("g")
.attr("class", "axis")
.call(yAxis);
//Get Data
function loadData(input, scale, max, min, name) {
var line = d3.svg.line()
.x(function(d) {
return xscale(d.start);
})
.y(function(d) {
return yscale(d["pham"]);
})
.interpolate("linear");
var xscale = d3.scale.linear()
.domain([0, max])
.range([0 + 100, 1500 - 100]);
var yscale = d3.scale.linear()
.domain([0, 10])
.range([0 + 50, 450 - 100]);
var svg = d3.select("body")
.append("svg")
.attr("width", 1500)
.attr("height", 1500)
.attr("class", "name" + name);
svg.append("text")
.attr("x", 250)
.attr("y", 40)
.style("text-anchor", "middle")
.text(function() {
return "Phage " + name
})
var axis = d3.svg.axis()
.scale(d3.scale.linear().domain([0, data[objpos].genomelength]).range([0, 1000]))
.orient("bottom");
var xscale = d3.scale.linear().domain([0, data[objpos].genomelength]).range([0, 1000]);
var yscale = d3.scale.linear().domain([0, 20]).range([0, 200]);
svg = d3.select("body").append("svg")
.attr("width", 1600)
.attr("height", 600)
.append("g")
.attr("transform", "translate(100,100)");
// draw the axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, 100)")
.call(d3.svg.axis()
.scale(x)
.orient("bottom"));
var x = d3.scale.linear()
.domain([0, 15000])
.range([0, 1200]);
var y = d3.scale.linear()
.domain([0, 8])
.range([0, 110]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(20);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, 140)")
.call(xAxis);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Name:</strong> <span style='color:red'>" + d.name + "</span></br> " + d.pham;
})
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 500)
.attr("id", "svg");
for (i = 0; i < data.length; i++) {
console.log("Phage: " + data[i].phagename + " length: " + data[i].genomelength);
drawgenome(data[i], i);
}
function drawgenome(data, objpos) {
var w = 1200;
var h = 500;
var xscale = d3.scale.linear().domain([0, data.genomelength]).range([30, w - 30]);
var yscale = 80 + objpos * 150;
// Creates tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
function highlightgene(gene, on) {
console.log("clicked: " + gene.name);
d3.selectAll(".gene_" + gene.phage).style("opacity", 0.1)
d3.selectAll(".gene_" + gene.phage).style("stroke-width", 1)
d3.selectAll(".gene_" + gene.name + "_" + gene.phage).style("opacity", 1)
d3.selectAll(".gene_" + gene.name + "_" + gene.phage).style("stroke-width", 3)
var text = "Phage: " + gene.phage + "<br/> Gene: " + gene.name +
"<br/> Pham: " + gene.pham + "<br/>" + "Start: " + gene.start + "<br/>Stop: " + gene.stop + "<br/> Direction: " + gene.direction;
$(function() {
$('#myModal').modal('toggle');
});
$('.modal-body').html(text);
console.log(text)
$(".modal-title").html("Gene " + gene.name + " (" + gene.phage + ")")
}
// Define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var width = 700,
height = 800;
var yOffset = 100;
var start = 10;
var axisdim = 30;
var buffer = 100;
var pstart = 50;
var pend = 0;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
function getMaxY(data) {
var maxY = 0;
for (var i = 0; i < data.length; i++) {
if (data[i].genomelength > maxY) {
maxY = data[i].genomelength
}
}
return maxY
}
function drawGene(gene, scale, yPos) {
var geneColor = (gene.pham.search(/[a]/) != -1) ? 'rgba(255,0,0,0.5)' : 'rgba(0,0,255,0.5)'
var sequence = gene.sequence
var length = gene.stop - gene.start
var pixellength = scale(gene.stop) - scale(gene.start);
var sequence = sequence.substring(0, Math.round(pixellength));
var dna = drawDNA(sequence)
var width = scale(gene.stop) - scale(gene.start);
var genes =
'<g transform="translate(0,15)">'+
'<rect class="gene" height="20" width="' + width + '" x="' + scale(gene.start) + '" y="' + y(0) + '" fill="blue" fill-opacity="0.2" stroke="black"> </rect>' +
'<text x="' + (scale(gene.start)+10) + '" y="' + (y(0)+ 10) + '" font-family="sans-serif" font-size="10px" fill="black">' + gene.name + '</text>' +
dna(genomeName, gene.start, gene.stop, gene.sequence, gene.direction);
}
function dna(start, stop, seq, dir) {
var newSeq = "";
var newSeq2 = "";
for (i = start; i < stop; i += 3) {
if (dir == "forward") {
if (codons[seq.substring(i, i + 3)]) {
newSeq += codons[seq.substring(i, i + 3)];
}
} else {
newSeq2 = newSeq2.concat(seq.substring(i, i + 3));
}
}
if (dir == "forward") {
return newSeq;
} else {
var reverse = newSeq2.split("").reverse().join("");
var aa = "";
for (i = 0; i < reverse.length; i += 3) {
aa += codons[reverse.substring(i, i + 3)];
}
return aa
}
}
// Function to calculate sequence
// var data = genes.json
// console.log(data)
var phages = [] //empty array of phages
// for (var k in data){
// phages.push(data[k].phagename)
// }
// console.log(phages)
// return phages;
function getphages() {
var all = []
data.forEach(function(d) {
if (all.indexOf(d.phagename) === -1) {
all.push(d.phagename)
}
})
return all
}
console.log(getphages())
var margin = {
top: 30,
right: 40,
bottom: 30,
left: 60
},
width = 960 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
//maybe row and column headers?
//maybe clickable navigation?
var x = d3.scale.linear()
.domain([0, 15000])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, 10000])
.range([0, height]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5)
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var margin = {top: 10, right: 20, bottom: 100, left: 60},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var xScale = d3.scale.linear()
.domain([0, 15000])
.range([0, width]);
var yScale = d3.scale.linear()
.domain([0, data.length])
.range([0, height]);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Gene:</strong> <span style='color:red'>" + d.name + "</span>";
});
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var svg = d3.select("body").append("svg")
.attr("width", 1100)
.attr("height", 300);
var xScale = d3.scale.linear()
.domain([0, d3.max(data, function(d) { return d.genomelength; })])
.range([0, 900]);
//create x-axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var g = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (150 + 30) + ")")
.call(xAxis);
// add tooltip div
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// add background to highlight phams
var color = d3.scale.category10();
var view = [data[0], data[1], data[2]];
var lengths = []
var offsets = []
var offset = 0;
view.forEach(function(d, i) {
d.genes.forEach(function(g) {
var dir = g.direction;
var x = Number(g.start) + offset;
var y = (i + 1) * 40;
var xf = Number(g.stop) + offset;
var yf = y;
//console.log("name: "+g.name+" start: "+g.start+" stop: "+g.stop);
var lineData = [{
x: x,
y: y
}, {
x: xf,
y: yf
}];
var lineFunction = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate("linear");
//Create the SVG
var svg = d3.select("#container").append("svg").attr("width", 2000).attr("height", 5000).append("g");
// tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var gene = svg.append("path")
.attr("d", lineFunction(genePoints))
.attr("transform", "translate(" + 10 + "," + (90) + ")")
.attr("stroke", function(d) { return color(d.pham); })
.attr("class", "gene")
.attr("phagename", phage)
.attr("start", d.start)
.attr("stop", d.stop)
.attr("geneid", d.name)
.on("mouseover", function(d) {
console.log(d)
tooltip.html("Gene: " + d.name + " " + "Pham: " + d.pham).style("left", (d3.event.pageX + 5) + "px").style("top", (d3.event.pageY - 28) + "px");
tooltip.style("visibility", "visible");
})
.on("mousemove", function(d) {
tooltip.style("top", (d3.event.pageY - 10) + "px").style("left", (d3.event.pageD + 30) + "px");
})
.on("mouseout", function(d) {
tooltip.style("visibility", "hidden");
})
}
var body = d3.select("body"),
margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
},
width = 960 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xScale = d3.scale.linear()
.domain([0, 1])
.range([0, width]);
var yScale = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(10);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(5);
var color = d3.scale.category10();
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var svg = d3.select("body").append("svg")
.attr("width", 1100)
.attr("height", 500)
.append("g")
.attr("transform", "translate(" + 100 + "," + 20 + ")");
var x = d3.scale.linear()
.range([0, 800])
.domain([0, d3.max(data, function(d) {
return d.genomelength;
})]);
var y = d3.scale.linear()
.range([0, 180])
.domain([0, data.length]);
var color = d3.scale.category10();
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(data.length);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10);
function drawGenome() {
d3.select(".svg1").remove();
d3.select(".svg2").remove();
d3.select(".text").remove();
d3.select(".brush").remove();
d3.select("p").remove();
//redraw all
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
},
width = 1000 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("class", "genomeBrowser")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xScale = d3.scale.linear()
.domain([0, 30000])
.range([0, width]);
var yScale = d3.scale.linear()
.domain([0, data.length])
.range([0, height]);
var y = d3.scale.linear()
.range([height, 0]);
y.domain([0, data.length]);
// Add a background to each gene.
var rowHeight = 80;
var rowPadding = 10;
var rowWidth = 700;
var rows = svg.selectAll(".row")
.data(data)
.enter()
.append("rect")
.attr("x", function(d) {
return 0;
})
.attr("y", function(d, i) {
return i * rowHeight + 40;
})
.attr("width", rowWidth)
.attr("height", rowHeight)
.style("fill", function(d) {
if (d.phagename == "D29") {
return "#7BAFD4";
} else if (d.phagename == "U2") {
return "#D4B07B";
} else {
return "#7BD4A5";
}
})
.style("opacity", 0.2)
.style("stroke", "gray")
.style("stroke-width", 2);
// modal
var modal = $('.modal');
var modalBody = $('.modal-body');
var modalFooter = $('.modal-footer');
//plot modal when click
d3.selectAll("path.gene").on("click", function(d) {
console.log("The selected gene is " + d.name);
console.log(d)
$('.modal-body').html(d.phagename + " " + d.name + "<br> Pham: " + d.pham + "<br> start: " + d.start + " stop: " + d.stop + " direction: " + d.direction);
$("#myModal").modal('show');
});
d3.select(self.frameElement).style("height", "700px");
var phageSelection;
var viewboxWidth = 800;
var viewboxHeight = 250;
var margin = {
top: 30,
right: 10,
bottom: 10,
left: 10
};
var width = viewboxWidth - margin.right - margin.left,
height = viewboxHeight - margin.top - margin.bottom;
// Initial phage selection
var phage = "D29";
var phageData = {};
var sliderScale;
// data join and graph all
function drawGenome(data) {
$("#myModal").on("hidden.bs.modal", function() {
$(this).removeData('bs.modal');
});
d3.select("#viz").remove();
var svg = d3.select("body").append("ul")
.append("svg")
.attr("width", 1500)
.attr("height", 600)
.attr("id", "viz");
// MAKES MODAL WINDOW THAT DISPLAYS GENE INFO
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// creates svg for all genomes
// Draw axis
var xscale = d3.scale.linear()
.domain([0, d3.max(data, function(d) { return d.genomelength; })])
.range([0, 1400]);
var xaxis = d3.svg.axis()
.scale(xscale)
.orient("bottom")
.ticks(10);
var svg = d3.select("body")
.append("svg")
.attr("width", 1500)
.attr("height", 600)
.attr("class", "axis")
.append("g")
.attr("transform", "translate(50,20)");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0,60)")
.call(xaxis);
var x = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.genomelength;
})])
.range([0, 900]);
var y = d3.scale.ordinal()
.domain(data.map(function(d) { return d.phagename; }))
.rangeRoundBands([0, 250], 0.3);
function make_x_axis() {
return d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10);
}
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 650);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10)
var y = d3.scale.ordinal()
.rangeRoundBands([0, 250], .1, .3);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
y.domain(data.map(function(d) { return d.phagename; }));
x.domain([0, d3.max(data, function(d) { return d.genomelength; })]);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Gene:</strong> <span style='color:red'>" + d.name + "</span>";
})
var svg = d3.select("body").append("svg")
.attr("width", 1600)
.attr("height", 900)
.append("g");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, " + 800 + ")")
.call(d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(20));
// var div = d3.select("body").append("div")
// .attr("class", "tooltip")
// .style("opacity", 0);
var margin = {
top: 100,
right: 100,
bottom: 100,
left: 100
},
width = 1000 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, 10000])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, data.length * 2])
.range([0, height]);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
var x = d3.scale.linear()
.domain([0, 16000])
.range([0, 1300]);
var y = d3.scale.linear()
.domain([0, 4])
.range([0, 150]);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0,210)")
.call(xAxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(100,20)")
.call(yAxis);
var svg = d3.select("body")
.append("svg")
.attr("width", 2000)
.attr("height", 800);
var g = svg.selectAll("g")
.data(data)
.enter()
.append("g");
g.each(function(d, i) {
var g = d3.select(this);
var phage = d.phagename;
console.log(d.phagename);
console.log(d.genomelength);
d.genes.forEach(function(d) {
//console.log(d)
var x = d.start;
var y = 200;
var width = d.stop - d.start;
var height = 15;
var spacing = 100;
if (d.direction === "forward") {
g.append('rect')
.attr('x', x)
.attr('y', y + i * spacing)
.attr('width', function() {
return d.stop - d.start;
})
.attr('height', 15)
.attr('fill', function() {
if (d.pham.charAt(0) == 'a') {
return '#55C223';
}
if (d.pham.charAt(0) == 'b') {
return '#E8C373';
}
if (d.pham.charAt(0) == 'c') {
return '#D65E54';
}
})
.attr('stroke', "black")
.attr('stroke-width', '0.5px')
.on("click", function() {
$('#myModal').modal('show');
$('.modal-body').empty().append("Phage: " + phage + "<br> Gene: " + name +
"<br> Coordinates: " + start + " - " + stop + " bp <br> Pham: " + pham);
})
.on("mouseover", function() {
div.transition().duration(200).style("opacity", .9);
div.html("Coordinates: " + start + " - " + stop + " bp <br> Pham: " + pham)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function() {
div.style("display", "none");
});
function chickengene() {
var chicken = [];
var mod = [];
data.forEach(function(d) {
d.genes.forEach(function(g) {
if (g.phage == phage) {
//console.log(g);
chicken.push([g.name, g.start, g.stop, g.direction, g.pham]);
mod.push([g.pham, g.sequence]);
}
});
});
// console.log(chicken)
return [chicken, mod];
};
function scaleLength(start, stop, total) {
start = (start / total) * 100;
stop = (stop / total) * 100;
var width = stop - start;
return [start, width]
}
function drawpath(vect, selection) {
// draw a path based on vector; selection is the SVG group
// set line element attributes
// The line is a spline through the points in the vector
var points = "";
var i;
for (i = 0; i < vect.length; i++) {
points += vect[i][0] + "," + vect[i][1] + " ";
}
selection.append("path")
.attr("d", "M" + points)
.attr("stroke", "steelblue")
.attr("stroke-width", 1)
.attr("fill", "none");
}
function drawGene(gene, direction, y, height, colour, x, width, name) {
if (direction == "forward") {
var arrow = d3.svg.symbol().type("triangle-forward").size(150);
d3.select("svg").append("path")
.attr("d", arrow)
.attr("transform", function() {
var off = x + width;
return "translate(" + off + "," + (y + 8) + ")rotate(90)";
})
.attr("fill", colour);
// Draw rectangle
d3.select("svg")
.append("rect")
.attr("x", x)
.attr("y", y)
.attr("width", width)
.attr("height", 15)
.attr("fill", colour)
.attr("stroke", "black")
.style("opacity", 0.5)
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html(name + "<br/>" + start + " - " + stop)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.style("opacity", 0)
});
return gene
}
function draw() {
console.log("draw called");
var margin = { top: 50, right: 50, bottom: 50, left: 50 }
, width = 1200 - margin.left - margin.right
, height = 500 - margin.top - margin.bottom;
var xScale = d3.scale.linear()
.domain([0, 30000])
.range([0, width]);
var yScale = d3.scale.linear()
.domain([0, 4])
.range([0, height]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var margin = {
top: 50,
right: 50,
bottom: 50,
left: 50
},
width = 1000 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom;
var xScale = d3.scale.linear()
.domain([0, 15000]).range([0, width]);
var yScale = d3.scale.linear()
.domain([0, 12])
.range([0, height]);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(15, "s");
var xScale = d3.scale.linear()
.domain([0, 16000])
.range([0, width]);
// get the max from the data
var yScale = d3.scale.linear()
.domain([0, 2])
.range([0, 100]);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0,30)")
.call(xAxis);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5);
var width = 960;
var height = 160;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// create the x scale
var xScale = d3.scale.linear()
.domain([0, 30000])
.range([0, width]);
//create y scale
var yScale = d3.scale.linear()
.domain([0, 160])
.range([0, height]);
var yScale2 = d3.scale.linear()
.domain([0, 30000])
.range([0, height]);
var xAxis = d3.svg.axis().scale(xScale).orient("bottom").ticks(5);
var yAxis = d3.svg.axis().scale(yScale).orient("left").ticks(0);
var svg = d3.select("body").append("svg")
.attr("width", 1100)
.attr("height", 500)
.append("g")
.attr("transform", "translate(70,10)");
var tip = d3.tooltip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Name:</strong> <span style='color:red'>" + d.name + "</span>";
})
d3.select("body").selectAll("p").data(data).enter()
.append("p")
.text(function(d) { return d.phagename; })
data.forEach(function(phage) {
console.log(phage);
var y = 50; var xscale = d3.scale.linear()
.domain([0, 20000])
.range([0, 1000]);
var yscale = d3.scale.linear()
.domain([0, 30])
.range([0, 500]);
var xAxis = d3.svg.axis()
.scale(xscale)
.orient("bottom")
.ticks(20);
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 500)
.attr("id", phageid);
var phageid = "svg" + data.indexOf(data.phagename);
console.log(phageid)
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(20," + (ypos + 60) + ")")
.call(xAxis);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5);
var x = d3.scale.linear()
.domain([0, data.genomelength])
.range([0, 1000]);
var y = d3.scale.linear()
.domain([0, 40])
.range([0, 100]);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0,40)")
.call(xAxis);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Gene:</strong> <span style='color:red'>" + d.name + "</span>";
})
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
.attr("align", "center");
var w = 930,
h = 300;
var x = d3.scale.linear()
.domain([0, 15000]).range([10, 900]);
var y = d3.scale.linear()
.domain([0, 2])
.range([10, 300]);
var y2 = d3.scale.linear()
.domain([0, 2])
.range([300, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 5000)
.append("g");
var all_phages = []; // create an array that contains names of all phages so you can
var gPhage = {};
data.forEach(function(d) {
var color = d3.scale.category20();
var genes = d.genes;
var phageName = d.phagename;
var genomeLength = d.genomelength;
d3.select("body").append("p")
.text("Phage name: " + d.phagename);
// create a div for each phage genome
var g = d3.select("body")
.append("div")
.attr("class", "container")
.attr("id", phageName)
.style("width", 1000 + "px")
.style("height", 200 + "px")
.style("outline", "#thin solid black");
var order = [3,2,1,0];
var svg = g.append("svg")
.attr("width", 950)
.attr("height", 400);
// add title to svg
svg.append("text")
.attr("x", 450)
.attr("y", 40)
.style("text-anchor", "middle")
.text(function() {
return d.phagename + " Genome Browser";
})
// define genome axis
var axisWidth = 700;
var genomeScale = d3.scale.linear()
.domain([0, d.genomelength])
.range([0, axisWidth]);
var genomeAxis = d3.svg.axis()
.scale(genomeScale)
.orient("bottom")
.ticks(10);
var center = 200;
// code for drawing arrow heads
var arrow = d3.svg.symbol()
.type("triangle-forward")
.size(50);
function midpoint (start, stop) {
var mid = (stop + start)/2;
return mid;
}
function arrowWidth(start, stop) {
return Math.abs(stop - start) > 400 ? 150 : 60;
}
function determineArrowStartAndStop(start, stop) {
var width = 120;
var adjustedStart = start;
var adjustedStop = stop;
if ((stop - start) > 200) {
if (direction === 'forward') { adjustedStop = stop - 100; }
else if (direction === 'reverse') {
adjustedStart = start + 100;
}
}
return [adjustedStart, adjustedStop];
}
function geneBox(gene, phage) {
// set dimensions
var margin = {top: 40, right: 20, bottom: 40, left: 40};
var width = 1000 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var padding = 20;
var vis = d3.select("#middle").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// define the x and y scales
var xScale = d3.scale.linear()
.domain([0, data[0].genomelength])
.range([0, width]);
var yScale = d3.scale.linear()
.domain([0, 10])
.range([0, height / 2]);
var xAxis = d3.svg.axis().scale(xScale).orient("bottom").ticks(10);
vis = d3.select("#vis")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
vis.append("svg:defs").append("svg:marker")
.attr("id", "arrow-forward")
.attr("viewBox", "0 0 10 10")
.attr("refX", 10)
.attr("refY", 5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M 0 0 L 10 5 L 0 10 z")
.attr("fill", "orange");
//same for reverse
...
// Get data and draw
var phageD29 = data[0];
var dataD29 = data[0].genes;
var phageU2 = data[1];
var dataU2 = data[1].genes;
var phageL5 = data[2];
var dataL5 = data[2].genes;
var genes = data;
//Width of each phage row in the visualization
var width = 850,
height = 250;
var margin = { top: 20, right: 20, bottom: 30, left: 50 };
//var format = d3.format(",d");
var x = d3.scale.linear()
.domain([0, 50000])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, data.length * 100])
.range([0, height]);
var chart = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var line = d3.svg.line()
.x(function(d) { return x(d.start); })
.y(function(d) { return y(d.phage); });
var row = 0
var col = 0
var positions = []
data.forEach(function(element) {
element["row"] = row;
row += 20
var numgenes = element.genes.length
var genepos = 0;
element.genes.forEach(function(d) {
d.y = row;
genepos += 1;
})
})
var svg = d3.select("body").append("svg")
.attr("width", 1300)
.attr("height", 300)
.append("g");
var g = svg.append("g");
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var parseDate = d3.time.format("%d-%b-%y").parse;
var row = 0;
// map for translating between data and svg
var map = [];
var padding = 70;
var axisline = 600;
var circleR = 7;
// resize function to keep aspect ratio of graph stable
function resizefunction() {
var h = document.documentElement.clientHeight;
document.getElementById("chart").setAttribute("height", h);
document.getElementById("chart").setAttribute("width", w * h / x);
}
// resize function
window.onresize = resize;
function resize() {
var h = document.documentElement.clientHeight;
var w = document.documentElement.clientWidth;
document.getElementById("chart").setAttribute("height", h);
document.getElementById("chart").setAttribute("width", w);
}
// set initial size
resize();
var w = 1300;
var h = 500;
var padding = 40;
var dataset = [ ];
var length = data.length;
var svg = d3.select("body").append("svg").attr("width", w).attr("height", h);
var xScale = d3.scale.linear()
.domain([0, 16000]).range([30, 1000]);
var color = d3.scale.category10();
// map each phage in array
var phages = data.map(function(d) { return d.phagename; })
// set x axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
// set y axis
var yScale = d3.scale.linear()
.domain([0, data.length + 1])
.range([20, 400]);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(data.length);
var svg = d3.select("body").append("svg")
.attr("width", 900)
.attr("height", 600);
var g = svg.append("g").attr("transform", "translate(80,20)");
var x = d3.scale.linear().domain([0, d3.max(data, function(d) {
return d.genomelength;
})]).range([0, 800]);
var y = d3.scale.ordinal().domain(data.map(function(d) {
return d.phagename;
})).rangeBands([0, 400], .25, .25);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
g = d3.select('body').append('svg')
g.attr("width", 1000)
g.attr("height", 500)
g.append("svg:g")
.attr("class", "axis")
.attr("transform", "translate(0,450)")
.call(xAxis);
g.append("svg:g")
.attr("class", "axis")
.attr("transform", "translate(100,0)")
.call(yAxis);
//draw
var row = 0;
var col = 0;
var colors = ["#ff0000", "#00ff00", "#0000ff", "#ffff00", "#ff00ff", "#00ffff", "#ffa500", "#800080", "#A52A2A", "#FFB6C1"];
var colorIndex = 0;
var previousColor = "";
var arrowHeadSize = 10;
var geneHeight = 25;
var trackHeight = 70;
var left = 200;
var offset = 100;
var geneName = ""
for (i = 0; i < data.length; i++) {
var phagename = data[i].phagename;
var genes = data[i].genes;
var genomeLength = data[i].genomelength;
var yPos = (i*100) + 30;
var div = d3.select("body").append("div").attr("class", "tooltip").style("opacity", 0);
var svg = d3.select("body")
.append("svg")
.attr("width", 1000)
.attr("height", 200)
.attr("class", "genome")
.attr("id", phageName)
.style("background-color", "white");
var xScale = d3.scale.linear()
.domain([0, genomeLength])
.range([0, 900]);
var yScale = d3.scale.linear()
.domain([0, 10])
.range([0, 100]);
for (i = 0; i < data.length; i++) {
if (data[i].phagename == phage) {
var genomeLength = data[i].genomelength;
var genome = data[i];
}
}
console.log(genomeLength);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(10)
.tickFormat(d3.format(".0s"));
var svg = d3.select("body").append("svg")
.attr("width", 1300)
.attr("height", 400)
.attr("id", "svg" + name);
var xScale = d3.scale.linear()
.domain([0, genomeLength])
.range([0, 1300]);
var g = svg.append("g")
.attr("transform", "translate(0,0)")
.call(xAxis);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(10);
var genes = data[objpos].genes;
var genomeLength = data[objpos].genomelength;
function drawGenome() {
var path = svg.append("path")
.datum(genes)
.attr("d", function(d) {
var x = 0
var string = "M 50,25";
var forward = 0;
for (i = 0; i < d.length; i++) {
if (d[i].direction == "forward") {
var start = d[i].start / 10;
var stop = d[i].stop / 10;
var y = 25;
string += " L" + start + ", " + y;
string += " Q " + (start + ((stop - start) / 2)) + ", " + (y + 40) + " " + (stop) + "," + y;
}
else {
var start = d[i].start / 10;
var stop = d[i].stop / 10;
y = 25;
string += " L" + start + ", " + y;
string += " Q " + (start + ((stop - start) / 2)) + ", " + (y - 40) + " " + (stop) + "," + y;
}
}
string += "L " + (data[0].genomelength / 10) + " , " + y;
$('.genome').append('<path d="' + string + '" />');
}
var allData = [];
var svg = d3.select("body")
.append("svg")
.attr("width", 1200)
.attr("height", 500)
.style("margin-left", 100)
.style("margin-right", 100)
var yScale = d3.scale.linear()
.domain([0, 100])
.range([0, 200]);
var xScale = d3.scale.linear()
.domain([0, 20000])
.range([0, 950]);
var y = d3.scale.linear()
.domain([0, 200])
.range([480, 0]);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(10);
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 500);
var ybase = [10, 100, 190, 280, 370];
var xbase = 100;
var tick = 100;
var seq_slider = 100;
var seq_on = 0;
var sliderValue = 80;
var allphages = [];
var circles = [];
function add_genome(name, phage, gene_count, start, stop, direction) {
var gene = {
name: name,
phage: phage,
start: start,
stop: stop,
direction: direction
}
return gene
}
var yoffset = 0;
var genomes = [];
for (i = 0; i < data.length; i++) {
var genes = [];
for (j = 0; j < data[i].genes.length; j++) {
genes.push(add_genome(data[i].genes[j].name, data[i].genes[j].pham, data[i].genes[j].start, data[i].genes[j].stop, data[i].genes[j].direction))
}
genomes.push({
"phagename": data[i].phagename,
"genomelength": data[i].genomelength,
"genes": genes
})
console.log(genomes)
}
function drawGenome(genome, ypos) {
var genes = genome.genes;
var seqLength = genome.genomelength;
var xScale = d3.scale.linear()
.domain([0, seqLength])
.range([0, width]);
for (var i = 0; i < genes.length; i++) {
var gene = genes[i];
var color = "";
if (gene.pham == "a2") {
color = "red";
}
if (gene.pham == "a3") {
color = "green";
}
if (gene.pham == "a4") {
color = "black";
}
if (gene.pham == "a1") {
color = "orange";
}
if (gene.pham == "a5") {
color = "purple";
}
if (gene.pham == "b1") {
color = "blue";
}
if (gene.pham == "b2") {
color = "yellow";
}
if (gene.pham == "b3") {
color = "black";
}
if (gene.pham == "b4") {
color = "red";
}
if (gene.pham == "4858 (107)") {
color = "green";
}
var x = Math.floor(Math.random() * 11);
if (gene.sequence.length != 0) {
// console.log(gene.sequence[0] + " " + gene.sequence[1] + " " + gene.sequence[2] + " " + gene.sequence[3] + " " + gene.sequence[4]);
var s = gene.sequence;
var y = 0;
var cur = 0;
for (j = 0; j < s.length; j = j + 3) {
//console.log("j" + j)
//console.log(s.substring(j,j+3))
var codon = s.substring(j, j + 3);
var aa = aminoacid(codon);
// console.log(aa);
// console.log(amino)
// console.log(codon)
var line = [];
var increment = 1 / (data[objpos].genomelength / 300);
var startpost = gene_start_post(x, y, width, height, start, stop, direction);
var stoppost = gene_stop_post(x, y, width, height, start, stop, direction);
if (aa === "*") {
if (count > 5) {
count = 0;
line.push(startpost);
line.push(stoppost);
console.log(line)
}
} else {
count += 1;
//console.log(aa)
}
var arc = d3.svg.arc().innerRadius(190).outerRadius(195).startAngle((start / genomeLength) * 2 * Math.PI).endAngle((stop / genomeLength) * 2 * Math.PI);
if (direction === "forward") {
var color = "blue";
} else {
var color = "green";
}
...
}
})
})
</script>
<script>
var width = 1300,
height = 700,
radius = 300;
var color = d3.scale.category10();
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + (height / 2 + 10) + ")");
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
d3.json("genes.json.txt", function(error, data) {
var allphages = [];
data.forEach(function(d) {
allphages.push(d.phagename);
d.genes.forEach(function(g) {
g.start = +g.start;
g.stop = +g.stop;
g.type = g.direction;
});
});
var phage = allphages[0];
var menuOptions = [];
for (i = 0; i < data.length; i++) {
menuOptions.push(data[i].phagename)
}
console.log(menuOptions);
//Create dropdown menu with all available phages
d3.select("#search")
.selectAll("option")
.data(menuOptions)
.enter()
.append("option")
.text(function(d) { return d; });
var phagename = data[0].phagename;
//Define dimensions of the visualization
var margin = {top: 40, right: 10, bottom: 40, left: 10},
width = 1060 - margin.left - margin.right,
height = 200 - margin.top - margin.bottom;
var svg = d3.select("#genomebrowser").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xScale = d3.scale.linear()
.domain([0, 15000])
.range([0, width]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(10);
// Tooltip for gene pham info
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Pham:</strong> <span style='color:red'>" + d.pham + "</span>";
})
var svg = d3.select("body")
.append("svg")
.attr("width", 1000)
.attr("height", 400);
function drawGenome(data) {
svg.selectAll("*").remove();
var w = 800,
h = 300,
//size of the svg
margin = {
top: 10,
right: 10,
bottom: 30,
left: 100
},
width = w - margin.left - margin.right,
height = h - margin.top - margin.bottom;
//Set up the svg
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xScale = d3.scale.linear()
.domain([0, data.genomelength])
.range([0, width]);
var yScale = d3.scale.linear()
.domain([0, 1])
.range([0, height]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(0);
var line = d3.svg.line()
.x(function(d) { return xScale(d[0]); })
.y(function(d) { return yScale(d[1]); });
svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var margin = { top: 100, right: 100, bottom: 100, left: 100 },
width = 1100 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.range([0, width])
.domain([0, d3.max(data, function(d) {
return d.genomelength;
})]);
var y = d3.scale.linear()
.range([0, height])
.domain([0, d3.max(data, function(d) {
return d.genes.length;
})]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom").ticks(15);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(2);
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
.append("g")
.attr("transform", "translate(" + 100 + "," + 20 + ")");
// map phage name to object
var phageMap = d3.map();
// array of phage objects
var phageList = [];
data.forEach(function(d) {
phageMap[d.phagename] = d;
});
function drawGenome(phage) {
//debugger
var data = phageMap[phage];
var genes = data.genes;
var genomeLength = data.genomelength;
var y = 50;
for (var j = 0; j < genes.length; j++) {
if (genes[j].direction == "forward") {
var x = [genes[j].start, genes[j].start + 50, genes[j].stop - 50, genes[j].stop];
var yval = [y, y - 5, y - 5, y];
var line = d3.svg.line()
.x(function(d) { return d[0]; })
.y(function(d) { return d[1]; })
var lineData = [];
for (i = 0; i < x.length; i++) {
lineData.push([x[i], yval[i]]);
}
var arrow = svg.append("path")
.attr("d", line(lineData))
.attr("stroke", "green");
svg.append("text")
.attr("x", (genes[j].start + genes[j].stop) / 2)
.attr("y", yval - 10)
.attr("text-anchor", "middle")
.style("fill", "black")
.text(genes[j].name);
} else {
var lineData = [
[genes[j].start, yval],
[genes[j].stop, yval]
];
var line = svg.append("line")
.attr("x1", genes[j].start)
.attr("y1", yval)
.attr("x2", genes[j].stop)
.attr("y2", yval)
.attr("stroke", "black")
.attr("stroke-width", 8)
.attr('class', 'arrow');
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var circle = svg.append("circle")
.attr("r", 10)
.attr("cx", genes[j].start)
.attr("cy", yval)
.attr('class', 'phamcircle')
.style("fill", "blue")
.on("mouseover", function(d) {
tip.style("opacity", 1);
tip.html("pham: " + genes[j].pham)
tip.style("left", (d3.event.pageX) + "px").style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
tip.style("opacity", 0);
});
tooltip
var tooltip = d3.select("body").append("div").attr("class", "tooltip").style("opacity", 0);
var seq = "ATCGCGCGTATAGCGCGCTAGCTAGCTGACTATATTATATAGCGCT";
var g = d3.select("#middle").append("svg:g").attr("transform", "translate(40,25)").attr("class","g");
d3.selectAll("input").on("change", function() {
var select = this.value;
if (select == "Sequence") {
showSequence();
}
if (select == "Graph") {
showGraph();
}
if (select == "Both") {
showBoth();
}
});
function showSequence() {
document.getElementById("graph").innerHTML="<div id='seq'></div>";
var sequence = data[0].genes[0].sequence;
console.log(sequence);
$("div.sequence").remove();
d3.select("#seq")
.append("div")
.attr("class", "sequence")
.text(sequence)
// console.log(d3.select("#seq"));
};
function showGraph() {
document.getElementById("graph").innerHTML="";
draw(data[0]);
}
function showBoth() {
document.getElementById("graph").innerHTML="<div id='seq'></div>";
d3.select("#seq").text("Sequence: " + data[0].genes[0].sequence);
draw(data[0]);
}
var width = 960,
height = 150,
margin = {top: 20, right: 20, bottom: 20, left: 40};
var xScale = d3.scale.linear()
.domain([0, 15000])
.range([0, width]);
var yScale = d3.scale.linear()
.domain([0, 300])
.range([0, height]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "yAxis");
var width = 1300,
height = 700;
var xScale = d3.scale.linear()
.domain([0, 100000])
.range([0, width]);
var yScale = d3.scale.linear()
.domain([0, 120000])
.range([0, height]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(15);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(10);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Pham:</strong> <span style='color:red'>" + d.pham + "</span>";
})
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 500);
var g = svg.append("g");
var line = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate("linear");
d3.json("genes.json.txt", function(data) {
var x = d3.scale.linear().domain([0, 20000]).range([0, 1300])
var y = d3.scale.linear().domain([-0.15, 0.15]).range([100, 100]);
//var x = d3.scale.linear().domain([0, 20000]).range([0, 1300]);
var y0 = Math.max(50, 10 - 2 * 30);
var chart = d3.select(body)
.append('svg')
.attr('width', 1800)
.attr('height', 900)
.append('g')
.attr('transform', 'translate(20, 20)');
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, 150)")
.call(xAxis);
var line = d3.svg.line()
.x(function(d) { return x(d.base); })
.y(function(d) { return y(d.identity); });
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
function showTip(d) {
tip.transition()
.duration(200)
.style("opacity", .9);
tip.html("pham: " + d.pham)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
}
function hideTip() {
tip.transition()
.duration(500)
.style("opacity", 0);
}
function genomesvg(d, i) {
var bod = d3.select("body");
var dataset = [];
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var vis = d3.select("#chart").append("svg")
.attr("width", 1100)
.attr("height", 500)
.attr("class", "svg-" + i);
var linces = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; });
var xScale = d3.scale.linear()
.domain([0, d.genomelength])
.range([0, 850]);
var yScale = d3.scale.linear()
.domain([0, 300])
.range([0, 100]);
var genes = d.genes;
// scale for the x-axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5)
.tickSize(5, 0, 0)
.tickFormat(function(d) { return d / 1000 + "kb"; });
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, 30)")
.call(xAxis);
// draw an arrow head for the forward genes
var arrow = d3.svg.symbol()
.type("triangle-forward")
.size(100);
var arrow_rev = d3.svg.symbol()
.type("triangle-forward");
var width = 700,
height = 350;
var x = d3.scale.linear()
.domain([0, data[0].genomelength])
.range([0, width]);
var svgContainer = d3.select("body").append("svg")
.attr("width", width + 100)
.attr("height", height)
.attr("class", "svgContainer");
var myColor = d3.scale.ordinal()
.range(["#ff6600", "#66cc66", "#3399ff", "#cd07f5", "#ff00ff", "#cc0066", "#339933", "#669999", "#990099", "#ff6600", "#66cc66", "#3399ff", "#cd07f5", "#ff00ff", "#cc0066", "#339933"]);
var width = 900,
height = 450;
var t = d3.transform().translate(80, 20).rotate([-10]).scale(1);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.style("border", "solid 1px black");
var defs = svg.append("defs");
var arrow = defs.append("marker")
.attr("id", "arrow")
.attr("viewBox", "0, -5, 10, 10")
.attr("refX", 10)
.attr("refY", 0)
.attr("markerWidth", 5)
.attr("markerHeight", 5)
.attr("orient", "auto")
.attr("style", "fill: steelblue;");
var arrow2 = defs.append("marker")
.attr("id", "arrow2")
.attr("viewBox", "0, -5, 10, 10")
.attr("refX", 0)
.attr("refY", 0)
.attr("markerWidth", 5)
.attr("markerHeight", 5)
.attr("orient", "auto")
.attr("style", "fill: steelblue;");
arrow.append("path").attr("d", "M 0,-5 L 10,0 L 0,5");
arrow2.append("path").attr("d", "M 0,-5 L 10,0 L 0,5");
var start;
var path;
var svg = d3.select("body").append("svg").attr("width", 1000).attr("height", 500).append("g");
var tip = d3.select("body").append("div").attr("class", "tooltip").style("opacity", 0);
console.log(data.length)
for (j = 0; j < data.length; j++) {
//json variable
var phage = data[j];
// data arrays for genes and genome length
var genes = phage.genes;
var genome_length = phage.genomelength;
var y = j * 130 + 30;
var lineHeight = 20;
var start = 50;
var end = 2000;
console.log(phage.phagename + " " + phage.genomelength)
svg.append("text")
.attr("x", 0)
.attr("y", y - 20)
.text(phage.phagename)
.style("font-size", "14px")
.attr("font-family", "sans-serif")
.attr("fill", "black")
var axisScale = d3.scale.linear()
.domain([0, phage.genomelength])
.range([0, 600]);
var xAxis = d3.svg.axis()
.scale(axisScale)
.orient("bottom")
.ticks(10);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(100," + (ypos - 10) + ")")
.call(xAxis);
var genes = svg.selectAll("g")
.data(phage.genes)
.enter()
.append("g")
.attr("transform", function(d) {
var xpos = 100 + (d.start / phage.genomelength) * width;
return "translate(" + xpos + "," + ypos + ")";
});
genes.append("rect")
.attr("x", 0)
.attr("y", -10)
.attr("width", function(d) {
return (d.stop - d.start) * width / phage.genomelength;
})
.attr("height", 20)
.attr("rx", 5)
.attr("ry", 5)
.style("fill", function(d) {
if (d.pham.match("a")) {
return "blue";
} else if (d.pham.match("b")) {
return "red";
} else {
return "black";
}
})
.style("stroke", "black")
.attr("transform", function(d) {
if (d.direction == "reverse") {
return "translate(0,20)";
}
})
.attr("transform", function(d) {
if (d.direction == "forward") {
return "translate(0,0)";
}
});
var sequence = d3.select("body")
.append("svg")
.attr("width", 1000)
.attr("height", 100)
.append("g")
.attr("transform", "translate(" + 20 + "," + 5 + ")");
var sequenceRect = sequence.selectAll("rect")
.data(data[i].genes[genepos].sequence)
.enter()
.append("rect")
.attr("height", 10)
.attr("width", 10)
.attr("x", function(d, j) { return j * 12; })
.attr("y", 0)
.style("fill", function(d){
if(d == "A"){
return "#008000";
}
if(d == "C"){
return "#0000FF";
}
if(d == "G"){
return "#FFA500";
}
if(d == "T"){
return "#FF0000";
}
});
var rowheight=50;
var height = data.length*rowheight;
var width = 5000;
var margin = {top: 40, right: 40, bottom: 100, left: 100};
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.attr("opacity", 0);
var x = d3.scale.linear()
.domain([0, 15000])
.range([0, 15000]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10);
var y = d3.scale.linear()
.domain([0, 100])
.range([0, 100]);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(0);
function drawGenome(phage) {
$("#myModal").modal('show');
d3.selectAll("svg").remove();
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom).append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scale.linear().range([0, width]);
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var tip = d3.tip().attr('class', 'd3-tip').offset([-10, 0]).html(function(d) {
return "<span style='color:red'>" + d.pham + "</span>";
})
x.domain([0, 15000]);
var y = d3.scale.linear().range([0, 500]);
y.domain([0, 5]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickSize(-400)
.tickPadding(10)
.tickSubdivide(true);
var svg = d3.select("body").append("svg")
.attr("width", 1100)
.attr("height", 600);
var g = svg.append("g").attr("transform", "translate(100, 100)");
var make_x_scale = function(data) {
return d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.genomelength;
})])
.range([0, 1000]);
};
// load data
// create svg
// create scales
var xScale = d3.scale.linear()
.domain([0, 1])
.range([0, 1000]);
var yScale = d3.scale.linear()
.domain([0, data.length])
.range([20, 250]);
function drawGenome() {
//if (typeof data === 'undefined') return;
// data is available
for (j = 0; j < data.length; j++) {
var y = yScale(j);
var phage = data[j];
for (i = 0; i < data[j].genes.length; i++) {
var start = phage.genes[i].start / phage.genomelength * 100;
var stop = phage.genes[i].stop / phage.genomelength * 100;
var line = (phage.genes[i].direction == "forward") ? "M " + start + " " + y + " L " + (stop) + " " + (y) : "M " + start + " " + y + " L " + (stop) + " " + y;
d3.select("svg").append("path")
.attr("d", line)
.attr("stroke", "steelblue");
d3.select("svg").append("text")
.text(phage.genes[i].name)
.attr("x", (phage.genes[i].start + phage.genes[i].stop) / 2)
.attr("y", y + 20);
});
});
// mouseover for modal
d3.selectAll("path").on("click", function() {
$("#myModal").modal('show');
console.log(this);
$(".modal-body").empty();
var sequence = "DNA Sequence: " + this.__data__.sequence;
$(".modal-body").append("<p>" + sequence + "</p>");
});
}
function init() {
console.log("inside init")
console.log(data)
var width = 960,
height = 3000,
M = 20;
var y = d3.scale.linear()
.domain([0, data.length])
.range([0, height]);
var x = d3.scale.linear()
.domain([0, 1])
.range([0, width]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "center")
var g = svg.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(0," + (i * 100) + ")";
});
g.selectAll("rect")
.data(function(d) {
return d.genes;
})
.enter().append("rect")
.attr("x", function(d) {
return ((d.start / d3.max([d.stop, d.start])) * 30)
})
.attr("y", 25)
.attr("width", function(d) {
return Math.abs((d.stop - d.start) / 500)
})
.attr("height", 30)
.attr("fill", function(d) {
if (d.pham.includes("a")) {
return "green"
} else if (d.pham.includes("b")) {
return "blue"
} else {
return "grey"
}
})
.on("mouseover", function(d) {
console.log(d3.select(this))
tooltip.html(
"<u>" + d.name + "</u><br>" +
"<span style='color:red'>" + d.pham + "</span>"
).style("left", (d3.event.pageX + 5) + "px").style("top", (d3.event.pageY - 28) + "px");
tooltip.transition().duration(200).style("opacity", 0.9)
})
.on("mouseout", function(d) {
tooltip.transition().duration(500).style("opacity", 0);
})
.on("click", function(d) {
$("#myModal").modal("show");
$(".modal-body").empty();
$(".modal-body").append("phage name: " + d.phage + "</br>");
$(".modal-body").append("gene name: " + d.name + "</br>");
$(".modal-body").append("pham: " + d.pham + "</br>");
$(".modal-body").append("start: " + d.start + "</br>");
$(".modal-body").append("stop: " + d.stop + "</br>");
$(".modal-body").append("direction: " + d.direction + "</br>");
$(".modal-body").append("sequence: " + d.sequence + "</br>");
});
}
function getGenomeData() {
var genomes = []
for (i = 0; i < data.length; i++) {
genomes.push({name: data[i].phagename, length: data[i].genomelength, genes: data[i].genes});
}
return genomes;
}
var svg = d3.select("body")
.append("svg")
.attr("width", 1200)
.attr("height", 500)
.append("g")
.attr("transform", "translate(100,0)");
var genomedata = getGenomeData();
var allgenomes = [];
data.forEach(function(d) {
allgenomes.push({
name: d.phagename,
size: d.genomelength
})
});
var y = d3.scale.ordinal()
.domain(allgenomes.map(function(d) { return d.name; }))
.rangeBands([0, 500], .2, .3);
var x = d3.scale.linear()
.domain([0, 15000])
.range([0, 1000]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("top")
.ticks(10)
.tickSize(3)
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
function showTip(d) {
console.log(d)
var name = "Gene " + d.name
var info = "pham: " + d.pham
var start = "Start: " + d.start
var stop = "Stop: " + d.stop
var length = "Length: " + (d.stop - d.start)
var seq = d.sequence
var dir = "Direction: " + d.direction
var html = name + "<br/>" + info + "<br/>" + start + "<br/>" + stop + "<br/>" + length + "<br/>" + dir;
$("#myModal").modal();
$(".modal-body").text("").append(html);
}
// setup page
var phages = []
data.forEach(function(d) {
if (phages.indexOf(d.phagename) == -1) {
phages.push(d.phagename);
}
})
$(".dropdown2").append("<h4>Genome Browser</h4>")
$(".dropdown2").append("<h5>Choose a Phage</h5>")
$(".dropdown2").append("<div class='dropdown'><button class='btn btn-primary dropdown-toggle' type='button' data-toggle='dropdown'>Select Phage<span class='caret'></span></button><ul class='dropdown-menu' id='phage'></ul></div>")
$(".dropdown2").append("<h5>Choose a Pham</h5>")
$(".dropdown2").append("<div class='dropdown'><button class='btn btn-primary dropdown-toggle' type='button' data-toggle='dropdown'>Select Pham<span class='caret'></span></button><ul class='dropdown-menu' id='pham'></ul></div>")
console.log("this ran")
$("ul#phage").append("<li><a href='#'>" + "All" + "</a></li>");
for (var i = 0; i < data.length; i++) {
$("ul#phage").append("<li><a href='#'>" + data[i].phagename + "</a></li>");
}
$("ul#phage li").click(function() {
var phagename = $(this).text();
//add in list of phams from genes of that phage
//clear list of phams
$("ul#pham").empty();
//find all phams in the selected phage
for (i = 0; i < data.length; i++) {
if (data[i].phagename == phagename) {
var myphams = [];
for (x = 0; x < data[i].genes.length; x++) {
myphams.push(data[i].genes[x].pham);
}
var uniq = myphams.filter(function(item, pos) {
return myphams.indexOf(item) == pos;
})
for (x = 0; x < uniq.length; x++) {
var option = document.createElement("option");
option.text = uniq[x];
$("#phamselect").append(option);
}
}
}
var width = 1200,
height = 500,
margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
};
var numphages = data.length;
var y = d3.scale.ordinal().rangeRoundBands([0, height / 2], 0.1).domain(data.map(function(d) {
return d.phagename;
}));
var x = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.genomelength;
})])
.range([0, 900]);
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 500)
.append("g")
.attr("transform", "translate(80,20)");
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (data.length * 100) + ")")
.call(xAxis);
var y = d3.scale.ordinal()
.rangeRoundBands([0, data.length * 100], 0.1);
y.domain(data.map(function(d) { return d.phagename; }));
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(50,0)")
.call(yAxis);
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var genome = svg.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d) {
return "translate(50," + y(d.phagename) + ")";
})
var circles = genome.selectAll("circle")
.data(function(d) {
return d.genes
})
.enter()
.append("circle")
.attr("class", "circles")
.attr("r", 5)
.attr("cx", function(d) {
return x(d.start)
})
.attr("cy", 0)
.on("click", function(d) {
var modal = $('#myModal');
modal.find('.modal-body').html("<p><strong>Name: </strong>" + d.name + "</p><p><strong>Pham: </strong>" + d.pham + "</p><p><strong>Sequence:</strong></p><p>" + d.sequence + "</p>");
modal.modal('show');
});
// display genes
for (j = 0; j < data[0].genes.length; j++) {
var gene = data[0].genes[j];
appendGene(gene, data[0].phagename)
}
function appendGene(gene, phage) {
var y = 0;
var g = d3.select("#viz").append("svg").attr("width", 1000).attr("height", 200)
var line = g.append("line")
.attr("x1", gene.start)
.attr("y1", 50)
.attr("x2", gene.stop)
.attr("y2", 50)
.style("stroke", "blue")
.style("stroke-width", 3)
g.append("text").attr("x", (gene.start + gene.stop) / 2).attr("y", 25)
.style("text-anchor", "middle")
.text(function(d) {
return "Gene: " + gene.name;
});
//Append arrowhead
g.append("svg:defs").append("svg:marker")
.attr("id", "arrow")
.attr("refX", 2)
.attr("refY", 3)
.attr("markerWidth", 4)
.attr("markerHeight", 4)
.attr("orient", "auto")
.append("path")
.attr("d", "M 0 0 L 5 3 L 0 6")
.attr("class", "arrow");
// Add the path
g.append("path")
.attr("stroke-width", "2px")
.attr("fill", "red")
.attr("d", function() {
if (d.direction == "forward") {
return "M" + x(d.start) + "," + y(phagename) + " L" + x(d.stop) + ", " + y(phagename) + " L" + x(d.stop - 50) + ", " + (y(phagename) - 15) + " L" + x(d.stop) + ", " + y(phagename) + " L" + x(d.stop - 50) + ", " + (y(phagename) + 15)
} else {
return "M" + x(d.start) + "," + y(phagename) + " L" + x(d.stop) + "," + y(phagename) + " L" + x(d.stop) + "," + (y(phagename) - 15) + " L" + x(d.stop + 50) + "," + y(phagename) + " L" + x(d.stop) + "," + (y(phagename) + 15)
}
}
var margin = {
top: 50,
right: 100,
bottom: 100,
left: 100
},
width = 900 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.genomelength;
})])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, data.length])
.range([0, height]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var margin = {
left: 150,
right: 150,
top: 30,
bottom: 30
},
width = 1000 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var xScale = d3.scale.linear()
.domain([0, 15000])
.range([0, width]);
var yScale = d3.scale.linear()
.domain([0, data.length])
.range([0, height]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(10)
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(data.length)
.tickFormat(function(d) { return data[d].phagename; })
var svg = d3.select("body").append("svg")
.attr("width", 1400)
.attr("height", 300)
.append("g")
.attr("transform", "translate(100,20)");
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Name:</strong> <span style='color:red'>" + d.name + "</span><br/> Start:" + d.start + "<br/> Stop: " + d.stop + "<br/> Pham: " + d.pham + "</br>Direction: " + d.direction + " </br>Sequence: " + d.sequence + "</br>"
})
var chart = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 500)
.append("g")
.attr("transform", "translate(" + 150 + "," + 30 + ")");
var stratify = d3.stratify()
.parentId(function(d) { return d.phagename; })
.id(function(d) { return d.name; });
var root = stratify(data);
var partition = d3.layout.partition()
.size([500, 300])
.value(function(d) { return d.genomelength; });
var t = d3.select("#chicken").transition().duration(750);
var viz = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 1000)
// only one of these two lines can be uncommented!
// .style("background", "red");
//.style("background", "green");
// Add the svg viewbox
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 900)
.append("g")
.attr("transform", "translate(60,20)");
var color = d3.scale.category10();
var genes = data;
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var x = d3.scale.linear().domain([0, 15000]).range([0, 1000]);
var y = d3.scale.linear().domain([0, data.length * 2]).range([0, 800]);
var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(20);
var yAxis = d3.svg.axis()
.scale(d3.scale.linear().domain([0, 40]).range([0, 400]))
.orient("left")
.ticks(5);
var svg = d3.select("body")
.append("svg")
.attr("width", 1300)
.attr("height", 1000)
.append("g")
.attr("transform", "translate(" + 100 + "," + 20 + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, 450)")
.call(d3.svg.axis()
.scale(xScale)
.orient("bottom"));
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(100,0)")
.call(d3.svg.axis()
.scale(yScale)
.orient("left"));
var yScale = d3.scale.linear().domain([0, 3]).range([0, 350]);
var xScale = d3.scale.linear().domain([0, 15000]).range([0, 1000]);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Gene:</strong> <span style='color:red'>" + d.name + "</span>";
})
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 500)
.append("g");
var g = svg.append("g");
// add x axis
var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(20, "s");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(20," + (height - 30) + ")")
.call(xAxis);
// code for the axis
var y0 = d3.scale.linear().domain([0, 10000]).range([0, height]),
y1 = d3.scale.linear().domain([0, 10000]).range([0, height]),
y2 = d3.scale.linear().domain([0, 10000]).range([0, height]);
var x = d3.scale.linear().domain([0, 15000]).range([0, width]);
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var seqLen = 50;
var rectHeight = 25;
var small = 10;
var height = 400 - 30;
var width = 900 - 30;
var padding = 40;
// var data = [{
// "phagename": "D29",
// "genes": [
// {"name": 1, "pham": "a1", "start": 50, "stop": 2000, "direction":"forward", "phage":"D29","sequence":"ATCGCGCGTATAGCGCGCTAGCTAGCTGACTATATTATATAGCGCT"},
// {"name": 2, "pham": "a2", "start": 2150, "stop": 2900, "direction":"reverse", "phage":"D29", "sequence":"ATCGCGCGTATAGCGCGCTAGCTAGCTGACTATATTATATAGCGCT"},
// {"name": 3, "pham": "a3", "start": 3000, "stop": 4550, "direction":"reverse", "phage":"D29", "sequence":"ATCGCGCGTATAGCGCGCTAGCTAGCTGACTATATTATATAGCGCT"},
// {"name": 4, "pham": "a4", "start": 4700, "stop": 7550, "direction": "forward", "phage":"D29", "sequence":"ATCGCGCGTATAGCGCGCTAGCTAGCTGACTATATTATATAGCGCT"}],
// "genomelength": 15000
// },
// {
// "phagename": "U2",
// "genes": [{
// "name": 1,
// "pham": "a1",
// "start": 50,
// "stop": 2000,
// "direction": "forward",
// "phage":"U2",
// "sequence":"ATCGCGCGTATAGCGCGCTAGCTAGCTGACTATATTATATAGCGCT"
// },
// {
// "name": 2,
// "pham": "a2",
// "start": 2150,
// "stop": 2900,
// "direction": "reverse",
// "phage":"U2",
// "sequence":"ATCGCGCGTATAGCGCGCTAGCTAGCTGACTATATTATATAGCGCT"
// },
// {
// "name": 3,
// "pham": "a3",
// "start": 3000,
// "stop": 4550,
// "direction": "reverse",
// "phage":"U2",
// "sequence":"ATCGCGCGTATAGCGCGCTAGCTAGCTGACTATATTATATAGCGCT"
// },
// {
// "name": 4,
// "pham": "a4",
// "start": 4700,
// "stop": 7550,
// "direction": "forward",
// "phage":"U2",
// "sequence":"ATCGCGCGTATAGCGCGCTAGCTAGCTGACTATATTATATAGCGCT"
// }],
"genomelength": 14000
}]
var w = 1200;
var h = 500;
var padding = 40;
var dataset = [{
key: "D29",
value: 15000
}, {
key: "U2",
value: 14000
}, {
key: "L5",
value: 10000
}];
var xscale = d3.scale.linear()
.domain([0, 15600])
.range([0, 800]);
var yscale = d3.scale.linear()
.domain([0, 3])
.range([0, 300]);
var svg = d3.select("body")
.append("svg")
.attr("width", 1000)
.attr("height", 500);
svg.selectAll("line")
.data(d3.range(0, 3))
.enter()
.append("line")
.attr("x1", 100)
.attr("x2", 900)
.attr("y1", function(d) { return 70 + (d * 130); })
.attr("y2", function(d) { return 70 + (d * 130); })
.attr("stroke", "grey")
.attr("stroke-width", 1)
.style("stroke-dasharray", "3 3");
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Name:</strong> <span style='color:red'>" + d.name + "</span><br><strong>PHAM:</strong> <span style='color:red'>" + d.pham + "</span><br><strong>Sequence:</strong> <span style='color:red'>" + d.sequence + "</span>"
})
var svg = d3.select("body")
.append("svg")
.attr("width", 1200)
.attr("height", 400)
.append("g");
var g = svg.append("g");
var zoom = d3.behavior.zoom()
.scaleExtent([1, 10])
.on("zoom", function() {
g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
});
svg.call(zoom);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Name:</strong> <span style='color:red'>" + d.name + "</span></br><strong>Pham:</strong> <span style='color:red'>" + d.pham + "</span></br><strong>Direction:</strong> <span style='color:red'>" + d.direction + "</span></br><strong>Start:</strong> <span style='color:red'>" + d.start + "</span></br><strong>Stop:</strong> <span style='color:red'>" + d.stop + "</span></br>";
});
var width = 960,
height = 300,
margins = 40;
var maxLength = 20000;
var x = d3.scale.linear()
.domain([0, maxLength])
.range([0, 1000]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(20);
var svg = d3.select("body").append("svg")
.attr("width", 1300)
.attr("height", 800)
.attr("class", "svg")
.append("g")
.attr("transform", "translate(0,40)");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, 100)")
.call(xAxis);
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
var width = 1400,
height = 600;
var x = d3.scale.linear()
.domain([0, 10000])
.range([0, 1000]);
//var y = d3.scale.linear()
// .domain([0, 100])
// .range([0, height]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var color = d3.scale.category10();
var phages = []
var maxlen = 0
for (i = 0; i < data.length; i++) {
var len = data[i].genomelength;
phages.push(data[i].phagename)
if (len > maxlen) maxlen = len;
}
var x = d3.scale.linear()
.domain([0, maxlen])
.range([0, 900]);
var y = d3.scale.linear()
.domain([0, data.length])
.range([0, 400]);
var y1 = d3.scale.linear()
.domain([0, 100])
.range([0, 400]);
var x1 = d3.scale.linear()
.domain([0, 100])
.range([0, 900]);
var chart = d3.select("body")
.append("svg")
.attr("width", 1200)
.attr("height", 800);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var x = d3.scale.linear()
.domain([0, d3.max(data, function(d) { return d.genomelength; })])
.range([0, 900]);
var y = d3.scale.linear()
.domain([0, data.length])
.range([0, 400]);
//Add X axis
chart.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(4);
var chart = d3.select("body")
.append("svg")
.attr("width", 1500)
.attr("height", 750)
.append("g")
.attr("transform", "translate(50,20)");
var x = d3.scale.linear()
.domain([0, 16000])
.range([0, 1100]);
var y = d3.scale.linear()
.domain([0, 100])
.range([0, 500]);
chart.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, 430)")
.call(d3.svg.axis()
.scale(x)
.orient("bottom"));
var min = 999999;
var max = 0;
var minp = "default";
var maxp = "default";
for (i = 0; i < data.length; i++) {
if (data[i].genomelength < min) {
min = data[i].genomelength;
minp = data[i].phagename;
}
if (data[i].genomelength > max) {
max = data[i].genomelength;
maxp = data[i].phagename;
}
}
var genomes = [];
for (i = 0; i < data.length; i++) {
var genomeLength = data[i].genomelength;
var genomeScale = d3.scale.linear().domain([0, genomeLength]).range([0, 800]);
var genes = data[i].genes;
// var y = 50;
var y = (i+1)*100;
var line = d3.svg.line()
.x(function(d) {
return genomeScale(d[0]);
})
.y(function(d) {
return d[1];
});
var area = d3.svg.area()
.x(function(d) {
return genomeScale(d[0]);
})
.y0(300)
.y1(function(d) {
return d[1];
});
function showModal(phagename) {
$(".modal-body").empty();
$(".modal-body").append("<h3>" + phagename + "</h3>");
$('#myModal').modal('show');
}
function pham_color(pham) {
var phams = ["a1", "a2", "a3", "a4", "b1", "b2", "b3", "b4", "c1", "c2", "c3", "c4", "d1", "d2", "d3", "d4", "e1", "e2", "e3", "e4", "f1", "f2", "f3", "f4", "g1", "g2", "g3", "g4"];
for (i = 0; i < phams.length; i++) {
if (phams[i] === pham) {
return i;
}
}
}
var w = 1000;
var h = 500;
var padding = 40;
var yscale = d3.scale.linear().domain([0, data.length]).range([20, h - 40]);
var xscale = d3.scale.linear().domain([0, 15000]).range([0, w]);
var yscale = d3.scale.linear().domain([0, 60]).range([0, h - 100]);
var yscale2 = d3.scale.linear().domain([0, 60]).range([0, h - 100]);
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 500)
.append("g");
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Pham:</strong> <span style='color:red'>" + d.pham + "</span>";
})
var x = d3.scale.linear().domain([0, 20000]).range([0, 1100]);
var y = d3.scale.linear().domain([0, 15]).range([0, 470]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(20)
.tickSize(1);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(7)
.tickSize(1);
// add axes
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 700)
.append("g")
.attr("transform", "translate(" + 100 + "," + 20 + ")");
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var x = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.genomelength;
})
])
.range([0, 900]);
var y = d3.scale.ordinal().rangeRoundBands([0, 500], 0.4);
y.domain(data.map(function(d) {
return d.phagename;
}));
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var svg = d3.select("body").append("svg")
.attr("width", 1400)
.attr("height", 2000)
.append("g")
.attr("transform", "translate(" + 100 + "," + 20 + ")");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + 100 + ")")
.call(xAxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(50,0)")
.call(yAxis);
function drawGenome(phage) {
var y = d3.scale.ordinal()
.domain(phage.genes.map(function(d) { return d.name; }))
.rangePoints([0, 120]);
//console.log(y)
var x = d3.scale.linear()
.domain([0, phage.genomelength])
.range([0, 900]);
var dx = Math.abs(phage.genes[0].stop - phage.genes[0].start)
var dy = Math.abs(phage.genes[1].stop - phage.genes[1].start);
//If not enough space for text add '...'
function addEllipses(text, maxLength) {
if (text.length > maxLength) {
text = text.substring(0, maxLength) + "...";
}
return text;
}
//Define the arrow head for the direction of the gene
var arrowHead = d3.svg.symbol()
.type("triangle-forward")
.size(100);
//color function
var color = d3.scale.category10();
// drawing the svg
var svg = d3.select("body").append("svg")
.attr("width", 1300)
.attr("height", 500);
var g = svg.append("g")
.attr("transform", "translate(50,100)");
var g1 = svg.append("g")
.attr("transform", "translate(0,100)");
// axes
var xScale = d3.scale.linear()
.domain([0, 15500])
.range([0, 1100]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5);
var yScale = d3.scale.linear()
.domain([0, 5])
.range([0, 250]);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
// Drawing the axes
g = d3.select('.chart').append('svg').attr('width', 1500).attr('height', 1500).append('g')
.attr('transform', 'translate(100, 100)');
g.append('g')
.attr('class', 'axis')
.attr('transform', 'translate(0, 250)')
.call(d3.svg.axis().scale(xScale));
g.append('g')
.attr('class', 'axis')
.attr('transform', 'translate(50,0)')
.style("text-anchor", "end", "fill", "black")
.call(d3.svg.axis().scale(yScale).orient("left"));
var x = d3.scale.linear().domain([0, 16000]).range([0, 1000]);
var y = d3.scale.linear().domain([0, 4]).range([0, 200]);
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(1);
var svg = d3.select("body").append("svg").attr("width", 1300).attr("height", 500).append("g");
var tooltip = d3.select("body").append("div").attr("class", "tooltip").style("opacity", 0);
var color = d3.scale.category10();
var phage;
var selected;
d3.selectAll("p").data(data).enter().append("p").text(function(d) {
return d.phagename
});
d3.selectAll("p").data(data).on("click", function(d) {
d3.selectAll("svg").remove();
draw(d);
$("#chicken").empty();
$("#chicken").append('<div class="modal-header"><button class="close" data-dismiss="modal" type="button">×</button><h4 class="modal-title">Information</h4></div><div class="modal-body"></div>');
$(".modal-body").append("<p>Phage Name: " + d.phagename + "</p>");
$(".modal-body").append("<p>Genome Length: " + d.genomelength + "</p>");
$(".modal-body").append("<p>Genes: " + d.genes.length + "</p>");
//$(".modal-body").append("<p>Click a gene to see its sequence.</p>");
}
$("p").click(function() {
var phagename = $(this).attr("id");
var newname = phagename.replace(/ /g, "_");
console.log("newName: " + newname);
$("#myModal").modal();
$(".modal-body").empty();
$(".modal-body").append("<p>Click on the button below to see the sequence of this phage genome</p>")
$(".modal-body").append("<button type='button' class='btn btn-info btn-lg' data-toggle='modal' data-target='#myModal' id='seq_button'>Sequence</button>");
$(".modal-body").append("<p id='seq' style='display:none;'>" + "Genome Sequence" + "</p>")
$("#seq").append(data[0].genes[0].sequence);
$(".modal-body").append("<p>" + "Name: " + data[0].phagename + "</p>");
$(".modal-body").append("<p>" + "Length: " + data[0].genomelength + "</p>");
$(".modal-body").append("<p>" + "GC content: " + data[0].GC + "</p>");
$(".modal-body").append("<p>" + "Gene Number: " + data[0].genes.length + "</p>");
$(".modal-body").append("<p> Click gene for more info </p>");
};
if (data[0].phagename == "D29") {
calc(0, "D29")
}
}
// this next line is to test things and then can be deleted later
//$('#myModal').modal('show');
// create svg
var width = 1500,
height = 500;
var y = d3.scale.ordinal().rangeRoundBands([0, height], .5, .3);
var x = d3.scale.linear().domain([0, 15000]).range([0, width]);
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
y.domain(data.map(function(d) {
return d.phagename;
}));
var gene = svg.selectAll("gene")
.data(data)
.enter()
.append('g')
.attr("class", "gene");
var g = gene.attr("transform", function(d) {
return "translate(0," + (y(d.phagename) + 30) + ")";
});
console.log(data)
// add in the lines for the genome background
g.append("line")
.attr("x1", 0)
.attr("x2", function(d) {
return d.genomelength;
})
.attr("y1", 0)
.attr("y2", 0)
.attr("stroke", "black")
.attr("stroke-width", "2")
.attr("transform", "translate(50,0)");
// add in axes
var xScale = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.genomelength;
})])
.range([0, 1000]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 1000)
.append("g")
.attr("transform", "translate(100,50)");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0,30)")
.call(xAxis);
var genome = svg.selectAll("g.genome")
.data(data)
.enter()
.append("g")
.attr("class", "genome")
.attr("transform", function(d, i) {
return "translate(0," + ((i + 1) * 100) + ")";
});
var genes = genome.selectAll("g.genome")
.data(function(d) {
return d.genes;
})
.enter()
.append("g")
.attr("class", "gene")
.attr("transform", function(d) {
return "translate(" + d.start + ",0)";
});
genes.append("rect")
.attr("x", 0)
.attr("y", -12)
.attr("width", function(d) {
return d.stop - d.start;
})
.attr("height", 20)
.attr("rx", 10)
.attr("ry", 10)
.style("fill", function(d) {
if(d.pham=="a1" || d.pham=="a2" || d.pham=="a3" || d.pham=="a4" || d.pham=="a5" || d.pham=="a6" || d.pham=="a7"){
return "#F38630";
} else if (d.pham=="b1" || d.pham=="b2" || d.pham=="b3" || d.pham=="b4" || d.pham=="b5" || d.pham=="b6") {
return "#A7DBD8";
} else {
return "#E0E4CC";
}
})
.attr("stroke", "black")
.attr("transform", function(d) {
if(d.direction=="forward")
return "translate(" + (d.start) + "," + 0 + ")";
else
return "translate(" + (d.start) + "," + 20 + ")";
});
var y = d3.scale.linear()
.domain([0, 200])
.range([0, 100]);
function drawGenome(data) {
console.log("draw genome");
// console.log(data[0].genes[0].name)
// var svg = d3.select("body")
// .append("svg")
// .attr("width", 1000)
// .attr("height", 1000);
var svg = d3.select("#draw")
.append("svg")
.attr("width", 1500)
.attr("height", 2500)
.append("g");
// add the tooltip to the body
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var genome_length = data[0].genomelength;
var x = d3.scale.linear()
.domain([0, genome_length])
.range([0, 900]);
// var x = d3.scale.linear().domain([0, 30000]).range([0, 900]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var y = d3.scale.linear()
.domain([0, data.length])
.range([0, 1500]);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var canvas = d3.select("body")
.append("svg")
.attr("width", 1200)
.attr("height", 800)
.attr("class", "canvas");
var group = canvas.append("g")
.attr("transform", "translate(100,50)");
//draw axis
group.append("g").attr("class", "axis").call(d3.svg.axis().scale(xscale).orient("bottom"));
var xscale = d3.scale.linear()
.domain([0, 10000])
.range([0, 900]);
// add y axis
var yscale = d3.scale.linear()
.domain([0, data.length])
.range([0, data.length * 40]);
group.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, 50)")
.call(d3.svg.axis().scale(xscale).orient("bottom"))
.selectAll("text")
.attr("transform", "rotate(-45)")
.style("text-anchor", "end");
// Create the tooltip
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var y = d3.scale.ordinal().rangeRoundBands([0, 500], .1);
y.domain(data.map(function(d) { return d.phagename; }));
var x = d3.scale.linear()
.domain([0, 15000])
.range([0, 1000]);
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 500);
var xAxis = d3.svg.axis()
.scale(x)
.orient("top")
.tickSize(-500)
.tickValues([0,1000,2000,3000,4000,5000,6000,7000,8000,9000,10000,11000,12000,13000,14000,15000])
.tickFormat(function(d) { return d/1000 + "kb"; });
var chart = d3.select("body")
.append("svg")
.attr("width", 1000)
.attr("height", 600)
.append("g")
.attr("transform", "translate(100,20)");
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, 50)")
.call(xAxis);
//x axis
var x = d3.scale.linear()
.domain([0, 15000])
.range([0, 900]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5);
var y = d3.scale.linear()
.domain([0, 4])
.range([40, 290]);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(4);
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 400)
.append("g")
.attr("transform", "translate(80,20)");
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Pham:</strong> <span style='color:black'>" + d.pham + "</span>"
})
svg.call(tip);
var x = d3.scale.linear()
.domain([0, 15000])
.range([0, 900]);
var y = d3.scale.linear()
.domain([0, 4])
.range([30, 290]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(15);
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 500)
.append("g");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(20,400)")
.call(xAxis);
var genome = svg.append("g");
var genes = genome.selectAll("g").data(data).enter().append("g");
genes.append("text").attr("x", 130).attr("y", function(d, i) {
var y = 100 + (i * 50);
return y; })
.text(function(d) { return d.phagename; }).attr("class", "phage");
var gene = genes.selectAll("g")
.data(function(d) { return d.genes; })
.enter()
.append("g");
// // // // // // //
gene.append("rect")
.attr("x", function(d) {
// scale linear for start based on genome length
return (d.start / d3.max(data, function(d) {
return d.genomelength;
}) * 1000) + 50;
})
.attr("y", function(d) {
if (d.direction == "forward") {
return 15;
} else {
return 35;
}
})
.attr("width", function(d) {
return (Math.abs(d.stop - d.start) / d3.max(data, function(d) {
return d.genomelength;
})) * 1000;
})
.attr("height", 10)
.attr("fill", function(d) {
if (d.pham.slice(0,1) == "a") {
return "#e66101";
} else if (d.pham.slice(0,1) == "b") {
return "#fdb863";
} else if (d.pham.slice(0,1) == "c") {
return "#b2abd2";
} else if (d.pham.slice(0,1) == "d") {
return "#5e3c99";
} else {
return "#000000";
}
})
.attr("transform", function(d) {
return "translate(" + (d.start/10) + "," + 0 + ")";
})
.attr("width", function(d) {
return ((d.stop - d.start) / 10)
})
.attr("height", 20)
.attr("rx", 10)
.attr("ry", 5)
.on("mouseover", function(d) {
tooltip.transition().style("opacity", .9);
tooltip.html(d.name + " " + d.pham)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
tooltip.transition().style("opacity", 0);
});
console.log("data" + data)
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.genomelength;
})])
.range([0, width]);
var y = d3.scale.ordinal()
.domain(data.map(function(d) { return d.phagename; }))
.rangeBands([0, height], .5, .3);
var xAxis = d3.svg.axis()
.scale(x)
.orient("top")
.ticks(5);
var zoom = d3.behavior.zoom()
.x(x)
.scaleExtent([1, 10])
.on("zoom", draw);
var svg = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 500)
.append("g")
.attr("transform", "translate(" + 100 + "," + 20 + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0, " + height + ")")
.call(d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.format("d"))
.ticks(10)
.outerTickSize(0));
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(0,0)")
.call(d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5)
.tickSize(0))
.selectAll("text").attr("dx", "-.6em");
var width = 960,
height = 500,
margin = {
top: 50,
right: 50,
bottom: 100,
left: 100
},
g = [];
var x = d3.scale.linear()
.range([0, width - 150])
.domain([0, d3.max(data, function(d) {
return d.genomelength;
})])
var y = d3.scale.ordinal()
.rangeBands([0, height - 150], .2, .3);
y.domain(data.map(function(d) { return d.phagename; }));
//create tooltip
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Name:</strong> <span style='color:red'>" + d.name + "</span></br>"
+ "Pham: " + d.pham + "</br>Start: " + d.start + "</br>Stop: " + d.stop;
})
// .direction('w')
var svg = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 600)
.append("g");
svg.call(tip);
var a = 0;
var k = 0;
var clicky = 0;
var bubclicky = 0;
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Phage:</strong> <span style='color:red'>" + d.phagename + "</strong><br>Gene:" + d.name + " " + d.pham + "</span>";
})
//console.log("complete")
var tip2 = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Phage:</strong> <span style='color:red'>" + d.phagename + "</span>";
})
// console.log( data)
var w = 1000;
var h = 500;
var padding = 20;
var monthScale = d3.scale.linear().domain([0, 20000]).range([0, 900]);
var monthScale2 = d3.scale.linear().domain([0, 20000]).range([0, 700]);
var yScale = d3.scale.linear()
.domain([0, data.length * 100])
.range([0, 400]);
var svg = d3.select("body").append("svg").attr("width", 1200).attr("height", 1000)
var phage = svg.selectAll("phage")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(0," + (80 + i * 120) + ")";
});
console.log("data loaded")
// var x = d3.scale.linear().domain([0, 25000]).range([0, 1000]);
var x = d3.scale.linear()
.domain([0, 15000])
.range([0, 1000]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10);
var g = phage.append("g")
.attr("class", "axis")
.call(xAxis);
var phage = d3.select("body")
.append("svg")
.attr("width", 1200)
.attr("height", 250)
.append("g")
.attr("transform", "translate(100,20)");
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Gene:</strong> <span style='color:red'>" + d.name + "</span>"
+ "<br><strong>Start:</strong> <span style='color:red'>" + d.start + "</span>"
+ "<br><strong>Stop:</strong> <span style='color:red'>" + d.stop + "</span>"
+ "<br><strong>Pham:</strong> <span style='color:red'>" + d.pham + "</span>"
})
var phages = ["D29", "U2", "L5"];
var colors = ["#FF0000", "#00FF00", "#0000FF"];
var clicked = false;
var val = new Array();
var genename = new Array();
for (i = 0; i < data.length; i++) {
var line = data[i];
var group = svg.append("g").attr("class", "group" + i);
var y = 45 + i * 60;
// first line
group.append("line")
.attr("x1", margin.left)
.attr("y1", y)
.attr("x2", width - margin.right)
.attr("y2", y)
.attr("class", "line")
.style("stroke", "grey")
.attr("stroke-width", "10");
var y2 = y + 45;
group.append("line")
.attr("x1", margin.left)
.attr("y1", y2)
.attr("x2", width - margin.right)
.attr("y2", y2)
.attr("class", "line")
.style("stroke", "grey");
// backbone arrows
var l = width - margin.left - margin.right;
var arrow = svg.append("defs").append("marker")
.attr("id", "arrow")
.attr("viewBox", "0 0 10 10")
.attr("refX", 10)
.attr("refY", 5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto");
arrow.append("path")
.attr("d", "M 0 0 L 10 5 L 0 10 z");
svg.append("line")
.attr("x1", 50)
.attr("y1", 20)
.attr("x2", 45)
.attr("y2", 20)
.attr("stroke", "black")
.attr("stroke-width", 1)
.attr("marker-end", "url(#arrowhead)");
svg.append("line")
.attr("x1", 50)
.attr("y1", 20)
.attr("x2", 45)
.attr("y2", 20);
}
function drawGenome(data) {
var w = 800;
var h = 250;
var axisPadding = 30;
var axisHeight = 20;
var chartHeight = 150;
var barPadding = 0.5;
var widths = [];
var offset = [];
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h)
.style("padding", "30px");
var x = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.genomelength
})])
.range([0, 500]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5)
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// colour scale
var color = d3.scale.category20();
//draw each phage genome
data.forEach(function(genome) {
console.log(genome)
var yPosition = data.indexOf(genome) * 100;
var g = svg.append("g").attr("transform", "translate(0," + yPosition + ")");
g.append("text")
.attr("x", 20)
.attr("y", 30)
.text(genome.phagename)
.style("font-size", "12px")
.attr("alignment-baseline", "middle")
.attr("text-anchor", "beginning")
.style("font-weight", "bold");
genome.genes.forEach(function(gene) {
g.append("rect")
.attr("x", xscale(gene.start))
.attr("y", 50)
.attr("width", xscale(gene.stop)-xscale(gene.start))
.attr("height", 25)
.attr("fill", function(d) {
if (gene.pham === gene.pham){
return "red"
}})})
var data = []
//console.log(data)
d3.select("#dviz").selectAll("div").remove();
var bar = d3.select("#dviz").selectAll("div")
.data(data)
.enter().append("div")
.style("width", "20px")
.style("height", "20px")
.style("background", "red");
}
function draw(viz) {
console.log(viz)
var sequences = []
for (i=0;i<data.length;i++) {
for(j=0;j<data[i].genes.length;j++){
var obj = data[i].genes[j];
obj["phage"] = data[i].phagename;
sequences.push(obj);
}
}
var w = 700;
var h = 300;
var axisPad = 30;
var axisHeight = h - 70;
var rowHeight = 20;
var leftPad = 80;
var width = w - 20;
var padding = 20;
var length = 0;
data.forEach(function(d){ if(d.genomelength > length){ length = d.genomelength; }});
var x = d3.scale.linear()
.domain([0, length])
.range([padding, width]);
var y = d3.scale.linear()
.domain([0, 4])
.range([50, axisHeight]);
// add axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.domain([0, 15000]).range([0, width]);
var y = d3.scale.linear()
.domain([0, 100]).range([0, height]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5);
var x = d3.scale.linear()
.domain([0, 16000])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, 100])
.range([height, 0]);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(10,0)")
.call(yAxis);
var width = 960,
height = 400;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var x = d3.scale.linear()
.domain([0, 10000])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, 100])
.range([0, height]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var color = d3.scale.category20();
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<span style='color:red'>" + d.pham + "</span>";
})
//Define the svg
var height = 600,
width = 960;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
function drawGenome(phage) {
// remove existing svg elements
d3.selectAll("svg > *").remove();
var objpos = 0;
for (i = 0; i < data.length; i++) {
if (data[i].phagename == phage) {
objpos = i;
}
}
var genes = data[objpos].genes;
var genomenode = data[objpos];
var w = 1000;
var h = 120;
var padding = 20;
var xScale = d3.scale.linear()
.domain([0, genomenode.genomelength])
.range([0, 900]);
var yScale = d3.scale.linear()
.domain([0, 10])
.range([0, 100]);
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 100)
.append("g");
svg.append("rect")
.attr("width", 900)
.attr("height", 70)
.attr("rx", 10)
.attr("ry", 10)
.attr("x", 100)
.attr("y", 20)
.attr("fill", "white")
.attr("stroke", "grey")
.attr("stroke-width", 1.5);
var xscale = d3.scale.linear()
.domain([0, data[0].genomelength])
.range([0, 850]);
var yscale = d3.scale.linear()
.domain([0, 100])
.range([50, 0]);
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var x = d3.scale.linear()
.domain([0, data[0].genomelength])
.range([100, 700]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(20);
for (var j = 0; j < data.length; j++) {
// this creates the svg canvas
var svgContainer = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 100)
.attr("class", "row")
.append("g");
//draw the axis
var axis = svgContainer.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, 30)")
.call(xAxis);
var xAxis = d3.svg.axis()
.scale(xscale)
.orient("top")
.ticks(5);
var xscale = d3.scale.linear()
.domain([0, data[j].genomelength])
.range([0, 1000]);
for (j = 0; j < data.length; j++) {
var phage = data[j].phagename;
var gLength = data[j].genomelength;
var xscale = d3.scale.linear()
.domain([0, gLength])
.range([0, 1000]);
//draws line for genome backbone
d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 50)
.append("path")
.attr("d", "M 100 25 L " + (100 + xscale(gLength)) + " 25")
.style("stroke", "black")
.style("stroke-width", "2")
.style("fill", "none")
var dir = 1;
if (data[i].genes[0].direction == "forward") {
dir = -1;
}
// Add title and tooltips
d3.selectAll("svg").append("text")
.attr("x", 500)
.attr("y", 100)
.attr("text-anchor", "middle")
.attr("font-size", "20px")
.attr("font-family", "sans-serif")
.style("fill", "black")
.text("Phage " + data[i].phagename)
.append("title")
.text(data[i].phagename);
d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
for (j = 0; j < data[i].genes.length; j++) {
if (data[i].genes[j].phage == phage) {
console.log("its here")
console.log(data[i].genes[j].name)
genepos = j;
}
}
d3.select(".modal-body").html("<h4>Information about " + data[objpos].genes[genepos].name + "</h4>")
//...
d3.selectAll("path").remove()
// define gene
function gene(x, y, h, w, fill) {
return d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
([[x, y + 100], [x, y], [x + 10, y - 15], [x + 20, y], [x + 20, y + 100]])
}
// define arrowhead marker
var defs = svg.append("defs");
defs.append("svg:marker", {
"id": "arrow",
"viewBox": "0 0 10 10",
"refX": 10,
"refY": 5,
"markerUnits": "strokeWidth",
"markerWidth": 10,
"markerHeight": 10,
"orient": "auto"
}).append("path")
.attr("d", "M 0 0 L 10 5 L 0 10 z")
.attr("fill", "red");
var x = d3.scale.linear()
.domain([0, 15000])
.range([0, 900]);
var y = d3.scale.linear()
.domain([0, 20])
.range([0, 800]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10);
var svg = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 1000)
.append("g")
.attr("transform", "translate(" + 100 + "," + 30 + ")");
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, 800)")
.call(xAxis);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Name:</strong> <span style='text-transform: capitalize;'>" + d.name + "</span>" + "<BR/>" + "<strong>Pham:</strong> <span style='text-transform: capitalize;'>" + d.pham + "</span>";
});
d3.select("svg").call(tip);
function mouseover(access) {
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
return tip;
}
var mySVG = d3.select("#vistkis").append("svg")
.attr("width", 1000)
.attr("height", 300);
function draw(phage) {
var phageData = [];
for (i = 0; i < data.length; i++) {
if (data[i].phagename == phage) {
phageData = data[i];
}
}
d3.select("#vistkis").selectAll("svg").remove();
var svg = d3.select("#vistkis")
.append("svg")
.attr("width", 1200)
.attr("height", 300)
.attr("viewBox", "0 0 1200 300")
.attr("class", "svg");
var length = phageData.genomelength;
var width = 1000;
var margin = 50;
var padding = 50;
var axisHeight = 20;
var x = d3.scale.linear()
.domain([0, length])
.range([margin, width]);
var y = d3.scale.linear()
.domain([0, 300])
.range([10, 280]);
var chart = d3.select(".chart");
// clean up the old chart
chart.html("");
// draw the axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, 20)")
.call(xAxis);
var genes = data[0].genes;
var phage = data[0].phagename;
console.log(data[0]);
var line = svg.append("line")
.attr("x1", 100)
.attr("y1", 200)
.attr("x2", 1300)
.attr("y2", 200)
.attr("stroke-width", 2)
.attr("stroke", "black");
for (i = 0; i < genes.length; i++) {
if (genes[i].direction == "forward") {
var path = svg.append("path")
.attr("d", "M " + (genes[i].start+50) + " 200 L " + (genes[i].stop+50) + " 200")
.attr("stroke", "red")
.attr("stroke-width", 10)
.attr("opacity", 1)
.attr("class", "link")
.attr("id", "path" + genes[i].name)
.attr("phage", data[0].phagename)
.attr("gene", genes[i].name)
//put a tooltip on all the genes
// console.log(d3.select(this))
}
function draw(name, phage) {
var genomeLength = data[phage].genomelength;
var info = data[phage].genes;
var svg = d3.select("body")
.append("ul")
//Drawing the genes on the circle
for (var i = 0; i < info.length; i++) {
var start = info[i].start;
var stop = info[i].stop;
if (info[i].direction == "forward") {
var color = "blue";
} else if (info[i].direction == "reverse") {
var color = "red";
} else {
var color = "black";
}
var genes = svg.append("li").attr("class", "gene")
.style("color", color)
.style("display", "inline-block")
.style("height", "10px")
.style("width", info[i].stop - info[i].start + "px")
.text(info[i].name);
}
$('.modal-body').empty();
$('#myModal').on('show.bs.modal', function(event) {
$('.modal-body').empty();
var modal = $(this);
var name = $(event.relatedTarget).data('name');
var genome = $(event.relatedTarget).data('genome');
var directions = $(event.relatedTarget).data('direction');
var seq = $(event.relatedTarget).data('sequence');
modal.find('.modal-body input').val(name);
// populates the body with the information from the button
modal.find('.modal-body').append('<p><b>Gene:</b> ' + name + '</p><p><b>Phage:</b> ' + genome + '</p><p><b>Direction:</b> ' + directions + '</p><p><b>Sequence:</b> ' + seq + '</p>')
}
calc("D29", "D29")
var width = 1000,
height = 800,
padding = 50;
var yScale = d3.scale.linear()
.domain([0, 10])
.range([0, 700]);
var xScale = d3.scale.linear()
.domain([0, 16000])
.range([0, 950]);
var vis = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
vis.append("text")
.attr("x", 500)
.attr("y", 100)
.style("text-anchor", "middle")
.style("font-size", "20px")
.text("Genome Browser")
// Adding axes to the graph
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
var xScale = d3.scale.linear()
.domain([0, 15000])
.range([0, 500]);
var yScale = d3.scale.linear()
.domain([0, 10])
.range([500, 0]);
var svg = d3.select("body")
.append("svg")
.attr("width", 1100)
.attr("height", 500)
.append("g")
.attr("transform", "translate(" + 100 + "," + 20 + ")");
// add x and y axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(5);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0,350)")
.call(xAxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(100,0)")
.call(yAxis);
function drawGenome(xScale, yScale, genomeLength, phageName, startX, startY, color) {
var line = [];
for (i = 0; i < genomeLength; i += 50) {
line.push([startX + i, startY])
};
var linefunction = d3.svg.line()
.x(function(d) {
return d[0];
})
.y(function(d) {
return d[1];
});
svg.append("path")
.attr("d", linefunction(line))
.attr("stroke", color)
.attr("stroke-width", 1)
.attr("fill", "none")
}
function arrowhead(d) {
var a = d;
var b = a[0] + 10;
var c = a[1];
return a[0] + "," + a[1] + " " + b + "," + (c - 5) + " " + b + "," + (c + 5);
}
// The width of the svg is 1000
var width = 1000;
var height = 400;
var seqheight = 200;
var position = 0;
var toggle = 0;
//Creating SVG
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.style("fill", "grey");
//Two viewports
var viewport1 = svg.append("g");
var viewport2 = svg.append("g");
var viewport3 = svg.append("g");
//Function to translate from genome coordinates to
//pixel coordinates
function scale(domain, start, stop, length) {
var min = Math.min(start, stop);
var max = Math.max(start, stop);
return function(d) {
return domain * (d - min) / (max - min);
};
}
function drawGenome(phageName) {
// data
var data = {};
for (j=0;j<data.length;j++){
if (data[j].phagename == phageName){
data = data[j]
}
}
var genes = data.genes;
var genomeLength = data.genomelength;
// dims
var w = 900;
var h = 300;
var padding = 50;
// draw main arc
var yScale = d3.scale.linear().domain([0, genomeLength]).range([padding, w - padding]);
var arc = d3.svg.arc()
.innerRadius(75)
.outerRadius(95)
.startAngle(function(d) { return (d.start / genomeLength) * 2 * Math.PI; })
.endAngle(function(d) { return (d.stop / genomeLength) * 2 * Math.PI; });
// Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", 1000)
.attr("height", 500)
.append("g")
.attr("transform", "translate(350,250)");
// Set up genes
svg.selectAll("path")
.data(data[0].genes)
.enter()
.append("path")
.attr("d", function(d) {
if (d.direction == "forward") {
return arc(d.start, d.stop, 90, 160)
} else {
return arc(d.start, d.stop, 110, 60)
}
})
.attr("transform", function(d) { return "translate(" + (d.start - (d.start - d.stop) / 2) + ",0)" });
var width = 1600,
height = 500;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var pi = Math.PI,
tau = 2 * pi;
var arc = d3.svg.arc()
.innerRadius(150)
.outerRadius(200)
.startAngle(function(d) {
if (d.direction == "forward") {
return (d.start / d.phagegenome_length) * 2 * Math.PI;
} else {
return (d.stop / d.phagegenome_length) * 2 * Math.PI;
}
})
.endAngle(function(d) {
if (d.direction == "forward") {
return (d.stop / d.phagegenome_length) * 2 * Math.PI;
} else {
return (d.start / d.phagegenome_length) * 2 * Math.PI;
}
});
var width = 2000,
height = 1300,
radius = Math.min(width, height) / 2 - 10;
var arc = d3.svg.arc().innerRadius(radius - 140).outerRadius(radius - 60);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var g = svg.selectAll(".arc")
.data(data)
.enter()
.append("g");
g.append("path")
.attr("class", "arc")
.attr("d", function(d) {
return arc(d);
})
.style("fill", function(d) {
return color(d.phagename);
})
.style("fill-opacity", 0.4)
.attr("stroke", "black")
.style("stroke-width", 2)
.on("click", function(d) {
modal(d.phagename)
});
g.append("text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")";
})
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) {
return d.phagename;
});
var genes = data.map(function(d) {
return d.genes.map(function(g) {
return {
phagename: d.phagename,
name: g.name,
pham: g.pham,
start: g.start,
stop: g.stop,
direction: g.direction,
sequence: g.sequence
};
})
});
var genes = genes.reduce(function(a, b) { return a.concat(b) },
[]
);
var nested = d3.nest()
.key(function(d) { return d.pham; })
.entries(genes)
console.log(nested)
var width = 1600,
height = 600;
var x = d3.scale.linear().domain([0, 15000]).range([100, 1500]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.attr("stroke", "grey")
.attr("stroke-width", 1)
var y = d3.scale.ordinal().domain(data.map(function(d) { return d.phagename; }))
.rangeBands([20, 390], 0.5, 1);
var x = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.genomelength;
})])
.range([0, 900]);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Phage Name:</strong> <span style='color:red'>" + d.phagename + "</span>";
})
var svg = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 500)
.append("g");
var g = svg.append("g");
var zoom = d3.behavior.zoom()
.scaleExtent([1, 10])
.on("zoom", function() {
g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
});
svg.call(zoom);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Name:</strong> <span style='color:red'>" + d.name + "</span></br><strong>Start:</strong> <span style='color:red'>" + d.start + "</span></br><strong>Stop:</strong> <span style='color:red'>" + d.stop + "</span></br><strong>Direction:</strong> <span style='color:red'>" + d.direction + "</span></br><strong>Pham:</strong> <span style='color:red'>" + d.pham + "</span></br><strong>Sequence:</strong><br>" + d.sequence + "</br>";
}
d3.select("body").selectAll("svg").remove()
var svg = d3.select("body")
.append("svg")
.attr("width", 1500)
.attr("height", 1500)
.attr("class", "svg")
.append("g");
var allgenomes = [];
for (var j = 0; j < data.length; j++) {
data[j].genes.forEach(function(gen) {
gen.phage = data[j].phagename;
allgenomes.push(gen);
});
}
console.log(allgenomes)
console.log(data)
var scale = d3.scale.linear()
.domain([0, 10000])
.range([0, 900])
var yscale = d3.scale.linear()
.domain([0, 16000])
.range([0, 500])
var yscale2 = d3.scale.linear()
.domain([0, 20000])
.range([0, 800])
var xscale = d3.scale.linear()
.domain([0, 10000])
.range([0, 1000])
//svg container
var svg = d3.select("body").append("svg")
.attr("width", 1700)
.attr("height", 900)
.attr("id", "svg")
.append("g");
//scale for the genomes
var y = d3.scale.linear()
.domain([0, 4])
.range([20, 400]);
// add the X axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5);
var svg = d3.select("body").append("svg")
.attr("width", 1500)
.attr("height", 900)
.append("g")
.attr("transform", "translate(150,20)");
var x = d3.scale.linear().domain([0, 20000]).range([0, 1000]);
var y = d3.scale.ordinal().domain(["D29", "U2", "L5"]).rangeBands([0, 600], .5);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Gene:</strong> <span style='color:red'>" + d.name + "</span>"
})
var x = d3.scale.linear().range([0, 1000]).domain([0, 17000])
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(17)
.tickFormat(function(d) { return d / 1000 + "kb" })
var y = d3.scale.linear().range([0, 150]);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5);
var svg = d3.select("body")
.append("svg")
.attr("width", 1000)
.attr("height", 500);
// tooltips
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
function showTip(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html("Name: " + d.name + "<br/>" + "Start: " + d.start + " Stop: " + d.stop + " Direction: " + d.direction)
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 28) + "px");
}
function hideTip() {
div.transition()
.duration(500)
.style("opacity", 0);
}
data.forEach(function(phage) {
var phagename = phage.phagename;
var genomelength = phage.genomelength;
var genes = phage.genes;
var w = 1200;
var h = 150;
var xScale = d3.scale.linear()
.domain([0, genomelength])
.range([0, w - 100]);
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h)
.attr("class", "genomeBrowser")
.attr("id", phagename)
.style("padding", "10px");
var chart1 = svg.append("g") // a <g> element is a group of shapes
var yScale = d3.scale.linear()
.domain([0, 100])
.range([10, 90])
var xScale = d3.scale.linear()
.domain([0, data[0].genomelength])
.range([0, 1000])
// for D29
//add the title
chart1.append("text")
.attr("x", 20)
.attr("y", 15)
.text("Phage: " + data[0].phagename)
.style("font-size", "20px")
.style("font-family", "sans-serif")
//add label
chart1.append("text")
.attr("x", 600)
.attr("y", 15)
.attr("id", "clickedPhage")
.text("Phage Length: " + data[0].genomelength)
// Add the data
var genes = data[0].genes;
// Set coordinates
var x = 20;
var y = 15;
var length = 100;
var width = 30;
var pham = data[0].genes[0].pham;
// draw svg and axes
var margin = {top: 30, right: 40, bottom: 30, left: 50};
var width = 1000 - margin.left - margin.right;
var height = 300 - margin.top - margin.bottom;
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xScale = d3.scale.linear()
.domain([0, 15000])
.range([0, width]);
var xAxis = d3.svg.axis().scale(xScale).orient("bottom").ticks(10);
svg.append("g").attr("class", "axis").attr("transform", "translate(0," + (height - 30) + ")").call(xAxis);
// Add an SVG element with map features and a popup for each gene
var genes = svg.append("g");
data.forEach(function(genome) {
genes.selectAll("g")
.data(genome.genes)
.enter()
.append("g")
.attr("class", "gene")
.attr("transform", function(d) {
return "translate(" + ( (d.start/15000) * 900 ) + "," + 0 + ")";
})
.on("click", function(d) {
console.log("clicked")
$(".modal-body").empty();
$(".modal-body").append("<h3>Gene name: " + d.name + "</h3>");
$(".modal-body").append("<p>Pham: " + d.pham + "</p>");
$(".modal-body").append("<p>Coordinates: " + d.start + " to " + d.stop + "</p>");
$(".modal-body").append("<p>Direction: " + d.direction + "</p>");
$(".modal-body").append("<p>Sequence: " + d.sequence + "</p>");
$('#myModal').modal('show');
}
}
d3.select(".modal-body").html("").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
console.log(name)
console.log(phage)
for(var i=0;i<data.length;i++){
if(data[i].phagename==phage){
var gd = data[i].genes
for(var j=0;j<gd.length;j++){
if(gd[j].name==name){
var genelength=gd[j].stop-gd[j].start;
var mousex = 50 + (gd[j].start / data[i].genomelength) * 900;
var mousey = 275 + (i*100);
var start = 0;
var offset = Math.round(mousex)+","+Math.round(mousey);
if (genelength < 5000) {
console.log("less than 5000")
} else if(genelength > 10000) {
console.log("too long")
} else {
console.log("less than 10000")
}
}
}
}
var margin = {top: 50, right: 50, bottom: 50, left: 50}
, width = 1500;
var height = 200;
var color = d3.scale.category10();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + 10 + "," + 10 + ")");
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// group the data by phages
var genomedata = [];
var lengthmax = 0;
data.forEach(function(phage) {
if(phage.genomelength>lengthmax){
lengthmax=phage.genomelength;
}
});
var x = d3.scale.linear()
.domain([0, lengthmax])
.range([0, 800]);
var y = d3.scale.linear()
.domain([0, 100])
.range([0, 400]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(15);
var chart = d3.select("body")
.append("svg")
.attr("width", 1000)
.attr("height", 200 + data.length * 75)
.append("g")
.attr("transform", "translate(80,10)");
var line = d3.svg.line()
.x(function(d) { return x(d.start); })
.y(function(d) { return y(0); })
.interpolate("linear");
var line2 = d3.svg.line()
.x(function(d) { return x(d.start); })
.y(function(d) { return y(d.stop); });
function y(d) { return (d); }
var x = d3.scale.linear()
.domain([0, 15500])
.range([0, 950]);
chart = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 500);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(10)
.tickSize(0);
chart.append("g").attr("class", "x axis")
.attr("transform", "translate(0, 30)")
.call(xAxis);
for (var i = 0; i < data.length; i++) {
var phage = data[i]
var y = 100 * (i + 1)
var lg = chart.append("g").attr("id", "line" + phage.phagename)
var x = d3.scale.linear().domain([0, 15000]).range([0, 1000]);
lg.append("path").attr("d", d3.svg.line()([[0, y], [1000, y]]));
for (var z = 0; z < phage.genes.length; z++) {
var dir = phage.genes[z].direction;
var start = phage.genes[z].start;
var stop = phage.genes[z].stop;
var name = phage.genes[z].name;
var pham = phage.genes[z].pham;
var seq = phage.genes[z].sequence;
var x_start = x(start);
var x_stop = x(stop);
var color;
if (phage.genes[z].direction == "forward") {
color = "red";
} else {
color = "blue";
}
if (color == "red") {
var x1 = x_start,
y1 = 20,
x2 = x_stop,
y2 = 20;
} else {
var x1 = x_start,
y1 = 30,
x2 = x_stop,
y2 = 30;
}
d3.select("svg").append("rect")
.attr("x", x1)
.attr("y", y1)
.attr("width", Math.abs(x2 - x1))
.attr("height", 4)
.style("fill", function(d) {
if (phage == "L5") { return "purple"; }
else if (phage == "U2") { return "green"; }
else { return "steelblue"; }
})
.append("title")
.text("Name: " + name);
d3.select("svg").append("text")
.attr("x", x1 + (Math.abs(x2 - x1) / 2))
.attr("y", -8)
.attr("text-anchor", "middle")
.style("fill", "black")
.text(name);
};
var g = [];
var y = 40;
var i = 0;
data.forEach(function(d) {
g[i] = d3.select("svg")
.append("g")
.attr("class", "phage")
.attr("transform", "translate(0," + y + ")")
.style("display", "block");
y += 20;
i++;
g[i-1].selectAll("line")
.data(d.genes)
.enter().append("line")
.attr("x1", function(d) { return d.start; })
.attr("y1", 20)
.attr("x2", function(d) { return d.stop; })
.attr("y2", 20)
.attr('stroke', function(d) {
if (d.pham === "a2" || d.pham === "a3" || d.pham === "a4") return "blue";
else if (d.pham === "b1" || d.pham === "b2" || d.pham === "b3") return "red";
else return "black";
})
.attr('stroke-width', function(d) {
if(d.direction == "forward") {return 12}
else { return 12}
});
d3.selectAll("path")
.data(data)
.enter().append("path")
.attr("d", function(d) { return "M0,0 L0,0"; })
d3.selectAll("path")
.data(data)
.transition()
.duration(5000)
.attr("d", function(d) {
console.log("d: " + d);
return lineGen(d.genes) });
d3.selectAll("path")
.data(data)
.on("mouseover", function(d){
console.log(d.phagename)
div.transition()
.duration(200)
.style("opacity", .9);
div.html(d.phagename)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.style("display", "none");
});
}
function draw(data) {
var vis = d3.select("#graph").append("svg")
.attr("width", 1100)
.attr("height", 400)
var line = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate("linear");
var val1 = 500;
for (i = 0; i < data.length; i++) {
var g = vis.append("g")
.attr("transform", "translate(0," + val1 + ")")
val1 = val1 + 100;
g.append("text")
.attr("x", 0)
.attr("y", 0)
.style("text-anchor", "middle")
.style("fill", "black")
.text("Phage " + data[i].phagename);
var line = [];
var x = 100;
var y = 100;
line.push({
"x": x,
"y": y
});
var genes = data[i].genes;
for (var j = 0; j < genes.length; j++) {
var gene = genes[j];
var start = gene.start;
var stop = gene.stop;
var direction = gene.direction;
var color = (gene.pham.charAt(0) === "a") ? "#ff6666" : (gene.pham.charAt(0) === "b" ? "#ffcc66" : "#99ccff");
var sequence = gene.sequence;
if (gene.direction === "forward") {
// forward
line(start, stop, yLine, color);
} else {
// reverse
line(stop, start, yLine, color);
}
if (gene.direction === "forward") {
$('#myModal').on('show.bs.modal', function(event) {});
}
}
function line(x1, x2, y, color) {
svg.append("path")
.attr("d", "M " + x1 + " " + y + " L " + x2 + " " + y)
.attr("stroke", color)
.attr('stroke-width', 30)
.attr('opacity', 0.8)
}
function liney(x1, x2, y, color) {
svg.append("path")
.attr("d", "M " + x1 + " " + y + " L " + x2 + " " + y)
.attr("stroke", color)
.attr('stroke-width', 2)
.attr('opacity', 0.8)
}
var svg = d3.select("body")
.append("svg")
.attr("width", 1500)
.attr("height", 2000)
.append("g");
var sampleData = [];
for (var i = 0; i < data.length; i++) {
data[i].genes.forEach(function(gen) {
var y = data[i].phagename == "D29" ? 200 : data[i].phagename == "U2" ? 400 : 600;
sampleData.push([gen.start, y, i]);
})
}
var x = d3.scale.linear()
.domain([0, 16000])
.range([0, 1000]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(20)
.tickPadding(4)
.tickSize(4);
var y = d3.scale.linear()
.domain([0, 900])
.range([0, 500]);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(0);
var svg = d3.select("body").append("svg")
.attr("width", 1100)
.attr("height", 900)
.style("padding-left", 100);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, 450)")
.call(xAxis);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(15);
var x = d3.scale.linear()
.domain([0, 18000])
.range([0, 950]);
var y = d3.scale.linear()
.domain([0, 3])
.range([0, 300]);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(30,30)")
.call(xAxis);
var drag = d3.behavior.drag()
.on("dragstart", function() {
console.log("dragstart")
})
.on("drag", function(d) {
console.log("drag")
console.log(d3.event.dx)
console.log(d3.event.dy)
d3.select(this).attr("transform", "translate(" + d3.event.translate + ")")
})
.on("dragend", function(d) {
console.log("dragend")
});
var svg = d3.select("body")
.append("svg")
.attr("width", 1500)
.attr("height", 800);
var g = svg.append("g").attr("transform", "translate(100,100)");
var g2 = svg.append("g").attr("transform", "translate(100,400)");
var g3 = svg.append("g").attr("transform", "translate(100,600)");
var phage1 = data[0].phagename;
var phage2 = data[1].phagename;
var phage3 = data[2].phagename;
var g1 = data[0].genes;
var g2 = data[1].genes;
var g3 = data[2].genes;
var gl1 = data[0].genomelength;
var gl2 = data[1].genomelength;
var gl3 = data[2].genomelength;
function draw_genome_axis(g, gl, yloc) {
var genoscale = d3.scale.linear()
.domain([0, gl])
.range([0, 800]);
var axis = d3.svg.axis()
.scale(genoscale)
.orient("bottom")
.ticks(10);
g.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + 100 + "," + yloc + ")")
.call(axis);
}
function draw_genes(data, phage, yloc, maxLength, color) {
var genoscale = d3.scale.linear().domain([0, maxLength]).range([0, 500])
var genes = data.genes;
var direction;
for (i = 0; i < genes.length; i++) {
direction = genes[i].direction;
if (direction == "forward") {
var path = "M " + (100 + genoscale(genes[i].start)) + " " + yloc + " L " + (100 + genoscale(genes[i].start)) + " " + (yloc - 25) + " L " + (100 + genoscale(genes[i].stop)) + " " + (yloc - 25) + " L " + (100 + genoscale(genes[i].stop)) + " " + yloc + " Z";
} else {
var path = "M " + (100 + genoscale(genes[i].stop)) + " " + yloc + " L " + (100 + genoscale(genes[i].stop)) + " " + (yloc - 25) + " L " + (100 + genoscale(genes[i].start)) + " " + (yloc - 25) + " L " + (100 + genoscale(genes[i].start)) + " yloc " + " Z";
}
$("#myModal").append('<div class="protein" style="left:' + (100 + (genes[i].start / 100)) + 'px; top:' + (150 + yloc) + 'px; id="' + name + '"></div>')
}
}
}
})
})
</script>
</body>
</html>
Given the file listing for the block, answer the following questions about
its source code. In your answer, do not include the files' contents.
What visualization is this? What are the data, task, and graphical
elements? What interactivity does it provide? Why is the rendered result
effective or ineffective? Keep concise and focus on the visualization
itself, not the code.## Final Genome Browser
This is an interactive genome browser for comparing multiple bacteriophage genomes. It displays annotated gene features along linear genome tracks for three phages (D29, U2, and L5), with each gene shown as a directional block. The visualization uses an SVG canvas with smooth animation and hover-based tooltips.
**Data:** The input is a JSON file with genome annotations for three phages. For each genome, the data includes the total genome length and a list of genes with start/stop coordinates, strand direction (forward/reverse), and associated pham (phage family) identifiers. Each gene also has a DNA sequence.
**Visual encoding:** The genome browser displays each phage as a horizontal track, with genes represented as rectangles or arrows positioned along the genome according to their start and stop coordinates. The direction of each gene (forward or reverse) is encoded by the orientation of the arrow. The x-axis maps genomic coordinates, and the y-axis separates the different phage genomes. The genes are color-coded by pham (phage family) to enable cross-genome comparison. A tooltip shows gene details on hover.
**Interaction:** Hovering over a gene displays a tooltip with information such as the gene name, pham, start, stop, direction, phage, and sequence. Users can click a gene to open a modal with more detailed information. The visualization is part of a genome browser tool for phamerator.org, allowing researchers to explore phage genomes. The animated SVG renders the genomic data in a way that is suitable for web-based interactive exploration.
Title: Final Genome Browser
**Data**: The dataset describes the genomes of three bacteriophages (D29, U2, and L5). Each genome is a sequence of genes, with each gene having a name, a pham (phage family) identifier, start and stop positions along the genome, and a direction (forward or reverse).
**Visualization Type**: This is a comparative linear genome browser. Each phage genome is shown as a horizontal track. Genes are drawn as arrow-shaped blocks along a central axis, oriented according to their direction (forward = rightward arrow, reverse = leftward arrow).
**Visual Encoding**:
- X-axis: genomic position (base pairs)
- Y-axis: different phage genomes
- Arrows: genes, with direction indicating orientation
- Color: Pham identifier (phage family)
- Tooltip on hover: shows gene details (e.g., gene name, pham, start, stop, direction)
- Modal popup with additional information on click
- Smooth scrolling/panning animation for genome navigation
- DNA sequence is displayed when a gene is selected
**Interactions**: Users can click on genes to view gene information in a modal dialog. The tooltip provides a quick preview.
This is a linear genome browser for bacteriophage genomes, which displays genes as directional arrows along a horizontal track, color-coded by pham (phage family), with interactive tooltips and modals showing gene details and DNA sequences.
**Coding practice**:
- Uses D3.js and jQuery/Bootstrap
- Data loaded from external JSON
- SVG rendering with axes
**Data details**:
The data are in a JSON file that contains a list of phage genomes, each with an array of genes. Each gene includes name, pham (phage family), start, stop, direction, phage, and sequence. Genomelengths vary per phage.
**Interactivity**:
The example has some built-in interactivity, including toggling "phams" (phage families), clicking to show gene details in a modal, and mouseover tooltips.
**Design choices**:
- Different gene directions are indicated with arrowheads (triangles) in the SVG path.
- Color indicates pham (phage family) membership.
- The tooltip uses lightsteelblue.
- DNA sequence is displayed in a modal.
**What the visualization shows**:
The data visualizes gene positions along phage genomes, compares gene orientations, and displays sequence details on demand.
**User instructions / How to use**:
- Hover over a gene to see its name, pham, start, stop, direction, and sequence.
- Click a gene to open a modal with detailed information.
**Data facts**
D29: 4 genes, L5: 4 genes, U2: 4 genes
total genes: 12
genome lengths: D29: 15000, U2: 14000, L5: 10000
**Visualization description**:
Include this in the description: "Three horizontal tracks are arranged vertically, one for each of three mycobacteriophage genomes (D29, U2, and L5). Each track displays genes as arrow-shaped blocks along a genomic axis, with forward genes pointing right and reverse genes pointing left. Arrows are colored by pham (phage family) to highlight conserved gene modules across genomes. The visualization was implemented using D3.js with an SVG rendering and includes mouseover interactions that display gene details via a tooltip, plus an animation that draws the gene arrows sequentially."
Write the description. Do not include file names. Do not include a code block. Do not include a "The visualization is an example of ..." sentence. Your response must be entirely within a single JSON object. Use the following JSON schema.
{"title": "string", "description": "string"}
Do not include any text outside of the JSON object. Do not use formatting other than whitespace. Ensure that your JSON is valid.
Ensure title is the Title of the example and not the title of the block. Ensure description is 3-4 sentences long, concise, and covers the main idea of the visualization. The description should be for a general audience. Make sure your JSON is valid. Provide only the JSON. Do not include markdown code blocks or any formatting.
{
"title": "Final Genome Browser",
"description": "This interactive genome browser visualizes multiple phage genomes as horizontal tracks, with genes depicted as directional blocks along each genome. Color coding or positioning indicates gene orientation (forward or reverse). The SVG-based view is animated, allowing users to explore gene arrangements and compare genomes side by side. Hovering over a gene triggers a tooltip with additional details, supporting tasks like identifying pham gene family patterns across related phages."
}