### Creating a JS9 Web Page

### Intro to JS9-enabled Web Pages

A JS9-enabled web page contains JS9 header directives to load JS9 Javascript and CSS files, and at least one HTML "div" element of class JS9 in the body to provide a JS9 display. Other div elements can be supplied to define additional displays, menubars, statusbars, and various other plugins.

When a JS9-enabled web page is loaded, a routine is called to initialize the JS9-class divs and their underlying support routines. You can arrange to load one or more images automatically when JS9 is fully initialized. You can even specify an image to load as part of the web page query parameters.

### Adding JS9 to Your Web Page

The sample js9basics.html file shows how to add JS9 to a web page by assigning JS9 CSS classes to div elements. The js9multi.html web page goes further by showing how multiple instances of JS9 can be added using unique IDs.

To start, a few JavaScript and CSS files must be loaded into the web page. Ordinarily this is done in the page's header, which typically will look something like this:

      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=Edge;chrome=1" >
      <meta name="viewport" content="width=device-width, initial-scale=1" >
      <link type="image/x-icon" rel="shortcut icon" href="./favicon.ico">
      <link type="text/css" rel="stylesheet" href="js9support.css">
      <link type="text/css" rel="stylesheet" href="js9.css">
      <script type="text/javascript" src="js9prefs.js"></script>
      <script type="text/javascript" src="js9support.min.js"></script>
      <script type="text/javascript" src="js9.min.js"></script>
      <script type="text/javascript" src="js9plugins.js"></script>
      </head>

The js9prefs.js file is optional. It contains a JS9Prefs object that holds various default settings for JS9, e.g. default colormap and scale for image display. Feel free to edit this file to set up your own site-specific parameters. See JS9 Site Preferences for a description of the available parameters.

Order is important: The js9prefs.js file must be loaded first. The js9support.min.js must be loaded before you load js9.min.js. You must load the plugin files after you load js9.min.js. You can simply copy the order of files as specified in the JS9 demo files.

You can, of course, arrange to have your web server gzip the javascript files, using browser-based capabilities to ungzip them automatically. The JS9 web site serves pre-compressed content, as described in the Apache Module mod_deflate page.

The text file js9support.txt is a list of the files contained in js9support.css, js9support.js, js9support.min,js, and js9plugins.js.

The js9support.min.js file contains a number of required third-party software modules, including jQuery, fabric.js (2D graphics), flot (for plotting), dhtmlwindow (for light windows), etc. It is separated from js9.min.js to optimize file caching. Although JS9 will not run properly without these third-party modules, you are free to load them manually, i.e., without loading js9support.min.js itself. A manual load is useful in cases where you want a different version of one of the third-party modules (e.g., js9support.min.js loads jQuery 1.12.2, but you need to utilize jQuery 1.11.3). In such a case, we still recommend creating a single file to hold third-party modules, in order to minimize load latency.

JS9 will run without the js9plugins.js file, but with much restricted functionality. In particular, core plugins such as blending, blinking, colorbar, data cube, magnifier, panner, etc. are loaded from this file, as are analysis plugins such as encircled energy, radial projection, region statistics, and 3D plot. Note that the regions and mouse/touch core plugins are always loaded from within js9.min.js itself, since they are essential to almost all JS9 functionality.

All of these Javascript plugin files are contained in the plugins subdirectory, so you can load them individually, e.g.:

      <script type="text/javascript" src="js9prefs.js"></script>
      <script type="text/javascript" src="js9support.min.js"></script>
      <script type="text/javascript" src="js9.min.js"></script>
      <script type="text/javascript" src="plugins/core/menubar.js"></script>
      <script type="text/javascript" src="plugins/core/info.js"></script>

will load only the menubar and info display plugins.

During startup, JS9 will asynchronously load the js9worker.js file in order to create a worker process. It also will load either the astroem.js file or the astroemw.js and astroemw.wasm files, depending on whether WebAssembly is supported on your browser. Therefore, if you install JS9 manually (i.e., not using the standard configure, make, make install sequence), please ensure these files are installed as well.

