Skip to content

Instantly share code, notes, and snippets.

@nimezhu
Last active April 5, 2018 13:37
Show Gist options
  • Save nimezhu/adb646c9ef87fdb1084b1d0876a8133d to your computer and use it in GitHub Desktop.
Save nimezhu/adb646c9ef87fdb1084b1d0876a8133d to your computer and use it in GitHub Desktop.
Nucleome Browser Plugin
// ==UserScript==
// @name Nucleome Browser Plugin
// @namespace http://genome.compbio.cs.cmu.edu:8080
// @version 0.0.4
// @description link nucleme browser with other genome browsers such as UCSC Genome Browser and WASHU Genome Browser. Works with NBrowser 'Browser Manager' Panel.
// @author xiaopeng.zhu([email protected])
// @include http://genome.ucsc.edu/cgi-bin/hgTracks*
// @include http://epigenomegateway.wustl.edu/browser/*
// @grant none
// @require https://d3js.org/d3.v5.min.js
// @updateURL https://gist.github.com/nimezhu/adb646c9ef87fdb1084b1d0876a8133d/raw/d2418ccc7bbcfe475274fd2c8b159a4d790f111e/cnb.user.js
// @downloadURL https://gist.github.com/nimezhu/adb646c9ef87fdb1084b1d0876a8133d/raw/d2418ccc7bbcfe475274fd2c8b159a4d790f111e/cnb.user.js
// ==/UserScript==
// == USER CONFIG ==
var src = "http://genome.compbio.cs.cmu.edu:8080";
//var src = "http://x7.andrew.cmu.edu:8080"; //dev server
var firstRegionToText = function(d) {
return d[0].chr+":"+d[0].start+"-"+d[0].end;
};
var regionText = function(d) {
return d.chr + ":" + d.start + "-" + d.end;
};
var regionsText = function(regions) {
var r = [];
regions.forEach(function(d) {
r.push(regionText(d));
});
return r.join(",");
};
var parseRegion = function(s){
var a = s.split(":");
if (a.length==1) {
return {
"chr": a[0],
"start": 0,
"end" : undefined
};
}
var x = a[1].split("-");
return {
"chr": a[0],
"start": +x[0],
"end": +x[1]
};
};
var watch = function(target, prop, handler) {
if (target.__lookupGetter__(prop) != null) {
return true;
}
var oldval = target[prop],
newval = oldval,
self = this,
getter = function () {
return newval;
},
setter = function (val) {
if (Object.prototype.toString.call(val) === '[object Array]') {
val = _extendArray(val, handler, self);
}
oldval = newval;
newval = val;
handler.call(target, prop, oldval, val);
};
if (delete target[prop]) { // can't watch constants
if (Object.defineProperty) { // ECMAScript 5
Object.defineProperty(target, prop, {
get: getter,
set: setter,
enumerable: false,
configurable: true
});
} else if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) { // legacy
Object.prototype.__defineGetter__.call(target, prop, getter);
Object.prototype.__defineSetter__.call(target, prop, setter);
}
}
return this;
};
var unwatch = function(target, prop) {
var val = target[prop];
delete target[prop]; // remove accessors
target[prop] = val;
return this;
};
var _extendArray = function(arr, callback, framework) {
if (arr.__wasExtended === true) return;
function generateOverloadedFunction(target, methodName, self) {
return function () {
var oldValue = Array.prototype.concat.apply(target);
var newValue = Array.prototype[methodName].apply(target, arguments);
target.updated(oldValue, motive);
return newValue;
};
}
arr.updated = function (oldValue, self) {
callback.call(this, 'items', oldValue, this, motive);
};
arr.concat = generateOverloadedFunction(arr, 'concat', motive);
arr.join = generateOverloadedFunction(arr, 'join', motive);
arr.pop = generateOverloadedFunction(arr, 'pop', motive);
arr.push = generateOverloadedFunction(arr, 'push', motive);
arr.reverse = generateOverloadedFunction(arr, 'reverse', motive);
arr.shift = generateOverloadedFunction(arr, 'shift', motive);
arr.slice = generateOverloadedFunction(arr, 'slice', motive);
arr.sort = generateOverloadedFunction(arr, 'sort', motive);
arr.splice = generateOverloadedFunction(arr, 'splice', motive);
arr.unshift = generateOverloadedFunction(arr, 'unshift', motive);
arr.__wasExtended = true;
return arr;
};
var ucscPlugin = function() {
'use strict';
var scale;
function addDiv() {
var pos = $("#imgTbl").position();
var width = $("#imgTbl").width();
var height = $("#imgTbl").height();
console.log("addDiv",pos,width,height);
var respdiv = d3.select("body")
.selectAll(".scope")
.data([0]);
respdiv.exit().remove();
respdiv.enter()
.append("div")
.classed("scope",true)
.attr("id","scope");
//.merge(respdiv)
respdiv.style("position","absolute")
.style("top",pos.top+"px")
.style("left",pos.left+"px")
.style("height",height+"px")
.style("width",width+"px")
.style("background-color","#FFF")
.style("opacity",0.1);
respdiv.selectAll(".brush").remove();
d3.select("#imgTbl").on("mouseover",function(){
respdiv.style("display","none");
})
.on("mouseout",function(){
respdiv.style("display",null);
});
}
var respdiv;
function onBrush(r){
var height = $("#imgTbl").height();
var pos = $("#imgTbl").position();
respdiv = d3.select("body")
.select("#scope");
respdiv.style("position","absolute")
.style("top",pos.top+"px")
.style("left",pos.left+"px")
.style("height",height+"px");
var r0 = respdiv.selectAll(".brush").data(r);
r0.exit().remove();
r0.enter().append("div")
.classed("brush",true)
.style("position","absolute")
.style("top","0px")
.style("background-color","#000")
.style("opacity",0.1)
.merge(r0)
.style("height",height+"px")
.style("left",function(d){return scale(d.start)+"px";})
.style("width",function(d){return (scale(d.end)-scale(d.start))+"px";});
}
var lastSent;
var recieve;
function onUpdate(d){
console.log("UPDATE???",d);
var r = d;
var txt = firstRegionToText(r);
recieve = txt;
var p=document.getElementById('positionInput');
p.value=txt;
var pNow = document.getElementById('position');
console.log('now',pNow.value,'old',p.value);
if(pNow.value!=p.value){
pNow.value=p.value;
var jump=document.getElementById('hgt.jump').click();
scale.domain([r[0].start,r[0].end]);
d3.select("body").select("#scope").selectAll(".brush").remove();
}
}
var lastRegion = "";
var _callback = function(){
var db = document.getElementsByName("db");
if (genomePos.original != undefined && genomePos.original != lastSent && genomePos.original!=recieve) {
var d0 = parseRegion(genomePos.original);
d0.genome = db[0].getAttribute("value");
console.log("D0",d0);
window.opener.postMessage({code:'update',data:d0},src);
scale.domain([d0.start,d0.end]);
lastSent = genomePos.original;
}
};
var onNav = function(d){
if(window.opener) {
_callback();
}
};
setTimeout(watch(genomePos,"original",onNav),200);
(function() {
var position = $("#imgTbl").position();
var width = $("#imgTbl").width();
scale = d3.scaleLinear();
scale.range([123,width]);
var d0 = parseRegion(genomePos.original);
scale.domain([d0.start,d0.end]);
addDiv();
onNav();
})();
window.addEventListener("message",function(d){
if (d.origin == src) {
if (d.data.code=="update"){
console.log("update",d.data.data);
onUpdate(d.data.data);
}
if (d.data.code=="brush"){
onBrush(d.data.data);
}
}
},false);
};
var washuPlugin = function() {
'use strict';
var receive;
var axis;
var svg;
var scale = d3.scaleLinear();
var processing = true;
window.loading_done = function(){
waitcloak.style.display = 'none';
var r = $(".header_b").first().text();
var d = parseRegion(r);
if (window.opener && !processing){
window.opener.postMessage({code:"update",data:d},src);
}
axis = d3.select("#sukn_main").select("table").select("tbody").select("tr:nth-child(3)").select("td:nth-child(2)").select("div");
axis.selectAll("svg").remove();
var width = axis.style("width").replace("px","");
svg = axis.append("svg").attr("width",width).attr("height",10);
scale.range([0,width]);
scale.domain([d.start,d.end]);
processing = false; //processed response.
console.log("processed",processing);
};
var lastRegion = "";
window.addEventListener("message",function(d){
if (d.origin == src) {
if (d.data.code=="update"){
console.log("update",d.data.data);
var el = $("#menu > div > div > table > tbody")[2];
var newRegion = regionText(d.data.data[0]);
if (lastRegion != newRegion) {
lastRegion = newRegion;
receive = newRegion;
processing = true;
$(el).find("input").first().val(regionText(d.data.data[0]));
$(".header_b").first().click();
$(el).find("button").first().click();
}
}
if (d.data.code=="brush"){
var rects = svg.selectAll("rect").data(d.data.data);
rects.exit().remove();
rects.enter().append("rect")
.merge(rects)
.attr("x",function(d){return scale(d.start);})
.attr("width",function(d){return scale(d.end)-scale(d.start);})
.attr("y",0)
.attr("height",10)
.attr("opacity",0.2);
}
}
},false);
};
window.addEventListener('load', function() {
var key = window.location.origin;
if (key == "http://epigenomegateway.wustl.edu") {
console.log("using washu plugin");
washuPlugin();
} else if (key == "http://genome.ucsc.edu") {
ucscPlugin();
}
},false);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment