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.
- checksums.yaml +4 -4
- data/lib/rbbt/rest/entity.rb +71 -1
- data/lib/rbbt/rest/entity/render.rb +3 -2
- data/lib/rbbt/rest/knowledge_base.rb +81 -28
- data/lib/rbbt/rest/main.rb +3 -0
- data/lib/rbbt/rest/workflow.rb +1 -1
- data/lib/rbbt/rest/workflow/jobs.rb +5 -4
- data/share/views/compass/app.sass +21 -11
- data/share/views/layout/footer.haml +0 -1
- data/share/views/layout/header.haml +9 -6
- data/share/views/layout/top_menu.haml +1 -0
- data/share/views/partials/table.haml +7 -1
- data/share/views/public/js/_ajax_replace.js +2 -0
- data/share/views/public/js/defer.js +1 -1
- data/share/views/public/js/helpers.js +89 -18
- data/share/views/public/js/rbbt.aesthetics.js +145 -34
- data/share/views/public/js/rbbt.basic.js +20 -0
- data/share/views/public/js/rbbt.entity.js +12 -2
- data/share/views/public/js/rbbt.entity_list.js +51 -5
- data/share/views/public/js/rbbt.exception.js +9 -1
- data/share/views/public/js/rbbt.job.js +2 -2
- data/share/views/public/js/rbbt.js +5 -1
- data/share/views/public/js/rbbt.knowledge_base.js +40 -0
- data/share/views/public/js/rbbt.modal.js +82 -75
- data/share/views/public/js/rbbt.plots.js +276 -0
- data/share/views/public/js/rbbt/list.js +2 -2
- data/share/views/public/plugins/cola/js/cola.v3.min.js +3 -0
- data/share/views/public/plugins/d3js/js/d3.js +9503 -0
- data/share/views/public/plugins/d3js/js/d3js.min.js +5 -0
- data/share/views/public/plugins/mithril-node-render/js/index.js +115 -0
- data/share/views/public/plugins/mithril/js/mithril.js +212 -77
- data/share/views/public/plugins/mithril/js/mithril.min.js +2 -2
- data/share/views/public/plugins/mithril/js/mithril.min.js.map +1 -1
- data/share/views/public/plugins/nvd3/css/nv.d3.css +641 -0
- data/share/views/public/plugins/nvd3/js/nv.d3.js +13298 -0
- data/share/views/public/plugins/svg-pan-zoom/js/svg-pan-zoom.js +1861 -0
- data/share/views/tools/nvd3.haml +16 -0
- data/share/views/tools/nvd3/chart.haml +55 -0
- data/share/views/tools/nvd3/histogram.haml +19 -0
- data/share/views/tools/nvd3/pie.haml +24 -0
- data/share/views/tools/nvd3/scatter.haml +33 -0
- data/share/views/wait.haml +2 -2
- metadata +15 -3
- 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
|
-
|
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
|
-
|
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
|
-
|
31
|
-
|
32
|
-
$(rbbt.modal.element).addClass('active')
|
33
|
-
m.redraw()
|
34
|
-
update_rbbt()
|
35
|
-
}
|
3
|
+
ModalComponent = function(element){
|
4
|
+
var component = {}
|
36
5
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
78
|
-
|
79
|
-
|
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
|
-
|
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 (
|
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
|
+
}
|