The main JS9 display as well as JS9 plugins are placed on a web page by assigning JS9 classes to ordinary div elements. Important JS9 classes include:

- JS9: this class will display the main JS9 image window
- JS9Menubar: this class will display the JS9 menubar
- JS9Statusbar: this class will display a nice JS9 statusbar

Thus, for example, to place a menubar on top of a JS9 display, use:

      <div class="JS9Menubar">
      <div class="JS9">
      <div class="JS9Statusbar">

Among the many JS9 plugins that you can add to your webpage are:

- Archives & Catalogs: access to external archives and catalogs
- Bin/Filter/Section: support for extracting sections from images
- Blending: blend images using standard composite techniques
- Blinking: blink two or more images
- Colormaps: create colormaps
- Console: display a console window for executing commands
- Contours: create contour maps
- Data Cube: process 3D FITS data cubes
- Extensions: view FITS extensions
- Info: display position, value, and other information as mouse moves
- Keyboard Actions: configure keyboard actions
- Magnifier: display a magnifier window centered on the mouse position
- Mouse/Touch: configure mouse/touch actions
- Panner: display a panner window of the whole image
- Pixel Table: display a pixel value table centered on the mouse position
- Preferences: configure JS9 preferences

Any of these can be added to a web page by specifying a div element with the appropriate class:

        <div class="JS9Menubar"></div>
        <div class="JS9Toolbar"></div>
        <div class="JS9"></div>
        <div style="margin-top: 2px;">
        <div class="JS9Colorbar"></div>

NB: all of these plugins can also be displayed at any time as light windows, using the appropriate View menu options. Light windows can moved around on the page and dismissed when no longer needed. Also note that if a plugin is declared statically in a page, it will not be made available in the View menu.

Placement of JS9 div elements should follow standard web page rules and constraints. This means that div elements can be placed in any order to create different graphical views. For example, the js9basics.html page places the menubar above the image display, in keeping with the traditional layout of DS9. The entire JS9 construct is placed in a data cell of a table, next to a data cell containing data URLs.

The JS9 display has a default width and height of 512x512. You can change this by adding data-width and data-height attributes to the div. For example, to create a display of size 256x256, use:

      <div class="JS9" data-width="256px" data-height="256px">

The data-width and data-height attributes can be applied to the other JS9 divs (which can be especially useful for the menubar). Thus, for example, if you shorten the width of the Js9 display, you might also want to shorten the width of the menubar:

      <div class="JS9Menubar" data-width="256px" data-height="48px">

Multiple instances of JS9 (including the main JS9 display element and secondary plugins elements) can be added to a single web page. This is done by specifying multiple sets of JS9 elements. Each main JS9 display element should have a unique HTML id associated with it:

       <div class="JS9" id="JS9"></div>
       <div class="JS9" id="myJS9"></div>

To connect a JS9 plugin element to a given JS9 display element, you can either use an HTML id that obeys certain rules, or you can use an HTML data attribute data-js9id, as described below.

To connect a JS9 display to one or more JS9 plugins using an HTML id attribute, the plugin ids should be specified as follows:

- start with a unique ID name, e.g. "myJS9" that matches the main JS9 id
- follow with an optional dash or underscore
- finish with the type of JS9 plugin, e.g. "Menubar", "Panner", "Magnifier" "Info", "3dPlot", "RegionStats", etc.

For example:

        <div class="JS9Menubar" id="myJS9Menubar"></div>
        <div class="JS9" id="myJS9"></div>
        <div class="JS9Colorbar" id="myJS9Colorbar"></div>
        <div class="ImExamRegionStats" id="myJS9RegionStats"></div>

Note that the type of plugin is the simple name of the plugin, without the class prefix, e.g., "RegionStats" instead of "ImExamRegionStats". (Esoteric note: for non-JS9 class plugins, you can prefix the class to avoid name collisions.)

