rbbt-rest 1.6.28 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rbbt/rest/entity.rb +71 -1
  3. data/lib/rbbt/rest/entity/render.rb +3 -2
  4. data/lib/rbbt/rest/knowledge_base.rb +81 -28
  5. data/lib/rbbt/rest/main.rb +3 -0
  6. data/lib/rbbt/rest/workflow.rb +1 -1
  7. data/lib/rbbt/rest/workflow/jobs.rb +5 -4
  8. data/share/views/compass/app.sass +21 -11
  9. data/share/views/layout/footer.haml +0 -1
  10. data/share/views/layout/header.haml +9 -6
  11. data/share/views/layout/top_menu.haml +1 -0
  12. data/share/views/partials/table.haml +7 -1
  13. data/share/views/public/js/_ajax_replace.js +2 -0
  14. data/share/views/public/js/defer.js +1 -1
  15. data/share/views/public/js/helpers.js +89 -18
  16. data/share/views/public/js/rbbt.aesthetics.js +145 -34
  17. data/share/views/public/js/rbbt.basic.js +20 -0
  18. data/share/views/public/js/rbbt.entity.js +12 -2
  19. data/share/views/public/js/rbbt.entity_list.js +51 -5
  20. data/share/views/public/js/rbbt.exception.js +9 -1
  21. data/share/views/public/js/rbbt.job.js +2 -2
  22. data/share/views/public/js/rbbt.js +5 -1
  23. data/share/views/public/js/rbbt.knowledge_base.js +40 -0
  24. data/share/views/public/js/rbbt.modal.js +82 -75
  25. data/share/views/public/js/rbbt.plots.js +276 -0
  26. data/share/views/public/js/rbbt/list.js +2 -2
  27. data/share/views/public/plugins/cola/js/cola.v3.min.js +3 -0
  28. data/share/views/public/plugins/d3js/js/d3.js +9503 -0
  29. data/share/views/public/plugins/d3js/js/d3js.min.js +5 -0
  30. data/share/views/public/plugins/mithril-node-render/js/index.js +115 -0
  31. data/share/views/public/plugins/mithril/js/mithril.js +212 -77
  32. data/share/views/public/plugins/mithril/js/mithril.min.js +2 -2
  33. data/share/views/public/plugins/mithril/js/mithril.min.js.map +1 -1
  34. data/share/views/public/plugins/nvd3/css/nv.d3.css +641 -0
  35. data/share/views/public/plugins/nvd3/js/nv.d3.js +13298 -0
  36. data/share/views/public/plugins/svg-pan-zoom/js/svg-pan-zoom.js +1861 -0
  37. data/share/views/tools/nvd3.haml +16 -0
  38. data/share/views/tools/nvd3/chart.haml +55 -0
  39. data/share/views/tools/nvd3/histogram.haml +19 -0
  40. data/share/views/tools/nvd3/pie.haml +24 -0
  41. data/share/views/tools/nvd3/scatter.haml +33 -0
  42. data/share/views/wait.haml +2 -2
  43. metadata +15 -3
  44. data/share/views/public/plugins/d3js/d3js.min.js +0 -5
