docs: Add v3 docs using docusaurus (Merge pull request #2468 from OHIF/feat/v2-main-docusaurus-netlify-monorepo)

This commit is contained in:
Erik Ziegler 2021-07-21 14:01:06 +02:00 committed by GitHub
commit 44e935f209
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
649 changed files with 13801 additions and 21514 deletions

View File

@ -15,11 +15,12 @@ node -v
yarn run build:ci
mkdir -p ./.netlify/www/pwa
mv platform/viewer/dist/* .netlify/www/pwa -v
echo 'Web application built and copied'
# Build && Move script output
# yarn run build:package
# Build && Move Docz Output
# Build && Move Docz Output (for the UI Component Library)
# Using local yarn install to prevent Gatsby from needing to access
# node_modules above the platform/ui folder
cd platform/ui
@ -28,6 +29,16 @@ yarn run build
cd ../..
mkdir -p ./.netlify/www/ui
mv platform/ui/.docz/dist/* .netlify/www/ui -v
echo 'UI Component docs (docz) built and copied'
# Build && Move Docusaurus Output (for the docs themselves)
cd platform/docs
yarn install
yarn run build
cd ../..
mkdir -p ./.netlify/www/docs
mv platform/docs/build/* .netlify/www/docs -v
echo 'Docs built (docusaurus) and copied'
# Cache all of the node_module dependencies in
# extensions, modules, and platform packages

View File

@ -6,3 +6,5 @@
/pwa/* /pwa/index.html 200
# UI Demo
/ui/* /ui/index.html 200
# UI Demo
/docs/* /docs/index.html 200

View File

@ -9,7 +9,10 @@
<ul>
<li>
<a href="/pwa">PWA: Viewer</a>
<a href="/pwa">OHIF Viewer</a>
</li>
<li>
<a href="/docs">Documentation</a>
</li>
<li>
<a href="/ui">UI: Component Library</a>

View File

@ -9,12 +9,13 @@ const loadShadersRule = require('./rules/loadShaders.js');
const loadWebWorkersRule = require('./rules/loadWebWorkers.js');
const transpileJavaScriptRule = require('./rules/transpileJavaScript.js');
// ~~ PLUGINS
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
.BundleAnalyzerPlugin;
const TerserJSPlugin = require('terser-webpack-plugin');
// ~~ ENV VARS
const NODE_ENV = process.env.NODE_ENV;
const QUICK_BUILD = process.env.QUICK_BUILD;
const BUILD_NUM = process.env.CIRCLE_BUILD_NUM || '0';
const { UnusedFilesWebpackPlugin } = require("unused-files-webpack-plugin");
//
dotenv.config();
@ -30,7 +31,7 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => {
const config = {
mode: isProdBuild ? 'production' : 'development',
devtool: isProdBuild ? 'source-map' : 'cheap-module-eval-source-map',
devtool: isProdBuild ? 'source-map' : 'eval',
entry: {
app: `${SRC_DIR}/index.js`,
},
@ -55,9 +56,16 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => {
transpileJavaScriptRule(mode),
loadWebWorkersRule,
loadShadersRule,
{
test: /\.m?js/,
resolve: {
fullySpecified: false,
},
},
],
},
resolve: {
mainFields: ['browser', 'module', 'main'],
alias: {
// Viewer project
'@': path.resolve(__dirname, '../platform/viewer/src'),
@ -81,6 +89,7 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => {
extensions: ['.js', '.jsx', '.json', '*'],
// symlinked resources are resolved to their real path, not their symlinked location
symlinks: true,
fallback: { fs: false, path: false },
},
plugins: [
new webpack.DefinePlugin({
@ -89,7 +98,9 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => {
'process.env.DEBUG': JSON.stringify(process.env.DEBUG),
'process.env.APP_CONFIG': JSON.stringify(process.env.APP_CONFIG || ''),
'process.env.PUBLIC_URL': JSON.stringify(process.env.PUBLIC_URL || '/'),
'process.env.VERSION_NUMBER': JSON.stringify(process.env.VERSION_NUMBER || PACKAGE.version || ''),
'process.env.VERSION_NUMBER': JSON.stringify(
process.env.VERSION_NUMBER || PACKAGE.version || ''
),
'process.env.BUILD_NUM': JSON.stringify(BUILD_NUM),
/* i18n */
'process.env.USE_LOCIZE': JSON.stringify(process.env.USE_LOCIZE || ''),
@ -99,33 +110,23 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => {
'process.env.LOCIZE_API_KEY': JSON.stringify(
process.env.LOCIZE_API_KEY || ''
),
'process.env.REACT_APP_I18N_DEBUG': JSON.stringify(
process.env.REACT_APP_I18N_DEBUG || ''
),
}),
new UnusedFilesWebpackPlugin({
failOnUnused: false,
globOptions: {
ignore: [
"node_modules/**/*",
"index.umd.js",
"sanity.test.js",
"__mocks__/fileMock.js",
"__tests__/globalSetup.js"
]
}
}),
// Uncomment to generate bundle analyzer
// new BundleAnalyzerPlugin(),
],
// Fix: https://github.com/webpack-contrib/css-loader/issues/447#issuecomment-285598881
// For issue in cornerstone-wado-image-loader
node: {
/*node: {
fs: 'empty',
},
},*/
};
if (isProdBuild) {
config.optimization.minimizer = [
new TerserJSPlugin({
// Supports:
// source-map and inline-source-map
sourceMap: isProdBuild && !isQuickBuild,
parallel: true,
terserOptions: {},
}),

View File

@ -2,7 +2,7 @@
<!-- markdownlint-disable -->
<div align="center">
<h1>OHIF Medical Imaging Viewer</h1>
<p><strong>The OHIF Viewer</strong> is a zero-footprint medical image viewer provided by the <a href="http://ohif.org/">Open Health Imaging Foundation (OHIF)</a>. It is a configurable and extensible progressive web application with out-of-the-box support for image archives which support <a href="https://www.dicomstandard.org/dicomweb/">DICOMweb</a>.</p>
<p><strong>The OHIF Viewer</strong> is a zero-footprint medical image viewer provided by the <a href="https://ohif.org/">Open Health Imaging Foundation (OHIF)</a>. It is a configurable and extensible progressive web application with out-of-the-box support for image archives which support <a href="https://www.dicomstandard.org/dicomweb/">DICOMweb</a>.</p>
</div>

1
docs/.gitignore vendored
View File

@ -1 +0,0 @@
./_book/*

View File

@ -1 +0,0 @@
docs.ohif.org

View File

@ -1,47 +0,0 @@
# 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:
(Note that gitbook 3.2.3 works with node 10.19.0 and node 10.24.0, but not with node 14.x.)
> `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

@ -1,3 +0,0 @@
# Netlify redirects
# SPA rules for our docs
/* /index.html 200

View File

@ -1 +0,0 @@
_book/

View File

@ -1,95 +0,0 @@
<div class='row'>
<div class='column' style='text-align: right; padding: 0 20px'>
<strong>Looking for a Live Demo?</strong>
<a href="http://viewer.ohif.org/">Preview The OHIF Viewer</a>
</div>
<div class='column' style='text-align: left; padding: 0 20px'>
<a href="https://www.netlify.com">
<img src="https://www.netlify.com/img/global/badges/netlify-color-bg.svg"/>
</a>
</div>
</div>
> ATTENTION! You are looking at the docs for the `OHIF-v3` Viewer (third time is always a charm). If you're looking for the our `OHIF-v2` (React stable version) or OHIF-v1 (deprecated `Meteor` version) select it's version from the dropdown box in the top left corner
> of this page.
&nbsp;
# Introduction
The [Open Health Imaging Foundation][ohif-org] (OHIF) Viewer is an open source,
web-based, medical imaging viewer. It can be configured to connect to Image
Archives that support [DicomWeb][dicom-web], and offers support for mapping to
proprietary API formats. OHIF maintained extensions add support for viewing,
annotating, and reporting on DICOM images in 2D (slices) and 3D (volumes).
![OHIF Viewer Screenshot](./assets/img/OHIF-viewer.png)
<center><i>The <strong>OHIF Viewer v3</strong>: A general purpose DICOM Viewer (<a href="http://viewer.ohif.org/">Live Demo</a>)</center>
&nbsp;
## What's new in `OHIF-v3`
`OHIF-v3` is our second try for a React-based viewer, and is the third version of
our medical image web viewers from the start. The summary of changes include:
- Addition of workflow modes
- Often, medical imaging use cases involves lots of specific workflows that re-use
functionalities. We have added the capability of workflow modes, that enable people
to customize user interface and configure application for specific workflow.
- The idea is to re-use the functionalities that extensions provide and create a workflow.
Brain segmentation workflow is different from prostate segmentation in UI for sure; however, they share the segmentation tools that can be re-used.
- Our vision is that technical people focus of developing extensions which provides
core functionalities, and experts to build modes by picking the appropriate functionalities
from each extension.
- Redux store has been removed from the viewer, and a cleaner, more powerful
- tailwind CSS
- End-to-end test suite
Below, you can find the gap analysis between the `OHIF-v2` and `OHIF-v3`:
{% include "./_gap_analysis.md" %}
## Where to next?
The Open Health Imaging Foundation intends to provide a simple general purpose
DICOM Viewer which can be easily extended for specific uses. If you find
yourself unable to extend the viewer for your purposes, please reach out via our
[GitHub issues][gh-issues]. We are actively seeking feedback on ways to improve
our integration and extension points.
Check out these helpful links:
- Ready to dive into some code? Check out our
[Getting Started Guide](./development/getting-started.md).
- We're an active, vibrant community.
[Learn how you can be more involved.](./development/contributing.md)
- Feeling lost? Read our [help page](./help.md).
<!--
Links
-->
<!-- prettier-ignore-start -->
[ohif-org]: http://www.ohif.org
[ohif-demo]: http://viewer.ohif.org/
[dicom-web]: https://en.wikipedia.org/wiki/DICOMweb
[gh-issues]: https://github.com/OHIF/Viewers/issues
<!-- prettier-ignore-end -->

View File

@ -1,83 +0,0 @@
# OHIF Viewers
- [Our Process](our-process.md)
- User Manuals
- [Overview](userManuals/index.md)
- [Study List](userManuals/studyList/index.md)
- [Viewer](userManuals/viewer/index.md)
- [Study Panel](userManuals/viewer/studyPanel/study-panel.md)
- [Measurement Panel](userManuals/viewer/measurementPanel/measurement-panel.md)
- [Viewport](userManuals/viewer/viewport/viewport.md)
- [Toolbar](userManuals/viewer/toolbar/toolbar.md)
- [Hot keys](userManuals/viewer/hotkeys/hotkeys.md)
- [Language](userManuals/viewer/language/language.md)
- Development
- [Getting Started](development/getting-started.md)
- [Contributing](development/contributing.md)
- [Continuous Integration](development/continous-integration.md)
- [Testing](development/testing.md)
- [Configuring Data Source](configuring/index.md)
- [Local DICOM Server](configuring/data-source.md)
---
- [Architecture](architecture/index.md)
- [Viewer](viewer/index.md)
- [Configuration](viewer/configuration.md)
- [Theming](viewer/themeing.md)
- [Internationalization](viewer/internationalization.md)
- [Extensions](extensions/index.md#Overview)
- [Registering](extensions/index.md#registering-an-extension)
- [OHIF Maintained](extensions/index.md#ohif-maintained-extensions)
- [Lifecycle Hooks](extensions/index.md#lifecycle-hooks)
- [preRegistration](extensions/lifecycle/pre-registration.md)
- [onModeEnter](extensions/lifecycle/on-mode-enter.md)
- [onModeExit](extensions/lifecycle/on-mode-exit.md)
- [Modules](extensions/index.md#modules)
- [Toolbar](extensions/modules/toolbar.md)
- [Commands](extensions/modules/commands.md)
- [DataSource](extensions/modules/data-source.md)
- [SOPClassHandler](extensions/modules/sop-class-handler.md)
- [Viewport](extensions/modules/viewport.md)
- [Panel](extensions/modules/panel.md)
- [LayoutTemplate](extensions/modules/layout-template.md)
- [HangingProtocol](extensions/modules/hpModule.md)
- [Context](extensions/index.md#contexts)
- [ExtensionManager](managers/extension.md)
- [Modes](modes/index.md)
- [LifeCycle](modes/lifeCycle.md#overview)
- [Validity](modes/validity.md#overview)
- [Routes](modes/routes.md#overview)
- [Managers](managers/index.md)
- [Extension Manager](managers/extension.md)
- [Service Manager](managers/service.md)
- [Commands Manager](managers/commands.md)
- [Hotkeys Manager](managers/hotkeys.md)
- [Services](services/index.md)
- [Data Services](services/data/index.md)
- [Dicom Metadata Store](services/data/DicomMetadataStore.md)
- [DisplaySet Service](services/data/DisplaySetService.md)
- [Hanging Protocol Service](services/data/HangingProtocolService.md)
- [Toolbar Service](services/data/ToolbarService.md)
- [Measurement Service](services/data/MeasurementService.md)
- [UI Services](services/ui/index.md)
- [UI Notification Service](services/ui/ui-notification-service.md)
- [UI Modal Service](services/ui/ui-modal-service.md)
- [UI Dialog Service](services/ui/ui-dialog-service.md)
- [UI Viewport Dialog Service](services/ui/ui-viewport-dialog-service.md)
- [Viewport Grid Service](services/ui/ViewportGridService.md)
- [Pub/Sub Pattern](services/pubsub.md)
- [Deployment](deployment/index.md)
- [Build for Production](deployment/recipes/build-for-production.md)
- [Static](deployment/recipes/static-assets.md)
- [Nginx + Image Archive](deployment/recipes/nginx--image-archive.md)
- [User Account Control](deployment/recipes/user-account-control.md)
- [Google Cloud Healthcare](connecting-to-image-archives/google-cloud-healthcare.md)
- [FAQ](faq/index.md)
- [Scope of Project](faq/scope-of-project.md)
- [Browser Support](faq/browser-support.md)
- [PWA vs Packaged](faq/pwa-vs-packaged.md)
- [Help](help.md) -->

View File

@ -1,110 +0,0 @@
<table>
<thead>
<tr>
<th align="left" width="50%">OHIF-v2 functionalities</th>
<th align="center">OHIF-v3</th>
<th align="center">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Rendering of 2D images via Cornerstone</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">Study List</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">Series Browser</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">DICOM JSON</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">2D Tools via CornerstoneTools</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">OpenID Connect standard authentication flow for connecting to identity providers</td>
<td align="center">🔜</td>
<td align="center">In Progress</td>
</tr>
<tr>
<td align="left">Internationalization</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">Drag/drop DICOM data into the viewer (see https://viewer.ohif.org/local)</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">IHE Invoke Image Display - Standard-compliant launching of the viewer (e.g. from PACS or RIS)</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">DICOM PDF support</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">DICOM Whole-slide imaging viewport</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">Displaying non-renderable DICOM as HTML</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">Segmentation support</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">RT STRUCT support</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">White-labelling: Easily replace the OHIF Logo with your logo</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">DICOM upload to PACS</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">Google Cloud adapter</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">VTK Extension + MIP / MPR layout</td>
<td align="center"></td>
<td align="center">Other plans</td>
</tr>
<tr>
<td align="left">UMD Build (Embedded Viewer). </td>
<td align="center"></td>
<td align="center">The problem is that this breaks a bunch of extensions that rely on third party scripts (e.g. VTK) which have their own web worker loaders.</td>
</tr>
</tbody>
</table>
🔜

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

View File

@ -1,54 +0,0 @@
{
"title": "OHIF",
"description": "Documentation for the OHIF framework",
"gitbook": ">3.0.0",
"plugins": [
"edit-link",
"theme-cornerstone",
"-fontsettings",
"github",
"ga",
"sitemap",
"anchors",
"versions"
],
"pluginsConfig": {
"edit-link": {
"base": "https://github.com/OHIF/Viewers/edit/master/docs",
"label": "Edit This Page"
},
"github": {
"url": "https://github.com/OHIF/Viewers"
},
"ga": {
"token": "UA-110573590-2"
},
"sitemap": {
"hostname": "https://docs.ohif.org"
},
"versions": {
"gitbookConfigURL": "https://raw.githubusercontent.com/OHIF/Viewers/master/docs/book.json",
"options": [
{
"value": "https://docs.ohif.org/history/v1/",
"text": "Version 1.0.0 (Meteor)"
},
{
"value": "https://docs.ohif.org/history/v2/",
"text": "Version 2.0.0"
},
{
"value": "https://docs.ohif.org/",
"text": "Version 3.0.0",
"selected": true
}
]
}
},
"links": {
"sharing": {
"facebook": false,
"twitter": false
}
}
}

View File

@ -1,4 +0,0 @@
<div style="text-align: center;">
<img src="/assets/img/embedded-viewer-diagram.png" alt="Embedded Viewer Diagram" style="margin: 0 auto;" />
<div><i>embedded viewer diagram</i></div>
</div>

View File

@ -1,4 +0,0 @@
<div style="text-align: center;">
<img src="/assets/img/nginx-image-archive.png" alt="request flow example" style="margin: 0 auto;" />
<div><i>simplified request flow diagram</i></div>
</div>

View File

@ -1,4 +0,0 @@
<div style="text-align: center;">
<img src="/assets/img/user-access-control-request-flow.png" alt="request flow example" style="margin: 0 auto;" />
<div><i>simplified request flow diagram</i></div>
</div>

View File

@ -1,67 +0,0 @@
<table>
<thead>
<tr>
<th>Extension</th>
<th>Description</th>
<th>Modules</th>
</tr>
</thead>
<tbody>
<!-- CORNERSTONE.js -->
<tr>
<td>
<a href="">
Default
</a>
</td>
<td>
Default extension provides default viewer layout, a study/series
browser, and a datasource that maps to a DICOMWeb compliant backend
</td>
<td>commandsModule, ContextModule, DataSourceModule, HangingProtocolModule, LayoutTemplateModule, PanelModule, SOPClassHandlerModule, ToolbarModule</td>
</tr>
<!-- CORNERSTONE.js -->
<tr>
<td>
<a href="https://www.npmjs.com/package/@ohif/extension-cornerstone">
Cornerstone
</a>
</td>
<td>
Provides rendering functionalities for 2D images.
</td>
<td>ViewportModule, CommandsModule</td>
</tr>
<!-- dicom-pdf -->
<!-- <tr>
<td>
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-pdf">DICOM PDF</a>
</td>
<td>
Renders PDFs for a <a href="https://github.com/OHIF/Viewers/blob/master/extensions/dicom-pdf/src/OHIFDicomPDFSopClassHandler.js#L4-L6">specific SopClassUID</a>.
</td>
<td>Viewport, SopClassHandler</td>
</tr> -->
<!-- dicom-sr -->
<tr>
<td>
<a href="">DICOM SR</a>
</td>
<td>
Maintained extensions for cornerstone and visualization of DICOM Structured Reports
</td>
<td>ViewportModule, CommandsModule, SOPClassHandlerModule</td>
</tr>
<!-- Measurement-tracking -->
<tr>
<td>
<a href="">Measurement tracking</a>
</td>
<td>
Tracking measurements in the measurement panel
</td>
<td> ContextModule,PanelModule,ViewportModule,CommandsModule</td>
</tr>
</tbody>
</table>

View File

@ -1,94 +0,0 @@
<table>
<thead>
<tr>
<th align="left" width="30%">
Types
</th>
<th align="left">Description</th>
<th align="left">Examples</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">
<a href="./modules/layout-template.md">
LayoutTemplate (NEW)
</a>
</td>
<td align="left">Control Layout of a route</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">
<a href="./modules/data-source.md">
DataSource (NEW)
</a>
</td>
<td align="left">Control the mapping from DICOM metadata to OHIF-metadata</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">
<a href="./modules/sop-class-handler.md">
SOPClassHandler
</a>
</td>
<td align="left">Determines how retrieved study data is split into "DisplaySets"</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">
<a href="./modules/panel.md">
Panel
</a>
</td>
<td align="left">Adds left or right hand side panels</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">
<a href="./modules/viewport.md">
Viewport
</a>
</td>
<td align="left">Adds a component responsible for rendering a "DisplaySet"</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">
<a href="./modules/commands.md">
Commands
</a>
</td>
<td align="left">Adds named commands, scoped to a context, to the CommandsManager</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">
<a href="./modules/toolbar.md">
Toolbar
</a>
</td>
<td align="left">Adds buttons or custom components to the toolbar</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">
<a href="./modules/context.md">
Context
</a>
</td>
<td align="left">Shared state for a workflow or set of extension module definitions</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">
<a href="./modules/hpModule.md">
HangingProtocol
</a>
</td>
<td align="left">Adds hanging protocol rules</td>
<td align="left"></td>
</tr>
</tbody>
</table>

View File

@ -1,263 +0,0 @@
# Extensions
- [Extensions](#extensions)
- [Overview](#overview)
- [Extension Skeleton](#extension-skeleton)
- [OHIF-Maintained Extensions](#ohif-maintained-extensions)
- [Registering an Extension](#registering-an-extension)
- [Registering at Runtime](#registering-at-runtime)
- [Registering at Build Time](#registering-at-build-time)
- [Lifecycle Hooks](#lifecycle-hooks)
- [Modules](#modules)
- [Contexts](#contexts)
## Overview
We have re-designed the architecture of the `OHIF-v3` to enable building applications
that are easily extensible to various use cases (modes) that behind the scene would utilize desired functionalities (extensions) to reach the goal of the use case.
Previously, extensions were “additive” and could not easily be mixed and matched within the same viewer for different use cases. Previous `OHIF-v2` architecture meant that
any minor extension alteration usually would require the user to hard fork. E.g. removing some of the tools from the toolbar of the cornerstone extension meant you had to hard fork it, which was frustrating if the implementation was otherwise the same as master.
> - Developers should make packages of *reusable* functionality as extensions, and can consume
> publicly available extensions.
> - Any conceivable radiological workflow or viewer setup will be able to be built with the platform through *modes*.
Practical examples of extensions include:
- A set of segmentation tools that build on top of the `cornerstone` viewport
- A set of rendering functionalities to volume render the data
- [See our maintained extensions for more examples of what's possible](#maintained-extensions)
<mark>Diagram showing how extensions are configured and accessed.
<!--
<div style="text-align: center;">
<a href="/assets/img/extensions-diagram.png">
<img src="/assets/img/extensions-diagram.png" alt="Extensions Diagram" style="margin: 0 auto; max-width: 500px;" />
</a>
<div><i>Diagram showing how extensions are configured and accessed.</i></div>
</div> -->
## Extension Skeleton
An extension is a plain JavaScript object that has an `id` property, and one or
more [modules](#modules) and/or [lifecycle hooks](#lifecycle-hooks).
```js
// prettier-ignore
export default {
/**
* Only required property. Should be a unique value across all extensions.
*/
id: 'example-extension',
// Lifecyle
preRegistration() { /* */ },
onModeEnter() { /* */ },
onModeExit() { /* */ },
// Modules
getLayoutTemplateModule() { /* */ },
getDataSourcesModule() { /* */ },
getSopClassHandlerModule() { /* */ },
getPanelModule() { /* */ },
getViewportModule() { /* */ },
getCommandsModule() { /* */ },
getContextModule() { /* */ },
getToolbarModule() { /* */ },
getHangingProtocolModule() { /* */ },
}
```
## 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`][viewers-repo] repository, in
the top level [`extensions/`][ext-source] directory.
{% include "./_maintained-extensions-table.md" %}
## Registering an Extension
Extensions are building blocks that need to be registered. There are two different ways to register and configure extensions: At
[runtime](#registering-at-runtime) and at
[build time](#registering-at-build-time).
You can leverage one or both strategies. Which one(s) you choose depend on your
application's requirements.
Each [module](#modules) defined by the extension
becomes available to the modes via the `ExtensionManager` by requesting it via
its id. [Read more about Extension Manager](#extension-manager)
### Registering at Runtime
The `@ohif/viewer` uses a [configuration file](../viewer/configuration.md) at
startup. The schema for that file includes an `extensions` key that supports an
array of extensions to register.
```js
import MyFirstExtension from '@ohif/extension-first'
import MySecondExtension from '@ohif/extension-second'
const extensionConfig = {/* extension configuration */}
// prettier-ignore
const config = {
routerBasename: '/',
extensions: [
MyFirstExtension,
[
MySecondExtension,
extensionConfig
],
],
modes: [/* modes */],
showStudyList: true,
dataSources: [ /* data source config */]
}
```
Then, behind the scene, the runtime-added extensions will get merged with the
default app extensions (note: default app extensions include: `OHIFDefaultExtension`,
`OHIFCornerstoneExtension`, `OHIFDICOMSRExtension`,
`OHIFMeasurementTrackingExtension`)
### Registering at Build Time
The `@ohif/viewer` works best when built as a "Progressive Web Application"
(PWA). If you know the extensions your application will need, you can specify
them at "build time" to leverage advantages afforded to us by modern tooling:
- Code Splitting (dynamic imports)
- Tree Shaking
- Dependency deduplication
You can update the list of bundled extensions by:
1. Having your `@ohif/viewer` project depend on the extension
2. Importing and adding it to the list of extensions in the
`<repo-root>/platform/src/index.js` entrypoint:
```js
import OHIFDefaultExtension from '@ohif/extension-default';
import OHIFCornerstoneExtension from '@ohif/extension-cornerstone';
import OHIFMeasurementTrackingExtension from '@ohif/extension-measurement-tracking';
import OHIFDICOMSRExtension from '@ohif/extension-dicom-sr';
import MyFirstExtension from '@ohif/extension-first'
/** Combine our appConfiguration and "baked-in" extensions */
const appProps = {
config: window ? window.config : {},
defaultExtensions: [
OHIFDefaultExtension,
OHIFCornerstoneExtension,
OHIFMeasurementTrackingExtension,
OHIFDICOMSRExtension,
MyFirstExtension
],
};
```
## Lifecycle Hooks
Currently, there are three lifecycle hook for extensions:
[`preRegistration`](./lifecycle/pre-registration.md)
This hook is called once on initialization of the entire viewer application, used to initialize the extensions state, and consume user defined extension configuration. If an extension defines the [`preRegistration`](./lifecycle/pre-registration.md)
lifecycle hook, it is called before any modules are registered in the
`ExtensionManager`. It's most commonly used to wire up extensions to
[services](./../services/index.md) and [commands](./modules/commands.md), and to
bootstrap 3rd party libraries.
[`onModeEnter`](./lifecycle/on-mode-enter.md): This hook is called whenever a new mode is entered, or a modes data or datasource is switched. This hook can be used to initialize data.
[`onModeExit`](./lifecycle/on-mode-exit.md): Similarly to onModeEnter, this hook is called when navigating away from a mode, or before a modes data or datasource is changed. This can be used to clean up data (e.g. remove annotations that do not need to be persisted)
## Modules
Modules are the meat of extensions, the `blocks` that we have been talking about a lot.
They provide "definitions", components, and filtering/mapping logic that are then made available to modes and services.
Each module type has a special purpose, and is consumed by our viewer
differently.
{% include "./_modules.md" %}
<figure style="text-align: center; font-style: italic;">Tbl. Module types with abridged descriptions and examples. Each module links to a dedicated documentation page.</figure>
### Contexts
The `@ohif/viewer` tracks "active contexts" that extensions can use to scope
their functionality. Some example contexts being:
- Route: `ROUTE:VIEWER`, `ROUTE:STUDY_LIST`
- Active Viewport: `ACTIVE_VIEWPORT:CORNERSTONE`, `ACTIVE_VIEWPORT:VTK`
An extension module can use these to say "Only show this Toolbar Button if the
active viewport is a Cornerstone viewport." This helps us use the appropriate UI
and behaviors depending on the current contexts.
For example, if we have hotkey that "rotates the active viewport", each Viewport
module that supports this behavior can add a command with the same name, scoped
to the appropriate context. When the `command` is fired, the "active contexts"
are used to determine the appropriate implementation of the rotate behavior.
<!-- <mark>do we want the followings?
## Consuming Extensions
We consume extensions, via the `ExtensionManager`, in our `@ohif/viewer`
project.
```js
const extensionManager = new ExtensionManager({
commandsManager,
servicesManager,
hotkeysManager
});
// prettier-ignore
extensionManager.registerExtensions([ /** **/ ]);
```
The `@ohif/viewer` project handles data fetching, basic routing, wires up UI
services, and is the home to the more bespoke application logic that doesn't
make as much sense to make reusable.
Long-term, replacing the `@ohif/viewer` application and consuming extensions
(and the `ExtensionManager`) in your own project is the ideal path for
applications requiring a high degree of customization that can't be achieved
with current theming, configuration, extension, and services support.
If you're not sure how to achieve your goals with the extensibility available
today, create a GitHub issue! -->
<!--
LINKS
-->
<!-- prettier-ignore-start -->
[viewers-repo]: https://github.com/OHIF/Viewers
[ext-source]: https://github.com/OHIF/Viewers/tree/master/extensions
[module-types]: https://github.com/OHIF/Viewers/blob/master/platform/core/src/extensions/MODULE_TYPES.js
<!-- prettier-ignore-end -->

View File

@ -1,29 +0,0 @@
# Lifecycle Hook: onModeEnter
If an extension defines the `onModeEnter` lifecycle hook, it is called
when a new mode is enters, or a mode's data or datasource is switched.
For instance, in DICOM structured report extension (`dicom-sr`), we are using
`onModeEnter` to re-create the displaySets after a new mode is entered.
_Example `onModeEnter` hook implementation_
```js
export default {
id: 'org.ohif.dicom-sr',
onModeEnter({ servicesManager}) {
const { DisplaySetService } = servicesManager.services;
const displaySetCache = DisplaySetService.getDisplaySetCache();
const srDisplaySets = displaySetCache.filter(
ds => ds.SOPClassHandlerId === SOPClassHandlerId
);
srDisplaySets.forEach(ds => {
// New mode route, allow SRs to be hydrated again
ds.isHydrated = false;
});
},
};
```

View File

@ -1,17 +0,0 @@
# Lifecylce Hook: onModeExit
If an extension defines the `onModeExit` lifecycle hook, it is called when navigating
away from a mode. This hook can be used to clean up data tasks such as unregistering services,
removing annotations that do not need to be persisted.
_Example `onModeExit` hook implementation_
```js
export default {
id: 'myExampleExtension',
onModeExit({ servicesManager, commandsManager}) {
myCacheServie.purge()
},
};
```

View File

@ -1,25 +0,0 @@
# Managers
## Overview
`OHIF` uses `Managers` to accomplish various purposes such as registering new services, dependency injection, and aggregating and exposing `extension` features.
`OHIF-v3` provides the following managers which we will discuss in depth.
{% include "./_managers.md" %}
<!--
LINKS
-->
<!-- prettier-ignore-start -->
[core-services]: https://github.com/OHIF/Viewers/tree/master/platform/core/src/services
[services-manager]: https://github.com/OHIF/Viewers/blob/master/platform/core/src/services/ServicesManager.js
[cross-cutting-concerns]: https://en.wikipedia.org/wiki/Cross-cutting_concern
<!-- prettier-ignore-end -->

View File

@ -1,95 +0,0 @@
<table>
<thead>
<tr>
<th align="left">Property</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">
id
</td>
<td align="left">unique mode id used to refer to the mode</td>
</tr>
<tr>
<td align="left">
displayName
</td>
<td align="left">actual name of the mode being displayed for each study in the study summary panel</td>
</tr>
<tr>
<td align="left">
<a href="./lifeCycle.md#onModeEnter">
onModeEnter
</a>
</td>
<td align="left">hook is called when the mode is entered by the specified route</td>
</tr>
<tr>
<td align="left">
<a href="./lifeCycle.md#onModeExit">
onModeExit
</a>
</td>
<td align="left">hook is called when the mode exited</td>
</tr>
<tr>
<td align="left">
<a href="">
validationTags
</a>
</td>
<td align="left">validationTags</td>
</tr>
<tr>
<td align="left">
<a href="">
isValidMode
</a>
</td>
<td align="left">Checks if the mode is valid for a study</td>
</tr>
<tr>
<td align="left">
<a href="">
routes
</a>
</td>
<td align="left">route config which defines the route address, and the layout for it</td>
</tr>
<tr>
<td align="left">
<a href="./index.md#consuming-extensions">
extensions
</a>
</td>
<td align="left">extensions needed by the mode</td>
</tr>
<tr>
<td align="left">
<a href="">
hanging protocol
</a>
</td>
<td align="left">list of hanging protocols that the mode should have access to</td>
</tr>
<tr>
<td align="left">
<a href="">
sopClassHandlers
</a>
</td>
<td align="left">list of SOPClass modules needed by the mode </td>
</tr>
<tr>
<td align="left">
<a href="">
hotkeys
</a>
</td>
<td align="left">hotkeys</td>
</tr>
</tbody>
</table>

View File

@ -1,340 +0,0 @@
# Modes
- [Modes](#modes)
- [Overview](#overview)
- [Anatomy](#anatomy)
- [Consuming Extensions](#consuming-extensions)
- [routes](#routes)
- [extensions](#extensions)
- [hangingProtocols](#hangingprotocols)
- [sopClassHandlers](#sopclasshandlers)
- [hotkeys](#hotkeys)
- [Registration](#registration)
## Overview
A mode can be thought of as a viewer app configured to perform a specific task,
such as tracking measurements over time, 3D segmentation, a guided radiological workflow, etc.
Addition of modes enables *application* with many *applications* as each mode become
a mini *app configuration* behind the scene.
Upon initialization the viewer will consume extensions and modes and build up the route desired, these can then be accessed via the study list, or directly via url parameters.
<!-- > Modes make extensions (features) more reusable and powerful. -->
OHIF-v3 architecture can be seen in the following:
![mode-archs](../assets/img/mode-archs.png)
>Note: Templates are now a part of “extensions”
>Routes are configured by modes and/or app
As mentioned, modes are tied to a specific route in the viewer, and multiple modes/routes can be present within a single application. This allows for tremendously more flexibility than before you can now:
- Simultaneously host multiple viewers with for different use cases from within the same app deploy.
- Make radiological viewers for specific purposes/workflows, e.g.:
- Tracking the size of lesions over time.
- PET/CT fusion workflows.
- Guided review workflows optimized for a specific clinical trial.
- Still host one single feature-rich viewer if you desire.
## Anatomy
A mode configuration has a `route` name which is dynamically transformed into a viewer route on initialization of the application. Modes that are available to a study will appear in the study list.
![user-study-summary](../assets/img/user-study-summary.png)
The mode configuration specifies which `extensions` the mode requires, which `LayoutTemplate` to use, and what props to pass to the template. For the default template this defines which `side panels` will be available, as well as what `viewports` and which `displaySets` they may hang.
Mode's config is actually a function that return a config object with certain properties, the high-level view of this config object is:
```js
// modes/example/src/index.js
export default function mode() {
return {
id: '',
displayName: '',
onModeEnter: () => {},
onModeExit: () => {},
validationTags: {},
isValidMode: () => {},
routes: [
{
path: '',
init: () => {},
layoutTemplate: () => {},
},
],
extensions: [],
hangingProtocols: [],
sopClassHandlers: [],
hotkeys: [],
}
}
```
{% include "./_anatomy.md" %}
### Consuming Extensions
As mentioned in the [Extensions](../extensions/index.md) section, in `OHIF-v3` developers
write their extensions to create re-usable functionalities that later can be used by `modes`.
Now, it is time to describe how the registered extensions will get utilized for a workflow mode
via its `id`.
To use a module element you can use the `${extensionId}.${moduleType}.${element.name}` schema.
For instance, if a mode requires the left panel with name of `AIPanel` that is added by the `myAIExtension` via the following `getPanelModule` code, it should address it as `myAIExtension.panelModule.AIPanel` inside the mode configuration file.
In the background `OHIF` will handle grabbing the correct panel via `ExtensionManager`.
```js
// extensions/myAIExtension/getPanelModule.js
import PanelAI from './PanelAI.js';
function getPanelModule({
commandsManager,
extensionManager,
servicesManager,
}) {
const wrappedAIPanel = () => {
return (
<PanelAI
commandsManager={commandsManager}
servicesManager={servicesManager}
/>
);
};
return [
{
name: 'AIPanel',
iconName: 'list-bullets',
iconLabel: '',
label: 'AI Panel',
isDisabled: studies => {}, // optional
component: wrappedAIPanel,
},
];
}
```
Now, let's look at `longitudinal` mode which consumes various functionalities from different extensions.
Note that, you don't need to have `org.ohif.extensionName`, this is a pattern we chose to
name our [OHIF-maintained](../extensions/index.md#ohif-maintained-extensions) extensions, you can simply
have `extensionName` as the `id` for yours and refer to it inside your modes.
```js
export default function mode({ modeConfiguration }) {
return {
/*
...
*/
routes: [
{
/*
...
*/
layoutTemplate: ({ location, servicesManager }) => {
return {
id: ohif.layout,
props: {
leftPanels: [
'org.ohif.measurement-tracking.panelModule.seriesList',
],
rightPanels: [
'org.ohif.measurement-tracking.panelModule.trackedMeasurements',
],
viewports: [
{
namespace:
'org.ohif.measurement-tracking.viewportModule.cornerstone-tracked',
displaySetsToDisplay: [
'org.ohif.default.sopClassHandlerModule.stack',
],
},
{
namespace: 'org.ohif.dicom-sr.viewportModule.dicom-sr',
displaySetsToDisplay: [
'org.ohif.dicom-sr.sopClassHandlerModule.dicom-sr',
],
},
],
},
}
},
},
],
extensions: [
'org.ohif.default',
'org.ohif.cornerstone',
'org.ohif.measurement-tracking',
'org.ohif.dicom-sr',
],
hangingProtocols: ['org.ohif.default.hangingProtocolModule.petCT'],
sopClassHandlers: [
'org.ohif.default.sopClassHandlerModule.stack',
'org.ohif.dicom-sr.sopClassHandlerModule.dicom-sr',
],
/*...*/
}
}
```
### routes
routes config is an array of route settings, and the overall look and behavior of the viewer at the designated route is defined by the `layoutTemplate` and `init` functions for the route. We will learn more about each of the above properties inside the [route documentation](./routes.md)
### extensions
Currently `extensions` property in the mode config is used to add *contextModule* of the mentioned extensions to the list of contexts and provide them through out the app. Since extensions are registered by the ExtensionManager, modes have access to the them even if they have not been referred in the mode config file inside *extensions* property. [Read more about extension registration](../extensions/index.md#registering-an-extension)
```js
// platform/viewer/src/routes/Mode/Mode.jsx
const { extensions } = mode;
extensions.forEach(extensionId => {
const allRegisteredModuleIds = Object.keys(extensionManager.modulesMap);
const moduleIds = allRegisteredModuleIds.filter(id =>
id.includes(`${extensionId}.contextModule.`)
);
const modules = moduleIds.map(extensionManager.getModuleEntry);
contextModules = contextModules.concat(modules);
});
```
### hangingProtocols
Currently, you can pass your defined hanging protocols inside the `hangingProtocols` property of
the mode's config. This will get used inside the `Mode.jsx` to configure the `HangingProtocolService`.
```js
// platform/viewer/src/routes/Mode/Mode.jsx
const { hangingProtocols } = mode;
hangingProtocols.forEach(extentionProtocols => {
const { protocols } = extensionManager.getModuleEntry(extentionProtocols);
HangingProtocolService.addProtocols(protocols);
});
```
### sopClassHandlers
Mode's configuration also accepts the `sopClassHandler` modules that have been added by the extensions.
This information will get used inside the `Mode.jsx` to initialize the `DisplaySetService` with the provided
SOPClass modules which handles creation of the displaySets.
```js
// platform/viewer/src/routes/Mode/Mode.jsx
const { sopClassHandlers } = mode;
DisplaySetService.init(extensionManager, sopClassHandlers);
```
### hotkeys
`hotkeys` is another property in the configuration of a mode that can be defined to add the specific hotkeys to the viewer at all routes.
```js
// default hotkeys
import { hotkeys } from '@ohif/core';
const myHotkeys = [
{
commandName: 'setToolActive',
commandOptions: { toolName: 'Zoom' },
label: 'Zoom',
keys: ['z'],
isEditable: true,
},
{
commandName: 'scaleUpViewport',
label: 'Zoom In',
keys: ['+'],
isEditable: true,
},
]
export default function mode() {
return {
id: '',
displayName: '',
/*
...
*/
hotkeys: [..hotkeys.defaults.hotkeyBindings, ...myHotkeys],
}
}
```
```js
// platform/viewer/src/routes/Mode/Mode.jsx
hotkeysManager.setDefaultHotKeys(hotkeys);
hotkeysManager.setHotkeys(hotkeys);
```
## Registration
Upon release modes will also be plugged into the app via configuration, but this is still an area which is under development/discussion, and they are currently pulled from the `window` in beta.
```js
// modes/longitudinal/src/index.js
export default function mode() {
return {
id: 'viewer',
displayName: 'Basic Viewer',
onModeEnter: () => {/**...**/},
onModeExit: () => {/**...**/},
validationTags: {/**...**/},
isValidMode: () => {/**...**/},
routes: [
{
path: 'longitudinal',
init: () => {/**...**/},
layoutTemplate: () => {/**...**/},
},
],
extensions: [/**...**/],
hangingProtocols: [/**...**/],
sopClassHandlers: [/**...**/],
hotkeys: [/**...**/],
}
}
window.longitudinalMode = mode({});
```
and inside `@ohif/viwer` we have:
```js
// platform/viewer/src/appInit.js
if (!appConfig.modes.length) {
appConfig.modes.push(window.longitudinalMode);
// appConfig.modes.push(window.segmentationMode);
}
```

View File

@ -1,44 +0,0 @@
{
"name": "ohif-viewer-latest-docs",
"version": "2.0.0",
"description": "Open Health Imaging Foundation Viewers Metarepo for documentation",
"main": ".eslintrc.js",
"directories": {
"doc": "docs"
},
"scripts": {
"docs": "gitbook install && gitbook serve"
},
"repository": {
"type": "git",
"url": "git+https://github.com/OHIF/Viewers.git"
},
"keywords": [
"dicom",
"cornerstone",
"OHIF",
"zero",
"footprint",
"medical",
"imaging",
"viewer"
],
"author": "Open Health Imaging Foundation",
"license": "MIT",
"bugs": {
"url": "https://github.com/OHIF/Viewers/issues"
},
"homepage": "https://github.com/OHIF/Viewers#readme",
"dependencies": {
"gitbook-plugin-anchors": "^0.7.1",
"gitbook-plugin-edit-link": "^2.0.2",
"gitbook-plugin-ga": "^2.0.0",
"gitbook-plugin-github": "^3.0.0",
"gitbook-plugin-sitemap": "^1.2.0",
"gitbook-plugin-theme-cornerstone": "^1.1.4",
"gitbook-plugin-versions": "^2.1.4"
},
"devDependencies": {
"gitbook-cli": "^2.3.2"
}
}

View File

@ -1,28 +0,0 @@
# Quick Start
This page details how to get an instance of the OHIF Viewer up and running as
fast as possible. It shows how to grab a pre-built version of the application,
point it at your data source (PACS), and plop it on a web server.
## Options
### 1. Pre-built PWA
...
### 2. Script-Tag
...
### 3. Docker
...
## Security Concerns
- Secure your data
## Common Issues
- Missing server rewrite rules
- CORS issues when requesting data from PACS

View File

@ -1,40 +0,0 @@
# Services And Managers
- [Services And Managers](#services-and-managers)
- [Overview](#overview)
- [Services](#services)
## Overview
Services are "concern-specific" code modules that can be consumed across layers. Services provide
a set of operations, often tied to some shared state, and are made available to
through out the app via the `ServicesManager`. Services are particularly well suited to
address [cross-cutting concerns][cross-cutting-concerns].
Each service should be:
- self-contained
- able to fail and/or be removed without breaking the application
- completely interchangeable with another module implementing the same interface
> In `OHIF-v3` we have added multiple non-UI services and have introduced **pub/sub** pattern to reduce coupling between layers.
>
> [Read more about Pub/Sub](./pubsub.md)
## Services
The following services is available in the `OHIF-v3`.
{% include "./_services.md" %}
<!--
LINKS
-->
<!-- prettier-ignore-start -->
[core-services]: https://github.com/OHIF/Viewers/tree/master/platform/core/src/services
[services-manager]: https://github.com/OHIF/Viewers/blob/master/platform/core/src/services/ServicesManager.js
[cross-cutting-concerns]: https://en.wikipedia.org/wiki/Cross-cutting_concern
<!-- prettier-ignore-end -->

View File

@ -1,19 +0,0 @@
# Overview
Our documentations in this section is tailored toward the end-user. Developers
can skip this section and visit the development section.
In this section, we explore various core functionalities and use cases that `OHIF viewer`
provides. In order to follow the guides below, you need to have a running instance
of the viewer.
- [Study List](./studyList/index.md)
- [Filters](./studyList/index.md#filters)
- [Study Summary](./studyList/index.md#study-summary)
- [Study-specific modes](./studyList/index.md#study-specific-modes)
- [Viewer (Basic Viewer)](./viewer/index.md)
- [Overview](./viewer/index.md#overview)
- [Study Panel](./viewer/studyPanel/study-panel.md#overview)
- [Measurement Panel](./viewer/measurementPanel/measurement-panel.md#overview)
- [Viewport](./viewer/viewport/viewport.md#overview)
- [Toolbar](./viewer/toolbar/toolbar.md#overview)
- [HotKeys](./viewer/hotkeys/hotkeys.md#overview)

View File

@ -1,70 +0,0 @@
# Study list
- [Study List](./index.md)
- [Filters](./index.md#filters)
- [Study Summary](./index.md#study-summary)
- [Study-specific modes](./index.md#study-specific-modes)
- [View Study](./index.md#view-study)
## Overview
The first page you will see when the viewer is loaded is called `Study List`.
In this page you can explore all the studies that are stored on the configured
server for the `OIHF Viewer`.
![user-study-list](../../assets/img/user-study-list.png)
At the end of the page you can navigate to the next/previous page or change the
default number of studies that are shown
![user-study-next](../../assets/img/user-study-next.png)
## Filters
There are certain filters that can be used to limit the study list to the desired
criteria.
- Patient Name: Searches between patients names
- MRN: Searches between patients Medical Record Number
- Study Data: Filters the date of the acquisition
- Description: Searches between study descriptions
- Modality: Filters the modalities
- Accession: Searches between patients accession number
An example of using study list filter is shown below:
![user-study-filter](../../assets/img/user-study-filter.png)
## Study Summary
If you you click on one of the studies, the panel for displaying the summary
of the study will shows up.
![user-study-summary](../../assets/img/user-study-summary.png)
As you can see, a summary of series available in the study is shown, which contains
the series description, series number, modality of the series, and instances in the series.
Next, We will discuss the modes, and their enabled/disabled states.
## Study Specific Modes
As seen for each study, all the available modes will get shown. What is a mode?
Modes define the higher-level functionalities and appearance for the viewer.
For instance, as seen, there are two modes shown for the selected study
- Basic Viewer: Default mode that enables rendering and measurement tracking
- PET/CT Fusion: Mode for visualizing the PET CT study in a 3x3 format.
However, based on the mode configurations (e.g., available modalities), they can be
enabled or disabled.
Below, you can see two studies, In Study 1, Basic Viewer mode is enabled and
ready to be used; however, the PET/CT fusion is disabled by the viewer since
only PET images are found in the study.
![user-studyist-modespecific](../../assets/img/user-studyist-modespecific.png)
## View Study
You can click on the `Basic Viewer` to open the viewer for the selected study.
![user-open-viewer](../../assets/img/user-open-viewer.png)

View File

@ -1,12 +0,0 @@
# Language
OHIF supports internationalization capabilities and setting the general language
of the Viewer.
It should be noted that we don't have complete translations for all the components
and all the languages; however, you can easily add the key value translation pairs
following developer guides.
Summary of language changing usage can be seen below:
<mark>Upload

View File

@ -1,62 +0,0 @@
# Measurement panel
In `Basic Viewer` mode, right panel is the `Measurement Panel`. When you use an annotation tool, a pop up will show up and asks the user if they want to track measurements for the
series on which the annotation was drawn.
![user-measurement-panel-modal](../../../assets/img/user-measurement-panel-modal.png)
If you select `yes`, the series becomes a `tracked series`, and the current drawn measurement and next measurements will get shown up on the measurement panel on the right.
![user-measurement-panel-tracked](../../../assets/img/user-measurement-panel-tracked.png)
# Renaming Measurements
You can edit the measurement name by hovering over the measurement and selecting the edit icon.
![user-measurement-edit](../../../assets/img/user-measurement-edit.png)
![user-measurement-edit-name](../../../assets/img/user-measurement-edit-name.png)
Result:
![user-measurement-name](../../../assets/img/user-measurement-name.png)
# Deleting a Measurement
A measurement can be deleting by dragging it outside the image in the viewport. You can
take a look at the overview video to see this behavior.
# Jumping to a Measurement
Measurements that appear on the measurement panel are linked directly to their original
tool on the viewport. This enables the user to click on a measurement and the viewport will jump to the slice that the measurement has been drawn. You can
take a look at the overview video to see this behavior.
# Prev/Next Measurement
Measurement navigation inside the top viewport can be used to move to previous and next measurement.
![user-measurement-prevnext](../../../assets/img/user-measurement-prevnext.png)
# Export Measurements
You can export the measurements by clicking on the `Export`. A CSV file will get downloaded to your local computer containing the drawn measurements.
![user-measurement-export](../../../assets/img/user-measurement-export.png)
If you have set up your DICOM server to be able to store instances from the viewer, then you are able to create a report by clicking on the `Create Report`.
This will create a DICOM Structured Report (SR) from the measurements and push it
to the server.
For instance, running the Viewer on a local DCM4CHEE:
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/557569965?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="DICOM SR Export"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>
# Overview video
An overview of measurement drawing and exporting can be seen below:
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/545986384?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="measurement-report"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>

View File

@ -1,16 +0,0 @@
# Study panel
In `Basic Viewer` mode, the left panel includes Studies related to the current patient.
You can see three main type of studies below
- Primary: The opened study from the study list
- Recent: Other studies for this patient
- All: Includes both primary and recent studies
![user-study-panel](../../../assets/img/user-study-panel.png)
This is a new feature that we have added to `OHIF-v3`, that shows all the studies that the patient with the specific MRN had and are available from the data storage.
![user-studylist-all](../../../assets/img/user-studylist-all.png)
As you can see the first picture, the dashed circle on the left side of each series demonstrates whether the series is being tracked for measurement or not.

View File

@ -1,70 +0,0 @@
# Toolbar
The four main components of the toolbar are:
- Navigation back to the [Study List](../../studyList/index.md)
- Logo and white labelling
- [Tools](#tools)
- [Preferences](#preferences)
![user-viewer-toolbar](../../../assets/img/user-viewer-toolbar.png)
# Tools
This section displays all the available tools inside the mode.
## Measurement tools
They can be used to measure the area of interest. This measurement can be performed
via:
- Length Tool: Calculated the distance between two points
- Bidirectional Tool: A 2D Length tool in two main axis
- Annotation: To label and point to an area
- Ellipse: Calculates statistics on a ellipse area
- Rectangle: Calculates statistics on a rectangle area
- Probe: To read the intensity value at a location
![user-viewer-toolbar-measurements](../../../assets/img/user-viewer-toolbar-measurements.png)
To draw a measurement you can select it from the toolbar and click and drag mouse
to reach the desired shape, size and direction.
A sample tool drawing is shown below
# Presets
Preset tool enables manipulating the window level and window width of the rendered
image, which basically modifies the contrast and brightness.
You can also choose from the list of pre-defined presets by clicking on the triangle.
![user-toolbar-preset](../../../assets/img/user-toolbar-preset.png)
# Download High Quality Image
By clicking on the Camera icon you can open the window for downloading the image as
common image formats (png, jpg)
![user-toolbar-download-icon](../../../assets/img/user-toolbar-download-icon.png)
In the opened modal, you can set the filename, image's width and height, and filetype and press download for downloading the image to your local computer.
![user-toolbar-download](../../../assets/img/user-toolbar-download.png)
# Extra tools
Lots of other tools are also available in the last tool icon drawer. If you
click on the triangle they will get appeared.
![user-toolbar-extra](../../../assets/img/user-toolbar-extra.png)
# Overview
An overview of tool usage can been seen below:
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/545989422?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="Toolbar-annotation"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>

View File

@ -1,3 +0,0 @@
# Hotkeys
...

View File

@ -1,7 +0,0 @@
# Viewer
The OHIF Viewing Platform strives to be highly configurable and extensible. This
makes it easier for our community members to keep their "secret sauce" private,
and incentives contributions back to the platform. The `@ohif/viewer` project
of the platform is the lynchpin that combines everything to create our
application.

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +0,0 @@
This folder contains the OHIF Viewer installation instructions, categorized by operating system

View File

@ -1,2 +0,0 @@
This folder contains the OHIF Viewer installation instructions on the Microsoft Windows operating system

View File

@ -1,2 +0,0 @@
This folder contains the OHIF Viewer documentation

View File

@ -1,61 +0,0 @@
# OHIF Viewers
- Essentials
- [Installation](essentials/installation.md)
- [Getting Started](essentials/getting-started.md)
- [Architecture](essentials/architecture.md)
- [Configuration](essentials/configuration.md)
- [Troubleshooting](essentials/troubleshooting.md)
- Connecting to Image Archives
- [What are my options?](connecting-to-image-archives/options.md)
- [DICOM Web](connecting-to-image-archives/dicomweb.md)
- [DICOM Message Service Element](connecting-to-image-archives/dimse.md)
- Examples
- [dcm4chee w/ Docker](connecting-to-image-archives/dcm4chee-with-docker.md)
- [Orthanc w/ Docker](connecting-to-image-archives/orthanc-with-docker.md)
- [Google Cloud Healthcare](connecting-to-image-archives/google-cloud-healthcare.md)
- [Osirix](connecting-to-image-archives/osirix.md)
- Data Organization
- [Data Hierarchy](data/data-hierarchy.md)
- [Image Viewport](data/image-viewport.md)
- Viewport Layout
- [Layout Management](layout/layout-management.md)
- [Hanging Protocols](layout/hanging-protocols.md)
- Packages
- [Measurements Package (ohif-measurements)](packages/measurements.md)
- Deployment
- [Building for Production](deployment/building-for-production.md)
- [Security](deployment/security.md)
- I Want To...
- [Add a Tool to the Viewer](I-want-to/add-a-tool-to-the-viewer.md)
- [Add a Logo to the Viewer](I-want-to/add-a-logo-to-the-viewer.md)
----
- Example Applications
- [OHIF Viewer](example-applications/ohif-viewer.md)
- [Lesion Tracker](example-applications/lesion-tracker.md)
- [Standalone Viewer](example-applications/standalone-viewer.md)
----
- Standalone Viewer Integration
- [Usage](standalone-viewer/usage.md)
----
- Lesion Tracker
- [User Manual](lesion-tracker/user-manual.md)
- [Installation on Windows](lesion-tracker/installation-on-windows.md)
- [Manage Studies in Orthanc](lesion-tracker/manage-studies-in-orthanc.md)
- [User Accounts](lesion-tracker/user-accounts.md)
- [Study and Timepoint Management](lesion-tracker/study-and-timepoint-management.md)
- [Using the Viewer](lesion-tracker/using-the-viewer.md)
- [User Preferences](lesion-tracker/user-preferences.md)
- [Server Management](lesion-tracker/server-management.md)
- [Audit Trail](lesion-tracker/audit-trail.md)
----
- FAQ
- [General](faq/general.md)
- [Technical](faq/technical.md)
----
- [Contributing](contributing.md)

View File

@ -1 +0,0 @@
docs.ohif.org

View File

@ -1,54 +0,0 @@
{
"title": "OHIF",
"description": "Documentation for the OHIF framework",
"gitbook": ">3.0.0",
"plugins": [
"edit-link",
"theme-cornerstone",
"-fontsettings",
"github",
"ga",
"sitemap",
"anchors",
"versions"
],
"pluginsConfig": {
"edit-link": {
"base": "https://github.com/OHIF/Viewers/edit/master/docs",
"label": "Edit This Page"
},
"github": {
"url": "https://github.com/OHIF/Viewers"
},
"ga": {
"token": "UA-110573590-2"
},
"sitemap": {
"hostname": "https://docs.ohif.org"
},
"versions": {
"gitbookConfigURL": "https://raw.githubusercontent.com/OHIF/Viewers/master/docs/book.json",
"options": [
{
"value": "https://docs.ohif.org/history/v1/",
"text": "Version 1.0.0 (Meteor)",
"selected": true
},
{
"value": "https://docs.ohif.org/history/v2/",
"text": "Version 2.0.0"
},
{
"value": "https://docs.ohif.org/",
"text": "Version 3.0.0"
}
]
}
},
"links": {
"sharing": {
"facebook": false,
"twitter": false
}
}
}

View File

@ -1,3 +0,0 @@
# Example: Osirix
...

View File

@ -1,3 +0,0 @@
# Getting Started
...

View File

@ -1,20 +0,0 @@
# Troubleshooting
## Common Problems
Problem | Most Common Reasons
--------|--------------------
** Can't retrieve Study List over DICOMWeb** | 1. QIDO root URL is incorrect<br> 2. DICOM Web is not enabled on PACS
** Can't retrieve Study List over DIMSE** | 1. PACS is not configured to allow connections from OHIF Meteor Server
** Can't retrieve images** | 1. WADO Root URL is incorrect<br> 2. DICOM Web is not enabled on PACS<br> 3. HTTP Basic Authentication username and password are incorrect or not provided.
## Debugging Steps
### Can't retrieve Study List over DICOMWeb
1. Check that you can query your PACS using an alternative DICOM Web client (e.g. cURL, or a Web Browser). If you cannot, then your PACS is configured incorrectly. Refer to the documentation of the image archive.
2.
### Can't retrieve Study List over DIMSE
### Can't retrieve images

View File

@ -1,10 +0,0 @@
# Lesion Tracker - User Manual
1. [Installation on Windows](../installation-on-windows.md)
2. [Manage Studies in Orthanc](../manage-studies-in-orthanc.md)
3. [User Accounts](../user-accounts.md)
4. [Study and Timepoint Management](../study-and-timepoint-management.md)
5. [Lesion Tracking](../lesion-tracking.md)
6. [User Preferences](../user-preferences.md)
7. [Server Management](../server-management.md)
8. [Audit Trail](../audit-trail.md)

View File

@ -1,44 +0,0 @@
{
"name": "ohif-viewer-v1-docs",
"version": "1.0.0",
"description": "Open Health Imaging Foundation Viewers Metarepo for documentation",
"main": ".eslintrc.js",
"directories": {
"doc": "docs"
},
"scripts": {
"docs": "gitbook install && gitbook serve"
},
"repository": {
"type": "git",
"url": "git+https://github.com/OHIF/Viewers.git"
},
"keywords": [
"dicom",
"cornerstone",
"OHIF",
"zero",
"footprint",
"medical",
"imaging",
"viewer"
],
"author": "Open Health Imaging Foundation",
"license": "MIT",
"bugs": {
"url": "https://github.com/OHIF/Viewers/issues"
},
"homepage": "https://github.com/OHIF/Viewers#readme",
"dependencies": {
"gitbook-plugin-anchors": "^0.7.1",
"gitbook-plugin-edit-link": "^2.0.2",
"gitbook-plugin-ga": "^2.0.0",
"gitbook-plugin-github": "^3.0.0",
"gitbook-plugin-sitemap": "^1.2.0",
"gitbook-plugin-theme-cornerstone": "^1.1.2",
"gitbook-plugin-versions": "^2.1.4"
},
"devDependencies": {
"gitbook-cli": "^2.3.2"
}
}

View File

@ -1,9 +0,0 @@
rm -rf _book
gitbook install
gitbook build
cp assets/CNAME _book/CNAME
cd _book
git init
git add -A
git commit -m 'Update compiled GitBook (this commit is automatic)'
git push -f git@github.com:OHIF/Viewers.git master:gh-pages

View File

View File

@ -1,61 +0,0 @@
# OHIF Viewers
- [Our Process](our-process.md)
- Development
- [Getting Started](development/getting-started.md)
- [Contributing](development/contributing.md)
- [Continuous Integration](development/continous-integration.md)
- [Testing](development/testing.md)
- [Configuring](configuring/index.md)
- [Data Source](configuring/data-source.md)
---
- [Architecture](architecture/index.md)
- [Viewer](viewer/index.md)
- [Configuration](viewer/configuration.md)
- [Themeing](viewer/themeing.md)
- [Internationalization](viewer/internationalization.md)
- [Extensions](extensions/index.md)
- [Registering](extensions/index.md#registering-an-extension)
- [Lifecycle Hooks](extensions/index.md#lifecycle-hooks)
- [preRegistration](extensions/lifecycle/pre-registration.md)
- [Modules](extensions/index.md#modules)
- [Commands](extensions/modules/commands.md)
- [Panel](extensions/modules/panel.md)
- [SOP Class Handler](extensions/modules/sop-class-handler.md)
- [Toolbar](extensions/modules/toolbar.md)
- [Viewport](extensions/modules/viewport.md)
- [Contexts](extensions/index.md#contexts)
- [ExtensionManager](extensions/index.md#extensionmanager)
- [OHIF Maintained](extensions/index.md#maintained-extensions)
- [Services](services/index.md)
- [Default](services/default/index.md)
- [UI](services/ui/index.md)
- [Dialog Service](services/ui/ui-dialog-service.md)
- [Modal Service](services/ui/ui-modal-service.md)
- [Notification Service](services/ui/ui-notification-service.md)
---
- [Deployment](deployment/index.md)
- [Embedded](deployment/index.md#embedded-viewer)
- [Stand-alone](deployment/index.md#stand-alone-viewer)
- [Data](deployment/index.md#data)
- Recipes
- Script Include
- [Embedding the Viewer](deployment/recipes/embedded-viewer.md)
- Stand-Alone
- [Build for Production](deployment/recipes/build-for-production.md)
- [Static](deployment/recipes/static-assets.md)
- [Nginx + Image Archive](deployment/recipes/nginx--image-archive.md)
- [User Account Control](deployment/recipes/user-account-control.md)
- [Google Cloud Healthcare](connecting-to-image-archives/google-cloud-healthcare.md)
---
- [FAQ](faq/index.md)
- [Scope of Project](faq/scope-of-project.md)
- [Browser Support](faq/browser-support.md)
- [PWA vs Packaged](faq/pwa-vs-packaged.md)
- [Help](help.md)

View File

@ -1,54 +0,0 @@
{
"title": "OHIF",
"description": "Documentation for the OHIF framework",
"gitbook": ">3.0.0",
"plugins": [
"edit-link",
"theme-cornerstone",
"-fontsettings",
"github",
"ga",
"sitemap",
"anchors",
"versions"
],
"pluginsConfig": {
"edit-link": {
"base": "https://github.com/OHIF/Viewers/edit/master/docs",
"label": "Edit This Page"
},
"github": {
"url": "https://github.com/OHIF/Viewers"
},
"ga": {
"token": "UA-110573590-2"
},
"sitemap": {
"hostname": "https://docs.ohif.org"
},
"versions": {
"gitbookConfigURL": "https://raw.githubusercontent.com/OHIF/Viewers/master/docs/book.json",
"options": [
{
"value": "https://docs.ohif.org/history/v1/",
"text": "Version 1.0.0 (Meteor)"
},
{
"value": "https://docs.ohif.org/history/v2/",
"text": "Version 2.0.0",
"selected": true
},
{
"value": "https://docs.ohif.org/",
"text": "Version 3.0.0"
}
]
}
},
"links": {
"sharing": {
"facebook": false,
"twitter": false
}
}
}

View File

@ -1,4 +0,0 @@
<div style="text-align: center;">
<img src="/assets/img/embedded-viewer-diagram.png" alt="Embedded Viewer Diagram" style="margin: 0 auto;" />
<div><i>embedded viewer diagram</i></div>
</div>

View File

@ -1,4 +0,0 @@
<div style="text-align: center;">
<img src="/assets/img/nginx-image-archive.png" alt="request flow example" style="margin: 0 auto;" />
<div><i>simplified request flow diagram</i></div>
</div>

View File

@ -1,4 +0,0 @@
<div style="text-align: center;">
<img src="/assets/img/user-access-control-request-flow.png" alt="request flow example" style="margin: 0 auto;" />
<div><i>simplified request flow diagram</i></div>
</div>

View File

@ -1,75 +0,0 @@
<table>
<thead>
<tr>
<th>Extension</th>
<th>Description</th>
<th>Modules</th>
</tr>
</thead>
<tbody>
<!-- CORNERSTONE.js -->
<tr>
<td>
<a href="https://www.npmjs.com/package/@ohif/extension-cornerstone">
Cornerstone
</a>
</td>
<td>
A viewport powered by <code>cornerstone.js</code>. Adds support for 2D DICOM rendering and manipulation, as well as support for the tools features in <a href="https://tools.cornerstonejs.org/examples/"><code>cornerstone-tools</code></a>. Also adds "CINE Dialog" to the Toolbar.
</td>
<td>Viewport, Toolbar</td>
</tr>
<!-- VTK.js -->
<tr>
<td>
<a href="https://www.npmjs.com/package/@ohif/extension-vtk">
VTK.js
</a>
</td>
<td>
A viewport powered by <code>vtk.js</code>. Adds support for volume renderings and advanced features like MPR. Also adds "3D Rotate" to the Toolbar.
</td>
<td>Viewport, Toolbar</td>
</tr>
<!-- dicom-html -->
<tr>
<td>
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-html">DICOM HTML</a>
</td>
<td>
Renders text and HTML content for <a href="https://github.com/OHIF/Viewers/blob/master/extensions/dicom-html/src/OHIFDicomHtmlSopClassHandler.js#L4-L12">specific SopClassUIDs</a>.
</td>
<td>Viewport, SopClassHandler</td>
</tr>
<!-- dicom-pdf -->
<tr>
<td>
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-pdf">DICOM PDF</a>
</td>
<td>
Renders PDFs for a <a href="https://github.com/OHIF/Viewers/blob/master/extensions/dicom-pdf/src/OHIFDicomPDFSopClassHandler.js#L4-L6">specific SopClassUID</a>.
</td>
<td>Viewport, SopClassHandler</td>
</tr>
<!-- dicom-microscopy -->
<tr>
<td>
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-microscopy">DICOM Microscopy</a>
</td>
<td>
Renders Microscopy images for a <a href="https://github.com/OHIF/Viewers/blob/master/extensions/dicom-microscopy/src/DicomMicroscopySopClassHandler.js#L5-L7">specific SopClassUID</a>.
</td>
<td>Viewport, SopClassHandler</td>
</tr>
<!-- dicom-segmentation -->
<tr>
<td>
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-segmentation">DICOM Segmentation</a>
</td>
<td>
Renders segmentation images for a <a href="https://github.com/OHIF/Viewers/blob/master/extensions/dicom-segmentation/src/OHIFDicomSegSopClassHandler.js#L5-L7">specific SopClassUID</a>.
</td>
<td>Panel, Toolbar</td>
</tr>
</tbody>
</table>

View File

@ -1,44 +0,0 @@
{
"name": "ohif-viewer-latest-docs",
"version": "2.0.0",
"description": "Open Health Imaging Foundation Viewers Metarepo for documentation",
"main": ".eslintrc.js",
"directories": {
"doc": "docs"
},
"scripts": {
"docs": "gitbook install && gitbook serve"
},
"repository": {
"type": "git",
"url": "git+https://github.com/OHIF/Viewers.git"
},
"keywords": [
"dicom",
"cornerstone",
"OHIF",
"zero",
"footprint",
"medical",
"imaging",
"viewer"
],
"author": "Open Health Imaging Foundation",
"license": "MIT",
"bugs": {
"url": "https://github.com/OHIF/Viewers/issues"
},
"homepage": "https://github.com/OHIF/Viewers#readme",
"dependencies": {
"gitbook-plugin-anchors": "^0.7.1",
"gitbook-plugin-edit-link": "^2.0.2",
"gitbook-plugin-ga": "^2.0.0",
"gitbook-plugin-github": "^3.0.0",
"gitbook-plugin-sitemap": "^1.2.0",
"gitbook-plugin-theme-cornerstone": "^1.1.4",
"gitbook-plugin-versions": "^2.1.4"
},
"devDependencies": {
"gitbook-cli": "^2.3.2"
}
}

View File

@ -1,28 +0,0 @@
# Quick Start
This page details how to get an instance of the OHIF Viewer up and running as
fast as possible. It shows how to grab a pre-built version of the application,
point it at your data source (PACS), and plop it on a web server.
## Options
### 1. Pre-built PWA
...
### 2. Script-Tag
...
### 3. Docker
...
## Security Concerns
- Secure your data
## Common Issues
- Missing server rewrite rules
- CORS issues when requesting data from PACS

View File

@ -1,65 +0,0 @@
# Services (default)
- [Overview](#overview)
- [Example](#example)
## Overview
Services are a work in progress. As we are still in the progress of creating a
non-ui maintained service, this usage may change.
<div style="text-align: center;">
<a href="/assets/img/services.png">
<img src="/assets/img/services.png" alt="UI Services Diagram" style="margin: 0 auto; max-width: 500px;" />
</a>
<div><i>Diagram showing relationship between React Context and UI Service</i></div>
</div>
## Example
The simplest service return a new object that has a `name` property, and
methods/properties that give the service its functionality. The "Factory
Function" that creates the service is provided with the implementation (this is
slightly different for UI Services).
```js
const _speak = () => {
console.warn('Speak is not implemented');
};
/**
* Factory function to create `HelloWorldService`
*
* @param {object} implementation
* @param {function} implementation.speak - Speak's implementation
* @returns HelloWorldService
*/
export default function createHelloWorldService({ speak }) {
return {
name: 'HelloWorldService',
speak: speak || _speak,
};
}
```
A service, once created, can be registered with the `ServicesManager` to make it
accessible to extensions. Similarly, the application code can access named
services from the `ServicesManager`.
```js
// In the application
const speak = () => {
window.alert('HELLO WORLD');
};
const HelloWorldService = createHelloWorldService({ speak });
const servicesManager = new ServicesManager();
servicesManager.registerService(HelloWorldService);
// In an extension
const { HelloWorldService } = servicesManager.services;
if (HelloWorldService) {
HelloWorldService.speak();
}
```

View File

@ -1,15 +0,0 @@
# Service: Measurements
...
## Usage
## How to define a Measurement tool
## How to validate Measurements
## Data exchange concepts
## Longitudinal Measurements
## Timepoints

View File

@ -1,3 +0,0 @@
# Hotkeys
...

View File

@ -1,9 +0,0 @@
# Viewer
The OHIF Viewing Platform strives to be highly configurable and extensible. This
makes it easier for our community members to keep their "secret sauce" private,
and incentivises contributions back to the platform. The `@ohif/viewer` project
of the platform is the lynchpin that combines everything to create our
application.
- When configuration and themeing aren't enough

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +0,0 @@
:: REQUIRES GLOBAL INSTALL OF GITBOOK and GITBOOK-CLI
::
:: Call this script from the command line while in the directory of the book
:: you want to actively edit + preview
::
:: `gitbook serve` can break with permission issues on Windows for misc.
:: machines. This script is a workaround. When `gitbook serve` fails, it silently
:: restarts it.
:: https://github.com/GitbookIO/gitbook/issues/1379#issuecomment-288048275
@Echo off
:Start
call gitbook serve
goto Start

View File

@ -39,8 +39,8 @@
"dicom-parser": "^1.8.3",
"hammerjs": "^2.0.8",
"prop-types": "^15.6.2",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-resize-detector": "^3.4.0"
},
"dependencies": {

View File

@ -35,7 +35,9 @@
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-i18next": "^10.11.0",
"webpack": "^4.0.0",
"react-router": "next",
"react-router-dom": "next",
"webpack": "^5.43.0",
"webpack-merge": "^5.7.3"
},
"dependencies": {

View File

@ -12,7 +12,7 @@ import {
import i18n from '@ohif/i18n';
import { hotkeys } from '@ohif/core';
import { useNavigate } from 'react-router-dom';
const { availableLanguages, defaultLanguage, currentLanguage } = i18n;
@ -91,6 +91,11 @@ function ViewerLayout({
ViewportGridComp,
}) {
const [appConfig] = useAppConfig();
const navigate = useNavigate();
const onClickReturnButton = () => {
navigate('/')
};
const { t } = useTranslation();
const { show, hide } = useModal();
@ -176,7 +181,7 @@ function ViewerLayout({
return (
<div>
<Header menuOptions={menuOptions} WhiteLabeling={appConfig.whiteLabeling} >
<Header menuOptions={menuOptions} onClickReturnButton={onClickReturnButton} WhiteLabeling={appConfig.whiteLabeling} >
<ErrorBoundary context="Primary Toolbar">
<div className="relative flex justify-center">
<Toolbar servicesManager={servicesManager} />

View File

@ -39,7 +39,7 @@
"dicom-parser": "^1.8.3",
"hammerjs": "^2.0.8",
"prop-types": "^15.6.2",
"react": "^16.11.0",
"react": "^17.0.2",
"react-cornerstone-viewport": "4.0.5"
},
"dependencies": {

View File

@ -36,7 +36,7 @@
"react": "^16.13.1",
"react-cornerstone-viewport": "^4.0.5",
"react-dom": "^16.13.1",
"webpack": "^4.0.0",
"webpack": "^5.43.0",
"webpack-merge": "^5.7.3"
},
"dependencies": {

View File

@ -35,7 +35,7 @@
"@babel/runtime": "7.7.6"
},
"devDependencies": {
"webpack": "^5.21.2",
"webpack": "^5.43.0",
"webpack-merge": "^5.7.3"
}
}

View File

@ -18,7 +18,6 @@ const dicomsr = {
viewport: 'org.ohif.dicom-sr.viewportModule.dicom-sr',
};
export default function mode({ modeConfiguration }) {
return {
// TODO: We're using this as a route segment

View File

@ -6,6 +6,9 @@
"platform/*",
"extensions/*",
"modes/*"
],
"nohoist": [
"**/html-minifier-terser"
]
},
"engines": {
@ -30,7 +33,6 @@
"test:unit": "jest --collectCoverage",
"test:unit:ci": "lerna run test:unit:ci --parallel --stream",
"test:e2e": "lerna run test:e2e --stream",
"test:e2e:script-tag": "lerna run test:e2e:script-tag --stream",
"test:e2e:ci": "lerna run test:e2e:ci --stream",
"test:e2e:dist": "lerna run test:e2e:dist --stream",
"test:e2e:serve": "lerna run test:e2e:serve --stream",
@ -38,6 +40,7 @@
"docs:preview": "lerna run docs:preview --stream",
"docs:publish": "chmod +x ./build-and-publish-docs.sh && ./build-and-publish-docs.sh",
"release": "yarn run lerna:version && yarn run lerna:publish",
"lerna:clean": "lerna clean",
"lerna:cache": "./netlify-lerna-cache.sh",
"lerna:restore": "./netlify-lerna-restore.sh",
"lerna:version": "npx lerna version prerelease --force-publish",
@ -48,13 +51,15 @@
"@babel/runtime": "7.7.6",
"core-js": "^3.2.1",
"cornerstone-core": "2.3.0",
"react": "16.11.0",
"react-dom": "16.11.0",
"shader-loader": "^1.3.1",
"webpack": "^4.35.2",
"worker-loader": "^2.0.0",
"webpack": "^5.43.0",
"worker-loader": "^3.0.8",
"wslink": "^0.1.8"
},
"peerDependencies": {
"react": "17.0.2",
"react-dom": "17.0.2"
},
"devDependencies": {
"@babel/core": "^7.5.0",
"@babel/plugin-proposal-class-properties": "^7.5.0",
@ -71,7 +76,7 @@
"babel-plugin-inline-react-svg": "1.1.0",
"babel-plugin-module-resolver": "^3.2.0",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^5.0.3",
"copy-webpack-plugin": "^9.0.1",
"cross-env": "^5.2.0",
"css-loader": "^3.2.0",
"dotenv": "^8.1.0",
@ -86,8 +91,8 @@
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "7.x",
"eslint-plugin-react-hooks": "4.2.0",
"extract-css-chunks-webpack-plugin": "^4.5.4",
"html-webpack-plugin": "^3.2.0",
"extract-css-chunks-webpack-plugin": "^4.9.0",
"html-webpack-plugin": "^5.3.2",
"husky": "^3.0.0",
"jest": "^24.8.0",
"jest-canvas-mock": "^2.1.0",
@ -95,22 +100,21 @@
"lerna": "^3.15.0",
"lint-staged": "^9.0.2",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss": "^8.2.15",
"postcss-import": "^12.0.1",
"postcss-loader": "^3.0.0",
"postcss-loader": "^4.0.3",
"postcss-preset-env": "^6.6.0",
"prettier": "^1.18.2",
"react-hot-loader": "^4.12.21",
"react-hot-loader": "^4.13.0",
"serve": "^11.1.0",
"start-server-and-test": "^1.10.0",
"style-loader": "^1.0.0",
"terser-webpack-plugin": "^2.1.0",
"unused-files-webpack-plugin": "^3.4.0",
"terser-webpack-plugin": "^5.1.4",
"unused-webpack-plugin": "2.4.0",
"webpack-cli": "^3.3.5",
"webpack-dev-server": "^3.7.2",
"webpack-cli": "^4.7.2",
"webpack-hot-middleware": "^2.25.0",
"webpack-merge": "^4.2.1",
"workbox-webpack-plugin": "^5.0.0-beta.1"
"webpack-merge": "^5.7.3",
"workbox-webpack-plugin": "^6.1.5"
},
"husky": {
"hooks": {

View File

@ -1,6 +1,6 @@
const merge = require('webpack-merge');
const path = require('path');
const webpackCommon = require('./../../../.webpack/webpack.commonjs.js');
const webpackCommon = require('./../../../.webpack/webpack.base.js');
const pkg = require('./../package.json');
const ROOT_DIR = path.join(__dirname, './..');
@ -33,5 +33,15 @@ module.exports = (env, argv) => {
libraryTarget: 'umd',
filename: pkg.main,
},
externals: [
{
'cornerstone-math': {
commonjs: 'cornerstone-math',
commonjs2: 'cornerstone-math',
amd: 'cornerstone-math',
root: 'cornerstoneMath',
},
},
],
});
};

View File

@ -32,8 +32,10 @@
"peerDependencies": {
"cornerstone-core": "^2.3.0",
"cornerstone-tools": "5.1.2",
"cornerstone-math": "0.1.9",
"cornerstone-wado-image-loader": "^3.1.2",
"dicom-parser": "^1.8.3"
"dicom-parser": "^1.8.3",
"@ohif/ui": "^1.8.2"
},
"dependencies": {
"@babel/runtime": "7.7.6",
@ -43,10 +45,8 @@
"lodash.merge": "^4.6.1",
"lodash.clonedeep": "^4.5.0",
"moment": "^2.24.0",
"mousetrap": "^1.6.3",
"query-string": "^6.14.0",
"object-hash": "2.1.1",
"cornerstone-math": "0.1.9",
"validate.js": "^0.12.0"
},
"devDependencies": {

View File

@ -1,6 +1,6 @@
import objectHash from 'object-hash';
import hotkeys from './../utils/hotkeys';
import log from './../log.js';
import { hotkeys } from '../utils';
/**
*
@ -26,6 +26,8 @@ export class HotkeysManager {
this._servicesManager = servicesManager;
this._commandsManager = commandsManager;
hotkeys.initialize();
}
/**
@ -163,25 +165,40 @@ export class HotkeysManager {
* @param {String} extension
* @returns {undefined}
*/
registerHotkeys({ commandName, commandOptions = {}, keys, label, isEditable } = {}, extension) {
registerHotkeys(
{ commandName, commandOptions = {}, keys, label, isEditable } = {},
extension
) {
if (!commandName) {
throw new Error(`No command was defined for hotkey "${keys}"`);
}
const commandHash = objectHash({ commandName, commandOptions });
const options = Object.keys(commandOptions).length ? JSON.stringify(commandOptions) : 'no';
const options = Object.keys(commandOptions).length
? JSON.stringify(commandOptions)
: 'no';
const previouslyRegisteredDefinition = this.hotkeyDefinitions[commandHash];
if (previouslyRegisteredDefinition) {
const previouslyRegisteredKeys = previouslyRegisteredDefinition.keys;
this._unbindHotkeys(commandName, previouslyRegisteredKeys);
log.info(`[hotkeys] Unbinding ${commandName} with ${options} options from ${previouslyRegisteredKeys}`);
log.info(
`[hotkeys] Unbinding ${commandName} with ${options} options from ${previouslyRegisteredKeys}`
);
}
// Set definition & bind
this.hotkeyDefinitions[commandHash] = { commandName, commandOptions, keys, label, isEditable };
this.hotkeyDefinitions[commandHash] = {
commandName,
commandOptions,
keys,
label,
isEditable,
};
this._bindHotkeys(commandName, commandOptions, keys);
log.info(`[hotkeys] Binding ${commandName} with ${options} options to ${keys}`);
log.info(
`[hotkeys] Binding ${commandName} with ${options} options to ${keys}`
);
}
/**

View File

@ -2,7 +2,7 @@ import CommandsManager from './CommandsManager.js';
import HotkeysManager from './HotkeysManager.js';
import hotkeys from './../utils/hotkeys';
import log from './../log.js';
import objectHash from "object-hash";
import objectHash from 'object-hash';
jest.mock('./CommandsManager.js');
jest.mock('./../utils/hotkeys');
@ -10,6 +10,9 @@ jest.mock('./../log.js');
describe('HotkeysManager', () => {
let hotkeysManager, commandsManager;
beforeAll(() => {
hotkeys.initialize();
});
beforeEach(() => {
commandsManager = new CommandsManager();
@ -19,7 +22,6 @@ describe('HotkeysManager', () => {
log.warn.mockClear();
jest.clearAllMocks();
});
it('has expected properties', () => {
const allProperties = Object.keys(hotkeysManager);
const expectedProprties = [
@ -122,11 +124,16 @@ describe('HotkeysManager', () => {
const definition = { commandName: undefined, keys: '+' };
expect(() => {
hotkeysManager.registerHotkeys(definition)
hotkeysManager.registerHotkeys(definition);
}).toThrow();
});
it('updates hotkeyDefinitions property with registered keys', () => {
const definition = { commandName: 'dance', commandOptions: {}, label: 'hello', keys: '+', };
const definition = {
commandName: 'dance',
commandOptions: {},
label: 'hello',
keys: '+',
};
hotkeysManager.registerHotkeys(definition);
@ -136,13 +143,15 @@ describe('HotkeysManager', () => {
const commandHash = objectHash({
commandName: definition.commandName,
commandOptions: definition.commandOptions
commandOptions: definition.commandOptions,
});
const hotkeyDefinitionForRegisteredCommand =
hotkeysManager.hotkeyDefinitions[commandHash];
expect(numOfHotkeyDefinitions).toBe(1);
expect(Object.keys(hotkeysManager.hotkeyDefinitions)[0]).toEqual(commandHash);
expect(Object.keys(hotkeysManager.hotkeyDefinitions)[0]).toEqual(
commandHash
);
expect(hotkeyDefinitionForRegisteredCommand).toEqual(definition);
});
it('calls hotkeys.bind for the group of keys', () => {

View File

@ -16,8 +16,8 @@ const serviceImplementation = {
_getState: () => console.warn('getState() NOT IMPLEMENTED'),
_setUser: () => console.warn('_setUser() NOT IMPLEMENTED'),
_getUser: () => console.warn('_setUser() NOT IMPLEMENTED'),
_getAuthorizationHeader: () =>
console.warn('_getAuthorizationHeader() NOT IMPLEMENTED'),
_getAuthorizationHeader: () => {}, // TODO: have enabled/disabled state?
//console.warn('_getAuthorizationHeader() NOT IMPLEMENTED'),
_handleUnauthenticated: () =>
console.warn('_handleUnauthenticated() NOT IMPLEMENTED'),
_reset: () => console.warn('reset() NOT IMPLEMENTED'),

View File

@ -2,7 +2,30 @@ import Mousetrap from 'mousetrap';
import pausePlugin from './pausePlugin';
import recordPlugin from './recordPlugin';
recordPlugin(Mousetrap);
pausePlugin(Mousetrap);
Mousetrap.initialize = () => {
if (!Mousetrap._initialized) {
recordPlugin(Mousetrap);
pausePlugin(Mousetrap);
Mousetrap._initialized = true;
}
};
// These are only here so that Jest mocks them properly before .initialize() is called
Mousetrap.handleKey = () =>
console.debug('Mousetrap recordPlugin not yet initialized');
Mousetrap.startRecording = () =>
console.debug('Mousetrap recordPlugin not yet initialized');
Mousetrap.stopRecording = () =>
console.debug('Mousetrap recordPlugin not yet initialized');
Mousetrap.record = () =>
console.debug('Mousetrap recordPlugin not yet initialized');
Mousetrap.stopCallback = () =>
console.debug('Mousetrap pausePlugin not yet initialized');
Mousetrap.pause = () =>
console.debug('Mousetrap pausePlugin not yet initialized');
Mousetrap.unpause = () =>
console.debug('Mousetrap pausePlugin not yet initialized');
export default Mousetrap;

View File

@ -46,7 +46,7 @@ const utils = {
resolveObjectPath,
hierarchicalListUtils,
progressTrackingUtils,
isLowPriorityModality
isLowPriorityModality,
};
export {
@ -69,7 +69,7 @@ export {
resolveObjectPath,
hierarchicalListUtils,
progressTrackingUtils,
isLowPriorityModality
isLowPriorityModality,
};
export default utils;

20
platform/docs/.gitignore vendored Normal file
View File

@ -0,0 +1,20 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

33
platform/docs/README.md Normal file
View File

@ -0,0 +1,33 @@
# Website
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
## Installation
```console
yarn install
```
## Local Development
```console
yarn start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
## Build
```console
yarn build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
## Deployment
```console
GIT_USER=<Your GitHub username> USE_SSH=true yarn deploy
```
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

View File

@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};

View File

@ -0,0 +1,186 @@
---
id: Introduction
slug: /
sidebar_position: 1
---
<div className="text--center">
<a style={{marginRight:'10px'}} href="http://viewer.ohif.org/">Preview The OHIF Viewer</a>
<a href="https://www.netlify.com"/>
<img style={{width:'70px'}} src="https://www.netlify.com/img/global/badges/netlify-color-bg.svg" />
</div>
> ATTENTION! You are looking at the docs for the `OHIF-v3` Viewer (third time is
> always a charm). If you're looking for the our `OHIF-v2` (React stable
> version) or OHIF-v1 (deprecated `Meteor` version) select it's version from the
> dropdown box in the top left corner of this page.
The [Open Health Imaging Foundation][ohif-org] (OHIF) Viewer is an open source,
web-based, medical imaging viewer. It can be configured to connect to Image
Archives that support [DicomWeb][dicom-web], and offers support for mapping to
proprietary API formats. OHIF maintained extensions add support for viewing,
annotating, and reporting on DICOM images in 2D (slices) and 3D (volumes).
![OHIF Viewer Screenshot](./assets/img/OHIF-Viewer.png)
<!-- <center><i>The <strong>OHIF Viewer v3</strong>: A general purpose DICOM Viewer (<a href="http://viewer.ohif.org/">Live Demo</a>)</center> -->
&nbsp;
## What's new in `OHIF-v3`
`OHIF-v3` is our second try for a React-based viewer, and is the third version
of our medical image web viewers from the start. The summary of changes include:
- Addition of workflow modes
- Often, medical imaging use cases involves lots of specific workflows that
re-use functionalities. We have added the capability of workflow modes, that
enable people to customize user interface and configure application for
specific workflow.
- The idea is to re-use the functionalities that extensions provide and create
a workflow. Brain segmentation workflow is different from prostate
segmentation in UI for sure; however, they share the segmentation tools that
can be re-used.
- Our vision is that technical people focus of developing extensions which
provides core functionalities, and experts to build modes by picking the
appropriate functionalities from each extension.
* Redux store has been removed from the viewer, and a cleaner, more powerful
* Tailwind CSS
* End-to-end test suite
Below, you can find the gap analysis between the `OHIF-v2` and `OHIF-v3`:
<table>
<thead>
<tr>
<th align="left" width="50%">OHIF-v2 functionalities</th>
<th align="center">OHIF-v3</th>
<th align="center">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Rendering of 2D images via Cornerstone</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">Study List</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">Series Browser</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">DICOM JSON</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">2D Tools via CornerstoneTools</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">OpenID Connect standard authentication flow for connecting to identity providers</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">Internationalization</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">Drag/drop DICOM data into the viewer (see https://viewer.ohif.org/local)</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">White-labelling: Easily replace the OHIF Logo with your logo</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="left">DICOM Whole-slide imaging viewport</td>
<td align="center">🔜</td>
<td align="center">In Progress</td>
</tr>
<tr>
<td align="left">IHE Invoke Image Display - Standard-compliant launching of the viewer (e.g. from PACS or RIS)</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">DICOM PDF support</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">Displaying non-renderable DICOM as HTML</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">Segmentation support</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">RT STRUCT support</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">DICOM upload to PACS</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">Google Cloud adapter</td>
<td align="center">🔜</td>
<td align="center">Not Started</td>
</tr>
<tr>
<td align="left">VTK Extension + MIP / MPR layout</td>
<td align="center"></td>
<td align="center">Other plans that involves amazing news soon!</td>
</tr>
<tr>
<td align="left">UMD Build (Embedded Viewer). </td>
<td align="center"></td>
<td align="center">The problem is that this breaks a bunch of extensions that rely on third party scripts (e.g. VTK) which have their own web worker loaders.</td>
</tr>
</tbody>
</table>
## Where to next?
The Open Health Imaging Foundation intends to provide a simple general purpose
DICOM Viewer which can be easily extended for specific uses. If you find
yourself unable to extend the viewer for your purposes, please reach out via our
[GitHub issues][gh-issues]. We are actively seeking feedback on ways to improve
our integration and extension points.
Check out these helpful links:
- Ready to dive into some code? Check out our
[Getting Started Guide](./development/getting-started.md).
- We're an active, vibrant community.
[Learn how you can be more involved.](./development/contributing.md)
- Feeling lost? Read our [help page](./help.md).
<!--
Links
-->
<!-- prettier-ignore-start -->
[ohif-org]: https://www.ohif.org
[ohif-demo]: http://viewer.ohif.org/
[dicom-web]: https://en.wikipedia.org/wiki/DICOMweb
[gh-issues]: https://github.com/OHIF/Viewers/issues
<!-- prettier-ignore-end -->

View File

Before

Width:  |  Height:  |  Size: 818 B

After

Width:  |  Height:  |  Size: 818 B

Some files were not shown because too many files have changed in this diff Show More