To connect a JS9 display to one or more JS9 plugins using a HTML data attribute js9id, specify the id of the main JS9 display element as its value:

        <div class="JS9Menubar" data-js9id="myJS9"></div>
        <div class="JS9" id="myJS9"></div>
        <div style="margin-top: 2px;">
        <div class="JS9Colorbar" data-js9id="myJS9"></div>

These two connection methods are equivalent. However, the js9id data attribute method also allows you to specify the single-character token * as a target value for many plugins. In this case, the display associated with the plugin is dynamically selected by clicking the mouse in a JS9 display window. In this way, a single plugin can serve several displays.

The plugins that support dynamic selection are:

- Blend
- Blink
- Colorbar
- Info
- Magnifier
- Menubar
- Panner
- Separate
- EncEnergy
- RadialProj
- Histogram
- RegionStats
- XProj
- YProj
- 3dPlot

Note that ids are not required at all if there is only one JS9 instance on the web page:

        <div class="JS9Menubar"></div>
        <div class="JS9Toolbar"></div>
        <div class="JS9"></div>
        <div style="margin-top: 2px;">
        <div class="JS9Colorbar"></div>

However, if your site needs to communicate with clients using the js9 script for external communication, you can differentiate between clients loading the same JS9-enabled web page by supplying a unique ID when the JS9 page is served.

A full example of how to define multiple instances of JS9 with ids is found, for example, in the js9multi.html file. Two DS9 instances are defined, having IDs of "JS9" (the default) and "myJS9". When "myJS9" is the display ID, "myJS9Menubar" specifies the associated menubar and "myJS9Console" specifies the associated console.

The js9.css file contains CSS directives for various parts of JS9. These can be modified (or overwritten) as needed, subject to ordinary CSS rules. In general, we recommend overwriting CSS rules by loading a site-specific CSS file after the js9.css file. This makes updating much easier.

One CSS directive worth noting is the JS9Button class, which defines the look and feel of the buttons found on the Menubar, inside plugins, etc. The JS9Button class currently is set to the JS9ClassicButton class, which mimics Mac OSX buttons in shape and color. An alternative is the JS9FlatButton class displays a flat blue button that highlights when the mouse hovers and darkens when clicked. A lightblue background is often used with this class of button. JS9 also defines a JS9BorderButton which has a blue colored border and a white background. The JS9 Menubar supports two data properties to make it easier to change the button and background:

- buttonClass: the class of button to use ("JS9ClassicButton", "JS9FlatButton", "JS9BorderButton" ... or your own class)
- backgroundColor: color of background (default: "lightblue")

The JS9 Size Demo displays different button styles.

Normally, JS9 will initialize itself automatically once the page is loaded and ready: internally, jQuery $(document).ready() calls JS9.init(). If you need to delay JS9 initialization (e.g., you are using a platform that fires $(document).ready() before the platform is really ready), you can set data-js9init to "false" on any JS9 div. In this case, you must call the init routine manually:

      JS9.init();

Until you do this, no JS9 div elements will be visible.

When JS9 is fully loaded and ready (including connection to the JS9 helper, if necessary), it fires the JS9:ready event. You can use this event to perform your own initialization:

      $(document).on("JS9:ready", function(){
          myinit();
      });

### JS9 Query Parameters

You can supply a url query parameter to a JS9-enabled web page in order to load a FITS image:

    https://js9.si.edu/?url=https://hea-www.cfa.harvard.edu/~eric/coma.fits.gz

Here, a remote FITS file is loaded using the JS9.LoadProxy() routine, (regardless of whether the remote server supports CORS.)

You can append query parameters to set various image options for the loaded image (these options are contained in the JS9.imageOpts object):

    https://js9.si.edu/js9/js9.html?url=https://hea-www.cfa.harvard.edu/~eric/coma.fits.gz&flip=y&rotate=90

