Merge branch 'chore/update-docs-outline' of github.com:dannyrb/Viewers into chore/update-docs-outline

# Conflicts:
#	docs/latest/SUMMARY.md
This commit is contained in:
dannyrb 2019-04-19 13:41:16 -04:00
commit 46337e7f8b
8 changed files with 104 additions and 47 deletions

46
docs/README.md Normal file
View File

@ -0,0 +1,46 @@
# How To: Documentation Step-by-Step
We use [GitBook](https://www.gitbook.com/) to create our documentation. It primarily uses markdown, html, css, js, misc. plugins, and configuration to generate high quality, easy to read, and easy to maintain documentation.
## Getting Started
_Requirements:_
Make sure you have the [`gitbook-cli`](https://www.npmjs.com/package/gitbook-cli) installed globally:
> `npm install -g gitbook-cli`
### Editing and Previewing Changes
Currently, you can only edit and preview a single "book" at a time. We maintain one "book" per API major version. You can find each version's book at:
_Past Versions:_
- Template:
- `<project-root>/docs/v<versionNumber>`
- Examples:
- `/docs/v1`
- `/docs/v2`
_Latest Version:_
The latest version will always be located in `/docs/latest`
_Live Preview:_
In your terminal / command prompt:
```bash
cd /docs/latest
gitbook install
gitbook serve
```
Which should generate output like:
> starting server...
> serving book on http://localhost:4000
Navigating to the the provided URL will show a preview of what the generated book should look like. Any edits you make to the book's markdown files should automatically update in your browser.
### Publishing

View File

@ -13,7 +13,7 @@
- [Overview](advanced/extensions.md#overview)
- [Modules](advanced/extensions.md#modules)
- [Registering](advanced/extensions.md#registering-extensions)
- [OHIF Maintained Extensions](advanced/extensions.md#ohif-maintained-extensions)
- [OHIF Maintained](advanced/extensions.md#ohif-maintained-extensions)
- Connecting to Image Archives
- [DICOM Web](connecting-to-image-archives/dicomweb.md)

View File

@ -1,6 +1,6 @@
# Extensions
Extensions add new functionality to the viewer by extending existing functionality. This can be something as simple as adding a new button to the toolbar, or as complex as a new viewport capable of rendering volumes in 3D.
Extensions add new functionality to the viewer by registering one or more modules. They go one step further than configuration in that they allow us to inject custom React components, so long as they adhere to the module's interface. This can be something as simple as adding a new button to the toolbar, or as complex as a new viewport capable of rendering volumes in 3D.
## Overview
@ -36,23 +36,43 @@ class myCustomExtension {
### Modules
Modules, or [PLUGIN_TYPES](https://github.com/OHIF/ohif-core/blob/43c08a29eff3fb646a0e83a03a236ddd84f4a6e8/src/plugins.js#L1-L6), help us determine where, when, and how a plugin should be used. For example,
There are a few different kinds of modules. Each kind of module allows us to extend the viewer in a different way, and provides a consistent API for us to do so. You can find a full list of the [different types of modules `in ohif-core`](https://github.com/OHIF/ohif-core/blob/43c08a29eff3fb646a0e83a03a236ddd84f4a6e8/src/plugins.js#L1-L6). Information on each type of module, it's API, and how we determine when/where it should be used is included below:
#### Viewport
A React Component
An extension can register a Viewport Module by providing a `getViewportModule()` method that returns a React Component. The React component will receive the following props:
```js
studies: PropTypes.object,
displaySet: PropTypes.object,
viewportIndex: PropTypes.number,
children: PropTypes.node,
customProps: PropTypes.object
children: PropTypes.arrayOf(PropTypes.element)
studies: PropTypes.object,
displaySet: PropTypes.object,
viewportData: PropTypes.object, // { studies, displaySet }
viewportIndex: PropTypes.number,
children: PropTypes.node,
customProps: PropTypes.object
```
Viewport components are managed by the `LayoutManager`. Which Viewport component is used depends on:
- The Layout Configuration
- Registered SopClassHandlers
- The SopClassUID for visible/selected datasets
![Cornerstone Viewport](../assets/img/extensions-viewport.png)
<center><i>An example of three Viewports</i></center>
For a complete example implementation, [check out the OHIFCornerstoneViewport](https://github.com/OHIF/Viewers/blob/react/extensions/ohif-cornerstone-extension/src/OHIFCornerstoneViewport.js).
#### Toolbar
...
An extension can register a Toolbar Module by providing a `getToolbarModule()` method that returns a React Component. The component does not receive any props. If you want to modify or react to state, you will need to connect to the redux store.
![Toolbar Extension](../assets/img/extensions-toolbar.gif)
<center><i>A toolbar extension example</i></center>
Toolbar components are rendered in the `ToolbarRow` component.
For a complete example implementation, [check out the OHIFCornerstoneViewport's Toolbar Module](https://github.com/OHIF/Viewers/blob/react/extensions/ohif-cornerstone-extension/src/ToolbarModule.js).
#### SopClassHandler
@ -60,15 +80,16 @@ A React Component
#### Panel
...
> The panel module is not yet in use.
### Registering Extensions
Extensions are registered for the application at startup. The `ExtensionManager`, exposed by `ohif-core`, registers a list of extensions with our application's store. Each module provided by the extension becomes available via `state.plugins.availablePlugins`, and consists of three parts: id, type (PLUGIN_TYPE), and the return value of the module method.
Extensions are registered for the application at startup. The `ExtensionManager`, exposed by `ohif-core`, registers a list of extensions with our application's store. Each module provided by the extension becomes available via `state.plugins.availablePlugins`, and consists of three parts: id, type ([PLUGIN_TYPE](https://github.com/OHIF/ohif-core/blob/43c08a29eff3fb646a0e83a03a236ddd84f4a6e8/src/plugins.js#L1-L6)), and the return value of the module method.
In a future version, we will likely expose a way to provide the extensions you would like included at startup.
_app.js_
```js
import { createStore, combineReducers } from 'redux';
import OHIF from 'ohif-core';
@ -83,21 +104,8 @@ const extensions = [ new OHIFCornerstoneExtension() ];
ExtensionManager.registerExtensions(store, extensions);
```
## OHIF Maintained Extensions
A small number of powerful extensions for popular use cases are maintained by OHIF. They're co-located in the [`OHIF/Viewers`](https://github.com/OHIF/Viewers/tree/react/) repository, in the top level [`extensions/`](https://github.com/OHIF/Viewers/tree/react/extensions) directory.
{% include "./_maintained-extensions-table.md" %}
https://github.com/OHIF/ohif-core/blob/43c08a29eff3fb646a0e83a03a236ddd84f4a6e8/src/redux/reducers/plugins.js#L7-L30
- Connected Layout Manager
- AvailablePlugins that match Viewport type
ToolbarRow
- AvailablePlugins that match Toolbar type

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

View File

@ -2,7 +2,6 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import OHIF from 'ohif-core';
import ConnectedCornerstoneViewport from './ConnectedCornerstoneViewport';
import cornerstoneTools from 'cornerstone-tools';
import cornerstone from 'cornerstone-core';
import './config';
import handleSegmentationStorage from './handleSegmentationStorage.js';

View File

@ -1,5 +1,4 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ConnectedToolbarSection from './ConnectedToolbarSection';
import { ToolbarButton } from 'react-viewerbase';
import ConnectedCineDialog from './ConnectedCineDialog';

View File

@ -3,32 +3,37 @@ import { LayoutManager } from 'react-viewerbase';
import OHIF from 'ohif-core';
const mapStateToProps = state => {
const viewportPluginIds = state.plugins.availablePlugins.filter(plugin => plugin.type === OHIF.plugins.PLUGIN_TYPES.VIEWPORT).map(plugin => plugin.id);
const availablePlugins = {}
viewportPluginIds.forEach(id => {
const plugin = OHIF.plugins.availablePlugins.find(plugin => plugin.id === id);
if (plugin) {
availablePlugins[id] = plugin.component;
}
});
const viewportPluginIds = state.plugins.availablePlugins
.filter(plugin => plugin.type === OHIF.plugins.PLUGIN_TYPES.VIEWPORT)
.map(plugin => plugin.id);
// TODO Use something like state.plugins.defaultPlugin[OHIF.plugins.PLUGIN_TYPES.VIEWPORT]
let defaultPlugin;
if (viewportPluginIds && viewportPluginIds.length) {
defaultPlugin = viewportPluginIds[0];
const availablePlugins = {};
viewportPluginIds.forEach(id => {
const plugin = OHIF.plugins.availablePlugins.find(
plugin => plugin.id === id
);
if (plugin) {
availablePlugins[id] = plugin.component;
}
});
return {
layout: state.viewports.layout,
activeViewportIndex: state.viewports.activeViewportIndex,
availablePlugins,
defaultPlugin
};
// TODO Use something like state.plugins.defaultPlugin[OHIF.plugins.PLUGIN_TYPES.VIEWPORT]
let defaultPlugin;
if (viewportPluginIds && viewportPluginIds.length) {
defaultPlugin = viewportPluginIds[0];
}
return {
layout: state.viewports.layout,
activeViewportIndex: state.viewports.activeViewportIndex,
availablePlugins,
defaultPlugin
};
};
const ConnectedLayoutManager = connect(
mapStateToProps,
null
mapStateToProps,
null
)(LayoutManager);
export default ConnectedLayoutManager;