omf_web 0.9.1 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. data/.gitignore +0 -1
  2. data/README.md +8 -2
  3. data/doc/screenshot.png +0 -0
  4. data/example/{basic → NOT_WORKING/basic}/hello-world-wired.rb +0 -0
  5. data/example/{basic → NOT_WORKING/basic}/visualisation.yml +0 -0
  6. data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklynDemo.sq3 +0 -0
  7. data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklyn_gps.dat +0 -0
  8. data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklyn_server.rb +0 -0
  9. data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklyn_wimax.dat +0 -0
  10. data/example/{brooklyn → NOT_WORKING/brooklyn}/sql_source.rb +0 -0
  11. data/example/{code → NOT_WORKING/code}/code_server.rb +0 -0
  12. data/example/{frisbee → NOT_WORKING/frisbee}/data_sources/parse_log.rb +0 -0
  13. data/example/{frisbee → NOT_WORKING/frisbee}/data_sources/pxe_slice-2012-06-02t02.25.00-04.00.log +0 -0
  14. data/example/{frisbee → NOT_WORKING/frisbee}/progress_chart.yaml +0 -0
  15. data/example/{frisbee → NOT_WORKING/frisbee}/progress_tab.yaml +0 -0
  16. data/example/{frisbee → NOT_WORKING/frisbee}/progress_table.yaml +0 -0
  17. data/example/{frisbee → NOT_WORKING/frisbee}/viz_server.rb +0 -0
  18. data/example/{gec12 → NOT_WORKING/gec12}/gec12-53.rb +0 -0
  19. data/example/{gec12 → NOT_WORKING/gec12}/gec12_demo.sq3 +0 -0
  20. data/example/{gec12 → NOT_WORKING/gec12}/gec12_demo_server.rb +0 -0
  21. data/example/{gec12 → NOT_WORKING/gec12}/visualization.rb +0 -0
  22. data/example/{incoming → NOT_WORKING/incoming}/ofpu_barchart_widget.yaml +0 -0
  23. data/example/{log → NOT_WORKING/log}/log_config.xml +0 -0
  24. data/example/{log → NOT_WORKING/log}/log_server.rb +0 -0
  25. data/example/{network → NOT_WORKING/network}/flow_tab.yaml +0 -0
  26. data/example/{network → NOT_WORKING/network}/network_server.rb +0 -0
  27. data/example/{text → NOT_WORKING/text}/test.md +0 -0
  28. data/example/{text → NOT_WORKING/text}/test.rb +0 -0
  29. data/example/{wimax → NOT_WORKING/wimax}/downlink.yaml +0 -0
  30. data/example/{wimax → NOT_WORKING/wimax}/power.yaml +0 -0
  31. data/example/{wimax → NOT_WORKING/wimax}/snapshot.db +0 -0
  32. data/example/{wimax → NOT_WORKING/wimax}/snapshot.sql +0 -0
  33. data/example/{wimax → NOT_WORKING/wimax}/test.rb +0 -0
  34. data/example/{wimax → NOT_WORKING/wimax}/uplink.yaml +0 -0
  35. data/example/{wimax → NOT_WORKING/wimax}/viz_server.rb +0 -0
  36. data/example/demo/data_sources/mobile_network.rb +3 -0
  37. data/example/demo/data_sources/static_network.rb +54 -0
  38. data/example/demo/widgets/charts_tab.yaml +21 -16
  39. data/example/demo/widgets/linked_graphs_tab.yaml +95 -0
  40. data/example/demo/widgets/mobile_network_widget.yaml +1 -1
  41. data/example/demo/widgets/pie_chart_widget.yaml +1 -1
  42. data/lib/omf-web/config.ru +2 -2
  43. data/lib/omf-web/data_source_proxy.rb +81 -19
  44. data/lib/omf-web/rack/websocket_handler.rb +77 -23
  45. data/lib/omf-web/theme/abstract_page.rb +43 -26
  46. data/lib/omf-web/theme/bright/code_renderer.rb +1 -1
  47. data/lib/omf-web/theme/bright/page.rb +1 -0
  48. data/lib/omf-web/theme/bright/tabbed_renderer.rb +7 -0
  49. data/lib/omf-web/version.rb +7 -0
  50. data/lib/omf-web/widget/data_widget.rb +38 -46
  51. data/lib/omf-web/widget/layout/stacked_layout.rb +2 -1
  52. data/lib/omf-web/widget/layout/tabbed_layout.rb +1 -2
  53. data/{MARUKU-LICENSE → lib/omf-web/widget/text/maruku/MARUKU-LICENSE} +0 -0
  54. data/lib/{maruku → omf-web/widget/text/maruku}/helpers.rb +0 -0
  55. data/lib/{maruku → omf-web/widget/text/maruku}/input/parse_block.rb +0 -0
  56. data/lib/{maruku → omf-web/widget/text/maruku}/output/to_html.rb +26 -21
  57. data/lib/omf-web/widget/text/maruku.rb +5 -0
  58. data/omf_web.gemspec +2 -1
  59. data/share/htdocs/{js → UNUSED}/log/table.js +0 -0
  60. data/share/htdocs/{css → graph/css}/graph.css +0 -0
  61. data/share/htdocs/{image/graph → graph/img}/bar_chart.png +0 -0
  62. data/share/htdocs/{image/graph → graph/img}/donut_chart.png +0 -0
  63. data/share/htdocs/{image/graph → graph/img}/funnel.png +0 -0
  64. data/share/htdocs/{image/graph → graph/img}/info.png +0 -0
  65. data/share/htdocs/{image/graph → graph/img}/line_chart.png +0 -0
  66. data/share/htdocs/{image/graph → graph/img}/line_chart_fill.png +0 -0
  67. data/share/htdocs/{image/graph → graph/img}/misc.png +0 -0
  68. data/share/htdocs/{image/graph → graph/img}/overview.png +0 -0
  69. data/share/htdocs/{image/graph → graph/img}/pie_chart.png +0 -0
  70. data/share/htdocs/{image/graph → graph/img}/scatter_plot.png +0 -0
  71. data/share/htdocs/{image/graph → graph/img}/stacked_bar_chart.png +0 -0
  72. data/share/htdocs/{image/graph → graph/img}/stacked_line_chart.png +0 -0
  73. data/share/htdocs/{image/graph → graph/img}/table.png +0 -0
  74. data/share/htdocs/{js/graph → graph/js}/abstract_chart.js +1 -1
  75. data/share/htdocs/{js/graph → graph/js}/abstract_nv_chart.js +8 -13
  76. data/share/htdocs/{js/graph → graph/js}/abstract_widget.js +9 -16
  77. data/share/htdocs/{js/graph → graph/js}/axis.js +1 -1
  78. data/share/htdocs/{js/graph → graph/js}/barchart.js +2 -2
  79. data/share/htdocs/{js/graph → graph/js}/code_mirror.js +1 -5
  80. data/share/htdocs/{js/graph → graph/js}/discrete_bar_chart.js +1 -1
  81. data/share/htdocs/{js/graph → graph/js}/histogram2.js +1 -1
  82. data/share/htdocs/{js/graph → graph/js}/holt_winters_chart.js +1 -1
  83. data/share/htdocs/{js/graph → graph/js}/line_chart3.js +1 -1
  84. data/share/htdocs/{js/graph → graph/js}/line_chart_with_focus.js +1 -1
  85. data/share/htdocs/{js/graph → graph/js}/map2.js +1 -1
  86. data/share/htdocs/{js/graph → graph/js}/multi_barchart.js +1 -1
  87. data/share/htdocs/graph/js/network2.js +412 -0
  88. data/share/htdocs/{js/graph → graph/js}/pie_chart2.js +1 -1
  89. data/share/htdocs/{js/graph → graph/js}/scatter_plot.js +1 -1
  90. data/share/htdocs/{js/graph → graph/js}/table2.js +17 -20
  91. data/share/htdocs/js/data_source2.js +187 -60
  92. data/share/htdocs/js/require3.js +38 -57
  93. data/share/htdocs/theme/bright/css/bright.css +4 -4
  94. data/share/htdocs/vendor/jquery/jquery.js +9404 -0
  95. data/share/htdocs/vendor/osa/LICENSE.txt +11 -0
  96. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_arrow_green_left.svg +0 -0
  97. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_arrow_yellow_right.svg +0 -0
  98. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_awareness.svg +0 -0
  99. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_camera-web.svg +0 -0
  100. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_cloud.svg +0 -0
  101. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_contract.svg +0 -0
  102. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_database.svg +0 -0
  103. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_desktop.svg +0 -0
  104. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_desktop_imac.svg +0 -0
  105. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-music.svg +0 -0
  106. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-scanner.svg +0 -0
  107. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-usb-wifi.svg +0 -0
  108. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-usb.svg +0 -0
  109. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-wireless-router.svg +0 -0
  110. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_disposal.svg +0 -0
  111. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_drive-harddisk.svg +0 -0
  112. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_drive-optical.svg +0 -0
  113. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_firewall.svg +0 -0
  114. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_home.svg +0 -0
  115. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_hub.svg +0 -0
  116. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_iPhone.svg +0 -0
  117. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_ics_drive.svg +0 -0
  118. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_ics_plc.svg +0 -0
  119. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_ics_thermometer.svg +0 -0
  120. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_id_card.svg +0 -0
  121. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_image-generic.svg +0 -0
  122. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_laptop.svg +0 -0
  123. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_lifecycle.svg +0 -0
  124. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_lightning.svg +0 -0
  125. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_media-flash.svg +0 -0
  126. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_media-optical.svg +0 -0
  127. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_media-tape.svg +0 -0
  128. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_mobile_pda.svg +0 -0
  129. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_padlock.svg +0 -0
  130. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_printer.svg +0 -0
  131. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server.svg +0 -0
  132. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_application.svg +0 -0
  133. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_database.svg +0 -0
  134. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_directory.svg +0 -0
  135. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_distribution.svg +0 -0
  136. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_file.svg +0 -0
  137. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_gateway.svg +0 -0
  138. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_identity.svg +0 -0
  139. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_mail.svg +0 -0
  140. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_media.svg +0 -0
  141. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_monitor.svg +0 -0
  142. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_proxy.svg +0 -0
  143. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_terminal.svg +0 -0
  144. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_web.svg +0 -0
  145. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-branch.svg +0 -0
  146. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-factory.svg +0 -0
  147. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-head-office.svg +0 -0
  148. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-neighbourhood.svg +0 -0
  149. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_audit.svg +0 -0
  150. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_black_hat.svg +0 -0
  151. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue.svg +0 -0
  152. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_security_specialist.svg +0 -0
  153. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_sysadmin.svg +0 -0
  154. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_tester.svg +0 -0
  155. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_tie.svg +0 -0
  156. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green.svg +0 -0
  157. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_architect.svg +0 -0
  158. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_business_manager.svg +0 -0
  159. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_developer.svg +0 -0
  160. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_operations.svg +0 -0
  161. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_project_manager.svg +0 -0
  162. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_service_manager.svg +0 -0
  163. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_warning.svg +0 -0
  164. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_large_group.svg +0 -0
  165. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_users_blue_green.svg +0 -0
  166. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_vpn.svg +0 -0
  167. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_warning.svg +0 -0
  168. data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_wireless_network.svg +0 -0
  169. data/share/htdocs/{image → vendor/unknown/image}/.DS_Store +0 -0
  170. data/share/htdocs/{image → vendor/unknown/image}/add_icon.gif +0 -0
  171. data/share/htdocs/{image → vendor/unknown/image}/alertbad_icon.gif +0 -0
  172. data/share/htdocs/{image → vendor/unknown/image}/alertgood_icon.gif +0 -0
  173. data/share/htdocs/{image → vendor/unknown/image}/back_disabled.jpg +0 -0
  174. data/share/htdocs/{image → vendor/unknown/image}/back_disabled.png +0 -0
  175. data/share/htdocs/{image → vendor/unknown/image}/back_enabled.jpg +0 -0
  176. data/share/htdocs/{image → vendor/unknown/image}/back_enabled.png +0 -0
  177. data/share/htdocs/{image → vendor/unknown/image}/back_enabled_hover.jpg +0 -0
  178. data/share/htdocs/{image → vendor/unknown/image}/back_enabled_hover.png +0 -0
  179. data/share/htdocs/{image → vendor/unknown/image}/bottom-bg.gif +0 -0
  180. data/share/htdocs/{image → vendor/unknown/image}/forward_disabled.jpg +0 -0
  181. data/share/htdocs/{image → vendor/unknown/image}/forward_disabled.png +0 -0
  182. data/share/htdocs/{image → vendor/unknown/image}/forward_enabled.jpg +0 -0
  183. data/share/htdocs/{image → vendor/unknown/image}/forward_enabled.png +0 -0
  184. data/share/htdocs/{image → vendor/unknown/image}/forward_enabled_hover.jpg +0 -0
  185. data/share/htdocs/{image → vendor/unknown/image}/forward_enabled_hover.png +0 -0
  186. data/share/htdocs/{image → vendor/unknown/image}/icon-remove.gif +0 -0
  187. data/share/htdocs/{image → vendor/unknown/image}/indicator.gif +0 -0
  188. data/share/htdocs/{image → vendor/unknown/image}/laptop.png +0 -0
  189. data/share/htdocs/{image → vendor/unknown/image}/logo-bottom.gif +0 -0
  190. data/share/htdocs/{image → vendor/unknown/image}/nav-tab-arrow.gif +0 -0
  191. data/share/htdocs/{image → vendor/unknown/image}/norbit_big.gif +0 -0
  192. data/share/htdocs/{image → vendor/unknown/image}/norbit_clipart.png +0 -0
  193. data/share/htdocs/{image → vendor/unknown/image}/progress_bar.gif +0 -0
  194. data/share/htdocs/{image → vendor/unknown/image}/right-bg.gif +0 -0
  195. data/share/htdocs/{image → vendor/unknown/image}/sort_asc.png +0 -0
  196. data/share/htdocs/{image → vendor/unknown/image}/sort_asc_disabled.png +0 -0
  197. data/share/htdocs/{image → vendor/unknown/image}/sort_both.png +0 -0
  198. data/share/htdocs/{image → vendor/unknown/image}/sort_desc.png +0 -0
  199. data/share/htdocs/{image → vendor/unknown/image}/sort_desc_disabled.png +0 -0
  200. data/share/htdocs/{image → vendor/unknown/image}/spinner.gif +0 -0
  201. data/share/htdocs/{svg → vendor/unknown/svg}/ap.svg +0 -0
  202. data/share/htdocs/{svg → vendor/unknown/svg}/router.svg +0 -0
  203. metadata +198 -216
  204. data/example/demo/widgets/dashboard_tab.yaml +0 -28
  205. data/example/demo/widgets/download_tab.yaml +0 -42
  206. data/example/demo/widgets/edit_tab.yaml +0 -20
  207. data/example/demo/widgets/generator_tab.yaml +0 -12
  208. data/lib/omf-oml/endpoint.rb +0 -175
  209. data/lib/omf-oml/indexed_table.rb +0 -57
  210. data/lib/omf-oml/network.rb +0 -413
  211. data/lib/omf-oml/oml_tuple.rb +0 -62
  212. data/lib/omf-oml/schema.rb +0 -191
  213. data/lib/omf-oml/sequel/sequel_server.rb +0 -412
  214. data/lib/omf-oml/sql_row.rb +0 -302
  215. data/lib/omf-oml/sql_source.rb +0 -131
  216. data/lib/omf-oml/table.rb +0 -131
  217. data/lib/omf-oml/tuple.rb +0 -97
  218. data/lib/omf_oml.rb +0 -4
  219. data/share/htdocs/css/coderay.css +0 -127
  220. data/share/htdocs/css/ie.css +0 -40
  221. data/share/htdocs/css/lightbox.css +0 -62
  222. data/share/htdocs/css/scaffold.css +0 -74
  223. data/share/htdocs/css/screen.css +0 -1313
  224. data/share/htdocs/css/search.css +0 -102
  225. data/share/htdocs/css/table.css +0 -538
  226. data/share/htdocs/css/table2.css +0 -191
  227. data/share/htdocs/css/welcome.css +0 -103
  228. data/share/htdocs/css/wfob.css +0 -171
  229. data/share/htdocs/css/wshow.css +0 -69
  230. data/share/htdocs/gec9_demo.html +0 -39
  231. data/share/htdocs/images +0 -1
  232. data/share/htdocs/js/graph/histogram.js +0 -229
  233. data/share/htdocs/js/graph/line_chart.js +0 -342
  234. data/share/htdocs/js/graph/line_chart2.js +0 -232
  235. data/share/htdocs/js/graph/line_chart_fc.js +0 -94
  236. data/share/htdocs/js/graph/map.js +0 -85
  237. data/share/htdocs/js/graph/network.js +0 -591
  238. data/share/htdocs/js/graph/network2.js +0 -318
  239. data/share/htdocs/js/graph/pie_chart.js +0 -130
  240. data/share/htdocs/js/graph/table.js +0 -94
  241. data/share/htdocs/js/require2.js +0 -1998
  242. data/share/htdocs/js/timelines.js +0 -101
  243. data/share/htdocs/stylesheet/grid.css +0 -31
