Skip to content

Commit 592d30a

Browse files
Deployment Improvements (#3)
* Simplify deployment, build JS into a directory that is served from the server to allow for automatic URL fill-in * Refactored client logic into the backend * Finished refactoring to support deployment changes * Removed unused functions * Migrated web server to tornado, made plotly use CDMS * Converted to tornado for websocket as well; need to remove numpy stuff to basically eliminate the total effort * Highly optimized websocket rendering in place * Fixed resizing issues, now have fairly performant autoscaling * Added 3d demo, click code * Added clear function * Added start/end events and made sure each plot call returns a promise * Added some missing dependencies * fixed more dependencies * Cleaned up dependencies and wrapped up a few loose ends * Fixes bug with closing connections * Actually add close function to backends * And maybe without syntax errors
1 parent e593f12 commit 592d30a

26 files changed

+859
-565
lines changed

.gitignore

+99-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ tags
6262
.LSOverride
6363

6464
# Icon must end with two \r
65-
Icon
65+
Icon
66+
6667

6768
# Thumbnails
6869
._*
@@ -92,3 +93,100 @@ Makefile
9293
cmake_install.cmake
9394
install_manifest.txt
9495
CTestTestfile.cmake
96+
97+
98+
# Created by https://www.gitignore.io/api/python
99+
100+
### Python ###
101+
# Byte-compiled / optimized / DLL files
102+
__pycache__/
103+
*.py[cod]
104+
*$py.class
105+
106+
# C extensions
107+
*.so
108+
109+
# Distribution / packaging
110+
.Python
111+
env/
112+
build/
113+
develop-eggs/
114+
dist/
115+
downloads/
116+
eggs/
117+
.eggs/
118+
lib/
119+
lib64/
120+
parts/
121+
sdist/
122+
var/
123+
*.egg-info/
124+
.installed.cfg
125+
*.egg
126+
127+
# PyInstaller
128+
# Usually these files are written by a python script from a template
129+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
130+
*.manifest
131+
*.spec
132+
133+
# Installer logs
134+
pip-log.txt
135+
pip-delete-this-directory.txt
136+
137+
# Unit test / coverage reports
138+
htmlcov/
139+
.tox/
140+
.coverage
141+
.coverage.*
142+
.cache
143+
nosetests.xml
144+
coverage.xml
145+
*,cover
146+
.hypothesis/
147+
148+
# Translations
149+
*.mo
150+
*.pot
151+
152+
# Django stuff:
153+
*.log
154+
local_settings.py
155+
156+
# Flask stuff:
157+
instance/
158+
.webassets-cache
159+
160+
# Scrapy stuff:
161+
.scrapy
162+
163+
# Sphinx documentation
164+
docs/_build/
165+
166+
# PyBuilder
167+
target/
168+
169+
# IPython Notebook
170+
.ipynb_checkpoints
171+
172+
# pyenv
173+
.python-version
174+
175+
# celery beat schedule file
176+
celerybeat-schedule
177+
178+
# dotenv
179+
.env
180+
181+
# virtualenv
182+
venv/
183+
ENV/
184+
185+
# Spyder project settings
186+
.spyderproject
187+
188+
# Rope project settings
189+
.ropeproject
190+
191+
vcs_server/js/*.js
192+
vcs_server/js/*.js.map

config/webpack.loaders.js

-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ module.exports = [
3232
test: /\.js$/,
3333
include: [
3434
/src/,
35-
/node_modules\/paraviewweb/,
3635
],
3736
loader: 'babel?presets[]=es2015-nostrict',
3837
},

config/webpack.resolve.js

-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@ module.exports = {
44
alias: {
55
vcs: path.resolve('./src'),
66
plotly: path.resolve('./node_modules/plotly.js/dist/plotly'),
7-
ParaViewWeb: path.resolve('./node_modules/paraviewweb/src'),
87
},
98
};

demo/demo.css

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
.plot {
2-
height: 600px;
3-
width: 800px;
1+
body, html {
2+
width:100%;
3+
height:100%;
44
}
55

6+
* {
7+
box-sizing: border-box;
8+
}
9+
10+
div.plot {
11+
width: 50%;
12+
height: 50%;
13+
float: left;
14+
}

demo/demo.js

+23-95
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,46 @@
11
var sessionPromise;
22

3-
$(function () {
4-
// Ordinarily this would be a URL string of a rest
5-
// interface for generating a new server side connection.
6-
// Here we short circuit that code to generate a simulated
7-
// session connecting to pregenerated files through
8-
// Girder's rest interface.
9-
var url = 'ws://localhost:9000/ws';
3+
(function () {
104

115
var variables = {
12-
"clt": {
13-
"id": "clt",
14-
"derivation":
15-
[
16-
{"type": "file", "uri": "clt.nc"},
17-
{"parents": [0], "operation": {"type": "get", "id": "clt"}, "type": "variable"},
18-
{"parents": [1], "operation": {"squeeze": 0, "type": "subset", "axes": {"longitude": [-180, 180], "latitude": [-90, 90]}}, "type": "variable"}
19-
]
20-
},
6+
"clt": {"id": "clt", "derivation": [{"type": "file", "uri": "clt.nc"}, {"parents": [0], "operation": {"type": "get", "id": "clt"}, "type": "variable"}]},
217
"u": {"id": "u", "derivation": [{"type": "file", "uri": "clt.nc"}, {"parents": [0], "operation": {"type": "get", "id": "u"}, "type": "variable"}]},
228
"v": {"id": "v", "derivation": [{"type": "file", "uri": "clt.nc"}, {"parents": [0], "operation": {"type": "get", "id": "v"}, "type": "variable"}]}
239
}
2410

25-
var boxfill = {"fillareaopacity": [], "datawc_timeunits": "days since 2000", "projection": "linear", "xticlabels1": "*", "xticlabels2": "*", "ymtics1": "", "ymtics2": "", "datawc_x1": 1e+20, "datawc_x2": 1e+20, "boxfill_type": "linear", "xmtics1": "", "fillareacolors": null, "xmtics2": "", "color_2": 255, "datawc_calendar": 135441, "fillareaindices": [1], "color_1": 0, "colormap": null, "missing": [0.0, 0.0, 0.0, 100.0], "xaxisconvert": "linear", "level_2": 1e+20, "ext_1": false, "ext_2": false, "datawc_y2": 1e+20, "datawc_y1": 1e+20, "yaxisconvert": "linear", "legend": null, "name": "__boxfill_717978942019492", "yticlabels1": "*", "yticlabels2": "*", "fillareastyle": "solid", "levels": [1e+20, 1e+20], "g_name": "Gfb", "level_1": 1e+20};
11+
var boxfill = {"fillareaopacity": [], "datawc_timeunits": "days since 2000", "projection": "linear", "xticlabels1": "*", "xticlabels2": "*", "ymtics1": "", "ymtics2": "", "datawc_x1": 1e+20, "datawc_x2": 1e+20, "boxfill_type": "linear", "xmtics1": "", "fillareacolors": null, "xmtics2": "", "color_2": 255, "datawc_calendar": 135441, "fillareaindices": [1], "color_1": 0, "colormap": null, "missing": [0.0, 0.0, 0.0, 100.0], "xaxisconvert": "linear", "level_2": 1e+20, "ext_1": false, "ext_2": false, "datawc_y2": 1e+20, "datawc_y1": 1e+20, "yaxisconvert": "linear", "legend": null, "color_2": 255, "datawc_calendar": 135441, "fillareaindices": [1], "color_1": 0, "colormap": null, "missing": [0.0, 0.0, 0.0, 100.0], "xaxisconvert": "linear", "level_2": 1e+20, "ext_1": false, "ext_2": false, "datawc_y2": 1e+20, "datawc_y1": 1e+20, "yaxisconvert": "linear", "legend": null, "name": "__boxfill_717978942019492", "yticlabels1": "*", "yticlabels2": "*", "fillareastyle": "solid", "levels": [1e+20, 1e+20], "g_name": "Gfb", "level_1": 1e+20};
2612
var vector = {"datawc_timeunits": "days since 2000", "projection": "linear", "reference": 1e+20, "xticlabels1": "*", "xticlabels2": "*", "linecolor": null, "ymtics1": "", "ymtics2": "", "linewidth": null, "datawc_x1": 1e+20, "datawc_x2": 1e+20, "xmtics1": "", "xmtics2": "", "datawc_calendar": 135441, "alignment": "center", "type": "arrows", "colormap": null, "xaxisconvert": "linear", "scale": 1.0, "linetype": null, "datawc_y2": 1e+20, "datawc_y1": 1e+20, "yaxisconvert": "linear", "name": "vector_full", "yticlabels1": "*", "yticlabels2": "*", "scalerange": [0.1, 1.0], "scaleoptions": ["off", "constant", "normalize", "linear", "constantNNormalize", "constantNLinear"], "g_name": "Gv", "scaletype": "constantNNormalize"};
2713
var vector_subview = {"datawc_timeunits": "days since 2000", "projection": "linear", "reference": 1e+20, "xticlabels1": "*", "xticlabels2": "*", "linecolor": null, "ymtics1": "", "ymtics2": "", "linewidth": null, "datawc_x1": 60, "datawc_x2": 180, "xmtics1": "", "xmtics2": "", "datawc_calendar": 135441, "alignment": "center", "type": "arrows", "colormap": null, "xaxisconvert": "linear", "scale": 1.0, "linetype": null, "datawc_y2": 90, "datawc_y1": 0, "yaxisconvert": "linear", "name": "subset_vector", "yticlabels1": "*", "yticlabels2": "*", "scalerange": [0.1, 1.0], "scaleoptions": ["off", "constant", "normalize", "linear", "constantNNormalize", "constantNLinear"], "g_name": "Gv", "scaletype": "constantNNormalize"};
14+
var isofill = {"g_name": "Gfi"};
15+
var dv3d = {ScaleColormap: null, ScaleOpacity: null, BasemapOpacity: null, Camera: "{}", ZSlider: null, YSlider: null, ToggleVolumePlot: null, PointSize: null, Configure: null, XSlider: null, SliceThickness: null, axes: "xyz", plot_attributes: {name: "3d_scalar", template: "default"}, IsosurfaceValue: null, VerticalScaling: null, ChooseColormap: null, ToggleSurfacePlot: null, Colorbar: null, ncores: 8, ScaleTransferFunction: null, name: "default", ToggleClipping: null, Animation: null, g_name: "3d_scalar" };
2816

2917
// create the session
30-
sessionPromise = vcs.createSession(url);
18+
var b = document.getElementById('vcs-boxfill');
19+
var canvas = vcs.init(b);
3120

32-
sessionPromise.catch(() => {
33-
console.log('Could not connect to ' + url);
21+
b.addEventListener('vcsPlotStart', function() {
22+
console.log("Began plotting boxfill");
3423
});
3524

36-
var canvasPromise = sessionPromise.then(function (session) {
37-
return session.init(document.getElementById('vcs-isofill'));
25+
b.addEventListener('vcsPlotEnd', function() {
26+
console.log("Finished plotting boxfill");
3827
});
3928

40-
// generate the plot when all of the promises resolve
41-
canvasPromise.then(function (canvas) {
42-
var dataSpec = variables.clt;
43-
canvas.plot(dataSpec, 'no_legend', boxfill, 'server');
29+
var dataSpec = variables.clt;
30+
canvas.plot(dataSpec, boxfill, 'no_legend').then(function(){
31+
console.log("Promise completed.");
4432
});
4533

46-
// generate another plot using client side rendering
47-
// we don't have an api for getting data yet, so we'll
48-
// just use an ajax request to data.kitware.com
49-
var cltPromise = $.ajax('https://data.kitware.com/api/v1/file/576aa3c08d777f1ecd6701ae/download');
50-
var latPromise = $.ajax('https://data.kitware.com/api/v1/item/576aa3c08d777f1ecd6701b0/download');
51-
var lonPromise = $.ajax('https://data.kitware.com/api/v1/item/576aa3c08d777f1ecd6701b9/download');
52-
var canvasPromise2 = sessionPromise.then(function (session) {
53-
return session.init(document.getElementById('plotly-isofill'));
54-
});
55-
56-
57-
// This is all very rough, likely much of this should be wrapped inside the api
58-
Promise.all([
59-
canvasPromise2, cltPromise, latPromise, lonPromise
60-
]).then(function (arg) {
61-
console.log("1")
62-
var canvas = arg[0];
63-
console.log("2")
64-
var clt = arg[1];
65-
console.log("3")
66-
var lat = arg[2];
67-
console.log("4")
68-
var lon = arg[3];
69-
console.log("5")
70-
var timestep = 0;
71-
console.log("6")
72-
73-
var data = {
74-
x: lon.data,
75-
y: lat.data
76-
};
77-
console.log("7")
34+
var canvas2 = vcs.init(document.getElementById('plotly-isofill'), 'client');
35+
canvas2.plot(dataSpec, isofill);
7836

79-
function draw() {
80-
console.log("8")
81-
data.z = ndarray(clt.data, clt.shape).pick(timestep, null, null);
82-
console.log("9")
83-
canvas.plot(data, 'default', { "g_type": "Gfi" }, 'client');
84-
console.log("10")
85-
timestep = (timestep + 1) % clt.shape[0];
86-
}
87-
console.log("11")
88-
// call again for the next time step
89-
draw();
90-
});
91-
92-
var canvasPromise3 = sessionPromise.then(function (session) {
93-
return session.init(document.getElementById('vcs-vector'));
94-
});
37+
var canvas3 = vcs.init(document.getElementById('vcs-vector'));
9538
// generate the plot when all of the promises resolve
96-
canvasPromise3.then(function (canvas) {
97-
var dataSpec = [variables.u, variables.v];
98-
canvas.plot(dataSpec, 'default', vector, 'server');
99-
});
100-
101-
var canvasPromise4 = sessionPromise.then(function (session) {
102-
return session.init(document.getElementById('vcs-vector-subset'));
103-
});
39+
var dataSpec = [variables.u, variables.v];
40+
canvas3.plot(dataSpec, vector_subview);
10441

105-
// generate the plot when all of the promises resolve
106-
canvasPromise4.then(function (canvas) {
107-
var dataSpec = [variables.u, variables.v];
108-
canvas.plot(dataSpec, 'default', vector_subview, 'server');
109-
});
110-
111-
$(window).on('beforeunload', function() {
112-
canvasPromise.then((canvas) => canvas.close());
113-
canvasPromise3.then((canvas) => canvas.close());
114-
canvasPromise4.then((canvas) => canvas.close());
115-
return 'Your own message goes here...';
116-
});
117-
});
42+
var canvas4 = vcs.init(document.getElementById('vcs-vector-subset'));
43+
var dataSpec = variables.clt;
44+
canvas4.plot(dataSpec, dv3d);
11845

46+
})();

demo/index.html

+13-27
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,16 @@
11
<!DOCTYPE html>
22
<html>
3-
4-
<head>
5-
<meta http-equiv="Content-Type" content="text/html; charset = UTF-8">
6-
<link rel="stylesheet" type="text/css" href="demo.css">
7-
</head>
8-
<body>
9-
<table>
10-
<tr>
11-
<td><div class="plot" id="vcs-isofill"></div></td>
12-
<td><div class="plot" id="plotly-isofill"></div></td>
13-
</tr>
14-
<tr>
15-
<td><div class="plot" id="vcs-vector"></div></td>
16-
<td><div class="plot" id="vcs-vector-subset"></div></td>
17-
</tr>
18-
</table>
19-
<script type="text/javascript" src="../dist/vcs.js"></script>
20-
<script type="text/javascript" src="demo.js"></script>
21-
22-
<ul>
23-
<!-- Need a 3D variable for this: <li><a onclick="cdat.create_plot('http://test.opendap.org/opendap/data/nc/coads_climatology.nc', 'AIRT', '3d_scalar', 'default', 'default')" href="javascript:void(0)">Volume example</a></li> -->
24-
<li><a onclick="print_variables('coads_climatology.nc')" href="javascript:void(0)">Rectilinear grid variables example</a></li>
25-
<li><a onclick="print_variables('clt.nc')" href="javascript:void(0)">clt.nc variables example</a></li>
26-
<li><a onclick="print_variables('sampleCurveGrid4.nc')" href="javascript:void(0)">Curvilinear grid variable example</a></li>
27-
<li><a onclick="print_variables('sampleGenGrid3.nc')" href="javascript:void(0)">Generic grid variable example</a></li>
28-
</body>
29-
3+
<head>
4+
<meta http-equiv="Content-Type" content="text/html; charset = UTF-8">
5+
<link rel="stylesheet" type="text/css" href="demo.css">
6+
</head>
7+
<body>
8+
<div class="plot" id="vcs-boxfill"></div>
9+
<div class="plot" id="plotly-isofill"></div>
10+
<div class="plot" id="vcs-vector"></div>
11+
<div class="plot" id="vcs-vector-subset"></div>
12+
<script type="text/javascript" src="http://localhost:8888/scripts/vcs.js"></script>
13+
<script type="text/javascript" src="demo.js"></script>
14+
<ul>
15+
</body>
3016
</html>

package.json

+16-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Javascript interface for vcs.",
55
"main": "dist/vcs.js",
66
"scripts": {
7-
"build": "webpack --progress --colors --optimize-minimize --optimize-dedupe",
7+
"build": "webpack --progress --colors",
88
"lint": "eslint --cache .",
99
"karma": "karma start --single-run",
1010
"test": "npm run lint && npm run karma",
@@ -15,13 +15,23 @@
1515
"author": "",
1616
"license": "Apache-2.0",
1717
"devDependencies": {
18+
"babel-cli": "^6.16.0",
19+
"babel-core": "^6",
20+
"babel-loader": "^6.2.5",
1821
"babel-polyfill": "^6.9.1",
1922
"babel-preset-es2015-nostrict": "^6.6.2",
2023
"bluebird": "^3.4.6",
2124
"chai": "^3.5.0",
2225
"chai-as-promised": "^5.3.0",
26+
"eslint": "^3.6.0",
27+
"eslint-config-airbnb": "^12.0.0",
2328
"eslint-import-resolver-webpack": "^0.3.1",
29+
"eslint-loader": "^1.6.0",
2430
"eslint-plugin-chai-expect": "^1.1.1",
31+
"eslint-plugin-import": "^1.16.0",
32+
"eslint-plugin-jsx-a11y": "^2.2.2",
33+
"eslint-plugin-react": "^6.3.0",
34+
"expose-loader": "^0.7.1",
2535
"inject-loader": "^2.0.1",
2636
"isparta": "^4.0.0",
2737
"isparta-loader": "^2.0.0",
@@ -39,17 +49,18 @@
3949
"kw-web-suite": "^2.0.1",
4050
"mocha": "^2.5.3",
4151
"phantomjs-prebuilt": "^2.1.7",
52+
"sinon": "*",
53+
"webpack": "^1.3.0",
4254
"webpack-dev-server": "^1.14.1"
4355
},
4456
"dependencies": {
45-
"autobahn": "github:crossbario/autobahn-js-built#v0.10.1",
57+
"axios": "^0.15.1",
58+
"css-element-queries": "^0.3.2",
4659
"hammerjs": "^2.0.8",
60+
"isndarray": "^1.0.0",
4761
"jquery": "^3.0.0",
48-
"monologue.js": "^0.3.5",
4962
"mout": "^1.0.0",
50-
"paraviewweb": "^1.10.0",
5163
"ndarray": "^1.0.18",
52-
"isndarray": "^1.0.0",
5364
"ndarray-pack": "^1.2.0",
5465
"ndarray-unpack": "^1.0.0",
5566
"plotly.js": "^1.14.0"

0 commit comments

Comments
 (0)