Here, the same remote FITS file is loaded and then flipped along the y axis and rotated by 90 degrees.

Finally, you can rename the JS9 display using the display query parameter:

    https://js9.si.edu/js9/js9.html?display=other

Here, the display name of the standard JS9 web site is renamed to "other". This feature can be useful in cases where you are loading the same web page multiple times and want a different JS9 id for each so that they can be controlled separately.

### Menubar Styles

The default menubar has a style in which all of the major menus are shown at the top-level of the menubar. This is the classic style. JS9 also supports a mac style menubar, in which the File, Edit and View menus are placed on the left side of the menubar and the Help menu on the right. The other main menus are displayed as sub-menus within the View menu. The mac style can be specified in two ways: you can set the JS9globalOpts.menubarStyle property to "mac" in your js9prefs.js file to set the default menubar style for all menus in the page. Alternatively you can supply a data-style="mac" attribute to the Menubar div element:

      <div class="JS9Menubar" data-style="mac">

This will set the menubar style for this element only.

### Supermenus: One Menubar to Rule Them All

By default, each menubar controls one JS9 display. You can, however, create a menubar that controls multiple displays, so that a given menu selection is applied to each display (or to a specifically selected image). This is done by creating a menubar div with two special characteristics:

- the id of the menubar starts with SUPERMENU_ (it can end with anything, or nothing)
- an HTML5 data attribute called data-displays lists the JS9 displays to control or "*" for all displays

For example, to control two JS9 displays:

      <div class="JS9Menubar" id="SUPERMENU_" data-displays="JS9,myJS9"></div>

As shown, the data-displays attribute is a comma-separated list of JS9 display ids to control with this super-menu.

A super-menu acts like an ordinary menu, except that it will control all of the JS9 displays in the list. Thus, you can change multiple colormaps at once, run analysis on all displays, etc.

You also can click on an individual display to make it the selected display for the supermenu. The selected display will be highlighted, and the supermenu will target its actions at this display alone, rather than at all of the displays. Click again in a selected display (or clicking in another display) to unselect it. In this way, a single supermenu can be used to control several displays individually (akin to how the top-level Apple menu functions with regard to applications).

A supermenu displays an additional Super menu button on the left side of the menubar. This button contains a list of all displays controlled by the supermenu, with the selected display starred. You can choose a new selected display from this menu, or choose "all displays" to unselect.

Of course, you also can define a menubar for each display in order to control them individually. Since the actions of an ordinary menu and a super-menu can be mixed for a given JS9 display, the displays will not always be perfectly synchronized. In such a case, the super-menu's selected values will be tied to the first display in the data-displays list. For example, if the first display listed is at zoom 2 and the second is at zoom 4, the Zoom menu will show a current zoom value of 2.

### Adding Server-side Analysis Tasks to Your Web Page

Server-side JS9 analysis tasks can be executed using the Analysis menu, but they also can be executed directly from the web page using HTML elements (buttons, forms, etc.) To do this, a web page author simply creates the web interface and calls either JS9.RunAnalysis() (for buttons, menus, etc.) or JS9.SubmitAnalysis() (for forms). These are described in the Local Tasks web page.

### Adding Local Analysis Tasks to Your Web Page

JS9 also supports the ability to perform local analysis, i.e., analysis tasks defined and executed right on your web page, rather than being executed by a back-end server. This is accomplished by offering access to the image data and region information via a public JS9 API. See the Local Tasks for more information.

### Adding JS9 Display Windows Dynamically

JS9 display windows can be created dynamically using the JS9 Public API call JS9.LoadWindow(). You can create a light window to hold a new JS9 display on the same page or you can create an entirely separate pop-up window. See the JS9 Public API for more information.

### Adding Data Files to a Web Page

Data file links are added to a web page by supplying URLs that call the JS9.Load() routine. You also can load images automatically when the web page loads using the JS9.Preload() routine. See: Adding Data Files To a Web Page for more information.

##### Last updated: June 6, 2022