omf_web 1.2.6 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/.travis.yml +13 -0
  2. data/README.md +6 -0
  3. data/example/bridge/README.md +1 -1
  4. data/example/bridge/bridge.yaml +10 -0
  5. data/example/bridge/bridge_viz_server +41 -0
  6. data/example/bridge/data_sources/sensor-sqlite.rb +3 -2
  7. data/example/bridge/htdocs/graph/js/event_table.js +2 -7
  8. data/example/bridge/tabs/overview.yaml +82 -0
  9. data/example/openflow-gec15/dashboard_tab.yaml +1 -0
  10. data/example/simple/simple.yaml +1 -1
  11. data/example/simple/simple_dynamic.yaml +5 -3
  12. data/example/topo_discovery/data_sources/links.csv +3 -0
  13. data/example/topo_discovery/data_sources/links2.csv +21 -0
  14. data/example/topo_discovery/data_sources/node_info.csv +10 -0
  15. data/example/topo_discovery/data_sources/nodes.csv +4 -0
  16. data/example/topo_discovery/data_sources/nodes2.csv +11 -0
  17. data/example/topo_discovery/introduction.md +17 -0
  18. data/example/topo_discovery/topo_discovery_simple.yaml +35 -0
  19. data/example/topo_discovery/topo_discovery_simple2.yaml +32 -0
  20. data/example/topo_discovery/widgets/network.yaml +52 -0
  21. data/example/topo_discovery/widgets/node_info.yaml +23 -0
  22. data/lib/omf-web/content/file_repository.rb +5 -1
  23. data/lib/omf-web/content/git_repository.rb +11 -0
  24. data/lib/omf-web/content/repository.rb +13 -2
  25. data/lib/omf-web/data_source_proxy.rb +22 -10
  26. data/lib/omf-web/theme.rb +11 -4
  27. data/lib/omf-web/theme/abstract_page.rb +5 -0
  28. data/lib/omf-web/thin/server.rb +62 -16
  29. data/lib/omf-web/version.rb +1 -1
  30. data/lib/omf-web/widget/code_widget.rb +24 -23
  31. data/lib/omf-web/widget/data_widget.rb +14 -5
  32. data/lib/omf-web/widget/text/maruku.rb +16 -1
  33. data/lib/omf-web/widget/text/text_widget.rb +1 -1
  34. data/share/htdocs/graph/js/abstract_chart.js +7 -1
  35. data/share/htdocs/graph/js/abstract_multiple_datasource_chart.js +21 -3
  36. data/share/htdocs/graph/js/abstract_nv_chart.js +17 -11
  37. data/share/htdocs/graph/js/abstract_widget.js +44 -14
  38. data/share/htdocs/graph/js/line_chart3.js +5 -9
  39. data/share/htdocs/graph/js/map2.js +122 -79
  40. data/share/htdocs/graph/js/network2.js +205 -36
  41. data/share/htdocs/graph/js/table2.js +7 -11
  42. data/share/htdocs/js/data_source3.js +24 -4
  43. data/share/htdocs/vendor/VERSION_MAP.yaml +1 -1
  44. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/css/font-awesome.css +251 -23
  45. data/share/htdocs/vendor/font-awesome-4.1.0/css/font-awesome.min.css +4 -0
  46. data/share/htdocs/vendor/font-awesome-4.1.0/fonts/FontAwesome.otf +0 -0
  47. data/share/htdocs/vendor/font-awesome-4.1.0/fonts/fontawesome-webfont.eot +0 -0
  48. data/share/htdocs/vendor/font-awesome-4.1.0/fonts/fontawesome-webfont.svg +504 -0
  49. data/share/htdocs/vendor/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf +0 -0
  50. data/share/htdocs/vendor/font-awesome-4.1.0/fonts/fontawesome-webfont.woff +0 -0
  51. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/less/bordered-pulled.less +0 -0
  52. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/less/core.less +0 -0
  53. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/less/fixed-width.less +0 -0
  54. data/share/htdocs/vendor/font-awesome-4.1.0/less/font-awesome.less +17 -0
  55. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/less/icons.less +97 -3
  56. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/less/larger.less +0 -0
  57. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/less/list.less +0 -0
  58. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/less/mixins.less +0 -0
  59. data/share/htdocs/vendor/font-awesome-4.1.0/less/path.less +14 -0
  60. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/less/rotated-flipped.less +0 -0
  61. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/less/spinning.less +8 -6
  62. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/less/stacked.less +0 -0
  63. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/less/variables.less +463 -329
  64. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_bordered-pulled.scss +0 -0
  65. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_core.scss +0 -0
  66. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_fixed-width.scss +0 -0
  67. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_icons.scss +97 -3
  68. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_larger.scss +0 -0
  69. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_list.scss +0 -0
  70. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_mixins.scss +2 -2
  71. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_path.scss +0 -0
  72. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_rotated-flipped.scss +0 -0
  73. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_spinning.scss +8 -6
  74. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_stacked.scss +0 -0
  75. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/_variables.scss +464 -330
  76. data/share/htdocs/vendor/{font-awesome-4.0.3 → font-awesome-4.1.0}/scss/font-awesome.scss +1 -1
  77. data/share/htdocs/vendor/jquery-ui-1.8.23/js/jquery-ui.js +125 -0
  78. data/share/htdocs/vendor/spin/jquery.spin.js +46 -24
  79. data/share/htdocs/vendor/spin/spin.js +20 -17
  80. metadata +277 -237
  81. data/example/bridge/data_sources/test2.oml +0 -1808
  82. data/example/bridge/data_sources/test2.sq3 +0 -0
  83. data/example/bridge/data_sources/test31.sq3 +0 -0
  84. data/example/bridge/viz_server.rb +0 -59
  85. data/share/htdocs/vendor/font-awesome-4.0.3/css/font-awesome.min.css +0 -4
  86. data/share/htdocs/vendor/font-awesome-4.0.3/fonts/FontAwesome.otf +0 -0
  87. data/share/htdocs/vendor/font-awesome-4.0.3/fonts/fontawesome-webfont.eot +0 -0
  88. data/share/htdocs/vendor/font-awesome-4.0.3/fonts/fontawesome-webfont.svg +0 -414
  89. data/share/htdocs/vendor/font-awesome-4.0.3/fonts/fontawesome-webfont.ttf +0 -0
  90. data/share/htdocs/vendor/font-awesome-4.0.3/fonts/fontawesome-webfont.woff +0 -0
  91. data/share/htdocs/vendor/font-awesome-4.0.3/less/font-awesome.less +0 -17
  92. data/share/htdocs/vendor/font-awesome-4.0.3/less/path.less +0 -14
  93. data/share/htdocs/vendor/spin/spin.min.js +0 -1
