Built with blockbuilder.org
Last active
February 18, 2017 04:47
-
-
Save GeneExplorer/342bad7b6e40985300e98ab186803f5f to your computer and use it in GitHub Desktop.
Gene Map
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"genes": [{"name": "gene w", "stop": 230, "orientation": "forward", "start": 49}, {"name": "gene x", "stop": 305, "orientation": "forward", "start": 265}, {"name": "gene y", "stop": 440, "orientation": "forward", "start": 361}, {"name": "gene z", "stop": 620, "orientation": "reverse", "start": 500}]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
polygon:hover { stroke: pink; stroke-width: 7px; } | |
rect:hover { stroke: cyan; stroke-width: 3px; } | |
text:hover { stroke: lightgray; } | |
</style> | |
</head> | |
<body> | |
<script> | |
var Orientation = { | |
FORWARD: 1, | |
REVERSE: 2, | |
BACKWARD: 2, // Alias for REVERSE | |
}; | |
// Object Constructors | |
function Point(x = 0, y = 0) { | |
this.x = x; | |
this.y = y; | |
} | |
function GeneArrow(name, offset, width, height, orientation) { | |
// GeneArrow object attributes. | |
this.name = name; | |
this.offset = offset; | |
this.width = width; | |
this.height = height; | |
this.orientation = orientation; | |
if (orientation == Orientation.FORWARD) | |
this.color = "blue"; | |
else | |
this.color = "red"; | |
this.arrowHeadPercentWidth = 30.0; // Default arrow head % width | |
this.arrowHeadPercentHeight = 80.0; // Default arrow head % height | |
this.arrowBodyPercentHeight = 40.0; // Default arrow body % height | |
this.showTickMarks = false; | |
this.tickMarks = []; | |
// GeneArrow object functions. | |
this.points = function() { | |
// Create the arrow shape using 7 points. | |
var oX = this.offset.x; | |
var oY = this.offset.y; | |
var w = this.width; | |
var h = this.height; | |
var x1 = oX; | |
var x2 = oX + (1.0 - (this.arrowHeadPercentWidth / 100)) * w; | |
var x3 = oX + w; | |
var x4 = oX + (this.arrowHeadPercentWidth / 100) * w; | |
var y1 = oY + (0.5 - (this.arrowHeadPercentHeight / 100)/2) * h; | |
var y2 = oY + (0.5 - (this.arrowBodyPercentHeight / 100)/2) * h; | |
var y3 = oY + 0.5 * h; | |
var y4 = oY + (0.5 + (this.arrowBodyPercentHeight / 100)/2) * h; | |
var y5 = oY + (0.5 + (this.arrowHeadPercentHeight / 100)/2) * h; | |
if (orientation == Orientation.FORWARD) | |
{ | |
return [ | |
new Point(x1, y4), | |
new Point(x2, y4), | |
new Point(x2, y5), | |
new Point(x3, y3), | |
new Point(x2, y1), | |
new Point(x2, y2), | |
new Point(x1, y2) | |
]; | |
} | |
else // Arrow going backwards. | |
{ | |
return [ | |
new Point(x1, y3), | |
new Point(x4, y5), | |
new Point(x4, y4), | |
new Point(x3, y4), | |
new Point(x3, y2), | |
new Point(x4, y2), | |
new Point(x4, y1) | |
]; | |
} | |
} | |
this.nameTagLocation = function() | |
{ | |
var xCoord = offset.x + (0.5 * width) - (this.name.length*5); | |
var yCoord = offset.y + (0.5 * height) + 5; | |
return new Point(xCoord, yCoord); | |
} | |
} | |
function drawGeneArrow(geneArrow, svgWidth, rangeX) { | |
var polygon = svg.append("polygon"); | |
var pointData = ""; | |
var p = geneArrow.points(); | |
for (var i = 0; i < p.length; i++) | |
{ | |
pointData += p[i].x + "," + p[i].y + " "; | |
} | |
polygon.attr("points", pointData); | |
polygon.attr("fill", geneArrow.color); | |
polygon.attr("stroke", "black"); | |
polygon.append("title").text(geneArrow.name); // Tooltip shows gene name. | |
if (geneArrow.showTickMarks == true) | |
{ | |
var t = geneArrow.tickMarks; | |
for (var j = 0; j < t.length; j++) | |
{ | |
var rect = svg.append("rect"); | |
var tickMarkHeight = geneArrow.height * (geneArrow.arrowBodyPercentHeight / 100) * 1.4; | |
var tickMarkX = t[j] * svgWidth / rangeX; | |
var tickMarkY = geneArrow.offset.y + (geneArrow.height / 2) - (tickMarkHeight / 2); | |
rect.attr("x", tickMarkX).attr("y", tickMarkY) | |
.attr("width", 6).attr("height", tickMarkHeight) | |
.attr("fill", "green"); | |
var bpTag = svg.append("text"); | |
var bpTagX = tickMarkX; | |
var bpTagY = tickMarkY - 5; | |
bpTag.text(t[j]) | |
.attr("x", bpTagX) | |
.attr("y", bpTagY) | |
.style("font-size", 12) | |
.style("font-family", "Verdana"); | |
} | |
} | |
var nameTag = svg.append("text"); | |
var nameTagLocation = geneArrow.nameTagLocation(); | |
nameTag.text(geneArrow.name) | |
.attr("x", nameTagLocation.x) | |
.attr("y", nameTagLocation.y) | |
.style("font-size", 20) | |
.style("font-family", "Verdana"); | |
} | |
// Create the svg canvas. | |
var svgWidth = 960; | |
var svgHeight = 600; | |
var svg = d3.select("body").append("svg").attr("width", svgWidth).attr("height", svgHeight); | |
// Load and draw gene data. | |
d3.json("data.json", function(error, data) { | |
if (error) console.warn(error); | |
else console.log(data); | |
var geneArrows = []; | |
var genes = data.genes; | |
var arrowYOffset = 120; | |
var arrowHeight = 120; | |
var minX = 1000000; | |
var maxX = -1; | |
for (var i = 0; i < genes.length; i++) | |
{ | |
var name = '' + genes[i].name; | |
var start = genes[i].start; | |
var stop = genes[i].stop; | |
if (genes[i].orientation == "forward") | |
var orientation = Orientation.FORWARD; | |
else | |
var orientation = Orientation.REVERSE; | |
var offset = new Point(start, arrowYOffset); | |
var arrowWidth = stop - start; | |
var geneArrow = new GeneArrow(name, offset, arrowWidth, arrowHeight, orientation); | |
geneArrow.tickMarks.push(start); | |
geneArrow.tickMarks.push(stop); | |
geneArrow.showTickMarks = true; | |
if (start < minX) minX = start; | |
if (stop > maxX) maxX = stop; | |
geneArrows.push(geneArrow); | |
} | |
// Normalize distances so that all gene data fits on the screen. | |
var svgWidth = 960; | |
var bufferPercentage = 16.0; // Add some buffer space at the right margin. | |
var rangeX = (maxX - minX) * (1 + (bufferPercentage / 100)); | |
// Draw the dna sequence bar. | |
var dnaSequenceBarStartLocation = new Point(0, 220); | |
var dnaSequenceBar = new GeneArrow("dna sequence bar", dnaSequenceBarStartLocation, svgWidth, 100, Orientation.FORWARD); | |
dnaSequenceBar.color = "orange"; | |
dnaSequenceBar.arrowHeadPercentWidth = 3; | |
dnaSequenceBar.arrowHeadPercentHeight = 40; | |
// Add interval tick marks. | |
var showIntervalTickMarks = true; | |
if (showIntervalTickMarks) | |
{ | |
dnaSequenceBar.showTickMarks = true; | |
var intervalBasePairs = 50; | |
for (var k = 0; k < svgWidth; k += intervalBasePairs) | |
{ | |
dnaSequenceBar.tickMarks.push(k); | |
} | |
} | |
drawGeneArrow(dnaSequenceBar, svgWidth, rangeX); | |
// Draw all the gene arrows. | |
for (i = 0; i < genes.length; i++) | |
{ | |
geneArrows[i].offset.x = geneArrows[i].offset.x * svgWidth / rangeX; | |
geneArrows[i].width = geneArrows[i].width * svgWidth / rangeX; | |
drawGeneArrow(geneArrows[i], svgWidth, rangeX); | |
} | |
}); | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment