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
data/.gitignore CHANGED
@@ -15,7 +15,6 @@ tmp
15
15
  # YARD artifacts
16
16
  .yardoc
17
17
  _yardoc
18
- doc/
19
18
 
20
19
  Gemfile.lock
21
20
  share/htdocs/vendor/valums-file-uploader-cf7bfb1/.gitignore
data/README.md CHANGED
@@ -10,12 +10,18 @@
10
10
  ## Try the simple example
11
11
 
12
12
  git init /tmp/foo
13
- ruby example/simple/simple_viz_server.rb start -p 4000
13
+ ruby -I lib -rubygems example/demo/demo_viz_server.rb start
14
+
15
+ This will start a web server at port 3000. Point your browser there and you should see somthing like:
14
16
 
15
- _4000 is the port number. For all options, please take a look at "thin -h" for more options_
17
+ ![Screenshot of starting page](https://raw.github.com/mytestbed/omf_web/master/doc/screenshot.png "Screenshot")
18
+
19
+ For additional options start the server with -h.
16
20
 
17
21
  ## Design Notes
18
22
 
23
+ ** These notes are way out of date. Look at the 'demo' example for some guidance **
24
+
19
25
  This module is used to define and run a web server which allows a user to explore and
20
26
  intereact with various experiments. It is a stand-alone unit communicating through
21
27
  the OMF messaging framework with other entities.
Binary file
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -24,16 +24,19 @@ OMF::Web.register_datasource nw, :index => :id
24
24
  # Move mobile node
25
25
  Thread.new do
26
26
  begin
27
+ ts = 0
27
28
  angle = 0
28
29
  delta = Math::PI / 6
29
30
  twoPi = 2 * Math::PI
30
31
  r = 0.25
31
32
  loop do
32
33
  sleep 1
34
+ ts = ts + 1
33
35
  angle += delta
34
36
  angle -= twoPi if angle >= twoPi
35
37
  nw.transaction do
36
38
  m = nw.node(:m1)
39
+ #m[:ts] = ts
37
40
  m[:x] = r * Math.sin(angle) + 0.5
38
41
  m[:y] = r * Math.cos(angle) + 0.5
39
42
  l[:load] = rand()
@@ -0,0 +1,54 @@
1
+
2
+
3
+
4
+
5
+ require 'omf-oml/network'
6
+ require 'omf-oml/table'
7
+
8
+ include OMF::OML
9
+
10
+ nw = OmlNetwork.new 'static_network'
11
+ nw.node_schema [[:x, :float], [:y, :float], [:capacity, :float]]
12
+ nw.create_node :n0, :x => 0.2, :y => 0.2, :capacity => 0.3
13
+ nw.create_node :n1, :x => 0.8, :y => 0.2, :capacity => 0.5
14
+ nw.create_node :n2, :x => 0.5, :y => 0.5, :capacity => 0.8
15
+ nw.create_node :n3, :x => 0.8, :y => 0.8, :capacity => 0.8
16
+ nw.create_node :n4, :x => 0.2, :y => 0.8, :capacity => 0.8
17
+
18
+ nw.link_schema [[:ts, :float], [:load, :float]]
19
+ links = []
20
+ links << nw.create_link(:l02, :n0, :n2, :ts => 0, :load => 0.0)
21
+ links << nw.create_link(:l12, :n1, :n2, :ts => 0, :load => 0.25)
22
+ links << nw.create_link(:l23, :n2, :n3, :ts => 0, :load => 0.5)
23
+ links << nw.create_link(:l24, :n2, :n4, :ts => 0, :load => 0.75)
24
+
25
+ require 'omf_web'
26
+ OMF::Web.register_datasource nw, :index => :id
27
+
28
+ # Create a table which serves the history of an individual link as a slice
29
+ #
30
+ link_history = nw.to_table(:links)
31
+ OMF::Web.register_datasource link_history, :name => 'link_history'
32
+
33
+ # Change load
34
+ Thread.new do
35
+ begin
36
+ ts = 0
37
+ loop do
38
+ sleep 1
39
+ ts = ts + 1
40
+ frac = 1.0 / links.length
41
+ nw.transaction do
42
+ links.each_with_index do |l, i|
43
+ l[:ts] = ts
44
+ l[:load] = rand() * frac + i * frac
45
+ end
46
+ end
47
+ end
48
+ rescue Exception => ex
49
+ puts ex
50
+ puts ex.backtrace.join("\n")
51
+ end
52
+ end
53
+
54
+
@@ -11,6 +11,21 @@ widget:
11
11
  priority: 900
12
12
  type: layout/tabbed
13
13
  widgets:
14
+
15
+ - name: Multi Barchart
16
+ type: data/multi_barchart
17
+ data_source:
18
+ name: movies_year_genre
19
+ mapping:
20
+ label: genre
21
+ value: count
22
+ group_by: year
23
+ rotate_labels: 0
24
+ axis:
25
+ x:
26
+ ticks:
27
+ format: false
28
+
14
29
  - name: Line Chart
15
30
  type: data/line_chart3
16
31
  data_source:
@@ -29,6 +44,9 @@ widget:
29
44
  margin:
30
45
  bottom: 30
31
46
 
47
+ - name: Dynamic
48
+ id_ref: line_chart
49
+
32
50
  - name: Discrete Barchart
33
51
  type: data/discrete_bar_chart
34
52
  data_source:
@@ -50,20 +68,6 @@ widget:
50
68
  ticks:
51
69
  format: ",.2f"
52
70
 
53
- - name: Multi Barchart
54
- type: data/multi_barchart
55
- data_source:
56
- name: movies_year_genre
57
- mapping:
58
- label: genre
59
- value: count
60
- group_by: year
61
- rotate_labels: 0
62
- axis:
63
- x:
64
- ticks:
65
- format: false
66
-
67
71
  - name: Pie Chart
68
72
  type: data/pie_chart2
69
73
  data_source:
@@ -91,11 +95,12 @@ widget:
91
95
  scale: 0.04 # 1.0 / 25
92
96
  color: red_yellow20_green() # () indicates a color scale
93
97
 
94
- - name: Network
98
+ - name: Mobile Network
95
99
  type: data/network2
96
100
  data_source:
97
101
  name: mobile_network
98
- dynamic: 1
102
+ unique_column: id # only use the latest link and row descriptions
103
+ dynamic: true
99
104
  mapping:
100
105
  nodes:
101
106
  x:
@@ -0,0 +1,95 @@
1
+
2
+
3
+ # Define a 'dashboard' consisting of two columns of widgets
4
+ #
5
+
6
+ widget:
7
+ id: linked_graphs
8
+ name: Linked Graphs
9
+ top_level: true
10
+ priority: 300
11
+ type: layout/two_columns/50_50
12
+ left:
13
+ - name: Network
14
+ type: data/network2
15
+ width: 1.0
16
+ data_source:
17
+ name: static_network
18
+ unique_column: id # only use the latest link and row descriptions
19
+ dynamic: true
20
+ mapping:
21
+ nodes:
22
+ x:
23
+ property: x
24
+ y:
25
+ property: y
26
+ links:
27
+ stroke_width:
28
+ property: load
29
+ scale: 20
30
+ min: 3
31
+ stroke_color:
32
+ property: load
33
+ color: red_yellow20_green() #green_yellow80_red()
34
+ margin:
35
+ left: 30
36
+ right: 30
37
+ interaction_mode: click # click on link to create event
38
+
39
+
40
+ # - name: Link Stats All
41
+ # type: data/line_chart3
42
+ # #area: true # color the area between line and zero line
43
+ # data_source:
44
+ # name: static_network/links
45
+ # dynamic: true
46
+ # group_by: name
47
+ # mapping:
48
+ # x_axis: ts
49
+ # y_axis:
50
+ # property: load
51
+ # min: 0
52
+ # max: 1
53
+ # axis:
54
+ # x:
55
+ # ticks:
56
+ # type: time
57
+ # #transition: 0
58
+ # legend: Time (sec)
59
+ # y:
60
+ # legend: Load (bps)
61
+ # margin:
62
+ # left: 100
63
+
64
+ right:
65
+ - name: Single Link Stats
66
+ type: data/line_chart3
67
+ #area: true # color the area between line and zero line
68
+ data_source:
69
+ name: link_history
70
+ #name: static_network/links
71
+
72
+ # Only fetch a 'slice' of the underlying data source. A slice
73
+ # is defined by specific value in the 'slice_column' of all rows
74
+ slice:
75
+ slice_column: id
76
+ event:
77
+ name: graph.static_network_links.selected
78
+ key: id
79
+ group_by: name
80
+ mapping:
81
+ x_axis: ts
82
+ y_axis:
83
+ property: load
84
+ min: 0
85
+ max: 1
86
+ axis:
87
+ x:
88
+ ticks:
89
+ type: time
90
+ #transition: 0
91
+ legend: Time (sec)
92
+ y:
93
+ legend: Load (bps)
94
+ margin:
95
+ left: 100
@@ -7,7 +7,7 @@ widget:
7
7
  width: 1.0
8
8
  data_source:
9
9
  name: mobile_network
10
- dynamic: 1
10
+ unique_column: id # only use the latest link and row descriptions
11
11
  mapping:
12
12
  nodes:
13
13
  x:
@@ -7,7 +7,7 @@
7
7
  widget:
8
8
  id: pie
9
9
  name: Pie Chart
10
- type: data/pie_chart
10
+ type: data/pie_chart2
11
11
  data_sources: animals
12
12
  mapping :
13
13
  value: count
@@ -2,7 +2,7 @@
2
2
  require 'omf_common/lobject'
3
3
 
4
4
  use ::Rack::ShowExceptions
5
- use ::Rack::Lint
5
+ #use ::Rack::Lint
6
6
 
7
7
  OMF::Web::Runner.instance.life_cycle(:pre_rackup)
8
8
  options = OMF::Web::Runner.instance.options
@@ -15,7 +15,7 @@ end
15
15
  map '/_ws' do
16
16
  begin
17
17
  require 'omf-web/rack/websocket_handler'
18
- run OMF::Web::Rack::WebsocketHandler.new # :backend => { :debug => true }
18
+ run OMF::Web::Rack::WebsocketHandler.new #:backend => { :debug => true }
19
19
  rescue Exception => ex
20
20
  OMF::Common::Loggable.logger('web').error "#{ex}"
21
21
  end
@@ -13,8 +13,14 @@ module OMF::Web
13
13
 
14
14
  @@datasources = {}
15
15
 
16
+ # Register a data source.
17
+ #
18
+ # params data_source - Data source to register
19
+ # params opts:
20
+ # name - Name to use instead of data source's native name
21
+ #
16
22
  def self.register_datasource(data_source, opts = {})
17
- name = data_source.name.to_sym
23
+ name = (opts[:name] || data_source.name).to_sym
18
24
  if (@@datasources.key? name)
19
25
  raise "Repeated try to register data source '#{name}'"
20
26
  end
@@ -31,6 +37,8 @@ module OMF::Web
31
37
  unless dsp = OMF::Web::SessionStore[name, :dsp]
32
38
  if ds = @@datasources[name]
33
39
  dsp = OMF::Web::SessionStore[name, :dsp] = self.new(name, ds)
40
+ else
41
+ warn "Requesting unknown datasource '#{name}', only know about '#{@@datasources.keys.join(', ')}'."
34
42
  end
35
43
  end
36
44
  dsp
@@ -49,28 +57,48 @@ module OMF::Web
49
57
  unless ds_descr.is_a? Hash
50
58
  raise "Expected Hash, but got '#{ds_descr.class}::#{ds_descr.inspect}'"
51
59
  end
52
- ds_name = ds_descr[:name].to_sym
60
+ unless ds_name = ds_descr[:name]
61
+ raise "Missing 'name' attribute in datasource description. (#{ds_descr.inspect})"
62
+ end
63
+ ds_name = ds_name.to_sym
53
64
  ds = @@datasources[ds_name]
54
65
  unless ds
55
- raise "Unknown data source '#{ds_name}' (#{@@datasources.keys.inspect})"
66
+ # let's check for sub table, such as network/nodes
67
+ main, sub = ds_descr[:name].split('/')
68
+ if (sub)
69
+ if ds_top = @@datasources[main.to_sym]
70
+ ds = ds_top[sub.to_sym]
71
+ end
72
+ end
73
+ unless ds
74
+ raise "Unknown data source '#{ds_name}' (#{@@datasources.keys.inspect})"
75
+ end
56
76
  end
57
77
  if ds.is_a? Hash
58
- n_name = "#{ds_name}_nodes".to_sym
59
- l_name = "#{ds_name}_links".to_sym
60
- if (nodes = OMF::Web::SessionStore[n_name, :dsp])
61
- # assume links exist as well
62
- links = OMF::Web::SessionStore[l_name, :dsp]
63
- else
64
- nodes = OMF::Web::SessionStore[n_name, :dsp] = self.new(n_name, ds[:nodes])
65
- links = OMF::Web::SessionStore[l_name, :dsp] = self.new(l_name, ds[:links])
78
+ proxies = ds.map do |name, ds|
79
+ id = "#{ds_name}_#{name}".to_sym
80
+ proxy = OMF::Web::SessionStore[id, :dsp] ||= self.new(id, ds)
66
81
  end
67
- return [nodes, links]
82
+ return proxies
83
+
84
+ # n_name = "#{ds_name}_nodes".to_sym
85
+ # l_name = "#{ds_name}_links".to_sym
86
+ # if (nodes = OMF::Web::SessionStore[n_name, :dsp])
87
+ # # assume links exist as well
88
+ # links = OMF::Web::SessionStore[l_name, :dsp]
89
+ # else
90
+ # nodes = OMF::Web::SessionStore[n_name, :dsp] = self.new(n_name, ds[:nodes])
91
+ # links = OMF::Web::SessionStore[l_name, :dsp] = self.new(l_name, ds[:links])
92
+ # end
93
+ # return [nodes, links]
68
94
  end
69
95
 
70
96
  proxy = OMF::Web::SessionStore[ds_name, :dsp] ||= self.new(ds_name, ds)
71
97
  return [proxy]
72
98
  end
73
99
 
100
+ attr_reader :name
101
+
74
102
  def reset()
75
103
  # TODO: Figure out partial sending
76
104
  end
@@ -80,19 +108,53 @@ module OMF::Web
80
108
  [res.to_json, "text/json"]
81
109
  end
82
110
 
111
+ # Register callback to be informed of changes to the underlying data source.
112
+ # Call block when new rows are becoming available. Block needs ot return
113
+ # true if it wants to continue receiving updates.
114
+ #
115
+ # offset: Number of records already downloaded
116
+ #
117
+ def on_changed(offset, &block)
118
+ ds = @data_source
119
+ rows = ds.rows[(offset - ds.offset) .. -1]
120
+ if rows && rows.length > 0
121
+ debug "on_changed: sending #{rows.length}"
122
+ block.call rows, ds.offset
123
+ end
124
+ @data_source.on_row_added(block.object_id) do |row, offset|
125
+ debug "on_changed: more data: #{row.inspect}"
126
+ block.call [row], offset
127
+ end
128
+ end
83
129
 
84
- def to_javascript(update_interval = 0)
85
- is_dynamic = update_interval > 0 ? ".is_dynamic(#{update_interval})" : ""
130
+ # Create a new data source which only contains a slice of the underlying data source
131
+ def create_slice(col_name, col_value)
132
+ ds = @data_source.create_sliced_table(col_name, col_value)
133
+ dsp = self.class.new(ds.name, ds)
134
+ def dsp.release; @data_source.release end
135
+ dsp
136
+ end
137
+
138
+ def to_javascript(opts)
139
+ #puts "to_java>>>>> #{opts.inspect}"
140
+ sid = Thread.current["sessionID"]
141
+ opts = opts.dup
142
+ opts[:name] = @name
143
+ opts[:schema] = @data_source.schema
144
+ opts[:update_url] = "/_update/#{@name}?sid=#{sid}"
145
+ opts[:sid] = sid
146
+ unless opts[:slice] # don't send any data if this is a sliced one
147
+ opts[:rows] = @data_source.rows[0 .. 20]
148
+ opts[:offset] = @data_source.offset
149
+ end
150
+ #puts "to_java2>>>>> #{opts.to_json.inspect}"
151
+
86
152
  %{
87
- OML.data_sources.register('#{@name}',
88
- '/_update/#{@name}?sid=#{Thread.current["sessionID"]}',
89
- #{@data_source.schema.to_json},
90
- #{@data_source.rows.to_json})#{is_dynamic};
153
+ OML.data_sources.register(#{opts.to_json});
91
154
  }
92
155
 
93
156
  end
94
157
 
95
-
96
158
  def initialize(name, data_source)
97
159
  @name = name
98
160
  @data_source = data_source
@@ -7,46 +7,100 @@ module OMF::Web::Rack
7
7
 
8
8
  class WebsocketHandler < ::Rack::WebSocket::Application
9
9
  include OMF::Common::Loggable
10
- extend OMF::Common::Loggable
10
+ extend OMF::Common::Loggable
11
+
12
+ def on_open(env)
13
+ #puts ">>>>> OPEN"
14
+ end
11
15
 
12
- def on_message(env, msg)
16
+ def on_message(env, msg_s)
13
17
  begin
14
- #puts "message received: " + msg
15
-
16
- ma = msg.split(':')
17
- cmd = ma.shift.to_sym
18
- if (cmd == :id)
19
- begin
20
- h = OMF::Web::SessionStore.find_tab_from_path(ma)
21
- Thread.current["sessionID"] = h[:sid]
22
- @tab_inst = h[:tab_inst]
23
- @sub_path = h[:sub_path]
24
- @tab_inst.on_ws_open(self, @sub_path.dup)
25
- rescue Exception => ex
26
- error ex
27
- debug "#{ex.backtrace.join("\n")}"
28
- send_data("{error: '#{ex.to_s}'}")
29
- return
30
- end
18
+ req = ::Rack::Request.new(env)
19
+ sid = req.params['sid']
20
+ Thread.current["sessionID"] = sid
31
21
 
32
- else
33
- send_data("{error: 'Unknown command -#{cmd}-'}")
22
+ msg = JSON.parse(msg_s)
23
+ debug("Msg(#{sid}): #{msg.inspect}")
24
+ msg_type = msg['type']
25
+ args = msg['args']
26
+ msg_handler = "on_#{msg_type}".to_sym
27
+ unless respond_to? msg_handler
28
+ warn "Received unknonw request '#{msg_type}'"
29
+ send_data({type: 'reply', status: 'error', err_msg: "Unknown message type '#{msg_type}'"}.to_json)
30
+ return
34
31
  end
32
+ context = OMF::Web::SessionStore[args['name'], :ws] ||= {}
33
+ send(msg_handler, args, context)
35
34
  rescue Exception => ex
36
- error(ex)
35
+ error ex
36
+ debug "#{ex.backtrace.join("\n")}"
37
+ send_data({type: 'reply', status: 'exception', err_msg: ex.to_s}.to_json)
37
38
  end
38
39
  #puts "message processed"
39
40
  end
40
41
 
41
42
  def on_close(env)
42
43
  begin
43
- puts "client disconnected"
44
+ debug "client disconnected"
44
45
  @tab_inst.on_ws_close(self, @sub_path) if @tab_inst
45
46
  @tab_inst = nil
46
47
  rescue Exception => ex
47
48
  error(ex)
48
49
  end
49
50
  end
51
+
52
+ def on_register_data_source(args, context)
53
+ dsp = find_data_source(args)
54
+ return unless dsp # should define appropriate exception
55
+ debug "Received registration for datasource proxy '#{dsp}'"
56
+ dsp.on_changed(args['offset']) do |new_rows, offset|
57
+ msg = {
58
+ type: 'datasource_update',
59
+ datasource: dsp.name,
60
+ rows: new_rows,
61
+ offset: offset
62
+ }
63
+ send_data(msg.to_json)
64
+ end
65
+ send_data({type: 'reply', status: 'ok'}.to_json)
66
+ end
67
+
68
+ # args {"slice"=>{"col_name"=>"id", "col_value"=>"e8..."}, "ds_name"=>"individual_link"}}
69
+ def on_request_slice(args, context)
70
+ dsp = find_data_source(args)
71
+ return unless dsp # should define appropriate exception
72
+
73
+ sargs = args['slice']
74
+ col_name = sargs['col_name']
75
+ col_value = sargs['col_value']
76
+ debug "Creating slice '#{col_name}:#{col_value}' data source '#{dsp}'"
77
+
78
+ if old_sdsp = context[:sliced_datasource]
79
+ return if old_sdsp[:column_name] == col_name
80
+ old_sdsp[:dsp].release
81
+ end
82
+ sdsp = dsp.create_slice(col_name, col_value)
83
+ context[:sliced_datasource] = {:col_name => col_name, :dsp => sdsp}
84
+ sdsp.on_changed(0) do |new_rows, offset|
85
+ msg = {
86
+ type: 'datasource_update',
87
+ datasource: args['ds_name'],
88
+ rows: new_rows,
89
+ offset: offset
90
+ }
91
+ send_data(msg.to_json)
92
+ end
93
+ end
94
+
95
+ def find_data_source(args)
96
+ ds_name = args['ds_name']
97
+ unless dsp = OMF::Web::DataSourceProxy[ds_name]
98
+ warn "Request for unknown datasource '#{ds_name}'."
99
+ send_data({type: 'reply', status: 'error', err_msg: "Unknown datasource '#{ds_name}'"}.to_json)
100
+ return nil
101
+ end
102
+ dsp
103
+ end
50
104
 
51
105
  end # WebsocketHandler
52
106