Compare commits

...
Author SHA1 Message Date
ohif-bot f9037f831d chore(release): publish [skip ci]
- @ohif/extension-vtk@1.3.8
 - @ohif/core@2.6.7
 - @ohif/viewer@3.8.16
2020-04-02 17:58:41 +00:00
James PettsandDanny Brown 9e0bd52c6a fix: 🐛 Fix multiframe images (#1595)
Co-authored-by: Danny Brown <danny.ri.brown@gmail.com>
2020-04-02 13:56:53 -04:00
ohif-bot f1b017dc08 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.3.7
 - @ohif/core@2.6.6
 - @ohif/viewer@3.8.15
2020-04-02 17:32:56 +00:00
81dcbe294d refactor: Reduce bundle size (#1575)
* async load cornerstoneWADOImageLoader chunk

* Lazy initializing of CornerstoneWADIImageLoader - delayed till Viewer creation

* Async loading of react-vtkjs-viewport

* withCornerstone HOC to wrap routes requiring CornerstoneWADOImageLoader initiazation

* removed dead code in comments

* initWeWorkers is no more. Remove al its references.

Co-authored-by: kedar.netelixir <kedar.choudhary@netelixir.com>
Co-authored-by: Danny Brown <danny.ri.brown@gmail.com>
2020-04-02 13:31:14 -04:00
Pierre-Antoine Ganaye e09a3d2e93 docs: Remove dead links in docs and improve SOP Class Handler docs (#1593)
* fix docs dead links

* add examples to SOP handler docs
2020-04-02 09:24:49 -04:00
ohif-bot 978a86bf12 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.5.1
 - @ohif/extension-dicom-html@1.1.2
 - @ohif/extension-dicom-microscopy@0.50.9
 - @ohif/extension-dicom-pdf@1.0.3
 - @ohif/viewer@3.8.14
2020-04-02 07:01:58 +00:00
0139a32213 chore: Switch asyncComponent to React Lazy/Suspense (Closes #1577) (#1582)
* Attempted Lazy load for OHIFCornerStoneViewport

* Converted dicom-(html, microscopy, pdf) & cornerstone extensions to React Lazy components

* Fixed incorrect import from OHIFDicomPDFSopClassHandler to ConnectedOHIFDicomPDFViewer

Co-authored-by: Ankit Mohan <ankit.mohan@live.in>
Co-authored-by: Erik Ziegler <erik.sweed@gmail.com>
2020-04-02 08:59:17 +02:00
60 changed files with 429 additions and 395 deletions

No files matched your search

+1 -1
View File
@@ -48,7 +48,7 @@ Check out these helpful links:
-->
<!-- prettier-ignore-start -->
[ohif-org]: https://www.ohif.org
[ohif-org]: http://www.ohif.org
[dicom-web]: https://en.wikipedia.org/wiki/DICOMweb
[gh-issues]: https://github.com/OHIF/Viewers/issues
<!-- prettier-ignore-end -->
+1
View File
@@ -5,6 +5,7 @@
- [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)
+5 -10
View File
@@ -13,7 +13,6 @@ architected, and the role each of it's dependent libraries plays.
- [Overview](#overview)
- [Business Logic](#business-logic)
- [Component Library](#react-component-library)
- [Internationalization](#internationalization-i18n)
- [Extensions & Configuration](#extensions--configuration)
- [Common Questions](#common-questions)
@@ -74,10 +73,10 @@ This diagram is a conceptual illustration of how the Viewer is architected.
The [`@ohif/core`][core-github] project offers pre-packaged solutions for
features common to Web-based medical imaging viewers. For example:
- [Hotkeys](#)
- Hotkeys
- DICOM Web requests
- Hanging Protocols
- [Managing a study's measurements](../services/default/measurements.md)
- Managing a study's measurements
- Managing a study's DICOM metadata
- [A flexible pattern for extensions](../extensions/index.md)
- And many others
@@ -99,10 +98,6 @@ application.
[Check out our component library!](https://react.ohif.org/)
## Internationalization (i18n)
...
## Extensions & Configuration
While OHIF maintains several high value and commonly requested features in its
@@ -120,7 +115,7 @@ the viewer. Some common use cases include:
We expose common integration points via [extensions](../extensions/index.md) to
make this possible. The viewer and many of our own extensions also offer
[configuration][configuration]. For a list of extensions maintained by OHIF,
[check out this helpful table](../extensions/index.mdl#maintained-extensions).
[check out this helpful table](../extensions/index.md#maintained-extensions).
If you find yourself thinking "I wish the Viewer could do X", and you can't
accomplish it with an extension today, create a GitHub issue! We're actively
@@ -147,12 +142,12 @@ you would need to recreate.
-->
<!-- prettier-ignore-start -->
[monorepo]: #
[monorepo]: https://github.com/OHIF/Viewers/issues/768
[viewers-project]: https://github.com/OHIF/Viewers
[viewer-npm]: https://www.npmjs.com/package/@ohif/viewer
[pwa]: https://developers.google.com/web/progressive-web-apps/
[configuration]: ../configuring/index.md
[extensions]: ../extensions/index.md
[core-github]: https://github.com/OHIF/viewers/platform/core
[ui-github]: https://github.com/OHIF/Viewers/platform/ui
[ui-github]: https://github.com/OHIF/Viewers/tree/master/platform/ui
<!-- prettier-ignore-end -->
+7 -7
View File
@@ -123,7 +123,7 @@ There are two important steps to making sure this setup works:
Most image archives do not provide either of these features "out of the box".
It's common to use IIS, Nginx, or Apache to route incoming requests and append
appropriate headers. You can find an example of this setup in our
[Nginx + Image Archive Deployment Recipe](deployment/recipes/nginx--image-archive.md).
[Nginx + Image Archive Deployment Recipe](./recipes/nginx--image-archive.md).
#### What if my archive doesn't support DicomWeb?
@@ -166,7 +166,7 @@ window.config = {
```
You can find an example of this setup in our
[User Account Control Deployment Recipe](deployment/recipes/user-account-control.md).
[User Account Control Deployment Recipe](./recipes/user-account-control.md).
#### Choosing a Flow for the Viewer
@@ -183,12 +183,12 @@ many possible configurations, so please don't feel limited to these setups.
Please feel free to suggest or contribute your own recipes.
- Script Include
- [Embedding the Viewer](deployment/recipes/embedded-viewer.md)
- [Embedding the Viewer](./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)
- [Build for Production](./recipes/build-for-production.md)
- [Static](./recipes/static-assets.md)
- [Nginx + Image Archive](./recipes/nginx--image-archive.md)
- [User Account Control](./recipes/user-account-control.md)
<!--
Links
@@ -50,7 +50,7 @@ window.config = {
```
To learn more about how you can configure the OHIF Viewer, check out our
[Configuration Guide](./index.md).
[Configuration Guide](../../configuring/index.md).
<ol start="3"><li>
Render the viewer in the web page's target <code>div</code>
@@ -49,9 +49,7 @@ We can solve this one of two ways:
1. Have our Image Archive located at the same domain as our Web App
2. Add appropriate `Access-Control-Allow-*` HTTP headers
This solution uses the first approach, but you can see an example of the second
in the `docker-compose` bundled with this project for local development:
[HERE](https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/Nginx-Orthanc/docker-compose.yml)
**This solution uses the first approach.**
You can read more about CORS in this Medium article: [Understanding
CORS][understanding-cors]
@@ -121,7 +119,10 @@ likely want to update:
#### OHIF Viewer
The OHIF Viewer's configuration is imported from a static `.js` file. The configuration we use is set to a specific file when we build the viewer, and determined by the env variable: `APP_CONFIG`. You can see where we set its value in the `dockerfile` for this solution:
The OHIF Viewer's configuration is imported from a static `.js` file. The
configuration we use is set to a specific file when we build the viewer, and
determined by the env variable: `APP_CONFIG`. You can see where we set its value
in the `dockerfile` for this solution:
`ENV APP_CONFIG=config/docker_openresty-orthanc.js`
@@ -138,11 +139,11 @@ Viewer's configuration, you can run:
All other files are found in: `/docker/OpenResty-Orthanc/`
| Service | Configuration | Docs |
| ----------------- | ---------------------------------------------- | ------------------------------------------- |
| OHIF Viewer | [dockerfile][dockerfile] / [config.js][config] | You're reading them now! |
| OpenResty (Nginx) | [`/nginx.conf`][config-nginx] | [lua-resty-openidc][lua-resty-openidc-docs] |
| Orthanc | [`/orthanc.json`][config-orthanc] | [Here][orthanc-docs] |
| Service | Configuration | Docs |
| ----------------- | --------------------------------- | ------------------------------------------- |
| OHIF Viewer | [dockerfile][dockerfile] | You're reading them now! |
| OpenResty (Nginx) | [`/nginx.conf`][config-nginx] | [lua-resty-openidc][lua-resty-openidc-docs] |
| Orthanc | [`/orthanc.json`][config-orthanc] | [Here][orthanc-docs] |
## Next Steps
@@ -218,10 +219,11 @@ following resources helpful:
- [OpenResty Guide](http://www.staticshin.com/programming/definitely-an-open-resty-guide/)
- [Lua Ngx API](https://openresty-reference.readthedocs.io/en/latest/Lua_Nginx_API/)
For a different take on this setup, check out the repository one of our
community members put together:
For a different take on this setup, check out the repositories our community
members put together:
- [mjstealey/ohif-orthanc-dimse-docker](https://github.com/mjstealey/ohif-orthanc-dimse-docker)
- [trypag/ohif-orthanc-postgres-docker](https://github.com/trypag/ohif-orthanc-postgres-docker)
<!--
Links
@@ -234,8 +236,7 @@ community members put together:
[orthanc-docs]: http://book.orthanc-server.com/users/configuration.html#configuration
[lua-resty-openidc-docs]: https://github.com/zmartzone/lua-resty-openidc
<!-- SRC -->
[config]: #
[dockerfile]: #
[config-nginx]: #
[config-orthanc]: #
[dockerfile]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc/dockerfile
[config-nginx]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc/config/nginx.conf
[config-orthanc]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc/config/orthanc.json
<!-- prettier-ignore-end -->
@@ -122,7 +122,10 @@ likely want to update:
#### OHIF Viewer
The OHIF Viewer's configuration is imported from a static `.js` file. The configuration we use is set to a specific file when we build the viewer, and determined by the env variable: `APP_CONFIG`. You can see where we set its value in the `dockerfile` for this solution:
The OHIF Viewer's configuration is imported from a static `.js` file. The
configuration we use is set to a specific file when we build the viewer, and
determined by the env variable: `APP_CONFIG`. You can see where we set its value
in the `dockerfile` for this solution:
`ENV APP_CONFIG=config/docker_openresty-orthanc-keycloak.js`
@@ -146,8 +149,8 @@ All other files are found in: `/docker/OpenResty-Orthanc-Keycloak/`
| Orthanc | [`/orthanc.json`][config-orthanc] | [Here][orthanc-docs] |
| Keycloak | [`/ohif-keycloak-realm.json`][config-keycloak]\* | |
- \* These are the seed values for Keycloak. They can be manually updated at
`http://127.0.0.1/auth/admin`
\* These are the seed values for Keycloak. They can be manually updated at
`http://127.0.0.1/auth/admin`
#### Keycloak Themeing
@@ -261,12 +264,12 @@ for OAuth:
- [Diagrams of OpenID Connect Flows](https://medium.com/@darutk/diagrams-of-all-the-openid-connect-flows-6968e3990660)
- [KeyCloak: OpenID Connect Flows](https://www.keycloak.org/docs/latest/securing_apps/index.html#authorization-code)
- [Good description on SSO Protocols](https://www.keycloak.org/docs/2.5/server_admin/topics/sso-protocols/oidc.html)
For a different take on this setup, check out the repository one of our
community members put together:
For a different take on this setup, check out the repositories our community
members put together:
- [mjstealey/ohif-orthanc-dimse-docker](https://github.com/mjstealey/ohif-orthanc-dimse-docker)
- [trypag/ohif-orthanc-postgres-docker](https://github.com/trypag/ohif-orthanc-postgres-docker)
<!--
Links
@@ -278,8 +281,8 @@ community members put together:
[lua-resty-openidc-docs]: https://github.com/zmartzone/lua-resty-openidc
<!-- SRC -->
[config]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/src/config.js
[dockerfile]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
[config-nginx]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
[config-orthanc]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
[config-keycloak]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
[dockerfile]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc-Keycloak/dockerfile
[config-nginx]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc-Keycloak/config/nginx.conf
[config-orthanc]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc-Keycloak/config/orthanc.json
[config-keycloak]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc-Keycloak/config/ohif-keycloak-realm.json
<!-- prettier-ignore-end -->
+2 -2
View File
@@ -114,8 +114,8 @@ the tips above will help ensure your changes are reviewed.
## Testing contribution pull requests
OHIF uses [netlify](netlify.com) so that pull requests are autogenerated and
available for testing.
OHIF uses [netlify](https://www.netlify.com/) so that pull requests are
autogenerated and available for testing.
For example, [this url][example-url] allows you to test [pull request 237, the
request that created this FAQ entry,][pr-237] using data pulled from Amazon S3.
+1 -1
View File
@@ -132,7 +132,7 @@ feature `X` or scenario `Y`? Open an issue and let's discuss.
[flow-org]: https://flow.org/
<!-- Talks -->
[assert-js-talks]: https://www.youtube.com/playlist?list=PLZ66c9_z3umNSrKSb5cmpxdXZcIPNvKGw
[kent-talk]: https://www.youtube.com/watch?list=PLV5CVI1eNcJgNqzNwcs4UKrlJdhfDjshf
[kent-talk]: https://www.youtube.com/watch?v=Fha2bVoC8SE
[gleb-talk]: https://www.youtube.com/watch?v=5FnalKRjpZk
[kent-blog]: https://kentcdodds.com/blog/unit-vs-integration-vs-e2e-tests
<!-- Images -->
@@ -31,6 +31,7 @@
</td>
<td>Viewport, Toolbar</td>
</tr>
<!-- dicom-html -->
<tr>
<td>
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-html">DICOM HTML</a>
@@ -40,6 +41,7 @@
</td>
<td>Viewport, SopClassHandler</td>
</tr>
<!-- dicom-pdf -->
<tr>
<td>
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-pdf">DICOM PDF</a>
@@ -49,6 +51,7 @@
</td>
<td>Viewport, SopClassHandler</td>
</tr>
<!-- dicom-microscopy -->
<tr>
<td>
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-microscopy">DICOM Microscopy</a>
@@ -58,5 +61,15 @@
</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>
+11 -9
View File
@@ -74,7 +74,8 @@ export default {
### Registering an Extension
There are two different ways to register and configure extensions: At
[runtime](#runtime-extensions) and at [build time](#bundled-extensions).
[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
@@ -82,9 +83,9 @@ becomes available to the core application via the `ExtensionManager`.
#### Registering at Runtime
The `@ohif/viewer` uses a [configuration file](#) at startup. The schema for
that file includes an `Extensions` key that supports an array of extensions to
register.
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
// prettier-ignore
@@ -193,8 +194,8 @@ today, create a GitHub issue!
The `ExtensionManager` is a class made available to us via the `@ohif/core`
project (platform/core). Our application instantiates a single instance of it,
and provides a `ServicesManager` and `CommandsManager` along with the application's
configuration through the appConfig key (optional).
and provides a `ServicesManager` and `CommandsManager` along with the
application's configuration through the appConfig key (optional).
```js
const commandsManager = new CommandsManager();
@@ -202,7 +203,7 @@ const servicesManager = new ServicesManager();
const extensionManager = new ExtensionManager({
commandsManager,
servicesManager,
appConfig
appConfig,
});
```
@@ -212,8 +213,9 @@ The `ExtensionManager` only has a few public members:
- `registerExtensions` - Registers an array of extensions
- `modules` - An object containing registered extensions by `MODULE_TYPE`
During registration, lifecycle hooks and modules have access to the extension's config,
the application's config and `ExtensionManager`'s `ServicesManager` and `CommandsManager` instances.
During registration, lifecycle hooks and modules have access to the extension's
config, the application's config and `ExtensionManager`'s `ServicesManager` and
`CommandsManager` instances.
Our `@ohif/viewer` uses the `modules` member to access registered extensions at
appropriate places in our application.
@@ -1,9 +1,9 @@
# Module: SOP Class Handler
An extension can register a SOP Class Handler Module by defining a
`getSopClassHandlerModule` method. The SOP Class Handler is a bit different from
the other modules, as it doesn't provide a `1:1` schema for UI or provide it's
own components. It instead defines:
An extension can register a [SOP Class][sop-class-link] Handler Module by
defining a `getSopClassHandlerModule` method. The [SOP Class][sop-class-link]
Handler is a bit different from the other modules, as it doesn't provide a `1:1`
schema for UI or provide it's own components. It instead defines:
- `sopClassUIDs`: an array of string SOP Class UIDs that the
`getDisplaySetFromSeries` method should be applied to.
@@ -76,6 +76,13 @@ getSopClassHandlerModule({ servicesManager, commandsManager }) {
};
```
### More examples :
- [Dicom-HTML SOP][dicom-html-sop]
- [Dicom-PDF SOP][dicom-pdf-sop]
- [Dicom-Microscopy SOP][dicom-micro-sop]
- [Dicom-Segmentation SOP][dicom-seg-sop]
## `@ohif/viewer` usage
We use the `sopClassHandlerModule`s in three different places:
@@ -88,3 +95,11 @@ Each time, it is used to map study and series data to `displaySets`. It does
this by working alongside the `StudyMetadataManager` in `@ohif/core`. That
manager has the method `createDisplaySets` that takes an array of
`sopClassHandlerModules`.
<!-- prettier-ignore-start -->
[sop-class-link]: http://dicom.nema.org/dicom/2013/output/chtml/part04/sect_B.5.html
[dicom-html-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-html/src/OHIFDicomHtmlSopClassHandler.js#L4-L12
[dicom-pdf-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-pdf/src/OHIFDicomPDFSopClassHandler.js#L4-L6
[dicom-micro-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-microscopy/src/DicomMicroscopySopClassHandler.js#L5-L7
[dicom-seg-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-segmentation/src/OHIFDicomSegSopClassHandler.js#L5-L7
<!-- prettier-ignore-end -->
+2 -2
View File
@@ -75,7 +75,7 @@ items to our ["Active Development" GitHub Project Board][gh-board]. Items on
this project board are either in active development by Core Team members, or
queued up for development as in-progress items are completed.
> :pencil: Want to contribute but not sure where to start? Check out [Up for
> 🖋 Want to contribute but not sure where to start? Check out [Up for
> grabs][label-grabs] issues and our [Contributing
> documentation][contributing-docs]
@@ -156,5 +156,5 @@ addressed and a Stable version is released.
[ohif-prod]: https://viewer.ohif.org
[gh-board]: https://github.com/OHIF/Viewers/projects/4
[label-grabs]: https://github.com/OHIF/Viewers/issues?q=is%3Aissue+is%3Aopen+label%3A%22Up+For+Grabs+%3Araising_hand_woman%3A%22
[contributing-docs]: https://docs.ohif.org/contributing/
[contributing-docs]: ./development/contributing.md
<!-- prettier-ignore-end -->
+1 -1
View File
@@ -62,7 +62,7 @@ able to fail or be removed. Related patterns that may reduce coupling include:
-->
<!-- prettier-ignore-start -->
[commands]: #/
[commands]: ../extensions/modules/commands.md
[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
+2 -2
View File
@@ -2,8 +2,8 @@
- [Overview](#overview)
- [Example](#example)
- [Tips & Tricks](#/)
- [Maintained Services](#/)
- [Tips & Tricks](#tips--tricks)
- [Maintained Services](#maintained-services)
## Overview
+4 -4
View File
@@ -135,7 +135,7 @@ console.log(T('$t(Common:Play) my translated text'));
# Main Concepts While Translating
## - Namespaces
## Namespaces
Namespaces are being used to organize translations in smaller portions, combined
semantically or by use. Each `.json` file inside `@ohif/i18n` npm package
@@ -157,7 +157,7 @@ NameSpace, like this following example getting data from `Common` NameSpace:
$t(Common:Reset)
```
## - Extending Languages in @ohif/i18n
## Extending Languages in @ohif/i18n
Sometimes, even using the same language, some nouns or jargons can change
according to the country, states or even from Hospital to Hospital.
@@ -212,7 +212,7 @@ object like this:
Please check the `index.js` files inside locales folder for an example of this
exporting structure.
### - Extending languages dynamically
### Extending languages dynamically
You have access to the i18next instance, so you can use the
[addResourceBundle](https://www.i18next.com/how-to/add-or-load-translations#add-after-init)
@@ -314,4 +314,4 @@ REACT_APP_I18N_DEBUG=true yarn run dev
### Contributing with new languages
Contributions of any kind are welcome! Please check the
[instructions](https://docs.ohif.org/contributing.html).
[instructions](../development/contributing.md).
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.5.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.5.0...@ohif/extension-cornerstone@2.5.1) (2020-04-02)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [2.5.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.4.3...@ohif/extension-cornerstone@2.5.0) (2020-03-13)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone",
"version": "2.5.0",
"version": "2.5.1",
"description": "OHIF extension for Cornerstone",
"author": "OHIF",
"license": "MIT",
@@ -1,37 +0,0 @@
/**
* We use this component to leverage "Code Splitting"
*
* Link: https://serverless-stack.com/chapters/code-splitting-in-create-react-app.html
*/
import React, { Component } from 'react';
export default function asyncComponent(importComponent) {
class AsyncComponent extends Component {
constructor(props) {
super(props);
this.state = {
component: null,
};
}
async componentDidMount() {
// Add dynamically loaded component to state
const { default: component } = await importComponent();
this.setState({
component: component,
});
}
render() {
const C = this.state.component;
// Render the loaded component, or null
return C ? <C {...this.props} /> : null;
}
}
return AsyncComponent;
}
+12 -6
View File
@@ -1,14 +1,20 @@
import React from 'react';
import init from './init.js';
import asyncComponent from './asyncComponent.js';
import commandsModule from './commandsModule.js';
import toolbarModule from './toolbarModule.js';
import CornerstoneViewportDownloadForm from './CornerstoneViewportDownloadForm';
const OHIFCornerstoneViewport = asyncComponent(() =>
import(
/* webpackChunkName: "OHIFCornerstoneViewport" */ './OHIFCornerstoneViewport.js'
)
);
const Component = React.lazy(() => {
return import('./OHIFCornerstoneViewport');
});
const OHIFCornerstoneViewport = props => {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<Component {...props} />
</React.Suspense>
);
};
/**
*
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.1.1...@ohif/extension-dicom-html@1.1.2) (2020-04-02)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.1.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.1.0...@ohif/extension-dicom-html@1.1.1) (2020-03-09)
**Note:** Version bump only for package @ohif/extension-dicom-html
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-dicom-html",
"version": "1.1.1",
"version": "1.1.2",
"description": "OHIF extension for rendering structured reports to HTML",
"author": "OHIF",
"license": "MIT",
@@ -1,37 +0,0 @@
/**
* We use this component to leverage "Code Splitting"
*
* Link: https://serverless-stack.com/chapters/code-splitting-in-create-react-app.html
*/
import React, { Component } from 'react';
export default function asyncComponent(importComponent) {
class AsyncComponent extends Component {
constructor(props) {
super(props);
this.state = {
component: null,
};
}
async componentDidMount() {
// Add dynamically loaded component to state
const { default: component } = await importComponent();
this.setState({
component: component,
});
}
render() {
const C = this.state.component;
// Render the loaded component, or null
return C ? <C {...this.props} /> : null;
}
}
return AsyncComponent;
}
+12 -6
View File
@@ -1,11 +1,17 @@
import asyncComponent from './asyncComponent.js';
import React from 'react';
import OHIFDicomHtmlSopClassHandler from './OHIFDicomHtmlSopClassHandler.js';
const OHIFDicomHtmlViewport = asyncComponent(() =>
import(
/* webpackChunkName: "OHIFDicomHtmlViewport" */ './OHIFDicomHtmlViewport.js'
)
);
const Component = React.lazy(() => {
return import('./OHIFDicomHtmlViewport');
});
const OHIFDicomHtmlViewport = props => {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<Component {...props} />
</React.Suspense>
);
};
export default {
/**
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.50.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-microscopy@0.50.8...@ohif/extension-dicom-microscopy@0.50.9) (2020-04-02)
**Note:** Version bump only for package @ohif/extension-dicom-microscopy
## [0.50.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-microscopy@0.50.7...@ohif/extension-dicom-microscopy@0.50.8) (2020-03-31)
**Note:** Version bump only for package @ohif/extension-dicom-microscopy
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-dicom-microscopy",
"version": "0.50.8",
"version": "0.50.9",
"description": "OHIF extension for Dicom Microscopy",
"author": "OHIF",
"license": "MIT",
@@ -1,37 +0,0 @@
/**
* We use this component to leverage "Code Splitting"
*
* Link: https://serverless-stack.com/chapters/code-splitting-in-create-react-app.html
*/
import React, { Component } from 'react';
export default function asyncComponent(importComponent) {
class AsyncComponent extends Component {
constructor(props) {
super(props);
this.state = {
component: null,
};
}
async componentDidMount() {
// Add dynamically loaded component to state
const { default: component } = await importComponent();
this.setState({
component: component,
});
}
render() {
const C = this.state.component;
// Render the loaded component, or null
return C ? <C {...this.props} /> : null;
}
}
return AsyncComponent;
}
+12 -6
View File
@@ -1,11 +1,17 @@
import asyncComponent from './asyncComponent.js';
import React from 'react';
import DicomMicroscopySopClassHandler from './DicomMicroscopySopClassHandler.js';
const DicomMicroscopyViewport = asyncComponent(() =>
import(
/* webpackChunkName: "DicomMicroscopyViewport" */ './DicomMicroscopyViewport.js'
)
);
const Component = React.lazy(() => {
return import('./DicomMicroscopyViewport');
});
const DicomMicroscopyViewport = props => {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<Component {...props} />
</React.Suspense>
);
};
export default {
/**
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.0.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-pdf@1.0.2...@ohif/extension-dicom-pdf@1.0.3) (2020-04-02)
**Note:** Version bump only for package @ohif/extension-dicom-pdf
## [1.0.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-pdf@1.0.1...@ohif/extension-dicom-pdf@1.0.2) (2020-03-09)
**Note:** Version bump only for package @ohif/extension-dicom-pdf
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-dicom-pdf",
"version": "1.0.2",
"version": "1.0.3",
"description": "OHIF extension for Dicom PDF",
"author": "OHIF",
"license": "MIT",
@@ -1,37 +0,0 @@
/**
* We use this component to leverage "Code Splitting"
*
* Link: https://serverless-stack.com/chapters/code-splitting-in-create-react-app.html
*/
import React, { Component } from 'react';
export default function asyncComponent(importComponent) {
class AsyncComponent extends Component {
constructor(props) {
super(props);
this.state = {
component: null,
};
}
async componentDidMount() {
// Add dynamically loaded component to state
const { default: component } = await importComponent();
this.setState({
component: component,
});
}
render() {
const C = this.state.component;
// Render the loaded component, or null
return C ? <C {...this.props} /> : null;
}
}
return AsyncComponent;
}
+12 -6
View File
@@ -1,11 +1,17 @@
import asyncComponent from './asyncComponent.js';
import React from 'react';
import OHIFDicomPDFSopClassHandler from './OHIFDicomPDFSopClassHandler.js';
const ConnectedOHIFDicomPDFViewer = asyncComponent(() =>
import(
/* webpackChunkName: "ConnectedOHIFDicomPDFViewer" */ './ConnectedOHIFDicomPDFViewer'
)
);
const Component = React.lazy(() => {
return import('./ConnectedOHIFDicomPDFViewer');
});
const ConnectedOHIFDicomPDFViewer = props => {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<Component {...props} />
</React.Suspense>
);
};
export default {
/**
+16
View File
@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.7...@ohif/extension-vtk@1.3.8) (2020-04-02)
**Note:** Version bump only for package @ohif/extension-vtk
## [1.3.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.6...@ohif/extension-vtk@1.3.7) (2020-04-02)
**Note:** Version bump only for package @ohif/extension-vtk
## [1.3.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.5...@ohif/extension-vtk@1.3.6) (2020-04-01)
**Note:** Version bump only for package @ohif/extension-vtk
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-vtk",
"version": "1.3.6",
"version": "1.3.8",
"description": "OHIF extension for VTK.js",
"author": "OHIF",
"license": "MIT",
@@ -53,7 +53,7 @@
"react-vtkjs-viewport": "^0.8.3"
},
"devDependencies": {
"@ohif/core": "^2.6.5",
"@ohif/core": "^2.6.7",
"@ohif/ui": "^1.4.1",
"cornerstone-tools": "4.12.5",
"cornerstone-wado-image-loader": "^3.0.0",
+22 -14
View File
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { getImageData, loadImageData } from 'react-vtkjs-viewport';
import { getReactVtkjsViewport } from './utils/getReactVtkjsViewport';
import ConnectedVTKViewport from './ConnectedVTKViewport';
import LoadingIndicator from './LoadingIndicator.js';
import OHIF from '@ohif/core';
@@ -69,7 +69,7 @@ class OHIFVTKViewport extends Component {
};
static defaultProps = {
onScroll: () => {},
onScroll: () => { },
};
static id = 'OHIFVTKViewport';
@@ -133,7 +133,8 @@ class OHIFVTKViewport extends Component {
displaySetInstanceUID,
SOPClassUID,
SOPInstanceUID,
frameIndex
frameIndex,
reactVtkjsViewport
) => {
const stack = OHIFVTKViewport.getCornerstoneStack(
studies,
@@ -144,7 +145,10 @@ class OHIFVTKViewport extends Component {
frameIndex
);
const imageDataObject = getImageData(stack.imageIds, displaySetInstanceUID);
const imageDataObject = reactVtkjsViewport.getImageData(
stack.imageIds,
displaySetInstanceUID
);
let labelmapDataObject;
let labelmapColorLUT;
@@ -257,7 +261,9 @@ class OHIFVTKViewport extends Component {
return volumeActor;
}
setStateFromProps() {
async setStateFromProps() {
const reactVtkjsViewport = await getReactVtkjsViewport();
const { studies, displaySet } = this.props.viewportData;
const {
StudyInstanceUID,
@@ -295,8 +301,10 @@ class OHIFVTKViewport extends Component {
studies,
StudyInstanceUID,
displaySetInstanceUID,
sopClassUIDs[0],
SOPInstanceUID,
frameIndex
frameIndex,
reactVtkjsViewport
);
this.imageDataObject = imageDataObject;
@@ -317,7 +325,7 @@ class OHIFVTKViewport extends Component {
dataDetails,
},
() => {
this.loadProgressively(imageDataObject);
this.loadProgressively(imageDataObject, reactVtkjsViewport);
// TODO: There must be a better way to do this.
// We do this so that if all the data is available the react-vtkjs-viewport
@@ -335,26 +343,26 @@ class OHIFVTKViewport extends Component {
);
}
componentDidMount() {
this.setStateFromProps();
async componentDidMount() {
await this.setStateFromProps();
}
componentDidUpdate(prevProps) {
async componentDidUpdate(prevProps) {
const { displaySet } = this.props.viewportData;
const prevDisplaySet = prevProps.viewportData.displaySet;
if (
displaySet.displaySetInstanceUID !==
prevDisplaySet.displaySetInstanceUID ||
prevDisplaySet.displaySetInstanceUID ||
displaySet.SOPInstanceUID !== prevDisplaySet.SOPInstanceUID ||
displaySet.frameIndex !== prevDisplaySet.frameIndex
) {
this.setStateFromProps();
await this.setStateFromProps();
}
}
loadProgressively(imageDataObject) {
loadImageData(imageDataObject);
loadProgressively(imageDataObject, reactVtkjsViewport) {
reactVtkjsViewport.loadImageData(imageDataObject);
const { isLoading, insertPixelDataPromises } = imageDataObject;
+9 -2
View File
@@ -1,9 +1,16 @@
import React, { useEffect, useCallback } from 'react';
import { View2D } from 'react-vtkjs-viewport';
// import { View2D } from 'react-vtkjs-viewport';
import PropTypes from 'prop-types';
import asyncComponent from './asyncComponent.js';
import { getReactVtkjsViewport } from './utils/getReactVtkjsViewport';
import './VTKViewport.css';
const View2D = asyncComponent(async () => {
const reactVtkjsViewport = await getReactVtkjsViewport();
return { default: reactVtkjsViewport.View2D };
});
const VTKViewport = props => {
const style = { width: '100%', height: '100%', position: 'relative' };
@@ -52,7 +59,7 @@ VTKViewport.propTypes = {
};
VTKViewport.defaultProps = {
onScroll: () => {},
onScroll: () => { },
};
export default VTKViewport;
+13 -14
View File
@@ -1,10 +1,5 @@
import throttle from 'lodash.throttle';
import {
vtkInteractorStyleMPRCrosshairs,
vtkInteractorStyleMPRWindowLevel,
vtkInteractorStyleMPRRotate,
vtkSVGCrosshairsWidget,
} from 'react-vtkjs-viewport';
import { getReactVtkjsViewport } from './utils/getReactVtkjsViewport';
import setMPRLayout from './utils/setMPRLayout.js';
import setViewportToVTK from './utils/setViewportToVTK.js';
@@ -124,16 +119,18 @@ const commandsModule = ({ commandsManager }) => {
_setView(api, [0, 1, 0], [0, 0, 1]);
},
enableRotateTool: () => {
enableRotateTool: async () => {
const reactVtkjsViewport = await getReactVtkjsViewport();
apis.forEach(api => {
const istyle = vtkInteractorStyleMPRRotate.newInstance();
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRRotate.newInstance();
api.setInteractorStyle({ istyle });
});
},
enableCrosshairsTool: () => {
enableCrosshairsTool: async () => {
const reactVtkjsViewport = await getReactVtkjsViewport();
apis.forEach((api, apiIndex) => {
const istyle = vtkInteractorStyleMPRCrosshairs.newInstance();
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRCrosshairs.newInstance();
api.setInteractorStyle({
istyle,
@@ -141,7 +138,7 @@ const commandsModule = ({ commandsManager }) => {
});
});
},
enableLevelTool: () => {
enableLevelTool: async () => {
function updateVOI(apis, windowWidth, windowCenter) {
apis.forEach(api => {
api.updateVOI(windowWidth, windowCenter);
@@ -162,8 +159,9 @@ const commandsModule = ({ commandsManager }) => {
},
};
const reactVtkjsViewport = await getReactVtkjsViewport();
apis.forEach(api => {
const istyle = vtkInteractorStyleMPRWindowLevel.newInstance();
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRWindowLevel.newInstance();
api.setInteractorStyle({ istyle, callbacks });
});
@@ -260,14 +258,15 @@ const commandsModule = ({ commandsManager }) => {
}
// Add widgets and set default interactorStyle of each viewport.
const reactVtkjsViewport = await getReactVtkjsViewport();
apis.forEach((api, apiIndex) => {
api.addSVGWidget(
vtkSVGCrosshairsWidget.newInstance(),
reactVtkjsViewport.vtkSVGCrosshairsWidget.newInstance(),
'crosshairsWidget'
);
const uid = api.uid;
const istyle = vtkInteractorStyleMPRCrosshairs.newInstance();
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRCrosshairs.newInstance();
api.setInteractorStyle({
istyle,
@@ -0,0 +1,5 @@
export function getReactVtkjsViewport() {
return import(
/* webpackChunkName: "ReactVtkjsViewport" */ 'react-vtkjs-viewport'
);
}
+19
View File
@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.6.7](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.6...@ohif/core@2.6.7) (2020-04-02)
### Bug Fixes
* 🐛 Fix multiframe images ([#1595](https://github.com/OHIF/Viewers/issues/1595)) ([9e0bd52](https://github.com/OHIF/Viewers/commit/9e0bd52c6a86648eb6673344a8555ad787043e5c))
## [2.6.6](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.5...@ohif/core@2.6.6) (2020-04-02)
**Note:** Version bump only for package @ohif/core
## [2.6.5](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.4...@ohif/core@2.6.5) (2020-04-01)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/core",
"version": "2.6.5",
"version": "2.6.7",
"description": "Generic business logic for web-based medical imaging applications",
"author": "OHIF Core Team",
"license": "MIT",
@@ -1,10 +1,10 @@
import cornerstone from 'cornerstone-core';
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
import {
clearStudyLoadingProgress,
setStudyLoadingProgress,
} from '../redux/actions';
import StackManager from '../utils/StackManager';
import { getCornerstoneWADOImageLoader } from '../utils/cornerstoneWADOImageLoader';
class BaseLoadingListener {
constructor(stack, options = {}) {
@@ -103,7 +103,8 @@ class DICOMFileLoadingListener extends BaseLoadingListener {
this._checkCachedData();
}
_checkCachedData() {
async _checkCachedData() {
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
const dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(
this._dataSetUrl
);
@@ -78,7 +78,7 @@ export class StudyMetadata extends Metadata {
Object.defineProperty(this, 'studyInstanceUID', {
configurable: false,
enumerable: false,
get: function () {
get: function() {
return this.getStudyInstanceUID();
},
});
@@ -1,8 +1,8 @@
import DICOMWeb from '../../../DICOMWeb';
import metadataProvider from '../../../classes/MetadataProvider';
import getWADORSImageId from '../../../utils/getWADORSImageId';
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
import getReferencedSeriesSequence from './getReferencedSeriesSequence';
import { getCornerstoneWADOImageLoader } from '../../../utils/cornerstoneWADOImageLoader';
/**
* Create a plain JS object that describes a study (a study descriptor object)
@@ -160,6 +160,7 @@ async function makeSOPInstance(server, study, instance) {
const wadoRSMetadata = Object.assign(instance);
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
if (sopInstance.NumberOfFrames) {
for (let i = 0; i < sopInstance.NumberOfFrames; i++) {
const wadorsImageId = getWADORSImageId(sopInstance, i);
+2 -3
View File
@@ -35,7 +35,8 @@ function createAndAddStack(stackMap, study, displaySet, stackUpdatedCallbacks) {
imageIndex: imageIndex + 1,
};
const NumberOfFrames = image.NumberOfFrames;
const naturalizedInstance = instance.getData().metadata;
const NumberOfFrames = naturalizedInstance.NumberOfFrames;
if (NumberOfFrames > 1) {
for (let i = 0; i < NumberOfFrames; i++) {
@@ -60,8 +61,6 @@ function createAndAddStack(stackMap, study, displaySet, stackUpdatedCallbacks) {
imageId = getImageId(image);
imageIds.push(imageId);
const naturalizedInstance = instance.getData().metadata;
const {
StudyInstanceUID,
SeriesInstanceUID,
@@ -0,0 +1,5 @@
export function getCornerstoneWADOImageLoader() {
return import(
/* webpackChunkName: "CornerstoneWADOImageLoader" */ 'cornerstone-wado-image-loader'
);
}
@@ -1,7 +1,7 @@
import cornerstone from 'cornerstone-core';
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
import { api } from 'dicomweb-client';
import DICOMWeb from '../DICOMWeb';
import { getCornerstoneWADOImageLoader } from './cornerstoneWADOImageLoader';
const getImageId = imageObj => {
if (!imageObj) {
@@ -86,7 +86,7 @@ const getImageLoaderType = imageId => {
};
class DicomLoaderService {
getLocalData(dataset, studies) {
async getLocalData(dataset, studies) {
if (dataset && dataset.localFile) {
// Use referenced imageInstance
const imageInstance = getImageInstance(dataset);
@@ -98,6 +98,7 @@ class DicomLoaderService {
}
if (!someInvalidStrings(imageId)) {
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
}
}
@@ -176,16 +177,16 @@ class DicomLoaderService {
}
}
*getLoaderIterator(dataset, studies) {
yield this.getLocalData(dataset, studies);
async *getLoaderIterator(dataset, studies) {
yield await this.getLocalData(dataset, studies);
yield this.getDataByImageType(dataset);
yield this.getDataByDatasetType(dataset);
}
findDicomDataPromise(dataset, studies) {
async findDicomDataPromise(dataset, studies) {
const loaderIterator = this.getLoaderIterator(dataset, studies);
// it returns first valid retriever method.
for (const loader of loaderIterator) {
for await (const loader of loaderIterator) {
if (loader) {
return loader;
}
+24
View File
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.8.16](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.15...@ohif/viewer@3.8.16) (2020-04-02)
**Note:** Version bump only for package @ohif/viewer
## [3.8.15](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.14...@ohif/viewer@3.8.15) (2020-04-02)
**Note:** Version bump only for package @ohif/viewer
## [3.8.14](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.13...@ohif/viewer@3.8.14) (2020-04-02)
**Note:** Version bump only for package @ohif/viewer
## [3.8.13](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.12...@ohif/viewer@3.8.13) (2020-04-01)
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/viewer",
"version": "3.8.13",
"version": "3.8.16",
"description": "OHIF Viewer",
"author": "OHIF Contributors",
"license": "MIT",
@@ -48,14 +48,14 @@
},
"dependencies": {
"@babel/runtime": "^7.5.5",
"@ohif/core": "^2.6.5",
"@ohif/extension-cornerstone": "^2.5.0",
"@ohif/extension-dicom-html": "^1.1.1",
"@ohif/extension-dicom-microscopy": "^0.50.8",
"@ohif/extension-dicom-pdf": "^1.0.2",
"@ohif/core": "^2.6.7",
"@ohif/extension-cornerstone": "^2.5.1",
"@ohif/extension-dicom-html": "^1.1.2",
"@ohif/extension-dicom-microscopy": "^0.50.9",
"@ohif/extension-dicom-pdf": "^1.0.3",
"@ohif/extension-dicom-segmentation": "^0.1.1",
"@ohif/extension-lesion-tracker": "^0.2.0",
"@ohif/extension-vtk": "^1.3.6",
"@ohif/extension-vtk": "^1.3.8",
"@ohif/i18n": "^0.52.7",
"@ohif/ui": "^1.4.1",
"@tanem/react-nprogress": "^1.1.25",
+1 -5
View File
@@ -34,10 +34,7 @@ import i18n from '@ohif/i18n';
import './config';
/** Utils */
import {
getUserManagerForOpenIdConnectClient,
initWebWorkers,
} from './utils/index.js';
import { getUserManagerForOpenIdConnectClient } from './utils/index.js';
/** Extensions */
import { GenericViewerCommands, MeasurementsPanel } from './appExtensions';
@@ -140,7 +137,6 @@ class App extends Component {
*/
_initHotkeys(appConfigHotkeys);
_initServers(servers);
initWebWorkers();
}
render() {
-30
View File
@@ -1,7 +1,4 @@
import OHIF from '@ohif/core';
import cornerstone from 'cornerstone-core';
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
import dicomParser from 'dicom-parser';
import version from './version.js';
let homepage;
@@ -15,31 +12,4 @@ window.info = {
homepage,
};
// For debugging
//if (process.env.node_env === 'development') {
window.cornerstone = cornerstone;
window.cornerstoneWADOImageLoader = cornerstoneWADOImageLoader;
//}
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
OHIF.user.getAccessToken = () => {
// TODO: Get the Redux store from somewhere else
const state = window.store.getState();
if (!state.oidc || !state.oidc.user) {
return;
}
return state.oidc.user.access_token;
};
cornerstoneWADOImageLoader.configure({
beforeSend: function(xhr) {
const headers = OHIF.DICOMWeb.getAuthorizationHeader();
if (headers.Authorization) {
xhr.setRequestHeader('Authorization', headers.Authorization);
}
},
});
+1 -1
View File
@@ -3,7 +3,7 @@ import FileLoaderService from './localFileLoaders/fileLoaderService';
const processFile = async file => {
try {
const fileLoaderService = new FileLoaderService(file);
const imageId = fileLoaderService.addFile(file);
const imageId = await fileLoaderService.addFile(file);
const image = await fileLoaderService.loadFile(file, imageId);
const dataset = await fileLoaderService.getDataset(image, imageId);
const studies = await fileLoaderService.getStudies(dataset, imageId);
@@ -1,13 +1,14 @@
import * as dcmjs from 'dcmjs';
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
import FileLoader from './fileLoader';
import OHIF from '@ohif/core';
import { getCornerstoneWADOImageLoader } from '../../utils/cornerstoneWADOImageLoader';
const metadataProvider = OHIF.cornerstone.metadataProvider;
const DICOMFileLoader = new (class extends FileLoader {
fileType = 'application/dicom';
loadFile(file, imageId) {
async loadFile(file, imageId) {
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
}
@@ -1,7 +1,7 @@
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
import FileLoader from './fileLoader';
import PDFFileLoader from './pdfFileLoader';
import DICOMFileLoader from './dicomFileLoader';
import { getCornerstoneWADOImageLoader } from '../../utils/cornerstoneWADOImageLoader';
class FileLoaderService extends FileLoader {
fileType;
@@ -53,7 +53,8 @@ class FileLoaderService extends FileLoader {
return result;
}
addFile(file) {
async addFile(file) {
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
return cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
}
@@ -1,9 +1,10 @@
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
import FileLoader from './fileLoader';
import { getCornerstoneWADOImageLoader } from '../../utils/cornerstoneWADOImageLoader';
const PDFFileLoader = new (class extends FileLoader {
fileType = 'application/pdf';
loadFile(file, imageId) {
async loadFile(file, imageId) {
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
}
+16 -7
View File
@@ -1,4 +1,5 @@
import asyncComponent from '../components/AsyncComponent.js';
import { withCornerstone } from '../utils/cornerstoneWADOImageLoader';
import OHIF from '@ohif/core';
const { urlUtil: UrlUtil } = OHIF.utils;
@@ -9,8 +10,10 @@ const IHEInvokeImageDisplay = asyncComponent(() =>
/* webpackChunkName: "IHEInvokeImageDisplay" */ './IHEInvokeImageDisplay.js'
)
);
const ViewerRouting = asyncComponent(() =>
import(/* webpackChunkName: "ViewerRouting" */ './ViewerRouting.js')
const ViewerRouting = withCornerstone(
asyncComponent(() =>
import(/* webpackChunkName: "ViewerRouting" */ './ViewerRouting.js')
)
);
const StudyListRouting = asyncComponent(() =>
@@ -18,12 +21,18 @@ const StudyListRouting = asyncComponent(() =>
/* webpackChunkName: "StudyListRouting" */ '../studylist/StudyListRouting.js'
)
);
const StandaloneRouting = asyncComponent(() =>
import(/* webpackChunkName: "ConnectedStandaloneRouting" */ '../connectedComponents/ConnectedStandaloneRouting.js')
const StandaloneRouting = withCornerstone(
asyncComponent(() =>
import(
/* webpackChunkName: "ConnectedStandaloneRouting" */ '../connectedComponents/ConnectedStandaloneRouting.js'
)
)
);
const ViewerLocalFileData = asyncComponent(() =>
import(
/* webpackChunkName: "ViewerLocalFileData" */ '../connectedComponents/ViewerLocalFileData.js'
const ViewerLocalFileData = withCornerstone(
asyncComponent(() =>
import(
/* webpackChunkName: "ViewerLocalFileData" */ '../connectedComponents/ViewerLocalFileData.js'
)
)
);
@@ -0,0 +1,79 @@
import OHIF from '@ohif/core';
import cornerstone from 'cornerstone-core';
import dicomParser from 'dicom-parser';
import React from 'react';
export function getCornerstoneWADOImageLoader() {
return import(
/* webpackChunkName: "CornerstoneWADOImageLoader" */ 'cornerstone-wado-image-loader'
);
}
let initialized = false;
export async function initCornerstoneWADOImageLoader() {
if (initialized) return;
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
// For debugging
//if (process.env.node_env === 'development') {
window.cornerstoneWADOImageLoader = cornerstoneWADOImageLoader;
//}
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
OHIF.user.getAccessToken = () => {
// TODO: Get the Redux store from somewhere else
const state = window.store.getState();
if (!state.oidc || !state.oidc.user) {
return;
}
return state.oidc.user.accesstoken;
};
cornerstoneWADOImageLoader.configure({
beforeSend: function (xhr) {
const headers = OHIF.DICOMWeb.getAuthorizationHeader();
if (headers.Authorization) {
xhr.setRequestHeader('Authorization', headers.Authorization);
}
},
});
const config = {
maxWebWorkers: Math.max(navigator.hardwareConcurrency - 1, 1),
startWebWorkersOnDemand: true,
taskConfiguration: {
decodeTask: {
initializeCodecsOnStartup: false,
usePDFJS: false,
strict: false,
},
},
};
cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
initialized = true;
}
export function withCornerstone(Component) {
// eslint-disable-next-line react/display-name
return props => {
const [
cornerstoneWADOImageLoaderInitialized,
setCornerstoneWADOImageLoaderInitialized,
] = React.useState(false);
React.useEffect(() => {
initCornerstoneWADOImageLoader().then(() =>
setCornerstoneWADOImageLoaderInitialized(true)
);
}, []);
if (!cornerstoneWADOImageLoaderInitialized) {
return null;
}
return <Component {...props} />;
};
}
+1 -2
View File
@@ -1,4 +1,3 @@
import getUserManagerForOpenIdConnectClient from './getUserManagerForOpenIdConnectClient.js';
import initWebWorkers from './initWebWorkers.js';
export { getUserManagerForOpenIdConnectClient, initWebWorkers };
export { getUserManagerForOpenIdConnectClient };
+1 -1
View File
@@ -5,7 +5,7 @@ describe('utils', () => {
const utilExports = Object.keys(utils).sort();
expect(utilExports).toEqual(
['getUserManagerForOpenIdConnectClient', 'initWebWorkers'].sort()
['getUserManagerForOpenIdConnectClient'].sort()
);
});
});
@@ -1,22 +0,0 @@
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
let initialized = false;
export default function initWebWorkers() {
const config = {
maxWebWorkers: Math.max(navigator.hardwareConcurrency - 1, 1),
startWebWorkersOnDemand: true,
taskConfiguration: {
decodeTask: {
initializeCodecsOnStartup: false,
usePDFJS: false,
strict: false,
},
},
};
if (!initialized) {
cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
initialized = true;
}
}
@@ -1,23 +0,0 @@
import initWebWorkers from './initWebWorkers.js';
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
describe('initWebWorkers', () => {
it("initializes cornerstoneWADOImageLoader's web workers", () => {
initWebWorkers();
expect(
cornerstoneWADOImageLoader.webWorkerManager.initialize
).toHaveBeenCalled();
});
});
describe('initWebWorkers', () => {
it("initializes cornerstoneWADOImageLoader's web workers only once", () => {
initWebWorkers();
initWebWorkers();
expect(
cornerstoneWADOImageLoader.webWorkerManager.initialize
).toHaveBeenCalledTimes(1);
});
});