@@ -6,7 +6,15 @@ rbbt.exception.null = function(variable, text){
6
6
 
7
7
  rbbt.exception.report = function(err){
8
8
  console.log("Error: " + err)
9
- rbbt.modal.controller().error(err, "Application Error")
9
+ var stack = err.stack
10
+ console.log(stack)
11
+ if (rbbt.modal){
12
+ stack = "<ul><li>" + stack.replace(/\n/g, '</li><li>') + '<li/></ul>'
13
+ stack = stack.replace(/<li><li\/>/g,'').replace(/<li>(.*?)@(.*?):(\d+:\d+)<\/li>/g, '<li>$2<span style="font-weight:bold">$3</span><br/><em>$1</em></li>')
14
+ rbbt.modal.controller.error(m('.ui.error.message', [m('.header', err), m('.description', m.trust(stack))]), "Application Error")
15
+ }else{
16
+ console.log(stack)
17
+ }
10
18
  }
11
19
 
12
20
  rbbt.try = function(func){
@@ -159,9 +159,9 @@ rbbt.Job = function(workflow, task, inputs){
159
159
 
160
160
  }
161
161
 
162
- rbbt.job = function(workflow, task, inputs){
162
+ rbbt.job = function(workflow, task, inputs,json){
163
163
  var job = new rbbt.Job(workflow, task, inputs)
164
- return job.run()
164
+ return job.run(json)
165
165
  }
166
166
 
167
167
  rbbt_job = function(workflow, task, inputs, complete){
@@ -23,6 +23,10 @@ rbbt.post.asFormUrlEncoded = function(xhr){
23
23
  }
24
24
 
25
25
  rbbt.log = function(obj){
26
- console.log(obj)
26
+ console.log((new Date()).toString() + ' => ' + obj)
27
27
  }
28
28
 
29
+ rbbt.mount = function(obj, component){
30
+ obj.className = obj.className + ' mithril-mount'
31
+ m.mount(obj, component)
32
+ }
@@ -14,6 +14,46 @@ KB.parents = function(database, entity){
14
14
  return m.request({url: url, method: "GET", type: Entity})
15
15
  }
16
16
 
17
+ KB.list_parents = function(database, list){
18
+ return list.get().then(function(list_info){
19
+ var url = '/knowledge_base/user/' + database + '/collection_parents'
20
+
21
+ collection = {}
22
+ collection[list.type] = list_info.entities
23
+ url = add_parameter(url, 'collection', JSON.stringify(collection))
24
+ url = add_parameter(url, '_format', 'tsv_json')
25
+ return m.request({url: url, method: "POST"})
26
+ })
27
+ }
28
+
29
+ KB.list_children = function(database, list){
30
+ return list.get().then(function(list_info){
31
+ var url = '/knowledge_base/user/' + database + '/collection_children'
32
+
33
+ var collection = {}
34
+ collection[list.type] = list_info.entities
35
+ var data = {}
36
+ data.collection = JSON.stringify(collection)
37
+ data._format = 'tsv_json'
38
+
39
+ return rbbt.post(url, data)
40
+ })
41
+ }
42
+
43
+ KB.list_subset = function(database, list, target){
44
+ return list.get().then(function(list_info){
45
+ var url = '/knowledge_base/user/' + database + '/subset'
46
+
47
+ var data = {}
48
+ var source = list_info.entities.join(",")
49
+ data._format = 'tsv_json'
50
+ data.source = source
51
+ if (target) data.target = target.join(",")
52
+
53
+ return rbbt.post(url, data)
54
+ })
55
+ }
56
+
17
57
  Entity.prototype.children = function(database){
18
58
  return KB.children(database, this)
19
59
  }
@@ -1,90 +1,97 @@
1
- rbbt.modal = {}
2
- rbbt.modal.element = document.getElementById('modal')
3
-
4
- rbbt.modal.vm = (function(){
5
- var vm = {}
6
- vm.init = function(){
7
- console.log(m)
8
- vm.visible = m.prop(false)
9
- vm.content = m.prop("")
10
- vm.title = m.prop("")
11
- }
12
1
 
13
- return vm
14
- }())
15
-
16
- rbbt.modal.controller = function(){
17
- var controller = rbbt.modal.controller
18
- var vm = rbbt.modal.vm
19
- vm.init()
20
-
21
- controller._set = function(content, title){
22
- vm.content(content)
23
- if (undefined !== title)
24
- vm.title(title)
25
- else
26
- vm.title("")
27
- vm.visible(true)
28
- }
29
2
 
30
- controller.show = function(content, title){
31
- controller._set(content, title)
32
- $(rbbt.modal.element).addClass('active')
33
- m.redraw()
34
- update_rbbt()
35
- }
3
+ ModalComponent = function(element){
4
+ var component = {}
36
5
 
37
- controller.error = function(content, title){
38
- controller._set(content, title)
39
- $(rbbt.modal.element).addClass('active')
40
- $(rbbt.modal.element).addClass('error')
41
- m.redraw()
42
- update_rbbt()
6
+ component.vm = {
7
+ element: element,
8
+ init: function(){
9
+ this.visible = m.prop(false)
10
+ this.content = m.prop("")
11
+ this.title = m.prop("")
12
+ }
43
13
  }
44
14
 
15
+ component.controller = function(){
16
+ var ctrl = component.controller
17
+ ctrl.vm = component.vm;
18
+ ctrl.vm.init();
45
19
 
46
- controller.show_url = function(url, title){
47
- if (typeof url == 'string') params = {url: url, method: 'GET',deserialize: function(v){return v}}
48
- else params = url
49
- vm.visible(true)
50
- vm.title("loading")
51
- vm.content(m('.ui.loading.basic.segment'))
52
- $(rbbt.modal.element).addClass('loading')
53
- $(rbbt.modal.element).addClass('active')
54
- m.redraw()
55
- return rbbt.insist_request(params).then(function(content){
56
- $(rbbt.modal.element).removeClass('loading')
57
- controller.show(content, title)
58
- })
59
- }
20
+ ctrl._set = function(content, title){
21
+ this.vm.content(content)
22
+ if (undefined !== title)
23
+ this.vm.title(title)
24
+ else
25
+ this.vm.title("")
26
+ this.vm.visible(true)
27
+ }
60
28
 
61
- controller.close = function(){
62
- vm.visible(false)
63
- $(rbbt.modal.element).removeClass('error')
64
- $(rbbt.modal.element).removeClass('active')
65
- m.redraw()
66
- }
29
+ ctrl.show = function(content, title){
30
+ this._set(content, title)
31
+ $(this.vm.element).addClass('active')
32
+ m.redraw()
33
+ update_rbbt()
34
+ }
67
35
 
68
- return controller
69
- }
36
+ ctrl.error = function(content, title){
37
+ this._set(content, title)
38
+ $(this.vm.element).addClass('active')
39
+ $(this.vm.element).addClass('error')
40
+ m.redraw()
41
+ update_rbbt()
42
+ }
70
43
 
71
- rbbt.modal.view = function(controller){
72
- if (rbbt.modal.vm.visible()){
73
- var title
74
- if ('object' == typeof rbbt.modal.vm.title()) title = rbbt.modal.vm.title()
75
- else title = m.trust(rbbt.modal.vm.title())
44
+ ctrl.show_url = function(url, title){
45
+ if (typeof url == 'string') params = {url: url, method: 'GET',deserialize: function(v){return v}}
46
+ else params = url
76
47
 
77
- var content
78
- if ('object' == typeof rbbt.modal.vm.content()) content = rbbt.modal.vm.content()
79
- else content = m.trust(rbbt.modal.vm.content())
48
+ this.vm.visible(true)
49
+ this.vm.title("loading")
50
+ this.vm.content(m('.ui.loading.basic.segment'))
51
+ $(this.vm.element).addClass('loading')
52
+ $(this.vm.element).addClass('active')
53
+ m.redraw()
54
+ return rbbt.insist_request(params).then(function(content){
55
+ $(ctrl.vm.element).removeClass('loading')
56
+ ctrl.show(content, title)
57
+ })
58
+ }
80
59
 
60
+ ctrl.close = function(){
61
+ ctrl.vm.visible(false)
62
+ $(ctrl.vm.element).removeClass('error')
63
+ $(ctrl.vm.element).removeClass('active')
64
+ m.redraw()
65
+ }
81
66
 
82
- var header = [title, rbbt.mview.ibutton({onclick: rbbt.modal.controller.close, class:'small close', style: 'margin-top: -4px'}, m('i.icon.close'))]
83
- var modal_content = [m('.header', header), m('.content', content)]
84
- return modal_content
85
- }else{
86
- return ""
67
+ return ctrl
87
68
  }
69
+
70
+ component.view = function(ctrl){
71
+ if (ctrl.vm.visible()){
72
+ var title
73
+ if ('object' == typeof ctrl.vm.title()) title = ctrl.vm.title();
74
+ else title = m.trust(ctrl.vm.title());
75
+
76
+ var content
77
+ if ('object' == typeof ctrl.vm.content()) content = ctrl.vm.content();
78
+ else content = m.trust(ctrl.vm.content());
79
+
80
+
81
+ var header = [title, rbbt.mview.ibutton({onclick: ctrl.close, class:'small close', style: 'margin-top: -4px'}, m('i.icon.close'))];
82
+ var modal_content = [m('.header', header), m('.content', content)];
83
+ return modal_content;
84
+ }else{
85
+ return "";
86
+ }
87
+ }
88
+
89
+
90
+ return component;
88
91
  }
89
92
 
90
- if (rbbt.modal.element) m.module(rbbt.modal.element, rbbt.modal)
93
+ if (document.getElementById('modal')){
94
+ rbbt.modal = new ModalComponent(document.getElementById('modal'))
95
+
96
+ m.mount(document.getElementById('modal'), rbbt.modal)
97
+ }
@@ -0,0 +1,276 @@
1
+ rbbt.plots = {}
2
+
3
+ rbbt.plots.list_plot = function(list, rules, create_obj){
4
+ var component = {}
5
+ component.create_obj = create_obj
6
+
7
+ component.vm = {
8
+ list: list,
9
+ rules: rules,
10
+
11
+ node_aesthetics: m.prop(),
12
+ update_aesthetics: function(){
13
+ rbbt.log('update-aesthetics')
14
+ //return rbbt.aesthetics.get_list_aesthetics(component.vm.list,component.vm.rules)
15
+ rbbt.aesthetics.get_list_aesthetics(component.vm.list,component.vm.rules)
16
+ .then(component.vm.node_aesthetics).then(component.vm.update_nodes)
17
+ m.redraw()
18
+ },
19
+
20
+ nodes: m.prop(),
21
+ no_layout: m.prop(false),
22
+ update_nodes: function(node_aesthetics){
23
+ rbbt.log('update-nodes')
24
+ var deferred = m.deferred()
25
+
26
+ component.vm.list.get().then(function(list_info){
27
+ var aes = list_info.entities.map(function(entity, i){
28
+ var e_aes = {id: entity, index: i}
29
+ forHash(node_aesthetics, function(key, value){
30
+ e_aes[key] = value[i]
31
+ })
32
+ return e_aes
33
+ })
34
+ rbbt.log('update-nodes:done')
35
+ return aes
36
+ }).then(component.vm.nodes).then(component.vm.update_layout).then(deferred.resolve)
37
+ return deferred.promise
38
+ },
39
+
40
+ associations: m.prop(),
41
+ graph: function(){
42
+ if (undefined === component.vm.associations() || undefined === component.vm.nodes()) return {links:[],nodes:[]}
43
+ var links = rbbt.plots.association_network(component.vm.nodes(), component.vm.associations())
44
+ var graph = {links: links, nodes: component.vm.nodes()}
45
+ return(graph)
46
+ },
47
+ update_layout: function(nodes){
48
+ rbbt.log('update-layout')
49
+
50
+ if (component.vm.no_layout() || undefined === component.vm.associations()){
51
+ var deferred = m.deferred()
52
+ deferred.resolve(nodes)
53
+ return deferred.promise
54
+ }
55
+
56
+ rbbt.log('update-layout:force')
57
+
58
+ return rbbt.plots.force_layout(component.vm.graph()).then(function(graph){return graph.nodes})
59
+ },
60
+
61
+ init: function(){
62
+ rbbt.log('init')
63
+ component.vm.update_aesthetics()
64
+ },
65
+ }
66
+
67
+ component.controller = function(){
68
+ var ctrl = this
69
+ this.vm = component.vm;
70
+ this.vm.init()
71
+ this.onunload = function() {
72
+ console.log("unloading component");
73
+ }
74
+ }
75
+
76
+ component.wrapper = function(objs){
77
+ if (undefined === objs){
78
+ rbbt.log("Loading")
79
+ return m('.ui.basic.segment.plot.loading', "Loading")
80
+ }else{
81
+ rbbt.log("Wrap")
82
+ return m('.ui.basic.segment.plot', objs)
83
+ }
84
+ }
85
+
86
+ component.view = function(ctrl){
87
+ rbbt.log('View')
88
+ if (ctrl.vm.nodes()){
89
+ var objs = ctrl.vm.nodes().map(function(aes,i){
90
+ return component.create_obj(aes)
91
+ })
92
+ return component.wrapper(objs)
93
+ }else{
94
+ return component.wrapper()
95
+ }
96
+ }
97
+
98
+ return component;
99
+ }
100
+
101
+ //{{{ PLOTS
102
+
103
+
104
+ //{{{ FORCE LAYOUT
105
+
106
+ rbbt.plots.force_layout = function(graph){
107
+ var deferred = m.deferred()
108
+ m.startComputation()
109
+ rbbt.log("force-start")
110
+ var force = d3.layout.force()
111
+ .charge(-5200)
112
+ .linkDistance(5000)
113
+ .size([10000, 10000])
114
+ .nodes(graph.nodes)
115
+ .links(graph.links)
116
+ .start();
117
+
118
+ force.on("end", function() {
119
+ m.endComputation()
120
+ rbbt.log("force-end")
121
+ deferred.resolve(graph)
122
+ })
123
+ return deferred.promise
124
+ }
125
+
126
+ rbbt.plots.association_network = function(nodes, associations){
127
+ var indices = {}
128
+ for (i = 0; i < nodes.length; i++){
129
+ var entity = nodes[i]
130
+ indices[entity.id] = i
131
+ }
132
+
133
+ var edges = []
134
+ forHash(associations, function(key,value){
135
+ var source = value[0]
136
+ var target = value[1]
137
+ var source_index = indices[source]
138
+ var target_index = indices[target]
139
+ edges.push({source: source_index, target: target_index, id: key})
140
+ })
141
+
142
+ return edges
143
+ }
144
+
145
+ //{{{ BASIC RULES
146
+
147
+
148
+ rbbt.plots.basic_rules = function(study){
149
+ var rules = []
150
+ rules.push({aes:'label', property: 'link', extract: m.trust})
151
+ rules.push({aes:'description', property: 'long_name'})
152
+ rules.push({aes:'highlight', property: 'significant_in_study', args:study})
153
+ rules.push({aes:'order', property: 'damage_bias_in_study', args:study})
154
+ rules.push({aes:'color_class', workflow: 'GEO', task: 'differential', args:{threshold: 0.05, dataset: 'GSE13507', to_gene: true, main:"/Primary/", contrast: "/ontrol/"}, extract: function(result, entity){
155
+ if (undefined === result[entity]) return ""
156
+ var pvalue = result[entity][result[entity].length-1]
157
+ if (pvalue > 0 && pvalue < 0.05){
158
+ return "green"
159
+ }else{
160
+ if (pvalue < 0 && pvalue > -0.05){
161
+ return "red"
162
+ }else{
163
+ return ""
164
+ }
165
+ }
166
+ }})
167
+ rules.push({aes:'color', workflow: 'GEO', task: 'differential', mapper: 'sign-gradient', args:{threshold: 0.05, dataset: 'GSE13507', to_gene: true, main:"/Primary/", contrast: "/ontrol/"}, extract: function(result, entity){
168
+ if (undefined === result[entity]) return ""
169
+ var pvalue = result[entity][result[entity].length-1]
170
+ return pvalue_score(pvalue)
171
+ }})
172
+
173
+ return rules
174
+ }
175
+
176
+ rbbt.plots.svg_wrapper = function(objs){
177
+ if (undefined === objs){
178
+ return m(".ui.basic.segment.loading", "Loading")
179
+ }else{
180
+ var cell_svg = m('image',{"xlink:href": 'https://upload.wikimedia.org/wikipedia/commons/1/1a/Biological_cell.svg',x:0,y:0,height:100, width:100})
181
+ objs.unshift(cell_svg)
182
+ return m("svg[height='800px'][width='100%'][viewPort='0 0 10000 10000'][xmlns:xlink='http://www.w3.org/1999/xlink']",{config: svgPanZoom}, objs)
183
+ }
184
+ }
185
+
186
+ rbbt.plots.tile_obj = function(aes){
187
+ var class_names = ""
188
+
189
+ if (aes.color_class){
190
+ class_names = class_names + ' ' + aes.color_class
191
+ aes.color_class = undefined
192
+ }
193
+
194
+ var title = aes.label
195
+ if (aes.highlight)
196
+ title = [m('i.icon.star',{style:"display:inline;font-size:1em"}), title]
197
+
198
+ var content = aes.description
199
+
200
+ var header = m('.ui.header', title)
201
+ var colors = m('.ui.segment', {"style":"background-color:" + aes.color})
202
+ aes.color = undefined
203
+ var body = m('.ui.description',[content, colors])
204
+
205
+ return m('.tile.ui.segment', {style: aes, class: class_names},
206
+ [header, body]
207
+ )
208
+ }
209
+
210
+ rbbt.plots.svg_obj = function(aes){
211
+ aes.width = '300px'
212
+ aes.height = '200px'
213
+ var tile = rbbt.plots.tile_obj(aes)
214
+
215
+ var location = {x: aes.x, y: aes.y}
216
+ if (undefined === location.x) location.x = Math.random() * 1000
217
+ if (undefined === location.y) location.y = Math.random() * 1000
218
+ location.width = aes.width
219
+ location.height = aes.height
220
+ location.requiredExtensions="http://www.w3.org/1999/xhtml"
221
+ location.class="node"
222
+
223
+ return m('foreignObject', location, m('body[xmlns="http://www.w3.org/1999/xhtml"]',tile))
224
+ }
225
+
226
+ rbbt.plots.d3js_graph = function(graph, object){
227
+ var xsize = 300, ysize = 200
228
+ var width = 1200
229
+ height = 800
230
+
231
+ var color = d3.scale.category20();
232
+
233
+ var svg = d3.select(object)
234
+ .attr("width", "100%")
235
+ .attr("height", height)
236
+
237
+ var force = d3.layout.force()
238
+ .charge(-20*xsize)
239
+ .linkDistance(3*xsize)
240
+ .size([width, height])
241
+ .nodes(graph.nodes)
242
+ .links(graph.links)
243
+
244
+ force.start()
245
+ force.on("tick", function() {
246
+ link.attr("x1", function(d) { return d.source.x + xsize/2; })
247
+ .attr("y1", function(d) { return d.source.y + ysize/2; })
248
+ .attr("x2", function(d) { return d.target.x + xsize/2; })
249
+ .attr("y2", function(d) { return d.target.y + ysize/2; });
250
+
251
+ node.attr("x", function(d) { return d.x; })
252
+ .attr("y", function(d) { return d.y; });
253
+ })
254
+
255
+ var link = svg.selectAll(".link")
256
+ .data(graph.links)
257
+ .enter().append("line")
258
+ .attr("class", "link")
259
+ .style("stroke-width", function(d) { return Math.sqrt(d.value); });
260
+
261
+ var node = svg.selectAll(".node")
262
+ .data(graph.nodes)
263
+ .enter().append("foreignObject").attr('width',xsize).attr('height',ysize).call(force.drag)
264
+ .attr("class", "node")
265
+ .html(function(d) { return mrender(rbbt.plots.tile_obj(d)) });
266
+
267
+ rbbt.log("force:warmup")
268
+ for(i=0; i<100; i++) force.tick()
269
+
270
+ rbbt.log("force:panZoom")
271
+ svgPanZoom(object)
272
+ }
273
+
274
+ rbbt.mrender = function(mobj){
275
+ return render(mobj)
276
+ }