README.md file for important objects in ohif-viewerbase lib/classes/ folder

This commit is contained in:
Eloízio Salgado 2017-02-01 15:35:49 -02:00
parent 55901e2b38
commit d7d15143aa
2 changed files with 209 additions and 12 deletions

View File

@ -10,6 +10,11 @@ import { OHIF } from 'meteor/ohif:core';
// Displays Series in Viewports given a Protocol and list of Studies
export class LayoutManager {
/**
* Constructor: initializes a Layout Manager object.
* @param {DOM element} parentNode DOM element representing the parent node, which wraps the Layout Manager content
* @param {Array} studies Array of studies objects that will be rendered in the Viewer. Each object will be rendered in a div.imageViewerViewport
*/
constructor(parentNode, studies) {
OHIF.log.info('LayoutManager constructor');
@ -29,16 +34,23 @@ export class LayoutManager {
this.updateSession = _.throttle(updateSessionFn, 300);
}
/**
* Returns the number of viewports rendered, based on layoutProps
* @return {integer} number of viewports
*/
getNumberOfViewports() {
return this.layoutProps.rows * this.layoutProps.columns;
}
/**
* It creates a new viewport data. This is useful for the first rendering when no viewportData is set yet.
*/
setDefaultViewportData() {
OHIF.log.info('LayoutManager setDefaultViewportData');
const self = this;
// Get the number of vieports to be rendered
// Get the number of viewports to be rendered
const viewportsAmount = this.getNumberOfViewports();
// Store the old viewport data and reset the current
@ -112,6 +124,10 @@ export class LayoutManager {
}
}
/**
* Returns the name of the class to be added to the parentNode
* @return {string} class name following the pattern layout-<rows>-<columns>. Ex: layout-1-1, layout-2-2
*/
getLayoutClass() {
const { rows, columns } = this.layoutProps;
const layoutClass = `layout-${rows}-${columns}`;
@ -119,8 +135,12 @@ export class LayoutManager {
return layoutClass;
}
// To help other apps using ohif-viewerbase,
// so they can style on their own
/**
* Add a class to the parentNode based on the layout configuration.
* This function is helpful to style the layout of viewports.
* Besides that, each inner div.viewportContainer will have helpful classes
* as well. See viewer/components/gridLayout/ component in this ohif-viewerbase package.
*/
updateLayoutClass() {
const newLayoutClass = this.getLayoutClass();
@ -134,6 +154,12 @@ export class LayoutManager {
this.parentNode.classList.add(newLayoutClass);
}
/**
* Updates the grid with the new layout props.
* It iterates over all viewportData to render the studies
* in the viewports.
* If no viewportData or no viewports defined, it renders the default viewport data.
*/
updateViewports() {
OHIF.log.info('LayoutManager updateViewports');
@ -170,9 +196,8 @@ export class LayoutManager {
/**
* This function destroys and re-renders the imageViewerViewport template.
* It uses the data provided to load a new display set into the produced viewport.
*
* @param viewportIndex
* @param data
* @param {integer} viewportIndex index of the viewport to be re-rendered
* @param {Object} data instance data object
*/
rerenderViewportWithNewDisplaySet(viewportIndex, data) {
OHIF.log.info(`LayoutManager rerenderViewportWithNewDisplaySet: ${viewportIndex}`);
@ -215,6 +240,10 @@ export class LayoutManager {
this.updateSession();
}
/**
* Enlarge a single viewport. Useful when the layout has more than one viewport
* @param {integer} viewportIndex Index of the viewport to be enlarged
*/
enlargeViewport(viewportIndex) {
OHIF.log.info(`LayoutManager enlargeViewport: ${viewportIndex}`);
@ -249,6 +278,10 @@ export class LayoutManager {
this.updateSession();
}
/**
* Resets to the previous layout configuration.
* Useful after enlarging a single viewport.
*/
resetPreviousLayout() {
OHIF.log.info('LayoutManager resetPreviousLayout');
@ -262,6 +295,11 @@ export class LayoutManager {
this.updateViewports();
}
/**
* Toogle viewport enlargement.
* Useful for user to enlarge or going back to previous layout configurations
* @param {integer} viewportIndex Index of the viewport to be toggled
*/
toggleEnlargement(viewportIndex) {
OHIF.log.info(`LayoutManager toggleEnlargement: ${viewportIndex}`);
@ -277,7 +315,9 @@ export class LayoutManager {
}
}
// Return the display sets map sequence of display sets and viewports
/**
* Return the display sets map sequence of display sets and viewports
*/
getDisplaySetSequenceMap() {
OHIF.log.info('LayoutManager getDisplaySetSequenceMap');
@ -324,7 +364,11 @@ export class LayoutManager {
return sequenceMap;
}
// Check if all the display sets and viewports are sequenced
/**
* Check if all the display sets and viewports are sequenced
* @param {Array} definedSequenceMap Array of display set sequence map
* @return {Boolean} Returns if the display set sequence map is sequenced or not
*/
isDisplaySetsSequenced(definedSequenceMap) {
OHIF.log.info('LayoutManager isDisplaySetsSequenced');
@ -361,7 +405,12 @@ export class LayoutManager {
return isSequenced;
}
// Check if is possible to move display sets on a specific direction
/**
* Check if is possible to move display sets on a specific direction.
* It checks if looping is allowed by OHIF.uiSettings.displaySetNavigationLoopOverSeries
* @param {Boolean} isNext Represents the direction
* @return {Boolean} Returns if display sets can be moved
*/
canMoveDisplaySets(isNext) {
OHIF.log.info('LayoutManager canMoveDisplaySets');
@ -442,7 +491,11 @@ export class LayoutManager {
return true;
}
// Move display sets forward or backward in the given viewport index
/**
* Move display sets forward or backward in the given viewport index
* @param {integer} viewportIndex Index of the viewport to be moved
* @param {Boolean} isNext Represents the direction (true = forward, false = backward)
*/
moveSingleViewportDisplaySets(viewportIndex, isNext) {
OHIF.log.info(`LayoutManager moveSingleViewportDisplaySets: ${viewportIndex}`);
@ -496,7 +549,10 @@ export class LayoutManager {
this.rerenderViewportWithNewDisplaySet(viewportIndex, newDisplaySetData);
}
// Move multiple display sets forward or backward in all viewports
/**
* Move multiple display sets forward or backward in all viewports
* @param {Boolean} isNext Represents the direction (true = forward, false = backward)
*/
moveMultipleViewportDisplaySets(isNext) {
OHIF.log.info('LayoutManager moveMultipleViewportDisplaySets');
@ -588,7 +644,10 @@ export class LayoutManager {
});
}
// Move display sets forward or backward
/**
* Move display sets forward or backward
* @param {Boolean} isNext Represents the direction (true = forward, false = backward)
*/
moveDisplaySets(isNext) {
OHIF.log.info('LayoutManager moveDisplaySets');
@ -605,10 +664,20 @@ export class LayoutManager {
}
}
/**
* Check if a study is loaded into a viewport
* @param {string} studyInstanceUid Study instance Uid string
* @param {integer} viewportIndex Index of the viewport to be checked
* @return {Boolean} Returns if the given study is in the given viewport or not
*/
isStudyLoadedIntoViewport(studyInstanceUid, viewportIndex) {
return (this.viewportData.find(item => item.studyInstanceUid === studyInstanceUid && item.viewportIndex === viewportIndex) !== void 0);
}
/**
* Check if the layout has multiple rows and columns
* @return {Boolean} Return if the layout has multiple rows and columns or not
*/
isMultipleLayout() {
return this.layoutProps.row !== 1 && this.layoutProps.columns !== 1;
}

View File

@ -0,0 +1,128 @@
# Table of contents
In this document, some important objects are described. In the files there are comments that can help better undestand methods and properties.
- [ResizeViewportManager object](#the-resize-viewport-manager-object)
- [ImageSet object](#the-image-set-object)
- [Layout Manager](#the-layout-manager-object)
- [Type Safe Collections](#the-type-safe-collections)
# The Resize Viewport Manager object
This object has multiple functions to manage window resize event. It relocates Dialogs, resizes viewport elements and scrollbars and some other UI components such as Study and Series Quick Switch, when available.
## Usage
It's only necessary to bind **handleResize** function to the window resize event as follows. The **ohif:viewerbase** package needs to be imported by the referring code as well.
```javascript
import { Viewerbase } from 'meteor/ohif:viewerbase';
const ResizeViewportManager = new Viewerbase.ResizeViewportManager();
window.addEventListener('resize', ResizeViewportManager.handleResize.bind(ResizeViewportManager));
```
An example os its usage can be found in **ohif-viewerbase/client/components/viewer/viewerMain/viewerMain.js**.
# The Image Set object
An object that represents a list of images that are associated by any arbitrary criteria being thus content agnostic. Besides the main attributes (**images** and **uid**) it allows additional attributes to be appended to it (currently indiscriminately, but this should be changed).
## Usage
ImageSet constructor requires an array of SOP instances like in the example below. It's necessary to import **ohif:viewerbase**.
```javascript
import { Viewerbase } from 'meteor/ohif:viewerbase';
const imageSet = new Viewerbase.ImageSet(sopInstances);
imageSet.setAttributes({
displaySetInstanceUid: imageSet.uid,
seriesInstanceUid: seriesData.seriesInstanceUid,
seriesNumber: seriesData.seriesNumber,
seriesDescription: seriesData.seriesDescription,
numImageFrames: instances.length,
frameRate: instance.getRawValue('x00181063'),
modality: seriesData.modality,
isMultiFrame: isMultiFrame(instance)
});
// Sort instances by InstanceNumber (0020,0013)
imageSet.sortBy((a, b) => {
return (parseInt(a.getRawValue('x00200013', 0)) || 0) - (parseInt(b.getRawValue('x00200013', 0)) || 0);
});
```
Each SOP instance in this example is an instance of **OHIFInstanceMetadata** object, which is a specialization of **InstanceMetadata**. To read more about the **Metadata API** click [here](metadata/).
# The Layout Manager object
Objects of this class are responsible for creating, organizing and maintaining (manage) viewport rendering. It creates a grid, positioning viewports accordingly to it's configuration keeping all viewports data (in **viewportData** property) for easy access from other components. It support many layout configurations and some of them were fully tested: 1x1, 1x2, 1x3, 2x1, 2x2, 2x3, 3x1, 3x2, 3x3. Other configurations may work as well.
Finally it provides some useful functions to move through viewports and zoom it.
## Usage
In order to use _LayoutManager_ the **ohif:viewerbase** package needs to be imported by the referring code and instantiated as follows. An example os its usage is in **ohif-viewerbase/client/components/viewer/viewerMain/viewerMain.js**.
```javascript
import { Viewerbase } from 'meteor/ohif:viewerbase';
// Get an array of studies object. This function needs to be implemented, it does not exist.
const studies = getArrayOfStudiesObjects();
const parentElement = document.getElementById('layoutManagerTarget');
const LayoutManager = new Viewerbase.LayoutManager(parentElement, studies);
```
The default configuration is 1x1, and to change it just set **layoutProps** and call **updateViewports** to update the layout as follows.
```javascript
import { Viewerbase } from 'meteor/ohif:viewerbase';
// Get an array of studies object. This function needs to be implemented, it does not exist.
const studies = getArrayOfStudiesObjects();
const parentElement = document.getElementById('layoutManagerTarget');
const LayoutManager = new LayoutManager(parentElement, studies);
// Set the layout proprerties to 2x2 layout
LayoutManager.layoutProps = {
rows: 2,
columns: 2
};
// It will render four viewports: two in each row.
LayoutManager.updateViewports();
```
The layoutManagerTarget element will have a new class **layout-2-2** (to allow further styling) and it's inner content will a new div#imageViewerViewports that has four inner elements like the following (some elements and attributes were removed for example purpose):
```html
<div class="viewportContainer active" style="height:50%; width:50%;">
<div class="removable">
<div class="imageViewerViewport">
<canvas></canvas>
</div>
<div class="imageViewerViewportOverlay"></div>
<div class="imageViewerLoadingIndicator"></div>
<div class="imageViewerErrorLoadingIndicator"></div>
<div class="viewportOrientationMarkers"></div>
</div>
</div>
```
Each of this _div.viewportContainer_ will have some classes to help CSS specific styling accordingly to the element's position in the grid: **top**, **middle** and **bottom**. This classes are added by **viewer/components/gridLayout/** component in ohif-viewerbase package.
# The Type Safe Collections
With the introduction of the new _Study Metadata API_ in which study metadata is represented by class hierarchies (using prototype-based inheritance), the usage of standard _Minimongo_ collections as a central client-side storage for this data became no longer an option. Standard _Mongo_ and _Minimongo_ collections internally _flatten_ data (in other words, data gets serialized) before storage hence no functions or prototype chains are preserved. In that scenario, when an object is restored (fetched), what is returned is actually a flattened copy of the original object with no functions or prototype (it's no longer an instance of it's original class). As an attempt to overcome this limitation a new type of collection was intruduced: the *TypeSafeCollection*.
The _TypeSafeCollection_ is a simple list-like collection which tries to implement an API _similar_ but not compatible with _Mongo_'s API. It supports basic features like search by attribute map and ID, retrieval by index, sorting of result sets, insertion, removal and reactive operations but, unlike _Mongo_'s API, it (still) lacks support to advanced functionality like complex search criterea or flexible sorting options.
## Usage
In order to use _TypeSafeCollection_ the **ohif:viewerbase** package needs to be imported by the referring code and instantiated as follows.
Basic usage:
```javascript
import { Viewerbase } from 'meteor/ohif:viewerbase';
const users = new Viewerbase.TypeSafeCollection();
let id = users.insert({
data: {
name: 'John Doe',
age: 45
},
getName() {
return this.data.name;
}
});
```