diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f133eb6..a8268f33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,142 @@ -# See elsewhere for changelog +# pypa:pywwt 0.10.0 (2020-10-21) -This project’s release notes are curated from the Git history of its main -branch. You can find them by looking at [the version of this file on the -`release` branch][branch] or the [GitHub release history][gh-releases]. +- Fix build for traitlets >= 5.0 and in fact start requiring it. +- Update minimum Python version to 3.7, as required by traitlets 5. +- Require version 1.0 of the NPM package, so that we extrapolate clock + information from data provided by the JavaScript layer. This dramatically + reduces the level of traffic between the JS and Python layers. +- Adopt Cranko for release automation, and revamp the continuous integration + infrastructure to implement such automation. -[branch]: https://github.com/WorldWideTelescope/pywwt/blob/release/CHANGELOG.md -[gh-releases]: https://github.com/WorldWideTelescope/pywwt/releases + +# pywwt 0.9.0 (2020-08-29) + +- pywwt now obtains the WWT WebGL SDK code from web.wwtassets.org, rather than + a private copy hosted on the pywwt GitHub Pages instance. +- Live notebook links now point to mybinder.org rather than the old private WWT + instance of BinderHub, because HTTPS support is now working! +- Fix Jupyter server plumbing when operating in the JupyterHub single-user + environment. + + +# pywwt 0.8.0 (2020-04-03) + +- Improve performance when changing size parameters for tabular layers. In these + cases, the performance is e.g. more than 1000x better for a 50,000 row + dataset. [#224] +- Improve performance when changing colormap parameters for tabular + layers, for a subset of colormaps. In these cases, the performance + is e.g. more than 1000x better for a 50,000 row dataset. [#223] +- Added a `cmap` parameter on image layers to control the colormap. [#244] +- Incorporate time series behavior for data layers; add method that + returns current time in the viewer. [#187] +- Drop support for Python 2.7 and now require at least Python 3.6. [#259] +- Fix compatibility with Jupyter 2.0. [#260] + + +# pywwt 0.7.0 (2019-09-20) + +- You can now save your WWT views as interactive figures to be used in journal + articles! (Actually, they're just standalone web pages, so they can be used + anywhere you've got a web server.) This feature is new so it will still have + some rough edges — keep your eyes open for improvements. And the docs haven't + been written yet :-( [#215, #227] +- Relatedly, there is new first-draft support for interactive controls for + image layers through the `image.controls` meta-property. This will also + evolve over the next few releases. [#217] +- Initial support for data layers with Cartesian (XYZ) rather than spherical + (lat, lon, alt) coordinates. [#190] +- Fix compatibility with the JupyterLab 1.0.x series. [#216, #219, #221] +- Expose all available imagery layers. [#220] +- Validate coordinate frame names used with tabular data layers. [#195] +- Fix the widget `reset` method . [#212] +- Various improvements to CI infrastructure, docs, landing pages, etc. [#218, + #225, #228, #229, #230] + + +# pywwt 0.6.1 (2019-06-10) + +- Fixed issues when calling `reset()`. [#212] +- Fixed resizing issues in Jupyter Lab. [#216] +- Fixed server URL when using Jupyter Lab. [#219] + + +# pywwt 0.6.0 (2019-05-29) + +- Implement support for color-coding and scaling points in layers according + to table attributes. [#183] +- Removed `load_fits_data` and added `layers.add_image_layer` instead, + which provides control over the image stretch, and renamed + `layers.add_data_layer` to `layers.add_table_layer`. [#188, #201] +- Added support for drag and drop events in Qt widget. [#202] +- Added support for `get_center` for the Jupyter widget, and add a new + `get_fov` method to get the current field of view. [#206] +- Fixed compatibility with notebook>=5.7.6 which requires mime + types for served files to be correct. [#192, #208] +- Fixed display of table layers on Windows. [#207] + + +# pywwt 0.5.3 (2019-01-16) + +- Exposed option to turn off large-scale SDSS data in 3D mode, improving + performance. [#176] +- Make sure default altitude type is set correctly. [#176] + + +# pywwt 0.5.2 (2019-01-08) + +- Added instructions for using Jupyter Lab. [#170] +- Fixed `set_view('Mars')`. [#171] +- Fixed issue with layers not appearing under certain circumstances. [#173] + + +# pywwt 0.5.1 (2019-01-04) + +- Fixed a bug that caused layers to not immediately update when updating + data. [#167] +- Fixed a bug that caused some columns to be pre-assigned to e.g. size_att + based on column name. [#167] + + +# pywwt 0.5.0 (2019-01-04) + +- Fixed issues with zooming using trackpad/scroll wheel. [#166] +- Added support for customizing the layer marker type (`marker_type`), the + option to specify whether the marker size is absolute or relative to the + screen (`marker_scale`), and the option to show points on the far side of + an object (`far_side_visible`). [#165] +- Fixed a bug that caused issues with the distance/altitude of points when not + centered on the Earth. [#165] + + +# pywwt 0.4.1 (2018-12-23) + +- Work around an issue with getting base URLs on e.g. mybinder. +- Improvements to documentation. [#160, #164] + + +# pywwt 0.4.0 (2018-12-20) + +- Added keyboard shortcuts for movement in-viewer. [#81] +- Disable crosshairs by default. [#157] +- Added `pause_time` and `play_time` for controlling time and make it + possible to control the rate of passage of time. [#146, #152] +- Added support for displaying fields of view for common telescope. [#102] +- Added `minor_orbits` and `stars` attributes to control the visibility + of minor orbits and stars in solar system mode. [#145] +- Added support for showing tables of data using layers. [#122, #136, #139, #140, #143, #147, #150] +- Added `load_fits_data` method for Qt and Jupyter clients. [#78] +- Added support for non-sky modes (e.g. solar system mode). [#74, #83, #95, #98] +- Added GUI controls for imagery layers using the `layer_controls` attribute. [#64] +- Added support for exploring available imagery layers. [#71] +- Added support for showing circle collections with annotations. [#54] +- Switch to use OpenGL API. [#73] +- Fixed compatibility with Jupyter Lab. [#63, #65] +- Fixed compatibility with older versions of Qt. [#133] +- Fixed compatibility with unicode strings for colors on Python 2. [#105] +- Improved documentation. [#60, #70, #84, #101, #109] + + +# pywwt 0.3.0 (2017-12-20) + +- Initial version with changelog diff --git a/ci/azure-build-and-test.yml b/ci/azure-build-and-test.yml index 2fdd526a..7d01c971 100644 --- a/ci/azure-build-and-test.yml +++ b/ci/azure-build-and-test.yml @@ -56,7 +56,7 @@ jobs: set -euo pipefail source activate-conda.sh set -x - \conda create -y -n build setuptools matplotlib pip pyopengl pyqt python="$PYTHON_SERIES" qtpy + \conda create -y -n build setuptools matplotlib pip pyopengl 'pyqt>=5.12' python="$PYTHON_SERIES" qtpy conda activate build pip install $BASH_WORKSPACE/sdist/*.tar.gz displayName: Install from sdist @@ -134,7 +134,7 @@ jobs: set -euo pipefail source activate-conda.sh set -x - \conda create -y -n build setuptools matplotlib pip pyopengl pyqt python=3.8 qtpy + \conda create -y -n build setuptools matplotlib pip pyopengl 'pyqt>=5.12' python=3.8 qtpy conda activate build pip install $BASH_WORKSPACE/sdist/*.tar.gz displayName: Install from sdist @@ -178,7 +178,7 @@ jobs: set -euo pipefail source activate-conda.sh set -x - \conda create -y -n build setuptools matplotlib pip pyopengl pyqt python=3.8 qtpy + \conda create -y -n build setuptools matplotlib pip pyopengl 'pyqt>=5.12' python=3.8 qtpy conda activate build pip install $BASH_WORKSPACE/sdist/*.tar.gz displayName: Install from sdist diff --git a/ci/azure-deployment.yml b/ci/azure-deployment.yml index 686ebdbc..609c29aa 100644 --- a/ci/azure-deployment.yml +++ b/ci/azure-deployment.yml @@ -76,7 +76,7 @@ jobs: # If we ever become a monorepo, we'll need to figure out how to make sure # that we only upload the proper packages. - if cranko show if-released --exit-code pywwt ; then + if cranko show if-released --exit-code pypa:pywwt ; then twine upload $BASH_WORKSPACE/sdist/*.tar.gz fi displayName: Publish PyPI releases diff --git a/docs/installation.rst b/docs/installation.rst index 95cc4d78..c7071902 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -109,7 +109,7 @@ If you want to use the Jupyter widget, you will also need to run:: And if you additionally want to use the widget in JupyterLab, run:: - jupyter labextension install . + jupyter labextension install frontend jupyter labextension list # check that the output shows pywwt as enabled and OK Besides ``pywwt``, the ``@jupyter-widgets/jupyterlab-manager`` and diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md index 4f7a0f8a..18bbc578 100644 --- a/frontend/CHANGELOG.md +++ b/frontend/CHANGELOG.md @@ -1,3 +1,10 @@ +# npm:pywwt 1.0.0 (2020-10-21) + +- Address #258 by transmitting WWT clock information using a reference point and + a rate, rather than constantly transmitting the current time. Dramatically + reduces JS <=> Python traffic. +- Tidy up the JavaScript files. + # npm:pywwt 0.9.1 (2020-10-18) - First release with version number decoupled from the pywwt Python package. diff --git a/frontend/lib/embed.js b/frontend/lib/embed.js deleted file mode 100644 index a1429a78..00000000 --- a/frontend/lib/embed.js +++ /dev/null @@ -1,9 +0,0 @@ -// Entry point for the unpkg bundle containing custom model definitions. -// -// It differs from the notebook bundle in that it does not need to define a -// dynamic baseURL for the static assets and may load some css that would -// already be loaded by the notebook otherwise. - -// Export widget models and views, and the npm package version number. -module.exports = require('./wwt.js'); -module.exports['version'] = require('../package.json').version; diff --git a/frontend/lib/extension.js b/frontend/lib/extension.js deleted file mode 100644 index 5735a62e..00000000 --- a/frontend/lib/extension.js +++ /dev/null @@ -1,19 +0,0 @@ -// This file contains the javascript that is run when the notebook is loaded. -// It contains some requirejs configuration and the `load_ipython_extension` -// which is required for any notebook extension. - -// Configure requirejs -if (window.require) { - window.require.config({ - map: { - "*" : { - "pywwt": "nbextensions/pywwt/index", - } - } - }); -} - -// Export the required load_ipython_extension -module.exports = { - load_ipython_extension: function() {} -}; diff --git a/frontend/lib/index.js b/frontend/lib/index.js index 298db72e..3b693e06 100644 --- a/frontend/lib/index.js +++ b/frontend/lib/index.js @@ -1,7 +1,2 @@ -// Entry point for the notebook bundle containing custom model definitions. -// -// Setup notebook base URL - -// Export widget models and views, and the npm package version number. module.exports = require('./wwt.js'); module.exports['version'] = require('../package.json').version; diff --git a/frontend/lib/plugin.js b/frontend/lib/jupyterlab.js similarity index 72% rename from frontend/lib/plugin.js rename to frontend/lib/jupyterlab.js index 585167cf..6c3115d1 100644 --- a/frontend/lib/plugin.js +++ b/frontend/lib/jupyterlab.js @@ -1,3 +1,6 @@ +// This file implements the JupyterLab extension, as linked up through this +// module's `package.json` file (`jupyerlab.extension` keyword). + var wwt = require('./index'); var base = require('@jupyter-widgets/base'); diff --git a/frontend/lib/version.js b/frontend/lib/version.js deleted file mode 100644 index d29068f7..00000000 --- a/frontend/lib/version.js +++ /dev/null @@ -1 +0,0 @@ -export const version = require('../package.json').version; diff --git a/frontend/lib/wwt.js b/frontend/lib/wwt.js index e1fca17c..2da73dc9 100644 --- a/frontend/lib/wwt.js +++ b/frontend/lib/wwt.js @@ -1,7 +1,7 @@ var widgets = require('@jupyter-widgets/base'); var _ = require("underscore"); -var version = require('./version').version; +var version = require('./index').version; var WWTModel = widgets.DOMWidgetModel.extend({ defaults: _.extend(widgets.DOMWidgetModel.prototype.defaults(), { @@ -24,7 +24,7 @@ var WWTModel = widgets.DOMWidgetModel.extend({ var WWTView = widgets.DOMWidgetView.extend({ - initialize : function() { + initialize: function() { // We use an iframe to show WorldWideTelescope, because it does not // otherwise support having multiple instances running on the same @@ -42,11 +42,14 @@ var WWTView = widgets.DOMWidgetView.extend({ WWTView.__super__.initialize.apply(this, arguments); + // Monitor the view data so that we can transmit updates. We handle the + // clock specially so as not to be sending updates continually. + this.lastClockUpdate = 0; var self = this; - setInterval(function () { self.update_view_data(); }, 100); + setInterval(function () { self.update_view_data(); }, 150); }, - _try_init_wwt_window : function() { + _try_init_wwt_window: function() { iframe = this.el.getElementsByTagName('iframe')[0]; if (iframe != null) { this.wwt_window = iframe.contentWindow; @@ -80,17 +83,17 @@ var WWTView = widgets.DOMWidgetView.extend({ }, processLuminoMessage: function(msg) { - // We listen for lumino resize events so that when Jupyter Lab is - // used, we adjust the canvas size to the tab/panel in Jupyter Lab. - // See relayout for more details. - WWTView.__super__.processLuminoMessage.apply(this, arguments); - switch (msg.type) { - case 'resize': - case 'after-show': - this.relayout(); - break; - } - }, + // We listen for lumino resize events so that when Jupyter Lab is + // used, we adjust the canvas size to the tab/panel in Jupyter Lab. + // See relayout for more details. + WWTView.__super__.processLuminoMessage.apply(this, arguments); + switch (msg.type) { + case 'resize': + case 'after-show': + this.relayout(); + break; + } + }, relayout: function() { // Only do resizing if we are not in the notebook context but in a @@ -145,42 +148,52 @@ var WWTView = widgets.DOMWidgetView.extend({ }, handle_custom_message: function(msg) { + if (this.wwt_window == null && !this._try_init_wwt_window()) { + return; + } - if (this.wwt_window == null && !this._try_init_wwt_window()) { - return; - } - - if (msg['url'] != null && msg['url'].slice(4) == '/wwt') { - msg['url'] = this.wwt_base_url + msg['url']; - } - - // If the user has created a view for our widget and then hidden it, our - // iframe gets removed and all sorts of things stop working (e.g., - // Chrome will refuse to send XMLHttpRequests anymore, and Firefox won't - // set timeouts). If we let exceptions from these operations bubble up, - // they break the code that applies widget events to *all* views, which - // then breaks the JupyterLab use case of (1) setting up a WWT widget, - // (2) creating a view of it in a separate tab, and then (3) hiding the - // view in the original notebook, because the second view will never - // receive any messages. We should handle things better when widgets get - // hidden, but in the meantime, try to keep things limping along by - // swallowing exceptions here. Note that this approach will mean that - // the two views will get out of sync regarding, e.g., image layers that - // have been loaded. - - try { - this.wwt_window.wwt_apply_json_message(this.wwt_window.wwt, msg); - - if (msg['event'] === 'center_on_coordinates') { - this.update_view_data(); + if (msg['url'] != null && msg['url'].slice(4) == '/wwt') { + msg['url'] = this.wwt_base_url + msg['url']; + } + + // If the user has created a view for our widget and then hidden it, our + // iframe gets removed and all sorts of things stop working (e.g., + // Chrome will refuse to send XMLHttpRequests anymore, and Firefox won't + // set timeouts). If we let exceptions from these operations bubble up, + // they break the code that applies widget events to *all* views, which + // then breaks the JupyterLab use case of (1) setting up a WWT widget, + // (2) creating a view of it in a separate tab, and then (3) hiding the + // view in the original notebook, because the second view will never + // receive any messages. We should handle things better when widgets get + // hidden, but in the meantime, try to keep things limping along by + // swallowing exceptions here. Note that this approach will mean that + // the two views will get out of sync regarding, e.g., image layers that + // have been loaded. + + try { + this.wwt_window.wwt_apply_json_message(this.wwt_window.wwt, msg); + + switch(msg['event']) { + case 'load_tour': + case 'resume_tour': + case 'pause_tour': + case 'resume_time': + case 'pause_time': + case 'set_datetime': + this.lastClockUpdate = 0; + break; + } + } catch (e) { + console.log('failed to process custom_message for a pyWWT Jupyter widget view:'); + console.log(msg); + (console.error || console.log).call(console, e.stack || e); } - } catch (e) { - console.log('failed to process custom_message for a pyWWT Jupyter widget view:'); - console.log(msg); - (console.error || console.log).call(console, e.stack || e); - } }, + // This function is called very frequently, so we make sure to not send + // updates unless something has changed. Ideally we'd be triggered on + // updates rather than polling, but we're not well set up to do that right + // now. update_view_data: function () { if ((this.wwt_window == null && !this._try_init_wwt_window()) || !this.wwt_window.wwt) { return; @@ -189,35 +202,58 @@ var WWTView = widgets.DOMWidgetView.extend({ var needUpdate = false; if (this.model.get('_ra') != this.wwt_window.wwt.getRA()) { - this.model.set({ '_ra': this.wwt_window.wwt.getRA() }); - needUpdate = true; + this.model.set({ '_ra': this.wwt_window.wwt.getRA() }); + needUpdate = true; } if (this.model.get('_dec') != this.wwt_window.wwt.getDec()) { - this.model.set({ '_dec': this.wwt_window.wwt.getDec() }); - needUpdate = true; + this.model.set({ '_dec': this.wwt_window.wwt.getDec() }); + needUpdate = true; } if (this.model.get('_fov') != this.wwt_window.wwt.get_fov()) { - this.model.set({ '_fov': this.wwt_window.wwt.get_fov() }); - needUpdate = true; + this.model.set({ '_fov': this.wwt_window.wwt.get_fov() }); + needUpdate = true; } - var stc = this.wwt_window.wwtlib.SpaceTimeController; - if (this.model.get('_datetime') != stc.get_now().toISOString()) { - this.model.set({ '_datetime': stc.get_now().toISOString() }); - needUpdate = true; + // By default, the clock is always ticking. We throttle updates by having + // the listener extrapolate the clock itself given reference times and the + // "time rate". + // + // For compatibility reasons, the engine's time must be exposed using a + // trait named `_datetime`. If any of the time-related parameters are + // changed discontinuously, set lastClockUpdate to 0 to force an update. + var nowUnixMs = Date.now(); + var updateTimeParams = (nowUnixMs - this.lastClockUpdate) > 60000; + + if (updateTimeParams) { + var stc = this.wwt_window.wwtlib.SpaceTimeController; + var rate = stc.get_timeRate(); + + if (!stc.get_syncToClock()) { + // When time is paused by setting syncToClock to false, the WWT + // "rate" remains unchanged, but as far as the Python layer is + // concerned, the rate should be 0. + rate = 0.0; + } + + this.model.set({ + '_datetime': stc.get_now().toISOString(), + '_systemDatetime': (new Date()).toISOString(), + '_timeRate': rate + }); + + this.lastClockUpdate = nowUnixMs; + needUpdate = true; } if (needUpdate) { - this.touch(); + this.touch(); } } - }); - module.exports = { - WWTModel : WWTModel, - WWTView : WWTView + WWTModel: WWTModel, + WWTView: WWTView }; diff --git a/frontend/package.json b/frontend/package.json index 82a95ea5..f4b90071 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -4,7 +4,8 @@ "url": "https://github.com/WorldWideTelescope/pywwt/issues" }, "dependencies": { - "@jupyter-widgets/base": "^2 || ^3" + "@jupyter-widgets/base": "^2 || ^3", + "underscore": "^1" }, "description": "AAS WorldWide Telescope from Python", "devDependencies": { @@ -18,7 +19,7 @@ ], "homepage": "https://github.com/WorldWideTelescope/pywwt", "jupyterlab": { - "extension": "lib/plugin" + "extension": "lib/jupyterlab" }, "keywords": [ "jupyter", @@ -38,5 +39,5 @@ "clean": "shx rm -rf dist", "pywwt-export": "npm run build && npm pack && node pywwt-export.js" }, - "version": "0.9.1" + "version": "1.0.0" } diff --git a/pyproject.toml b/pyproject.toml index e2bb03df..43ca2518 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,4 +9,4 @@ annotated_files = [ ] [tool.cranko.internal_dep_versions] -"npm:pywwt" = "manual:^0.9.0" +"npm:pywwt" = "thiscommit:29e64671926d2fce87bbcad78d54980a" diff --git a/pywwt/_version.py b/pywwt/_version.py index 79f4d964..e1570132 100644 --- a/pywwt/_version.py +++ b/pywwt/_version.py @@ -1,4 +1,4 @@ -version_info = (0, 9, 0, 'final', 0) # cranko project-version tuple +version_info = (0, 10, 0, 'final', 0) # cranko project-version tuple _specifier_ = {'alpha': '.a', 'beta': '.b', 'candidate': '.rc', 'final': '', 'dev': '.dev'} diff --git a/pywwt/jupyter.py b/pywwt/jupyter.py index 9f495740..9093a5df 100644 --- a/pywwt/jupyter.py +++ b/pywwt/jupyter.py @@ -3,6 +3,7 @@ # because we instead use JSON messages to transmit any changes between the # Python and Javascript parts so that we can re-use this for the Qt client. +from astropy.time import Time import ipywidgets as widgets from traitlets import Unicode, Float, default, link, directional_link @@ -14,7 +15,7 @@ __all__ = ['WWTJupyterWidget'] -_npm_version = '^0.9.0' # cranko internal-req npm:pywwt +_npm_version = '^1.0.0' # cranko internal-req npm:pywwt VIEW_MODULE_VERSION = _npm_version MODEL_MODULE_VERSION = _npm_version @@ -34,12 +35,17 @@ class WWTJupyterWidget(widgets.DOMWidget, BaseWWTWidget): _view_module_version = Unicode(VIEW_MODULE_VERSION).tag(sync=True) _model_module_version = Unicode(MODEL_MODULE_VERSION).tag(sync=True) + # wwt=None tag needed to avoid linkage to 'wwt.settings.set_' type traits + # (see _on_trait_change() in core.py) _ra = Float(0.0).tag(sync=True, wwt=None) _dec = Float(0.0).tag(sync=True, wwt=None) _fov = Float(60.0).tag(sync=True, wwt=None) + # this is the WWT engine's clock at last check-in: _datetime = Unicode('2017-03-09T12:30:00').tag(sync=True, wwt=None) - # wwt=None tag needed to avoid linkage to 'wwt.settings.set_' type traits - # (see _on_trait_change() in core.py) + # this is system clock at last check-in: + _systemDatetime = Unicode('2017-03-09T12:30:00').tag(sync=True, wwt=None) + # this is the rate at which the WWT engine clock proceeds relative to the system clock: + _timeRate = Float(1.0).tag(sync=True, wwt=None) def __init__(self): widgets.DOMWidget.__init__(self) @@ -67,7 +73,10 @@ def _get_view_data(self, field): elif field == 'fov': return self._fov elif field == 'datetime': - return self._datetime + engine_time = Time(self._datetime, format='isot') + system_time = Time(self._systemDatetime, format='isot') + engine_delta = self._timeRate * (Time.now() - system_time) + return engine_time + engine_delta else: raise ValueError("'field' should be one of: 'ra', 'dec', " "'fov', or 'datetime'") diff --git a/pywwt/nbextension/static/extension.js b/pywwt/nbextension/static/extension.js index 903980a3..81a568e8 100644 --- a/pywwt/nbextension/static/extension.js +++ b/pywwt/nbextension/static/extension.js @@ -1,3 +1,10 @@ ++// This file contains the Javascript that implements the Jupyter notebook ++// extension, as linked up in `pywwt/nbextension/__init__.py` with the `require` ++// keyword. ++// ++// It contains some requirejs configuration and the `load_ipython_extension` ++// which is required for any notebook extension. + define(function() { "use strict"; @@ -8,6 +15,7 @@ define(function() { }, } }); + // Export the required load_ipython_extention return { load_ipython_extension : function() {} diff --git a/pywwt/nbextension/static/wwt_json_api.js b/pywwt/nbextension/static/wwt_json_api.js index eb8e91fb..e65adade 100644 --- a/pywwt/nbextension/static/wwt_json_api.js +++ b/pywwt/nbextension/static/wwt_json_api.js @@ -129,7 +129,6 @@ function wwt_apply_json_message(wwt, msg) { break; case 'annotation_set': - var name = msg['setting']; // TODO: nice error message if annotation doesn't exist annotation = wwt.annotations[msg['id']]; @@ -137,7 +136,6 @@ function wwt_apply_json_message(wwt, msg) { break; case 'remove_annotation': - var name = msg["setting"]; // TODO: nice error message if annotation doesn't exist shape = wwt.annotations[msg['id']]; @@ -145,7 +143,6 @@ function wwt_apply_json_message(wwt, msg) { break; case 'circle_set_center': - var name = msg["setting"]; // TODO: nice error message if annotation doesn't exist circle = wwt.annotations[msg['id']]; @@ -153,7 +150,6 @@ function wwt_apply_json_message(wwt, msg) { break; case 'polygon_add_point': - var name = msg["setting"]; // same TODO as above polygon = wwt.annotations[msg['id']]; @@ -161,7 +157,6 @@ function wwt_apply_json_message(wwt, msg) { break; case 'line_add_point': - var name = msg["setting"]; // same TODO as above line = wwt.annotations[msg['id']]; @@ -169,9 +164,7 @@ function wwt_apply_json_message(wwt, msg) { break; case 'set_datetime': - var date = new Date(msg['isot']); - stc = wwtlib.SpaceTimeController; stc.set_timeRate(1); stc.set_now(date); @@ -190,16 +183,13 @@ function wwt_apply_json_message(wwt, msg) { break; case 'image_layer_create': - layer = wwt.loadFits(msg['url']); layer._stretch_version = 0; layer._cmap_version = 0; - wwt.layers[msg['id']] = layer; break; case 'image_layer_stretch': - var layer = wwt.layers[msg['id']]; if (layer.get_imageSet() == null) { @@ -228,42 +218,33 @@ function wwt_apply_json_message(wwt, msg) { } break; - case 'image_layer_cmap': - - // See image_layer_stretch for why we need to do what we do below - - var layer = wwt.layers[msg['id']]; - - if (layer.get_imageSet() == null) { - setTimeout(function(){ wwt_apply_json_message(wwt, msg); }, 200); - } else { - if (msg['version'] > layer._cmap_version) { - layer.set_colorMapperName(msg['cmap']); - layer._cmap_version = msg['version']; - } + case 'image_layer_cmap': + // See image_layer_stretch for why we need to do what we do below + var layer = wwt.layers[msg['id']]; + if (layer.get_imageSet() == null) { + setTimeout(function(){ wwt_apply_json_message(wwt, msg); }, 200); + } else { + if (msg['version'] > layer._cmap_version) { + layer.set_colorMapperName(msg['cmap']); + layer._cmap_version = msg['version']; } - break; + } + break; case 'image_layer_set': - var layer = wwt.layers[msg['id']]; var name = msg['setting']; - layer["set_" + name](msg['value']); - break; case 'image_layer_remove': - // TODO: could combine with table_layer_remove - var layer = wwt.layers[msg['id']]; wwtlib.LayerManager.deleteLayerByID(layer.id, true, true); break; case 'table_layer_create': - // Decode table from base64 csv = atob(msg['table']) @@ -306,7 +287,6 @@ function wwt_apply_json_message(wwt, msg) { break; case 'table_layer_update': - var layer = wwt.layers[msg['id']]; // Decode table from base64 @@ -319,7 +299,6 @@ function wwt_apply_json_message(wwt, msg) { break; case 'table_layer_set': - var layer = wwt.layers[msg['id']]; var name = msg['setting']; @@ -351,13 +330,10 @@ function wwt_apply_json_message(wwt, msg) { break; case 'table_layer_remove': - var layer = wwt.layers[msg['id']]; wwtlib.LayerManager.deleteLayerByID(layer.id, true, true); break; - } - } // We need to do this so that wwt_apply_json_message is available as a global