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.
- data/.gitignore +0 -1
- data/README.md +8 -2
- data/doc/screenshot.png +0 -0
- data/example/{basic → NOT_WORKING/basic}/hello-world-wired.rb +0 -0
- data/example/{basic → NOT_WORKING/basic}/visualisation.yml +0 -0
- data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklynDemo.sq3 +0 -0
- data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklyn_gps.dat +0 -0
- data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklyn_server.rb +0 -0
- data/example/{brooklyn → NOT_WORKING/brooklyn}/brooklyn_wimax.dat +0 -0
- data/example/{brooklyn → NOT_WORKING/brooklyn}/sql_source.rb +0 -0
- data/example/{code → NOT_WORKING/code}/code_server.rb +0 -0
- data/example/{frisbee → NOT_WORKING/frisbee}/data_sources/parse_log.rb +0 -0
- data/example/{frisbee → NOT_WORKING/frisbee}/data_sources/pxe_slice-2012-06-02t02.25.00-04.00.log +0 -0
- data/example/{frisbee → NOT_WORKING/frisbee}/progress_chart.yaml +0 -0
- data/example/{frisbee → NOT_WORKING/frisbee}/progress_tab.yaml +0 -0
- data/example/{frisbee → NOT_WORKING/frisbee}/progress_table.yaml +0 -0
- data/example/{frisbee → NOT_WORKING/frisbee}/viz_server.rb +0 -0
- data/example/{gec12 → NOT_WORKING/gec12}/gec12-53.rb +0 -0
- data/example/{gec12 → NOT_WORKING/gec12}/gec12_demo.sq3 +0 -0
- data/example/{gec12 → NOT_WORKING/gec12}/gec12_demo_server.rb +0 -0
- data/example/{gec12 → NOT_WORKING/gec12}/visualization.rb +0 -0
- data/example/{incoming → NOT_WORKING/incoming}/ofpu_barchart_widget.yaml +0 -0
- data/example/{log → NOT_WORKING/log}/log_config.xml +0 -0
- data/example/{log → NOT_WORKING/log}/log_server.rb +0 -0
- data/example/{network → NOT_WORKING/network}/flow_tab.yaml +0 -0
- data/example/{network → NOT_WORKING/network}/network_server.rb +0 -0
- data/example/{text → NOT_WORKING/text}/test.md +0 -0
- data/example/{text → NOT_WORKING/text}/test.rb +0 -0
- data/example/{wimax → NOT_WORKING/wimax}/downlink.yaml +0 -0
- data/example/{wimax → NOT_WORKING/wimax}/power.yaml +0 -0
- data/example/{wimax → NOT_WORKING/wimax}/snapshot.db +0 -0
- data/example/{wimax → NOT_WORKING/wimax}/snapshot.sql +0 -0
- data/example/{wimax → NOT_WORKING/wimax}/test.rb +0 -0
- data/example/{wimax → NOT_WORKING/wimax}/uplink.yaml +0 -0
- data/example/{wimax → NOT_WORKING/wimax}/viz_server.rb +0 -0
- data/example/demo/data_sources/mobile_network.rb +3 -0
- data/example/demo/data_sources/static_network.rb +54 -0
- data/example/demo/widgets/charts_tab.yaml +21 -16
- data/example/demo/widgets/linked_graphs_tab.yaml +95 -0
- data/example/demo/widgets/mobile_network_widget.yaml +1 -1
- data/example/demo/widgets/pie_chart_widget.yaml +1 -1
- data/lib/omf-web/config.ru +2 -2
- data/lib/omf-web/data_source_proxy.rb +81 -19
- data/lib/omf-web/rack/websocket_handler.rb +77 -23
- data/lib/omf-web/theme/abstract_page.rb +43 -26
- data/lib/omf-web/theme/bright/code_renderer.rb +1 -1
- data/lib/omf-web/theme/bright/page.rb +1 -0
- data/lib/omf-web/theme/bright/tabbed_renderer.rb +7 -0
- data/lib/omf-web/version.rb +7 -0
- data/lib/omf-web/widget/data_widget.rb +38 -46
- data/lib/omf-web/widget/layout/stacked_layout.rb +2 -1
- data/lib/omf-web/widget/layout/tabbed_layout.rb +1 -2
- data/{MARUKU-LICENSE → lib/omf-web/widget/text/maruku/MARUKU-LICENSE} +0 -0
- data/lib/{maruku → omf-web/widget/text/maruku}/helpers.rb +0 -0
- data/lib/{maruku → omf-web/widget/text/maruku}/input/parse_block.rb +0 -0
- data/lib/{maruku → omf-web/widget/text/maruku}/output/to_html.rb +26 -21
- data/lib/omf-web/widget/text/maruku.rb +5 -0
- data/omf_web.gemspec +2 -1
- data/share/htdocs/{js → UNUSED}/log/table.js +0 -0
- data/share/htdocs/{css → graph/css}/graph.css +0 -0
- data/share/htdocs/{image/graph → graph/img}/bar_chart.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/donut_chart.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/funnel.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/info.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/line_chart.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/line_chart_fill.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/misc.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/overview.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/pie_chart.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/scatter_plot.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/stacked_bar_chart.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/stacked_line_chart.png +0 -0
- data/share/htdocs/{image/graph → graph/img}/table.png +0 -0
- data/share/htdocs/{js/graph → graph/js}/abstract_chart.js +1 -1
- data/share/htdocs/{js/graph → graph/js}/abstract_nv_chart.js +8 -13
- data/share/htdocs/{js/graph → graph/js}/abstract_widget.js +9 -16
- data/share/htdocs/{js/graph → graph/js}/axis.js +1 -1
- data/share/htdocs/{js/graph → graph/js}/barchart.js +2 -2
- data/share/htdocs/{js/graph → graph/js}/code_mirror.js +1 -5
- data/share/htdocs/{js/graph → graph/js}/discrete_bar_chart.js +1 -1
- data/share/htdocs/{js/graph → graph/js}/histogram2.js +1 -1
- data/share/htdocs/{js/graph → graph/js}/holt_winters_chart.js +1 -1
- data/share/htdocs/{js/graph → graph/js}/line_chart3.js +1 -1
- data/share/htdocs/{js/graph → graph/js}/line_chart_with_focus.js +1 -1
- data/share/htdocs/{js/graph → graph/js}/map2.js +1 -1
- data/share/htdocs/{js/graph → graph/js}/multi_barchart.js +1 -1
- data/share/htdocs/graph/js/network2.js +412 -0
- data/share/htdocs/{js/graph → graph/js}/pie_chart2.js +1 -1
- data/share/htdocs/{js/graph → graph/js}/scatter_plot.js +1 -1
- data/share/htdocs/{js/graph → graph/js}/table2.js +17 -20
- data/share/htdocs/js/data_source2.js +187 -60
- data/share/htdocs/js/require3.js +38 -57
- data/share/htdocs/theme/bright/css/bright.css +4 -4
- data/share/htdocs/vendor/jquery/jquery.js +9404 -0
- data/share/htdocs/vendor/osa/LICENSE.txt +11 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_arrow_green_left.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_arrow_yellow_right.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_awareness.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_camera-web.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_cloud.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_contract.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_database.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_desktop.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_desktop_imac.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-music.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-scanner.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-usb-wifi.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-usb.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_device-wireless-router.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_disposal.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_drive-harddisk.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_drive-optical.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_firewall.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_home.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_hub.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_iPhone.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_ics_drive.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_ics_plc.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_ics_thermometer.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_id_card.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_image-generic.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_laptop.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_lifecycle.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_lightning.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_media-flash.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_media-optical.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_media-tape.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_mobile_pda.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_padlock.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_printer.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_application.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_database.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_directory.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_distribution.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_file.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_gateway.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_identity.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_mail.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_media.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_monitor.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_proxy.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_terminal.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_server_web.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-branch.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-factory.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-head-office.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_site-neighbourhood.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_audit.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_black_hat.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_security_specialist.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_sysadmin.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_tester.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_blue_tie.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_architect.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_business_manager.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_developer.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_operations.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_project_manager.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_service_manager.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_green_warning.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_user_large_group.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_users_blue_green.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_vpn.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_warning.svg +0 -0
- data/share/htdocs/{svg/osa → vendor/osa/svg}/osa_wireless_network.svg +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/.DS_Store +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/add_icon.gif +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/alertbad_icon.gif +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/alertgood_icon.gif +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/back_disabled.jpg +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/back_disabled.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/back_enabled.jpg +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/back_enabled.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/back_enabled_hover.jpg +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/back_enabled_hover.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/bottom-bg.gif +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/forward_disabled.jpg +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/forward_disabled.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/forward_enabled.jpg +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/forward_enabled.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/forward_enabled_hover.jpg +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/forward_enabled_hover.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/icon-remove.gif +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/indicator.gif +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/laptop.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/logo-bottom.gif +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/nav-tab-arrow.gif +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/norbit_big.gif +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/norbit_clipart.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/progress_bar.gif +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/right-bg.gif +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/sort_asc.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/sort_asc_disabled.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/sort_both.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/sort_desc.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/sort_desc_disabled.png +0 -0
- data/share/htdocs/{image → vendor/unknown/image}/spinner.gif +0 -0
- data/share/htdocs/{svg → vendor/unknown/svg}/ap.svg +0 -0
- data/share/htdocs/{svg → vendor/unknown/svg}/router.svg +0 -0
- metadata +198 -216
- data/example/demo/widgets/dashboard_tab.yaml +0 -28
- data/example/demo/widgets/download_tab.yaml +0 -42
- data/example/demo/widgets/edit_tab.yaml +0 -20
- data/example/demo/widgets/generator_tab.yaml +0 -12
- data/lib/omf-oml/endpoint.rb +0 -175
- data/lib/omf-oml/indexed_table.rb +0 -57
- data/lib/omf-oml/network.rb +0 -413
- data/lib/omf-oml/oml_tuple.rb +0 -62
- data/lib/omf-oml/schema.rb +0 -191
- data/lib/omf-oml/sequel/sequel_server.rb +0 -412
- data/lib/omf-oml/sql_row.rb +0 -302
- data/lib/omf-oml/sql_source.rb +0 -131
- data/lib/omf-oml/table.rb +0 -131
- data/lib/omf-oml/tuple.rb +0 -97
- data/lib/omf_oml.rb +0 -4
- data/share/htdocs/css/coderay.css +0 -127
- data/share/htdocs/css/ie.css +0 -40
- data/share/htdocs/css/lightbox.css +0 -62
- data/share/htdocs/css/scaffold.css +0 -74
- data/share/htdocs/css/screen.css +0 -1313
- data/share/htdocs/css/search.css +0 -102
- data/share/htdocs/css/table.css +0 -538
- data/share/htdocs/css/table2.css +0 -191
- data/share/htdocs/css/welcome.css +0 -103
- data/share/htdocs/css/wfob.css +0 -171
- data/share/htdocs/css/wshow.css +0 -69
- data/share/htdocs/gec9_demo.html +0 -39
- data/share/htdocs/images +0 -1
- data/share/htdocs/js/graph/histogram.js +0 -229
- data/share/htdocs/js/graph/line_chart.js +0 -342
- data/share/htdocs/js/graph/line_chart2.js +0 -232
- data/share/htdocs/js/graph/line_chart_fc.js +0 -94
- data/share/htdocs/js/graph/map.js +0 -85
- data/share/htdocs/js/graph/network.js +0 -591
- data/share/htdocs/js/graph/network2.js +0 -318
- data/share/htdocs/js/graph/pie_chart.js +0 -130
- data/share/htdocs/js/graph/table.js +0 -94
- data/share/htdocs/js/require2.js +0 -1998
- data/share/htdocs/js/timelines.js +0 -101
- data/share/htdocs/stylesheet/grid.css +0 -31
data/.gitignore
CHANGED
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/
|
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
|
-
|
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.
|
data/doc/screenshot.png
ADDED
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
|
data/example/{frisbee → NOT_WORKING/frisbee}/data_sources/pxe_slice-2012-06-02t02.25.00-04.00.log
RENAMED
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
|
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
|
-
|
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
|
data/lib/omf-web/config.ru
CHANGED
@@ -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
|
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]
|
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
|
-
|
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
|
-
|
59
|
-
|
60
|
-
|
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
|
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
|
-
|
85
|
-
|
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(
|
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,
|
16
|
+
def on_message(env, msg_s)
|
13
17
|
begin
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
33
|
-
|
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
|
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
|
-
|
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
|
|