@@ -5,8 +5,8 @@ OML.data_sources = function() {
5
5
 
6
6
  function context() {};
7
7
 
8
- context.register = function(name, updateURL, schema, events) {
9
- sources[name] = new OML.data_source(name, updateURL, schema, events);
8
+ context.register = function(opts) {
9
+ sources[opts.id || opts.name] = new OML.data_source(opts);
10
10
  return context;
11
11
  };
12
12
 
@@ -15,14 +15,14 @@ OML.data_sources = function() {
15
15
  var dynamic = false;
16
16
 
17
17
  if (typeof(ds_descr) == 'object') {
18
- name = ds_descr.name;
18
+ name = ds_descr.id || ds_descr.name;
19
19
  dynamic = ds_descr.dynamic;
20
20
  } else {
21
21
  name = ds_descr;
22
22
  }
23
23
  var source = sources[name];
24
24
  if (! source) {
25
- raise("Unknown data source '" + name + "'.");
25
+ throw("Unknown data source '" + name + "'.");
26
26
  }
27
27
  if (dynamic) {
28
28
  source.is_dynamic(dynamic);
@@ -33,48 +33,51 @@ OML.data_sources = function() {
33
33
  return context;
34
34
  }();
35
35
 
36
- OML.data_source = function(name, updateURL, schema, events) {
37
- var event_name = "data_source." + this.name + ".changed";
38
- var indexes = [];
39
- var update_interval = -1;
40
- var ws = null; // points to web socket instance
36
+ OML.data_source = function(opts) {
41
37
 
42
- function ds() {};
43
- ds.version = "0.1";
38
+ var name = opts.id || opts.name;
39
+ var event_name = "data_source." + name + ".changed";
40
+ var rows = opts.rows || [];
41
+ var offset = opts.offset || -1; // Number of (initial) rows skipped (count towards 'max_rows')
42
+ var schema = opts.schema;
44
43
 
45
- this.create_index = function(index) {
46
- var idx = this.indexes[index];
47
- if (idx) return;
48
-
49
- this._create_index(index);
50
- };
51
-
52
- ds.create_index = function(index) {
53
- var idx = indexes[index] = {};
54
- // index ignores rows with identical index
55
- _.map(events, function(r) {
56
- idx[r[index]] = r;
57
- });
58
- };
44
+ var data_source = {
45
+ version: "0.1",
46
+ name: name,
47
+ schema: schema,
48
+ rows: function() {return rows},
49
+ index_for_column: index_for_column,
50
+ is_dynamic: is_dynamic,
51
+ event_name: event_name,
52
+ }
53
+
54
+ var indexes = {};
55
+ var unique_index_check = null;
59
56
 
60
- ds.get_indexed_row = function(index, key) {
61
- var idx = indexes[index];
62
- if (idx == undefined) {
63
- throw "Need to create index first";
57
+ var update_interval = -1;
58
+ var ws = null; // points to web socket instance
59
+
60
+ function index_for_column(col_descr) {
61
+ var i = col_descr.index;
62
+ var index = indexes[i];
63
+ if (!index) {
64
+ index = indexes[i] = {};
65
+ _.each(rows, function(r) { index[r[i]] = r; })
66
+ }
67
+ return function(key) {
68
+ return indexes[i][key]; // need fresh lookup as we may redo index
64
69
  }
65
- return idx[key];
66
70
  }
67
71
 
68
- ds.update_indexes = function() {
69
- var self = this;
70
- _.each(indexes, function(value, key) {
71
- var i = 0;
72
- self._create_index(key);
72
+ function update_indexes() {
73
+ // This can most likley be done more efficiently if we consider what has changed
74
+ _.each(indexes, function(ignore, i) {
75
+ var index = indexes[i] = {};
76
+ _.each(rows, function(r) { index[r[i]] = r; })
73
77
  });
74
-
75
78
  }
76
-
77
- ds.is_dynamic = function(_) {
79
+
80
+ function is_dynamic(_) {
78
81
  if (!arguments.length) {
79
82
  return update_interval > 0 || ws;
80
83
  }
@@ -88,29 +91,22 @@ OML.data_source = function(name, updateURL, schema, events) {
88
91
  }
89
92
  if (interval < 0) return false;
90
93
 
91
- //if (window.WebSocket) {
92
- if (false) { // web sockets don't work right now
93
- _start_web_socket();
94
+ if (window.WebSocket) {
95
+ //if (false) { // web sockets don't work right now
96
+ //start_web_socket();
94
97
  } else {
95
- _start_polling_backend();
98
+ start_polling_backend();
96
99
  }
97
100
  }
98
101
 
99
- ds._start_web_socket = function() {
102
+ var ws = null; // Websocket identifier
103
+ function start_web_socket() {
100
104
  if (ws) return; // already running
101
105
 
102
- var url = 'ws://' + window.location.host + '/_ws';
103
- var ws = new WebSocket(url);
104
- var self = this;
105
- ws.onopen = function() {
106
- ws.send('id:' + name);
107
- };
108
- ws.onmessage = function(evt) {
109
- // evt.data contains received string.
110
- var msg = jQuery.parseJSON(evt.data);
111
- var data = msg;
112
- self.events.append(data);
113
- };
106
+ var url = 'ws://' + window.location.host + '/_ws?sid=' + opts.sid;
107
+ ws = new WebSocket(url);
108
+ ws.onopen = on_open;
109
+ ws.onmessage = on_message;
114
110
  ws.onclose = function() {
115
111
  var status = "onclose";
116
112
  };
@@ -118,8 +114,81 @@ OML.data_source = function(name, updateURL, schema, events) {
118
114
  var status = "onerror";
119
115
  };
120
116
  }
117
+
118
+ // Send a message to the server
119
+ //
120
+ // @params type - Type of message
121
+ // @params args - Hash of additional args ('ds_name' of this data source will be added)
122
+ //
123
+ // TODO: Would need to cache messages if connection isn't established yet
124
+ //
125
+ function send_server_msg(type, args) {
126
+ args.ds_name = name;
127
+ msg = {type: type, args: args}
128
+ ws.send(JSON.stringify(msg));
129
+ }
130
+
131
+
132
+ function on_open() {
133
+ if (!active_slice_col_name) {
134
+ send_server_msg('register_data_source', {offset: offset + rows.length})
135
+ }
136
+ };
137
+
138
+ function on_message(evt) {
139
+ // evt.data contains received string.
140
+ var msg = jQuery.parseJSON(evt.data);
141
+ switch(msg.type) {
142
+ case 'datasource_update':
143
+ on_update(msg);
144
+ break;
145
+ case 'reply':
146
+ // great
147
+ break;
148
+ default:
149
+ throw "Unknown message type '" + msg.type + "'.";
150
+ }
151
+ };
152
+
153
+ function on_update(msg) {
154
+ if (unique_index_check) {
155
+ // Let's first see if we simply replace a row
156
+ _.each(msg.rows, function(r) {
157
+ if (!unique_index_check(r)) {
158
+ rows.push(r); // new index
159
+ }
160
+ });
161
+ } else {
162
+ // need to append to 'rows' as it's referenced in other closures
163
+ _.each(msg.rows, function(r) { rows.push(r) });
164
+ var chop = msg.offset - offset;
165
+ if (offset >= 0 && chop > 0) {
166
+ rows = _.rest(rows, chop);
167
+ }
168
+ }
169
+ offset = msg.offset;
170
+
171
+ update_indexes();
172
+ var evt = {data_source: data_source};
173
+ OHUB.trigger(event_name, evt);
174
+ OHUB.trigger("data_source.changed", evt);
175
+ }
176
+
177
+ // Request a new slice from the server. Clear existing state
178
+ function set_slice_column(col_value) {
179
+ if (active_slice_value == col_value) return;
180
+
181
+ active_slice_column_id = col_value;
182
+ // Reset state
183
+ rows = [];
184
+ update_indexes();
185
+ sm = {col_name: active_slice_col_name, col_value: col_value}
186
+ send_server_msg('request_slice', {slice: sm})
187
+ }
188
+ var active_slice_col_name = null;
189
+ var active_slice_value = null;
121
190
 
122
- ds._start_polling_backend = function() {
191
+ function start_polling_backend() {
123
192
  var first_time = this.update_interval < 0;
124
193
 
125
194
  if (this.update_interval < 0 || this.update_interval > interval) {
@@ -128,7 +197,7 @@ OML.data_source = function(name, updateURL, schema, events) {
128
197
 
129
198
  if (first_time) {
130
199
  var self = this;
131
- L.require(['/resource/vendor/jquery/jquery.js', '/resource/vendor/jquery/jquery.periodicalupdater.js'], function() {
200
+ L.require(['vendor/jquery/jquery.js', 'vendor/jquery/jquery.periodicalupdater.js'], function() {
132
201
  var update_interval = self.update_interval * 1000;
133
202
  if (update_interval < 1000) update_interval = 3000;
134
203
  var opts = {
@@ -152,10 +221,68 @@ OML.data_source = function(name, updateURL, schema, events) {
152
221
  return true;
153
222
  }
154
223
 
155
- this.on_changed = function(update_f) {
156
- OHUB.bind(this.event_name, update_f);
224
+ // Let's check if this data_source maintains uniqueness along one axis (column)
225
+ if (opts.unique_column) {
226
+ var col_name = opts.unique_column;
227
+ var index = -1;
228
+ _.find(schema, function(cd) {
229
+ index += 1;
230
+ return cd.name == col_name;
231
+ });
232
+ if (index >= 0) {
233
+ var key2row = {};
234
+ unique_index_check = function (row) {
235
+ var key = row[index];
236
+ var existing_row = key2row[key];
237
+ if (existing_row) {
238
+ // replace content of existing row with 'row'
239
+ // Need to replace in place, there may be a better way
240
+ existing_row.length = 0;
241
+ _.each(row, function(e) { existing_row.push(e); })
242
+ return true;
243
+ }
244
+ key2row[key] = row;
245
+ return false;
246
+ }
247
+ // pre-seed
248
+ rows = _.uniq(rows, false, function(r) { return r[index]; });
249
+ _.each(rows, function(r) { key2row[r[index]] = r; });
250
+ } else {
251
+ throw "Error in processing option 'unique_column'. Unknown column '" + col_name + "'."
252
+ }
157
253
  }
158
254
 
159
- return ds;
255
+ // In slice mode, only fetch a 'slice' of the underlying data source. A slice
256
+ // is defined by specific value in the 'slice_column' of all rows.
257
+ //
258
+ // opts.slice:
259
+ // slice_column: id
260
+ // event:
261
+ // name: graph.static_network.links.changed
262
+ // key: id
263
+ if (opts.slice) {
264
+ var so = opts.slice;
265
+ active_slice_col_name = so.slice_column;
266
+
267
+ if (so.event) {
268
+ var evt_name = so.event.name;
269
+ if (! evt_name)
270
+ throw "Missing event name in slice definition for data source '" + name + "'.";
271
+ OHUB.bind(evt_name, function(evt) {
272
+ set_slice_column(evt.id);
273
+ })
274
+ }
275
+ }
276
+
277
+ if (window.WebSocket) {
278
+ start_web_socket();
279
+ }
280
+
281
+ // Bind to event directly
282
+ // this.on_changed = function(update_f) {
283
+ // OHUB.bind(this.event_name, update_f);
284
+ // }
285
+
286
+ return data_source;
160
287
  }
161
288
 
@@ -113,17 +113,36 @@ L = new function() {
113
113
  };
114
114
 
115
115
  } else { // css
116
- sel = document.createElement("link");
116
+ var sel = document.createElement("link");
117
117
  sel.href = url;
118
118
  sel.rel = "stylesheet";
119
119
  sel.type ="text/css";
120
- // there is no consistent support for detecting the successful loading of
121
- // a css file. Not sure what happens if we simply don't care.
122
- this._onLoad(url);
123
- //this._css_el = sel;
120
+ this._monitor_css_loaded(sel, url)
124
121
  }
125
122
  return sel;
126
123
  }
124
+
125
+ this._monitor_css_loaded = function(sel, url) {
126
+ var href = sel.href;
127
+ var self = this;
128
+ window.setTimeout(function() {
129
+ var sheets = document.styleSheets;
130
+ for (var i = 0; i < sheets.length; i++) {
131
+ var sheet = sheets[i];
132
+ if (sheet.href == href) {
133
+ // TODO: HACK ALLERT
134
+ // OK, stylesheet is loaded but we are having issues with SLickgrid and Chrome
135
+ // recoginisng it immediately, maybe a delay helps
136
+ window.setTimeout(function() {
137
+ self._onLoad(url);
138
+ }, 200);
139
+ return;
140
+ }
141
+ }
142
+ // still not loaded, try again
143
+ self._monitor_css_loaded(sel, url);
144
+ }, 100) ;
145
+ }
127
146
 
128
147
  this._getAbsoluteUrl = function(url) {
129
148
  if (url.indexOf(':') < 0) { // don't change when it contains protocol
@@ -134,7 +153,8 @@ L = new function() {
134
153
  s.push('js');
135
154
  }
136
155
  var ext = s.pop();
137
- url = this.baseURL + '/' + ext + "/" + url;
156
+ //url = this.baseURL + '/' + ext + "/" + url;
157
+ url = this.baseURL + '/' + url;
138
158
  }
139
159
  }
140
160
  return url;
@@ -247,56 +267,7 @@ L = new function() {
247
267
  }
248
268
  return true;
249
269
  };
250
-
251
- // Report that an URL has been loaded through some other means
252
- var self = this;
253
- $(document).ready(function() {
254
- self._loaded['#DOM_LOADED'] = true;
255
- self._checkAllPending();
256
- });
257
-
258
-
259
- // this._checkOnePending = function(p) {
260
- // var deps = p.deps;
261
- // var loaded = this._loaded;
262
- // var l = deps.length;
263
- // for (; l;) {
264
- // var name = deps[--l];
265
- // if (loaded[name] != true) {
266
- // return p;
267
- // }
268
- // }
269
- // // OK, all dependencies fulfilled.
270
- // var op = p.op;
271
- // switch (op) {
272
- // case "load":
273
- // var next = p.next;
274
- // var url = next.shift();
275
- // var new_pending = null;
276
- // if (next.length > 0) {
277
- // // load next one
278
- // new_pending = {op: 'load', deps: [url], next: next};
279
- // }
280
- // this._loadOne(url);
281
- // return new_pending;
282
- // case "provide":
283
- // if (p.onReady) {
284
- // p.onReady();
285
- // }
286
- // this._provided[p.obj_name] = true;
287
- // return null;
288
- // case "require":
289
- // if (this._provided[p.obj_name] == true) {
290
- // if (p.onReady) {
291
- // p.onReady();
292
- // }
293
- // return null; // done
294
- // }
295
- // return p;
296
- // }
297
- // return null; // not sure what op that is, let's remove it
298
- // }
299
-
270
+
300
271
  this._arr_flatten = function(array) {
301
272
  // http://tech.karbassi.com/2009/12/17/pure-javascript-flatten-array/
302
273
  var flat = [];
@@ -306,6 +277,16 @@ L = new function() {
306
277
  }
307
278
  return flat;
308
279
  }
280
+
281
+ // Report that an URL has been loaded through some other means
282
+ var self = this;
283
+ //this.require(['vendor/jquery/jquery.js'], function() {
284
+ $(document).ready(function() {
285
+ self._loaded['#DOM_LOADED'] = true;
286
+ self._checkAllPending();
287
+ });
288
+ //});
289
+
309
290
  };
310
- //L.deps = {};
291
+
311
292
 
@@ -233,19 +233,19 @@ ol.widget_tools_menu li.current a {
233
233
  }
234
234
 
235
235
  ol.widget_tools_menu li.data_line_chart2 a {
236
- background: url(/resource/image/graph/line_chart.png) 0px -50px no-repeat;
236
+ background: url(/resource/graph/img/line_chart.png) 0px -50px no-repeat;
237
237
  }
238
238
 
239
239
  ol.widget_tools_menu li.data_scatter_plot a {
240
- background: url(/resource/image/graph/scatter_plot.png) 0px 0px no-repeat;
240
+ background: url(/resource/graph/img/scatter_plot.png) 0px 0px no-repeat;
241
241
  }
242
242
 
243
243
  ol.widget_tools_menu li.data_table2 a {
244
- background: url(/resource/image/graph/table.png) 0px -50px no-repeat;
244
+ background: url(/resource/graph/img/table.png) 0px -50px no-repeat;
245
245
  }
246
246
 
247
247
  ol.widget_tools_menu li.info a {
248
- background: url(/resource/image/graph/info.png) 3px 3px no-repeat;
248
+ background: url(/resource/graph/img/info.png) 3px 3px no-repeat;
249
249
  margin-left: 10px
250
250
  }
251
251