@@ -27,7 +27,17 @@ define(["graph/abstract_chart"], function (abstract_chart) {
27
27
 
28
28
  defaults: function() {
29
29
  return this.deep_defaults({
30
+ line_mode: 'curved', // 'straight'
30
31
  interaction_mode: 'none', // none, hover, click
32
+ force: {
33
+ // see https://github.com/mbostock/d3/wiki/Force-Layout
34
+ link_distance: null, // 150,
35
+ link_strength: null, // [0, 1] set to 1
36
+ charge: null, // -30 -500,
37
+ charge_distance: null,
38
+ gravity: null, // default: 0.1
39
+ theta: null, // default: 0.8
40
+ }
31
41
  }, network2.__super__.defaults.call(this));
32
42
  },
33
43
 
@@ -37,7 +47,9 @@ define(["graph/abstract_chart"], function (abstract_chart) {
37
47
  this.graph_layer = vis.append("svg:g")
38
48
  .attr("transform", "translate(0, " + ca.h + ")")
39
49
  ;
40
- this.legend_layer = vis.append("svg:g");
50
+ this.link_layer = this.graph_layer.append("svg:g");
51
+ this.node_layer = this.graph_layer.append("svg:g");
52
+ this.legend_layer = this.graph_layer.append("svg:g");
41
53
  },
42
54
 
43
55
  base_css_class: 'oml-network',
@@ -53,23 +65,17 @@ define(["graph/abstract_chart"], function (abstract_chart) {
53
65
  throw "Expected an array";
54
66
  }
55
67
  if (sources.length == 1) {
56
- // Check if the source name is 'default' and we can find
68
+ // Check if we can find
57
69
  // a _links and _nodes source
58
70
  var s = sources[0];
59
- if (s.name == 'default') {
60
- // ok, lets expand it
61
- var ss = s.stream;
62
- if (typeof(ss) != 'object') {
63
- ss = { name: ss };
64
- }
65
- var prefix = ss.name;
66
- var sn = {}; for (var p in ss) { sn[p] = ss[p]; }; sn.name = prefix + '/nodes';
67
- var sl = {}; for (var p in ss) { sl[p] = ss[p]; }; sl.name = prefix + '/links';
68
- sources = [
69
- {name: 'nodes', stream: sn},
70
- {name: 'links', stream: sl},
71
- ];
71
+ var ss = s.stream || s.name;
72
+ if (typeof(ss) != 'object') {
73
+ ss = { name: ss };
72
74
  }
75
+ var prefix = ss.name;
76
+ var sn = {}; for (var p in ss) { sn[p] = ss[p]; }; sn.name = 'nodes'; sn.stream = prefix + '/nodes';
77
+ var sl = {}; for (var p in ss) { sl[p] = ss[p]; }; sl.name = 'links'; sl.stream = prefix + '/links';
78
+ sources = [sn, sl];
73
79
  }
74
80
  if (sources.length != 2) {
75
81
  throw "Expected TWO data source, one for nodes and one for links";
@@ -84,21 +90,81 @@ define(["graph/abstract_chart"], function (abstract_chart) {
84
90
  },
85
91
 
86
92
  process_schema: function() {
87
- this.schema = {
88
- nodes: this.process_single_schema(this.data_source.nodes),
89
- links: this.process_single_schema(this.data_source.links)
90
- };
93
+ var self = this;
94
+ var ds_names = ['nodes', 'links'];
95
+ var outstanding_schemas = ds_names.slice(0); // real copy
96
+
97
+ // CHeck for all the schemas first and when we have them, really
98
+ // process the schemas
99
+ _.each(ds_names, function(name) {
100
+ self.data_source[name].on_schema(function() {
101
+ outstanding_schemas = _.without(outstanding_schemas, name);
102
+ if (_.isEmpty(outstanding_schemas.length)) {
103
+ self._process_schema();
104
+ }
105
+ });
106
+ });
107
+ },
91
108
 
92
- var om = this.opts.mapping;
93
- if (om.links == undefined || om.nodes == undefined) {
94
- throw "Missing mapping instructions in 'options' for either 'links' or 'nodes', or both.";
109
+ _process_schema: function() {
110
+ var self = this;
111
+ var ds_names = ['nodes', 'links'];
112
+ var om = self.opts.mapping;
113
+ if (om == undefined) {
114
+ throw "Missing mapping instructions in 'options'.";
95
115
  }
96
- this.mapping = {
97
- nodes: this.process_single_mapping('nodes', om.nodes, this.decl_properties.nodes),
98
- links: this.process_single_mapping('links', om.links, this.decl_properties.links)
99
- };
116
+ self.mapping = {};
117
+ var schemas = self.schema = {};
118
+
119
+ _.each(ds_names, function(ds_name) {
120
+ schemas[ds_name] = self.process_single_schema(self.data_source[ds_name]);
121
+ });
122
+
123
+ _.each(ds_names, function(ds_name) {
124
+ var mapping = om[ds_name];
125
+ if (mapping == undefined) {
126
+ throw "Missing mapping instructions in 'options' for '" + ds_name + "'.";
127
+ }
128
+ self.mapping[ds_name] = self.process_single_mapping(ds_name, mapping, self.decl_properties[ds_name]);
129
+ });
130
+ self.init_mapping();
100
131
  },
101
132
 
133
+
134
+ // process_schema: function() {
135
+ //
136
+ //
137
+ // var self = this;
138
+ // var schemas = this.schema = {};
139
+ // var mappings = this.mapping = {};
140
+ // var om = this.opts.mapping;
141
+ // // if (om.links == undefined || om.nodes == undefined) {
142
+ // // throw "Missing mapping instructions in 'options' for either 'links' or 'nodes', or both.";
143
+ // // }
144
+ // // links: this.process_single_schema(this.data_source.links)
145
+ // // };
146
+ // // this.data_source.nodes.on_schema(function() {
147
+ // // schemas.nodes = self.process_single_schema(self.data_source.nodes);
148
+ // // mappings.nodes = self.process_single_mapping('nodes', om.nodes, self.decl_properties.nodes);
149
+ // // });
150
+ //
151
+ // _.each(['nodes', 'links'], function(name) {
152
+ // if (om[name] == undefined) {
153
+ // throw "Missing mapping instructions in 'options' for '" + name + "'.";
154
+ // }
155
+ // self.data_source[name].on_schema(function() {
156
+ // schemas[name] = self.process_single_schema(self.data_source[name]);
157
+ // mappings[name] = self.process_single_mapping(name, om[name], self.decl_properties[name]);
158
+ // });
159
+ // });
160
+ //
161
+ //
162
+ // // this.mapping = {
163
+ // // nodes: this.process_single_mapping('nodes', om.nodes, this.decl_properties.nodes),
164
+ // // links: this.process_single_mapping('links', om.links, this.decl_properties.links)
165
+ // // };
166
+ // },
167
+
102
168
  /*
103
169
  * Return schema for +stream+.
104
170
  */
@@ -115,27 +181,122 @@ define(["graph/abstract_chart"], function (abstract_chart) {
115
181
  return ds;
116
182
  },
117
183
 
184
+ // This is called once and just before update()
185
+ init_chart: function() {
186
+ network2.__super__.init_chart.call(this);
187
+
188
+ this.auto_placement = this.mapping.nodes.x == 'auto';
189
+ if (!this.auto_placement) return;
190
+
191
+ var self = this;
192
+ var o = this.opts.force;
193
+ var nmapping = this.mapping.nodes;
194
+ nmapping.x = function(d) {
195
+ return d.__force__.x / self.widget_area.w;
196
+ };
197
+ nmapping.y = function(d) {
198
+ return d.__force__.y / self.widget_area.h;
199
+ };
200
+
201
+ var ca = this.widget_area;
202
+ var force = this.force = d3.layout.force().size([ca.w, ca.h]);
203
+
204
+ if (o.link_distance) force.linkDistance(o.link_distance);
205
+ if (o.link_strength) force.linkStrength(o.link_strength);
206
+ if (o.charge) force.charge(o.charge);
207
+ if (o.charge_distance) force.chargeDistance(o.charge_distance);
208
+ if (o.gravity) force.gravity(o.gravity);
209
+ if (o.theta) force.theta(o.theta);
210
+
211
+ this.force.on('tick', function() {
212
+ var data = self.data;
213
+ self.redraw(data);
214
+ });
215
+ },
216
+
217
+ resize: function() {
218
+ network2.__super__.resize.call(this);
219
+
220
+ if (this.force) {
221
+ var ca = this.widget_area;
222
+ this.force.size([ca.w, ca.h]).start();
223
+ }
224
+ },
225
+
226
+
118
227
  update: function() {
119
228
 
120
229
  var ldata = this.data_source.links.rows();
121
230
  var ndata = this.data_source.nodes.rows();
122
231
 
232
+ if (this.force) {
233
+ // The following sets up data structures to be used by
234
+ // force layout. It also needs node and link arrays but
235
+ // in a different format from how we use it here.
236
+ // To still work with the rest of the library, we are
237
+ // attaching an '__force__' entry to each data element
238
+ // which we then hand over to the force layouter but also
239
+ // can revert to when drawing the graph.
240
+ //
241
+ var nm = this.mapping.nodes;
242
+ var nmap = {};
243
+ var nodes = _.map(ndata, function(d) {
244
+ var f = d.__force__;
245
+ if (!f) {
246
+ var id = nm.key(d);
247
+ f = d.__force__ = {index: id, d: d};
248
+ }
249
+ nmap[f.index] = f;
250
+ return f;
251
+ });
252
+
253
+ var lm = this.mapping.links;
254
+ var links = _.map(ldata, function(d) {
255
+ var f = d.__force__;
256
+ if (!f) {
257
+ var s = lm.from(d);
258
+ var t = lm.to(d);
259
+ var id = nm.key(d);
260
+ f = d.__force__ = {index: id, source: s.__force__, target: t.__force__, d: d};
261
+ }
262
+ return f;
263
+ });
264
+
265
+ // TODO: We need to check if any new data items have been added or old ones
266
+ // removed. So the following may be a bit slow.
267
+ function isDiff(a1, a2) {
268
+ if (a1.length != a2.length) return true;
269
+
270
+ var i1 = _.map(a1, function(d) {return d.index; });
271
+ var i2 = _.map(a2, function(d) {return d.index; });
272
+ var d = _.difference(i1, i2);
273
+ return d.length > 0;
274
+ }
275
+ var force = this.force;
276
+ if (isDiff(force.nodes(), nodes) || isDiff(force.links(), links)) {
277
+ force.nodes(nodes);
278
+ force.links(links);
279
+ force.start();
280
+ }
281
+ }
282
+
123
283
  this.redraw({links: ldata, nodes: ndata});
124
284
  },
125
285
 
126
286
  redraw: function(data) {
127
287
  var self = this;
288
+ self.data = data;
128
289
  var o = this.opts;
129
290
  var mapping = this.mapping; //o.mapping || {};
130
291
  var ca = this.widget_area;
131
292
 
132
293
  var x = function(v) {
133
- var x = v * ca.w + ca.x;
294
+ //var x = v * ca.w + ca.x;
134
295
  var x = v * ca.w;
135
296
  return x;
136
297
  };
137
298
  var y = function(v) {
138
- var y = -1 * (v * ca.h + ca.y);
299
+ //var y = -1 * (v * ca.h + ca.y);
139
300
  var y = -1 * (v * ca.h);
140
301
  return y;
141
302
  };
@@ -145,7 +306,7 @@ define(["graph/abstract_chart"], function (abstract_chart) {
145
306
  var nmapping = mapping.nodes;
146
307
  var iline_f = d3.svg.line().interpolate('basis');
147
308
 
148
- // curved line
309
+ // curved line or straight depending on line_mode
149
310
  var line_f = function(d) {
150
311
  var a = 0.2;
151
312
  var b = 0.3;
@@ -162,6 +323,9 @@ define(["graph/abstract_chart"], function (abstract_chart) {
162
323
  var dx = x3 - x1;
163
324
  var dy = y3 - y1;
164
325
  var l = Math.sqrt(dx * dx + dy * dy);
326
+ if (l == 0 || self.opts.line_mode != 'curved') {
327
+ return iline_f([[x1, y1], [x3, y3]]);
328
+ }
165
329
 
166
330
  var mx = x1 + a * dx;
167
331
  var my = y1 + a * dy;
@@ -172,8 +336,11 @@ define(["graph/abstract_chart"], function (abstract_chart) {
172
336
  };
173
337
 
174
338
  var ldata = data.links;
175
- var link2 = this.graph_layer.selectAll("path.link")
176
- .data(d3.values(ldata));
339
+ var link2 = this.link_layer.selectAll("path.link")
340
+ .data(d3.values(ldata), function(d) {
341
+ var k = lmapping.key(d);
342
+ return lmapping.key(d);
343
+ });
177
344
  link2
178
345
  //.each(position) // update existing markers
179
346
  .style("stroke", lmapping.stroke_color)
@@ -193,8 +360,10 @@ define(["graph/abstract_chart"], function (abstract_chart) {
193
360
  var ndata = data.nodes;
194
361
  // first draw white circle to allow actual node to become transparent
195
362
  // without links showing through
196
- var bg_node = this.graph_layer.selectAll("circle.bg_node")
197
- .data(ndata, function(d) { return nmapping.key(d); })
363
+ var bg_node = this.node_layer.selectAll("circle.bg_node")
364
+ .data(ndata, function(d) {
365
+ return nmapping.key(d);
366
+ })
198
367
  .attr("cx", function(d) { return x(nmapping.x(d)); })
199
368
  .attr("cy", function(d) { return y(nmapping.y(d)); })
200
369
  .attr("r", nmapping.radius)
@@ -217,7 +386,7 @@ define(["graph/abstract_chart"], function (abstract_chart) {
217
386
  .style("stroke-width", nmapping.stroke_width)
218
387
  ;
219
388
  }
220
- var node = this.graph_layer.selectAll("circle.node")
389
+ var node = this.node_layer.selectAll("circle.node")
221
390
  .data(ndata, function(d) {
222
391
  return nmapping.key(d);
223
392
  });
@@ -256,7 +425,7 @@ define(["graph/abstract_chart"], function (abstract_chart) {
256
425
  .style("font-size", nmapping.label_size)
257
426
  .text(function(d) { return nmapping.label_text(d); });
258
427
  }
259
- var label = this.graph_layer.selectAll("text.node_label")
428
+ var label = this.node_layer.selectAll("text.node_label")
260
429
  .data(ndata, function(d) {
261
430
  return nmapping.key(d);
262
431
  });
@@ -442,4 +611,4 @@ define(["graph/abstract_chart"], function (abstract_chart) {
442
611
  tab-width: 2
443
612
  indent-tabs-mode: nil
444
613
  End:
445
- */
614
+ */
@@ -1,15 +1,11 @@
1
1
 
2
- require.config({
3
- shim: {
4
- 'vendor/slickgrid/slick.formatters': ['vendor/slickgrid/slick.core'],
5
- 'vendor/slickgrid/slick.editors': ['vendor/slickgrid/slick.core'],
6
- 'vendor/slickgrid/plugins/slick.rowselectionmodel': ['vendor/slickgrid/slick.core'],
7
- 'vendor/slickgrid/slick.grid': ['vendor/slickgrid/slick.core'],
8
- 'vendor/slickgrid/slick.dataview': ['vendor/slickgrid/slick.core'],
9
- 'vendor/slickgrid/controls/slick.pager': ['vendor/slickgrid/slick.core'],
10
- 'vendor/slickgrid/controls/slick.columnpicker': ['vendor/slickgrid/slick.core']
11
- }
12
- });
2
+ OML.require_dependency('vendor/slickgrid/slick.formatters', ['vendor/slickgrid/slick.core']);
3
+ OML.require_dependency('vendor/slickgrid/slick.editors', ['vendor/slickgrid/slick.core']);
4
+ OML.require_dependency('vendor/slickgrid/plugins/slick.rowselectionmodel', ['vendor/slickgrid/slick.core']);
5
+ OML.require_dependency('vendor/slickgrid/slick.grid', ['vendor/slickgrid/slick.core']);
6
+ OML.require_dependency('vendor/slickgrid/slick.dataview', ['vendor/slickgrid/slick.core']);
7
+ OML.require_dependency('vendor/slickgrid/controls/slick.pager', ['vendor/slickgrid/slick.core']);
8
+ OML.require_dependency('vendor/slickgrid/controls/slick.columnpicker', ['vendor/slickgrid/slick.core']);
13
9
 
14
10
 
15
11
  define(["graph/abstract_widget",
@@ -19,6 +19,24 @@ function omf_web_data_source(opts) {
19
19
  event_name: event_name,
20
20
  };
21
21
 
22
+ var on_schema_callbacks = [];
23
+
24
+ data_source.on_schema = function(callback) {
25
+ if (schema) {
26
+ callback(schema);
27
+ } else {
28
+ // delay
29
+ on_schema_callbacks.push(callback);
30
+ }
31
+ };
32
+
33
+ function set_schema(new_schema) {
34
+ schema = data_source.schema = new_schema;
35
+ _.each(on_schema_callbacks, function(cbk) {
36
+ cbk(new_schema);
37
+ });
38
+ }
39
+
22
40
  var indexes = {};
23
41
  var unique_index_check = null;
24
42
 
@@ -188,7 +206,7 @@ function omf_web_data_source(opts) {
188
206
 
189
207
  if (first_time) {
190
208
  var self = this;
191
- L.require(['vendor/jquery/jquery.js', 'vendor/jquery/jquery.periodicalupdater.js'], function() {
209
+ require(['vendor/jquery/jquery.periodicalupdater.js'], function() {
192
210
  var update_interval = self.update_interval * 1000;
193
211
  if (update_interval < 1000) update_interval = 3000;
194
212
  var opts = {
@@ -213,7 +231,7 @@ function omf_web_data_source(opts) {
213
231
  }
214
232
 
215
233
  function fetch_data(data_url) {
216
- require(['vendor/jquery/jquery'], function() {
234
+ require(['jquery'], function() {
217
235
  $.ajax({
218
236
  url: data_url,
219
237
  dataType: 'json',
@@ -221,9 +239,11 @@ function omf_web_data_source(opts) {
221
239
  type: 'GET'
222
240
  }).done(function(reply) {
223
241
  var data = reply.data;
224
- rows.splice(0, rows.length); // this is an update, not an add
225
- _.each(data, function(r) { rows.push(r); });
242
+ set_schema(reply.schema);
226
243
 
244
+ // need to update 'rows' in place as it's referenced in other closures
245
+ rows.splice(0, rows.length);
246
+ _.each(data, function(r) { rows.push(r); });
227
247
  update_indexes();
228
248
  var evt = {data_source: data_source};
229
249
  OHUB.trigger(event_name, evt);
@@ -12,5 +12,5 @@ stacktrace: stacktrace-0.3
12
12
  underscore: underscore-1.4.4
13
13
  require: require-2.1.8
14
14
  require-css: require-css-0.0.7
15
- font-awesome: font-awesome-4.0.3
15
+ font-awesome: font-awesome-4.1.0
16
16
  smartmenus: smartmenus-0.9.6
@@ -1,13 +1,13 @@
1
1
  /*!
2
- * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome
2
+ * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
3
3
  * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4
4
  */
5
5
  /* FONT PATH
6
6
  * -------------------------- */
7
7
  @font-face {
8
8
  font-family: 'FontAwesome';
9
- src: url('../fonts/fontawesome-webfont.eot?v=4.0.3');
10
- src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.0.3') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.0.3') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg');
9
+ src: url('../fonts/fontawesome-webfont.eot?v=4.1.0');
10
+ src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');
11
11
  font-weight: normal;
12
12
  font-style: normal;
13
13
  }
@@ -22,7 +22,7 @@
22
22
  }
23
23
  /* makes the font 33% larger relative to the icon container */
24
24
  .fa-lg {
25
- font-size: 1.3333333333333333em;
25
+ font-size: 1.33333333em;
26
26
  line-height: 0.75em;
27
27
  vertical-align: -15%;
28
28
  }
@@ -39,12 +39,12 @@
39
39
  font-size: 5em;
40
40
  }
41
41
  .fa-fw {
42
- width: 1.2857142857142858em;
42
+ width: 1.28571429em;
43
43
  text-align: center;
44
44
  }
45
45
  .fa-ul {
46
46
  padding-left: 0;
47
- margin-left: 2.142857142857143em;
47
+ margin-left: 2.14285714em;
48
48
  list-style-type: none;
49
49
  }
50
50
  .fa-ul > li {
@@ -52,13 +52,13 @@
52
52
  }
53
53
  .fa-li {
54
54
  position: absolute;
55
- left: -2.142857142857143em;
56
- width: 2.142857142857143em;
57
- top: 0.14285714285714285em;
55
+ left: -2.14285714em;
56
+ width: 2.14285714em;
57
+ top: 0.14285714em;
58
58
  text-align: center;
59
59
  }
60
60
  .fa-li.fa-lg {
61
- left: -1.8571428571428572em;
61
+ left: -1.85714286em;
62
62
  }
63
63
  .fa-border {
64
64
  padding: .2em .25em .15em;
@@ -107,19 +107,13 @@
107
107
  -o-transform: rotate(359deg);
108
108
  }
109
109
  }
110
- @-ms-keyframes spin {
111
- 0% {
112
- -ms-transform: rotate(0deg);
113
- }
114
- 100% {
115
- -ms-transform: rotate(359deg);
116
- }
117
- }
118
110
  @keyframes spin {
119
111
  0% {
112
+ -webkit-transform: rotate(0deg);
120
113
  transform: rotate(0deg);
121
114
  }
122
115
  100% {
116
+ -webkit-transform: rotate(359deg);
123
117
  transform: rotate(359deg);
124
118
  }
125
119
  }
@@ -369,6 +363,8 @@
369
363
  .fa-video-camera:before {
370
364
  content: "\f03d";
371
365
  }
366
+ .fa-photo:before,
367
+ .fa-image:before,
372
368
  .fa-picture-o:before {
373
369
  content: "\f03e";
374
370
  }
@@ -732,6 +728,8 @@
732
728
  .fa-square:before {
733
729
  content: "\f0c8";
734
730
  }
731
+ .fa-navicon:before,
732
+ .fa-reorder:before,
735
733
  .fa-bars:before {
736
734
  content: "\f0c9";
737
735
  }
@@ -791,11 +789,11 @@
791
789
  content: "\f0dc";
792
790
  }
793
791
  .fa-sort-down:before,
794
- .fa-sort-asc:before {
792
+ .fa-sort-desc:before {
795
793
  content: "\f0dd";
796
794
  }
797
795
  .fa-sort-up:before,
798
- .fa-sort-desc:before {
796
+ .fa-sort-asc:before {
799
797
  content: "\f0de";
800
798
  }
801
799
  .fa-envelope:before {
@@ -985,12 +983,10 @@
985
983
  .fa-code:before {
986
984
  content: "\f121";
987
985
  }
986
+ .fa-mail-reply-all:before,
988
987
  .fa-reply-all:before {
989
988
  content: "\f122";
990
989
  }
991
- .fa-mail-reply-all:before {
992
- content: "\f122";
993
- }
994
990
  .fa-star-half-empty:before,
995
991
  .fa-star-half-full:before,
996
992
  .fa-star-half-o:before {
@@ -1336,3 +1332,235 @@
1336
1332
  .fa-plus-square-o:before {
1337
1333
  content: "\f196";
1338
1334
  }
1335
+ .fa-space-shuttle:before {
1336
+ content: "\f197";
1337
+ }
1338
+ .fa-slack:before {
1339
+ content: "\f198";
1340
+ }
1341
+ .fa-envelope-square:before {
1342
+ content: "\f199";
1343
+ }
1344
+ .fa-wordpress:before {
1345
+ content: "\f19a";
1346
+ }
1347
+ .fa-openid:before {
1348
+ content: "\f19b";
1349
+ }
1350
+ .fa-institution:before,
1351
+ .fa-bank:before,
1352
+ .fa-university:before {
1353
+ content: "\f19c";
1354
+ }
1355
+ .fa-mortar-board:before,
1356
+ .fa-graduation-cap:before {
1357
+ content: "\f19d";
1358
+ }
1359
+ .fa-yahoo:before {
1360
+ content: "\f19e";
1361
+ }
1362
+ .fa-google:before {
1363
+ content: "\f1a0";
1364
+ }
1365
+ .fa-reddit:before {
1366
+ content: "\f1a1";
1367
+ }
1368
+ .fa-reddit-square:before {
1369
+ content: "\f1a2";
1370
+ }
1371
+ .fa-stumbleupon-circle:before {
1372
+ content: "\f1a3";
1373
+ }
1374
+ .fa-stumbleupon:before {
1375
+ content: "\f1a4";
1376
+ }
1377
+ .fa-delicious:before {
1378
+ content: "\f1a5";
1379
+ }
1380
+ .fa-digg:before {
1381
+ content: "\f1a6";
1382
+ }
1383
+ .fa-pied-piper-square:before,
1384
+ .fa-pied-piper:before {
1385
+ content: "\f1a7";
1386
+ }
1387
+ .fa-pied-piper-alt:before {
1388
+ content: "\f1a8";
1389
+ }
1390
+ .fa-drupal:before {
1391
+ content: "\f1a9";
1392
+ }
1393
+ .fa-joomla:before {
1394
+ content: "\f1aa";
1395
+ }
1396
+ .fa-language:before {
1397
+ content: "\f1ab";
1398
+ }
1399
+ .fa-fax:before {
1400
+ content: "\f1ac";
1401
+ }
1402
+ .fa-building:before {
1403
+ content: "\f1ad";
1404
+ }
1405
+ .fa-child:before {
1406
+ content: "\f1ae";
1407
+ }
1408
+ .fa-paw:before {
1409
+ content: "\f1b0";
1410
+ }
1411
+ .fa-spoon:before {
1412
+ content: "\f1b1";
1413
+ }
1414
+ .fa-cube:before {
1415
+ content: "\f1b2";
1416
+ }
1417
+ .fa-cubes:before {
1418
+ content: "\f1b3";
1419
+ }
1420
+ .fa-behance:before {
1421
+ content: "\f1b4";
1422
+ }
1423
+ .fa-behance-square:before {
1424
+ content: "\f1b5";
1425
+ }
1426
+ .fa-steam:before {
1427
+ content: "\f1b6";
1428
+ }
1429
+ .fa-steam-square:before {
1430
+ content: "\f1b7";
1431
+ }
1432
+ .fa-recycle:before {
1433
+ content: "\f1b8";
1434
+ }
1435
+ .fa-automobile:before,
1436
+ .fa-car:before {
1437
+ content: "\f1b9";
1438
+ }
1439
+ .fa-cab:before,
1440
+ .fa-taxi:before {
1441
+ content: "\f1ba";
1442
+ }
1443
+ .fa-tree:before {
1444
+ content: "\f1bb";
1445
+ }
1446
+ .fa-spotify:before {
1447
+ content: "\f1bc";
1448
+ }
1449
+ .fa-deviantart:before {
1450
+ content: "\f1bd";
1451
+ }
1452
+ .fa-soundcloud:before {
1453
+ content: "\f1be";
1454
+ }
1455
+ .fa-database:before {
1456
+ content: "\f1c0";
1457
+ }
1458
+ .fa-file-pdf-o:before {
1459
+ content: "\f1c1";
1460
+ }
1461
+ .fa-file-word-o:before {
1462
+ content: "\f1c2";
1463
+ }
1464
+ .fa-file-excel-o:before {
1465
+ content: "\f1c3";
1466
+ }
1467
+ .fa-file-powerpoint-o:before {
1468
+ content: "\f1c4";
1469
+ }
1470
+ .fa-file-photo-o:before,
1471
+ .fa-file-picture-o:before,
1472
+ .fa-file-image-o:before {
1473
+ content: "\f1c5";
1474
+ }
1475
+ .fa-file-zip-o:before,
1476
+ .fa-file-archive-o:before {
1477
+ content: "\f1c6";
1478
+ }
1479
+ .fa-file-sound-o:before,
1480
+ .fa-file-audio-o:before {
1481
+ content: "\f1c7";
1482
+ }
1483
+ .fa-file-movie-o:before,
1484
+ .fa-file-video-o:before {
1485
+ content: "\f1c8";
1486
+ }
1487
+ .fa-file-code-o:before {
1488
+ content: "\f1c9";
1489
+ }
1490
+ .fa-vine:before {
1491
+ content: "\f1ca";
1492
+ }
1493
+ .fa-codepen:before {
1494
+ content: "\f1cb";
1495
+ }
1496
+ .fa-jsfiddle:before {
1497
+ content: "\f1cc";
1498
+ }
1499
+ .fa-life-bouy:before,
1500
+ .fa-life-saver:before,
1501
+ .fa-support:before,
1502
+ .fa-life-ring:before {
1503
+ content: "\f1cd";
1504
+ }
1505
+ .fa-circle-o-notch:before {
1506
+ content: "\f1ce";
1507
+ }
1508
+ .fa-ra:before,
1509
+ .fa-rebel:before {
1510
+ content: "\f1d0";
1511
+ }
1512
+ .fa-ge:before,
1513
+ .fa-empire:before {
1514
+ content: "\f1d1";
1515
+ }
1516
+ .fa-git-square:before {
1517
+ content: "\f1d2";
1518
+ }
1519
+ .fa-git:before {
1520
+ content: "\f1d3";
1521
+ }
1522
+ .fa-hacker-news:before {
1523
+ content: "\f1d4";
1524
+ }
1525
+ .fa-tencent-weibo:before {
1526
+ content: "\f1d5";
1527
+ }
1528
+ .fa-qq:before {
1529
+ content: "\f1d6";
1530
+ }
1531
+ .fa-wechat:before,
1532
+ .fa-weixin:before {
1533
+ content: "\f1d7";
1534
+ }
1535
+ .fa-send:before,
1536
+ .fa-paper-plane:before {
1537
+ content: "\f1d8";
1538
+ }
1539
+ .fa-send-o:before,
1540
+ .fa-paper-plane-o:before {
1541
+ content: "\f1d9";
1542
+ }
1543
+ .fa-history:before {
1544
+ content: "\f1da";
1545
+ }
1546
+ .fa-circle-thin:before {
1547
+ content: "\f1db";
1548
+ }
1549
+ .fa-header:before {
1550
+ content: "\f1dc";
1551
+ }
1552
+ .fa-paragraph:before {
1553
+ content: "\f1dd";
1554
+ }
1555
+ .fa-sliders:before {
1556
+ content: "\f1de";
1557
+ }
1558
+ .fa-share-alt:before {
1559
+ content: "\f1e0";
1560
+ }
1561
+ .fa-share-alt-square:before {
1562
+ content: "\f1e1";
1563
+ }
1564
+ .fa-bomb:before {
1565
+ content: "\f1e2";
1566
+ }