Chromosome subset viewer with sample data. Object constancy is maintained each time the page loads. Page loops through random subsets of the data. Click to stop. Refresh page to start again. Designed as a way to discover new trends in a 80,000+ entry dataset.
Created
March 17, 2015 02:09
-
-
Save dhoboy/66dc096d42919755d0fb to your computer and use it in GitHub Desktop.
This works
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
name | chrom | strand | txStart | txEnd | |
---|---|---|---|---|---|
uc001aaa.3 | chr1 | + | 11873 | 14409 | |
uc010nxr.1 | chr2 | + | 11873 | 14409 | |
uc010nxq.1 | chr3 | + | 11873 | 14409 | |
uc009vis.3 | chr4 | - | 14361 | 16765 | |
uc009vjc.1 | chr5 | - | 16857 | 17751 | |
uc009vjd.2 | chr6 | - | 15795 | 18061 | |
uc009vit.3 | chr7 | - | 14361 | 19759 | |
uc009viu.3 | chr8 | - | 14361 | 19759 | |
uc001aae.4 | chr9 | - | 14361 | 19759 | |
uc001aai.1 | chrM | - | 16857 | 19759 | |
uc001aah.4 | chrX | - | 14361 | 29370 | |
uc009vir.3 | chrY | - | 14361 | 29370 | |
uc009viq.3 | chr10 | - | 14361 | 29370 | |
uc001aac.4 | chr11 | - | 14361 | 29370 | |
uc009viv.2 | chr12 | - | 14406 | 29370 | |
uc009viw.2 | chr13 | - | 14406 | 29370 | |
uc009vix.2 | chr14 | - | 15602 | 29370 | |
uc009viy.2 | chr15 | - | 16606 | 29370 | |
uc009viz.2 | chr16 | - | 16606 | 29370 | |
uc010nxs.1 | chr17 | - | 16857 | 29370 | |
uc009vje.2 | chr1 | - | 17232 | 29370 | |
uc009vjf.2 | chr2 | - | 17605 | 29370 | |
uc009vjb.1 | chr3 | - | 16857 | 29961 | |
uc001aak.3 | chr4 | - | 34610 | 36081 | |
uc001aal.1 | chr5 | + | 69090 | 70008 | |
uc021oeg.2 | chr6 | - | 134772 | 140566 | |
uc001aaq.2 | chr7 | + | 321083 | 321115 | |
uc001aar.2 | chr8 | + | 321145 | 321207 | |
uc021oeh.1 | chr9 | + | 324287 | 325896 | |
uc009vjk.2 | chrM | + | 322036 | 326938 | |
uc021oei.1 | chrX | + | 327545 | 328439 | |
uc001aau.3 | chrY | + | 323891 | 328581 | |
uc010nxu.2 | chr10 | + | 367658 | 368597 | |
uc001aax.1 | chr11 | + | 420205 | 421839 | |
uc021oej.1 | chr1 | - | 566092 | 566115 |
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> | |
<meta charset="utf-8"> | |
<style> | |
.data_paths { | |
stroke: #000; | |
stroke-width: 3.5px; | |
fill: none; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: black; | |
stroke-width: 1.5px; | |
shape-rendering: crispEdges; | |
} | |
text { font-family: sans-serif; } | |
.axis text { font-size: 11px; } | |
.key { | |
font-size: 12px; | |
shape-rendering: crisp-edges; | |
} | |
.enter { stroke: green; } | |
.update { stroke: #333; } | |
.exit { stroke: brown; } | |
</style> | |
<body> | |
<script src="http://d3js.org/d3.v3.js"></script> | |
<script> | |
// margins | |
var margin = {top: 20, right: 30, bottom: 30, left: 90, axis_label: 5}, | |
w = 960 - margin.left - margin.right, | |
h = 500 - margin.top - margin.bottom, | |
key_area = 150, | |
size = 15; // size of subset | |
// scales | |
var xScale = d3.scale.linear() | |
.range([0, w]); | |
var yScale = d3.scale.ordinal() | |
.rangePoints([h, 0]); | |
var color = d3.scale.category20() // do i need to set the domain here? | |
.domain(["1", "2", "3", "4", "5", "6", "7", "8", "9", "M", "X", "Y", | |
"10", "11", "12", "13", "14", "15", "16", "17"]); | |
var keyScale = d3.scale.ordinal() | |
.rangeRoundBands([0,h]); | |
// axes | |
var xAxis = d3.svg.axis() | |
.scale(xScale) | |
.orient("bottom") | |
.ticks(10); | |
var yAxis = d3.svg.axis() | |
.scale(yScale) | |
.orient("left") | |
.ticks(size); | |
// svg | |
var svg = d3.select("body").append("svg") | |
.attr("height", h + margin.top + margin.bottom) | |
.attr("width", w + margin.left + margin.right + key_area); | |
// plot | |
var plot = svg.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
// line generator | |
var line = d3.svg.line() | |
.x(function(d) { return xScale(d.tx); }) | |
.y(function(d) { return yScale(d.i); }); | |
/**** THE CALLBACK FUNCTION ****/ | |
d3.csv("chrom_sample1.csv", form_the_data, function(error, data) { | |
/**** this stuff doesn't change each tick ****/ | |
xScale.domain([d3.min(data, function(d) { return d.x1; }), | |
d3.max(data, function(d) { return d.x2; })]); | |
yScale.domain(d3.range(size)); | |
// draw axes | |
plot.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + h + ")") | |
.call(xAxis) // places the axis | |
.append("text") // creates the axis label | |
.attr("transform", "translate(" + (w - margin.axis_label) + "," + margin.bottom + ")") | |
.style("text-anchor", "start") | |
.style("fill", "black") | |
.text("tx"); | |
plot.append("g") | |
.attr("class", "y axis") | |
.call(yAxis) | |
.append("text") | |
.attr("transform", "translate(" + margin.axis_label*-16 + "," + margin.axis_label*-1 + ") rotate(-90)") | |
.style("text-anchor", "end") | |
.style("fill", "black") | |
.text("gene"); | |
// add key, with all chromosomes listed (by explicitly setting domain at top) | |
keyScale.domain(color.domain()); | |
var keyData = toObjArr(keyScale.domain()); | |
var legend = svg.append("g") | |
.attr("transform", "translate(" + (w + margin.left + margin.right*2) + "," + margin.top + ")"); | |
var entries = legend.selectAll(".key") | |
.data(keyData) | |
.enter().append("g") | |
.attr("class", "key") | |
.attr("transform", function(d){ return "translate(0," + keyScale(d.valueOf()) + ")"; }); | |
entries.append("circle") | |
.attr("cx", 0).attr("cy", 0).attr("r", 5) | |
.attr("fill", function(d){ return color(d.valueOf()); }); | |
entries.append("text") | |
.attr("x", 7).attr("y", 4) | |
.text(function(d){ return "chr" + d.valueOf(); }) | |
/*********************************/ | |
// this is looking pretty good. needs a little work. and code needs tidying. | |
// some axis tick marks are thicker than others... | |
// looks good. i just don't understand transitions. yet. | |
/**************************/ | |
// add an index to the data, for making subsets | |
var index = 0; | |
data.forEach(function(d) { | |
d.index = index; | |
index += 1; | |
}); | |
// make and draw first subset right here. keeps key function from returning undefined | |
var subset = [], | |
candidate = 0, | |
flag = true; | |
// make the subset. no duplicates. | |
for (var i = 0; i < size; i++) { | |
flag = true; | |
while (flag == true) { | |
flag = false; | |
candidate = Math.floor(Math.random()*(data.length - 1 - 0 + 1) + 0); | |
subset.forEach(function(d) { | |
if (d.index == candidate) { | |
flag = true; | |
} | |
}); | |
} | |
subset.push(data[candidate]); | |
} | |
var paths = plot.selectAll(".data_paths") | |
.data(subset.map(function(d,i) { | |
return [ | |
{ tx: d.x1, i: i, gene_name: d.name, chr: d.chrom_val }, | |
{ tx: d.x2, i: i } | |
] | |
})) | |
.enter() | |
.append("path") | |
.attr("class", "data_paths") | |
.attr("d", line) | |
.style("stroke", function(d) { | |
// color lines according to the chromosome they're on | |
return color(d[0].chr); | |
}) | |
.append("title") | |
.text(function(d) { | |
return "gene: " + d[0].gene_name + " chr: " + d[0].chr + " tx: " + d[0].tx + "-" + d[1].tx; | |
}); | |
plot.selectAll(".y.axis text") | |
.data(subset) | |
.text(function(d) { return d.name; }) | |
// run until on click or browser close | |
var run = setInterval(function() { | |
var subset = [], | |
candidate = 0, | |
flag = true; | |
// make the subset. no duplicates. ultimately have this inside a tick function | |
for (var i = 0; i < size; i++) { | |
flag = true; | |
while (flag == true) { | |
flag = false; | |
candidate = Math.floor(Math.random()*(data.length - 1 - 0 + 1) + 0); | |
subset.forEach(function(d) { | |
if (d.index == candidate) { | |
flag = true; | |
} | |
}); | |
} | |
subset.push(data[candidate]); | |
} | |
display(subset); | |
}, 1500); | |
window.addEventListener("click", function(){ | |
clearInterval(run); | |
}); | |
}); | |
function display(subset) { // this is everything that changes each tick | |
// Data Join | |
var paths = plot.selectAll(".data_paths") | |
.data(subset.map(function(d,i) { | |
return [ | |
{ tx: d.x1, i: i, gene_name: d.name, chr: d.chrom_val }, | |
{ tx: d.x2, i: i } | |
] | |
}), function(d) { return d[0].gene_name; }); // we assume gene_name is a unique key for the moment | |
// Update | |
paths.attr("class", "data_paths") | |
.attr("d", line) | |
.style("stroke", function(d) { | |
// color lines according to the chromosome they're on | |
return color(d[0].chr); | |
}) | |
.append("title") | |
.text(function(d) { | |
return "gene: " + d[0].gene_name + " chr: " + d[0].chr + " tx: " + d[0].tx + "-" + d[1].tx; | |
}); | |
// Enter | |
paths | |
.enter() | |
.append("path") | |
.attr("class", "data_paths") | |
.attr("d", line) | |
.style("stroke", function(d) { | |
// color lines according to the chromosome they're on | |
return color(d[0].chr); | |
}) | |
.append("title") | |
.text(function(d) { | |
return "gene: " + d[0].gene_name + " chr: " + d[0].chr + " tx: " + d[0].tx + "-" + d[1].tx; | |
}); | |
// Exit | |
paths.exit() | |
.attr("class", "data_paths") | |
.remove(); | |
// label lines as to what gene they are on | |
// color labels according to chromosome? | |
plot.selectAll(".y.axis text") | |
.data(subset) | |
.text(function(d) { return d.name; }); | |
//.style("fill", function(d) { return color(d.chr); }) | |
} | |
function form_the_data(d) { | |
d.x1 = +d.txStart; | |
d.x2 = +d.txEnd; | |
d.chrom_val = (d.chrom.length == 4) ? d.chrom.slice(-1) : d.chrom.slice(-2); | |
return d; | |
} | |
function toObjArr(arr) { | |
var objArr = [], i = 0; | |
while(arr.length != 0) { | |
objArr.push(Object(arr.shift())); | |
i+= 1; | |
} | |
return objArr; | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment