rails-clustergrammer 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +11 -0
- data/lib/rails/clustergrammer/version.rb +1 -1
- data/vendor/assets/javascripts/Enrichrgram.js +755 -0
- data/vendor/assets/javascripts/graph-scroll.js +136 -0
- data/vendor/assets/javascripts/hzome_functions.js +83 -0
- data/vendor/assets/javascripts/scroll_section_functions.js +291 -0
- data/vendor/assets/javascripts/send_to_Enrichr.js +36 -0
- metadata +6 -1
@@ -0,0 +1,136 @@
|
|
1
|
+
function graphScroll() {
|
2
|
+
var windowHeight,
|
3
|
+
dispatch = d3.dispatch("scroll", "active"),
|
4
|
+
sections = d3.select('null'),
|
5
|
+
i = NaN,
|
6
|
+
sectionPos = [],
|
7
|
+
n,
|
8
|
+
graph = d3.select('null'),
|
9
|
+
isFixed = null,
|
10
|
+
isBelow = null,
|
11
|
+
container = d3.select('body'),
|
12
|
+
containerStart = 0,
|
13
|
+
belowStart,
|
14
|
+
eventId = Math.random()
|
15
|
+
|
16
|
+
function reposition(){
|
17
|
+
var i1 = 0
|
18
|
+
sectionPos.forEach(function(d, i){
|
19
|
+
if (d < pageYOffset - containerStart + 400) i1 = i
|
20
|
+
})
|
21
|
+
i1 = Math.min(n - 1, i1)
|
22
|
+
if (i != i1){
|
23
|
+
sections.classed('graph-scroll-active', function(d, i){ return i === i1 })
|
24
|
+
|
25
|
+
dispatch.active(i1)
|
26
|
+
|
27
|
+
i = i1
|
28
|
+
}
|
29
|
+
|
30
|
+
var isBelow1 = pageYOffset > belowStart
|
31
|
+
if (isBelow != isBelow1){
|
32
|
+
isBelow = isBelow1
|
33
|
+
graph.classed('graph-scroll-below', isBelow)
|
34
|
+
}
|
35
|
+
var isFixed1 = !isBelow && pageYOffset > containerStart
|
36
|
+
if (isFixed != isFixed1){
|
37
|
+
isFixed = isFixed1
|
38
|
+
graph.classed('graph-scroll-fixed', isFixed)
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
function resize(){
|
43
|
+
sectionPos = []
|
44
|
+
var startPos
|
45
|
+
sections.each(function(d, i){
|
46
|
+
if (!i) startPos = this.getBoundingClientRect().top
|
47
|
+
sectionPos.push(this.getBoundingClientRect().top - startPos) })
|
48
|
+
|
49
|
+
var containerBB = container.node().getBoundingClientRect()
|
50
|
+
var graphBB = graph.node().getBoundingClientRect()
|
51
|
+
|
52
|
+
containerStart = containerBB.top + pageYOffset
|
53
|
+
belowStart = containerBB.bottom - graphBB.height + pageYOffset
|
54
|
+
}
|
55
|
+
|
56
|
+
function keydown() {
|
57
|
+
if (!isFixed) return
|
58
|
+
var delta
|
59
|
+
switch (d3.event.keyCode) {
|
60
|
+
case 39: // right arrow
|
61
|
+
if (d3.event.metaKey) return
|
62
|
+
case 40: // down arrow
|
63
|
+
case 34: // page down
|
64
|
+
delta = d3.event.metaKey ? Infinity : 1 ;break
|
65
|
+
case 37: // left arrow
|
66
|
+
if (d3.event.metaKey) return
|
67
|
+
case 38: // up arrow
|
68
|
+
case 33: // page up
|
69
|
+
delta = d3.event.metaKey ? -Infinity : -1 ;break
|
70
|
+
case 32: // space
|
71
|
+
delta = d3.event.shiftKey ? -1 : 1
|
72
|
+
;break
|
73
|
+
default: return
|
74
|
+
}
|
75
|
+
|
76
|
+
var i1 = Math.max(0, Math.min(i + delta, n - 1))
|
77
|
+
d3.select(document.documentElement)
|
78
|
+
.interrupt()
|
79
|
+
.transition()
|
80
|
+
.duration(500)
|
81
|
+
.tween("scroll", function() {
|
82
|
+
var i = d3.interpolateNumber(pageYOffset, sectionPos[i1] + containerStart)
|
83
|
+
return function(t) { scrollTo(0, i(t)) }
|
84
|
+
})
|
85
|
+
|
86
|
+
d3.event.preventDefault()
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
var rv ={}
|
91
|
+
|
92
|
+
rv.container = function(_x){
|
93
|
+
if (!_x) return container
|
94
|
+
|
95
|
+
container = _x
|
96
|
+
return rv
|
97
|
+
}
|
98
|
+
|
99
|
+
rv.graph = function(_x){
|
100
|
+
if (!_x) return graph
|
101
|
+
|
102
|
+
graph = _x
|
103
|
+
return rv
|
104
|
+
}
|
105
|
+
|
106
|
+
rv.eventId = function(_x){
|
107
|
+
if (!_x) return eventId
|
108
|
+
|
109
|
+
eventId = _x
|
110
|
+
return rv
|
111
|
+
}
|
112
|
+
|
113
|
+
rv.sections = function (_x){
|
114
|
+
if (!_x) return sections
|
115
|
+
|
116
|
+
sections = _x
|
117
|
+
n = sections.size()
|
118
|
+
|
119
|
+
d3.select(window)
|
120
|
+
.on('scroll.gscroll' + eventId, reposition)
|
121
|
+
.on('resize.gscroll' + eventId, resize)
|
122
|
+
.on('keydown.gscroll' + eventId, keydown)
|
123
|
+
|
124
|
+
resize()
|
125
|
+
d3.timer(function() {
|
126
|
+
reposition()
|
127
|
+
return true
|
128
|
+
})
|
129
|
+
|
130
|
+
return rv
|
131
|
+
}
|
132
|
+
|
133
|
+
d3.rebind(rv, dispatch, "on")
|
134
|
+
|
135
|
+
return rv
|
136
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
function ini_hzome(root_id){
|
2
|
+
|
3
|
+
// save gene data to global variable
|
4
|
+
gene_data = {};
|
5
|
+
|
6
|
+
function get_mouseover(root_tip, gene_symbol){
|
7
|
+
|
8
|
+
// not sure if this is necessary
|
9
|
+
if ( d3.select(root_tip + '_row_tip').classed(gene_symbol) ){
|
10
|
+
get_request(root_tip, gene_symbol);
|
11
|
+
}
|
12
|
+
|
13
|
+
}
|
14
|
+
|
15
|
+
function get_request(root_tip, ini_gene_symbol){
|
16
|
+
|
17
|
+
var gene_symbol;
|
18
|
+
if (ini_gene_symbol.indexOf(' ') > 0){
|
19
|
+
gene_symbol = ini_gene_symbol.split(' ')[0];
|
20
|
+
} else if (ini_gene_symbol.indexOf('_') > 0){
|
21
|
+
gene_symbol = ini_gene_symbol.split('_')[0];
|
22
|
+
}
|
23
|
+
else {
|
24
|
+
gene_symbol = ini_gene_symbol;
|
25
|
+
}
|
26
|
+
|
27
|
+
var base_url = 'https://amp.pharm.mssm.edu/Harmonizome/api/1.0/gene/';
|
28
|
+
var url = base_url + gene_symbol;
|
29
|
+
|
30
|
+
$.get(url, function(data) {
|
31
|
+
|
32
|
+
data = JSON.parse(data);
|
33
|
+
|
34
|
+
// save data for repeated use
|
35
|
+
gene_data[gene_symbol] = {}
|
36
|
+
gene_data[gene_symbol].name = data.name;
|
37
|
+
gene_data[gene_symbol].description = data.description;
|
38
|
+
|
39
|
+
set_tooltip(data, root_tip, ini_gene_symbol);
|
40
|
+
|
41
|
+
return data;
|
42
|
+
|
43
|
+
});
|
44
|
+
}
|
45
|
+
|
46
|
+
function set_tooltip(data, root_tip, gene_symbol){
|
47
|
+
|
48
|
+
if (data.name != undefined){
|
49
|
+
|
50
|
+
d3.selectAll(root_tip + '_row_tip')
|
51
|
+
.html(function(){
|
52
|
+
var sym_name = gene_symbol + ': ' + data.name;
|
53
|
+
var full_html = '<p>' + sym_name + '</p>' + '<p>' +
|
54
|
+
data.description + '</p>';
|
55
|
+
return full_html;
|
56
|
+
});
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
function gene_info(root_tip, gene_info){
|
62
|
+
|
63
|
+
var gene_symbol = gene_info.name;
|
64
|
+
|
65
|
+
if (_.has(gene_data, gene_symbol)){
|
66
|
+
var inst_data = gene_data[gene_symbol];
|
67
|
+
set_tooltip(inst_data, root_tip, gene_symbol);
|
68
|
+
} else{
|
69
|
+
setTimeout(get_mouseover, 250, root_tip, gene_symbol);
|
70
|
+
}
|
71
|
+
|
72
|
+
}
|
73
|
+
|
74
|
+
hzome = {}
|
75
|
+
|
76
|
+
hzome.gene_info = gene_info;
|
77
|
+
hzome.gene_data = gene_data;
|
78
|
+
hzome.get_mouseover = get_mouseover;
|
79
|
+
hzome.get_request = get_request;
|
80
|
+
|
81
|
+
return hzome;
|
82
|
+
|
83
|
+
}
|
@@ -0,0 +1,291 @@
|
|
1
|
+
var section_fun = {};
|
2
|
+
|
3
|
+
section_fun['initialize_view'] = function(){
|
4
|
+
console.log('initializing view');
|
5
|
+
click_reorder_button('row','clust');
|
6
|
+
click_reorder_button('col','clust');
|
7
|
+
cgm.reset_cats();
|
8
|
+
cgm.update_view('N_row_sum','all');
|
9
|
+
close_enrichr_menu();
|
10
|
+
}
|
11
|
+
|
12
|
+
section_fun['run_filter_sum_10'] = function(){
|
13
|
+
console.log('sum filtering');
|
14
|
+
cgm.update_view('N_row_sum', 10);
|
15
|
+
}
|
16
|
+
|
17
|
+
section_fun['run_filter_sum_20'] = function(){
|
18
|
+
console.log('sum filtering');
|
19
|
+
cgm.update_view('N_row_sum', 20);
|
20
|
+
}
|
21
|
+
|
22
|
+
section_fun['run_filter_var_10'] = function(){
|
23
|
+
console.log('variance filtering');
|
24
|
+
click_reorder_button('row','clust');
|
25
|
+
click_reorder_button('col','clust');
|
26
|
+
highlight_sidebar_element(cgm.params, 'slider_N_row_var');
|
27
|
+
cgm.update_view('N_row_var', 10);
|
28
|
+
|
29
|
+
// update slider manually - 2 means the third position of the slider
|
30
|
+
// for some reason I need to call it twice
|
31
|
+
cgm.slider_functions['N_row_var'].value(1);
|
32
|
+
cgm.slider_functions['N_row_var'].value(2);
|
33
|
+
|
34
|
+
d3.select(cgm.params.root+' .title_N_row_var')
|
35
|
+
.text('Top rows variance: 10');
|
36
|
+
|
37
|
+
d3.select(cgm.params.root+' .slider_N_row_var')
|
38
|
+
.attr('current_state', '10');
|
39
|
+
}
|
40
|
+
|
41
|
+
section_fun['run_reorder_row_var'] = function(){
|
42
|
+
highlight_sidebar_element(cgm.params, 'toggle_row_order');
|
43
|
+
click_reorder_button('row','rankvar');
|
44
|
+
}
|
45
|
+
|
46
|
+
section_fun['run_reorder_single_row'] = function(){
|
47
|
+
|
48
|
+
var params = cgm.params;
|
49
|
+
|
50
|
+
var inst_element = get_row_element(params, 'EGFR');
|
51
|
+
|
52
|
+
var group_trans = d3.select(inst_element).attr('transform');
|
53
|
+
|
54
|
+
var container_trans = d3.select(params.root+' .clust_container')
|
55
|
+
.attr('transform')
|
56
|
+
.split(',')[1].replace(')','');
|
57
|
+
|
58
|
+
var x_trans = params.viz.norm_labels.width.row * 0.9;
|
59
|
+
|
60
|
+
var row_trans = group_trans.split(',')[1].replace(')','');
|
61
|
+
var y_trans = String(Number(row_trans) + Number(container_trans) +
|
62
|
+
params.viz.rect_height/2);
|
63
|
+
|
64
|
+
var wait_click = 500;
|
65
|
+
setTimeout(sim_click, wait_click, params, 'double', x_trans, y_trans);
|
66
|
+
var wait_reorder = wait_click + 300;
|
67
|
+
setTimeout(fire_double_click_row, wait_reorder, params, inst_element);
|
68
|
+
}
|
69
|
+
|
70
|
+
section_fun['run_conclusions'] = function(){
|
71
|
+
console.log('run conclusions');
|
72
|
+
click_reorder_button('row','clust');
|
73
|
+
click_reorder_button('col ','clust');
|
74
|
+
cgm.update_view('N_row_sum','all');
|
75
|
+
}
|
76
|
+
|
77
|
+
section_fun['run_zoom_and_pan'] = function(){
|
78
|
+
console.log('zoom_and_pan');
|
79
|
+
setTimeout(function(){cgm.zoom(0, 0, 3)}, 0);
|
80
|
+
setTimeout(function(){cgm.zoom(0, 0, 1)}, 1500);
|
81
|
+
}
|
82
|
+
|
83
|
+
section_fun['open_enrichr_menu'] = function(){
|
84
|
+
|
85
|
+
cgm.update_view('N_row_sum','all');
|
86
|
+
|
87
|
+
var x_trans = 72;
|
88
|
+
var y_trans = 25;
|
89
|
+
var wait_click = 500;
|
90
|
+
setTimeout(sim_click, wait_click, cgm.params, 'single', x_trans, y_trans);
|
91
|
+
|
92
|
+
setTimeout(open_enrichr_menu, 750);
|
93
|
+
}
|
94
|
+
|
95
|
+
section_fun['run_enrichr_cats'] = function(){
|
96
|
+
|
97
|
+
console.log('run_enrichr_cats\n--------------')
|
98
|
+
var lib_of_interest = 'ChEA 2015'
|
99
|
+
|
100
|
+
var x_trans = 115;
|
101
|
+
var y_trans = 93;
|
102
|
+
var wait_click = 500;
|
103
|
+
setTimeout(sim_click, wait_click, cgm.params, 'single', x_trans, y_trans);
|
104
|
+
|
105
|
+
setTimeout(click_lib, 750, lib_of_interest);
|
106
|
+
|
107
|
+
setTimeout(close_enrichr_menu, 1500);
|
108
|
+
|
109
|
+
}
|
110
|
+
|
111
|
+
section_fun['clear_enrichr_cats'] = function(){
|
112
|
+
|
113
|
+
setTimeout(open_enrichr_menu, 500);
|
114
|
+
|
115
|
+
var x_trans = 460;
|
116
|
+
var y_trans = 65;
|
117
|
+
var wait_click = 1500;
|
118
|
+
setTimeout(sim_click, wait_click, cgm.params, 'single', x_trans, y_trans);
|
119
|
+
|
120
|
+
function delay_enr_clear(){
|
121
|
+
console.log('delay_enr_clear')
|
122
|
+
$(d3.select('.enr_menu_clear')[0]).d3Click();
|
123
|
+
}
|
124
|
+
|
125
|
+
setTimeout(delay_enr_clear, 2000);
|
126
|
+
}
|
127
|
+
|
128
|
+
section_fun['dendro_groups'] = function(){
|
129
|
+
click_reorder_button('row','clust');
|
130
|
+
click_reorder_button('col','clust');
|
131
|
+
function highlight_dendro(){
|
132
|
+
highlight_sidebar_element(cgm.params, 'slider_row');
|
133
|
+
highlight_sidebar_element(cgm.params, 'slider_col');
|
134
|
+
}
|
135
|
+
setTimeout(highlight_dendro, 1500);
|
136
|
+
}
|
137
|
+
|
138
|
+
section_fun['row_search'] = function(){
|
139
|
+
highlight_sidebar_element(cgm.params, 'gene_search_container');
|
140
|
+
}
|
141
|
+
|
142
|
+
var update_section_db = _.debounce(update_section, 1500);
|
143
|
+
|
144
|
+
function update_section(current_section){
|
145
|
+
|
146
|
+
if (prev_section != current_section){
|
147
|
+
|
148
|
+
prev_section = current_section;
|
149
|
+
|
150
|
+
var function_name = tutorial_info[current_section].run_function;
|
151
|
+
var inst_function = section_fun[function_name];
|
152
|
+
|
153
|
+
// run if buttons are active
|
154
|
+
if (d3.select('.toggle_col_order').select('button').attr('disabled') === null){
|
155
|
+
inst_function();
|
156
|
+
|
157
|
+
// wait if still transitioning
|
158
|
+
} else {
|
159
|
+
|
160
|
+
// need to check that you are in the same section
|
161
|
+
setTimeout(inst_function, 2000);
|
162
|
+
}
|
163
|
+
|
164
|
+
} else {
|
165
|
+
console.log('already in section - do not run\n')
|
166
|
+
}
|
167
|
+
}
|
168
|
+
|
169
|
+
function highlight_sidebar_element(params, highlight_class){
|
170
|
+
|
171
|
+
var duration = 4000;
|
172
|
+
|
173
|
+
if (highlight_class.indexOf('slider') < 0){
|
174
|
+
d3.select(params.root+' .'+highlight_class)
|
175
|
+
.style('background','#007f00')
|
176
|
+
.style('box-shadow','0px 0px 10px 5px #007f00')
|
177
|
+
.transition().duration(1).delay(duration)
|
178
|
+
.style('background','#FFFFFF')
|
179
|
+
.style('box-shadow','none');
|
180
|
+
} else {
|
181
|
+
d3.select(params.root+' .'+highlight_class)
|
182
|
+
.style('box-shadow','0px 0px 10px 5px #007f00')
|
183
|
+
.transition().duration(1).delay(duration)
|
184
|
+
.style('box-shadow','none');
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
function sim_click(params, single_double, pos_x, pos_y){
|
189
|
+
|
190
|
+
var click_duration = 200;
|
191
|
+
|
192
|
+
var click_circle = d3.select(params.root+' .viz_svg')
|
193
|
+
.append('circle')
|
194
|
+
.attr('cx',pos_x)
|
195
|
+
.attr('cy',pos_y)
|
196
|
+
.attr('r',25)
|
197
|
+
.style('stroke','black')
|
198
|
+
.style('stroke-width','3px')
|
199
|
+
.style('fill','#007f00')
|
200
|
+
.style('opacity',0.5);
|
201
|
+
|
202
|
+
if (single_double === 'double'){
|
203
|
+
click_circle
|
204
|
+
.transition().duration(click_duration)
|
205
|
+
.style('opacity',0.0)
|
206
|
+
.transition().duration(50)
|
207
|
+
.style('opacity',0.5)
|
208
|
+
.transition().duration(click_duration)
|
209
|
+
.style('opacity',0.0)
|
210
|
+
.remove();
|
211
|
+
} else {
|
212
|
+
click_circle
|
213
|
+
.transition().duration(click_duration)
|
214
|
+
.style('opacity',0.0)
|
215
|
+
.transition().duration(250)
|
216
|
+
.remove();
|
217
|
+
}
|
218
|
+
|
219
|
+
}
|
220
|
+
|
221
|
+
|
222
|
+
function click_lib(lib_of_interest){
|
223
|
+
|
224
|
+
found_lib = d3.select(cgm.params.root+' .enr_lib_section')
|
225
|
+
.selectAll('g')
|
226
|
+
.filter(function(){
|
227
|
+
var inst_text = d3.select(this).select('text').text();
|
228
|
+
return inst_text === lib_of_interest;
|
229
|
+
})[0];
|
230
|
+
$(found_lib).d3Click();
|
231
|
+
console.log('click_lib')
|
232
|
+
}
|
233
|
+
|
234
|
+
function open_enrichr_menu(){
|
235
|
+
// only open, do not close
|
236
|
+
if (d3.select('.enrichr_menu').classed('showing') === false){
|
237
|
+
$(d3.select('#enrichr_menu_button_graph')[0]).d3Click();
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
function close_enrichr_menu(){
|
242
|
+
console.log('close_enrichr_menu')
|
243
|
+
// only open, do not close
|
244
|
+
if (d3.select('.enrichr_menu').classed('showing') === true){
|
245
|
+
$(d3.select('#enrichr_menu_button_graph')[0]).d3Click();
|
246
|
+
}
|
247
|
+
}
|
248
|
+
|
249
|
+
function click_reorder_button(inst_rc, inst_order){
|
250
|
+
var inst_button = d3.selectAll('.toggle_'+inst_rc+'_order .btn')
|
251
|
+
.filter(function(){
|
252
|
+
return this.__data__ == inst_order;
|
253
|
+
})[0];
|
254
|
+
|
255
|
+
$(inst_button).click();
|
256
|
+
}
|
257
|
+
|
258
|
+
|
259
|
+
|
260
|
+
function get_row_element(params, inst_row){
|
261
|
+
|
262
|
+
var inst_element = d3.selectAll(params.root+' .row_label_group')
|
263
|
+
.filter(function(){
|
264
|
+
var inst_data = this.__data__;
|
265
|
+
return inst_data.name == inst_row;
|
266
|
+
})[0][0];
|
267
|
+
|
268
|
+
return inst_element;
|
269
|
+
}
|
270
|
+
|
271
|
+
function fire_double_click_row(params, inst_element){
|
272
|
+
$(inst_element).d3DblClick();
|
273
|
+
}
|
274
|
+
|
275
|
+
// allows doubleclicking on d3 element
|
276
|
+
jQuery.fn.d3DblClick = function () {
|
277
|
+
this.each(function (i, e) {
|
278
|
+
var evt = document.createEvent("MouseEvents");
|
279
|
+
evt.initMouseEvent("dblclick", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
280
|
+
e.dispatchEvent(evt);
|
281
|
+
});
|
282
|
+
};
|
283
|
+
|
284
|
+
jQuery.fn.d3Click = function () {
|
285
|
+
this.each(function (i, e) {
|
286
|
+
var evt = document.createEvent("MouseEvents");
|
287
|
+
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false,
|
288
|
+
false, false, false, 0, null);
|
289
|
+
e.dispatchEvent(evt);
|
290
|
+
});
|
291
|
+
};
|