Compare commits
29
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fc7d93d73 | ||
|
|
33307d3cd2 | ||
|
|
c3ce909434 | ||
|
|
ad2c750503 | ||
|
|
cceb61f123 | ||
|
|
13bcba8c39 | ||
|
|
d2db026158 | ||
|
|
e4b0552db4 | ||
|
|
d7ba2fac69 | ||
|
|
761d54fbbf | ||
|
|
79548d2380 | ||
|
|
6a401c9e52 | ||
|
|
23376d279d | ||
|
|
4110b0422c | ||
|
|
ed501bb462 | ||
|
|
abf050e162 | ||
|
|
35ed82e161 | ||
|
|
d0ccc22fd9 | ||
|
|
31841c495f | ||
|
|
65505d9bce | ||
|
|
460fdeb534 | ||
|
|
f4b7091ae4 | ||
|
|
1e72684455 | ||
|
|
5b0b6301b9 | ||
|
|
03a34a75a1 | ||
|
|
729272a985 | ||
|
|
9194ec2404 | ||
|
|
52c95a1209 | ||
|
|
8903adaea7 |
No files matched your search
+11
-7
@@ -25,11 +25,9 @@ executors:
|
|||||||
docker:
|
docker:
|
||||||
# Primary container image where all steps run.
|
# Primary container image where all steps run.
|
||||||
- image: 'cypress/browsers:node14.15.0-chrome86-ff82'
|
- image: 'cypress/browsers:node14.15.0-chrome86-ff82'
|
||||||
- image: 'ohif/viewer-testdata:0.1-test'
|
|
||||||
|
|
||||||
defaults: &defaults
|
defaults: &defaults
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/node:14.15.0
|
- image: cimg/node:14.18
|
||||||
environment:
|
environment:
|
||||||
TERM: xterm # Enable colors in term
|
TERM: xterm # Enable colors in term
|
||||||
QUICK_BUILD: true
|
QUICK_BUILD: true
|
||||||
@@ -119,6 +117,7 @@ jobs:
|
|||||||
command: yarn install --frozen-lockfile
|
command: yarn install --frozen-lockfile
|
||||||
|
|
||||||
- setup_remote_docker:
|
- setup_remote_docker:
|
||||||
|
version: 19.03.13
|
||||||
docker_layer_caching: false
|
docker_layer_caching: false
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
@@ -295,6 +294,7 @@ jobs:
|
|||||||
- attach_workspace:
|
- attach_workspace:
|
||||||
at: ~/repo
|
at: ~/repo
|
||||||
- setup_remote_docker:
|
- setup_remote_docker:
|
||||||
|
version: 19.03.13
|
||||||
docker_layer_caching: false
|
docker_layer_caching: false
|
||||||
- run:
|
- run:
|
||||||
name: Build and push Docker image
|
name: Build and push Docker image
|
||||||
@@ -347,7 +347,8 @@ workflows:
|
|||||||
store_artifacts: true
|
store_artifacts: true
|
||||||
working_directory: platform/viewer
|
working_directory: platform/viewer
|
||||||
build:
|
build:
|
||||||
npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js
|
git submodule update --init &&
|
||||||
|
npx cross-env QUICK_BUILD=true APP_CONFIG=config/e2e.js
|
||||||
yarn run build
|
yarn run build
|
||||||
start: yarn run test:e2e:serve
|
start: yarn run test:e2e:serve
|
||||||
spec: 'cypress/integration/common/**/*,cypress/integration/pwa/**/*'
|
spec: 'cypress/integration/common/**/*,cypress/integration/pwa/**/*'
|
||||||
@@ -375,7 +376,8 @@ workflows:
|
|||||||
store_artifacts: true
|
store_artifacts: true
|
||||||
working_directory: platform/viewer
|
working_directory: platform/viewer
|
||||||
build:
|
build:
|
||||||
npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js
|
git submodule update --init &&
|
||||||
|
npx cross-env QUICK_BUILD=true APP_CONFIG=config/e2e.js
|
||||||
yarn run build:package
|
yarn run build:package
|
||||||
start: yarn run test:e2e:serve
|
start: yarn run test:e2e:serve
|
||||||
spec: 'cypress/integration/common/**/*,cypress/integration/script-tag/**/*'
|
spec: 'cypress/integration/common/**/*,cypress/integration/script-tag/**/*'
|
||||||
@@ -408,7 +410,8 @@ workflows:
|
|||||||
store_artifacts: false
|
store_artifacts: false
|
||||||
working_directory: platform/viewer
|
working_directory: platform/viewer
|
||||||
build:
|
build:
|
||||||
npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js
|
git submodule update --init &&
|
||||||
|
npx cross-env QUICK_BUILD=true APP_CONFIG=config/e2e.js
|
||||||
yarn run build
|
yarn run build
|
||||||
# start server --> verify running --> percy + chrome + cypress
|
# start server --> verify running --> percy + chrome + cypress
|
||||||
command: yarn run test:e2e:dist
|
command: yarn run test:e2e:dist
|
||||||
@@ -487,7 +490,8 @@ workflows:
|
|||||||
store_artifacts: false
|
store_artifacts: false
|
||||||
working_directory: platform/viewer
|
working_directory: platform/viewer
|
||||||
build:
|
build:
|
||||||
npx cross-env QUICK_BUILD=true APP_CONFIG=config/dicomweb-server.js
|
git submodule update --init &&
|
||||||
|
npx cross-env QUICK_BUILD=true APP_CONFIG=config/e2e.js
|
||||||
yarn run build
|
yarn run build
|
||||||
# start server --> verify running --> percy + chrome + cypress
|
# start server --> verify running --> percy + chrome + cypress
|
||||||
command: yarn run test:e2e:dist
|
command: yarn run test:e2e:dist
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "testdata"]
|
||||||
|
path = testdata
|
||||||
|
url = https://github.com/OHIF/viewer-testdata-dicomweb.git
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
14.18.0
|
||||||
@@ -28,7 +28,7 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => {
|
|||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
mode: isProdBuild ? 'production' : 'development',
|
mode: isProdBuild ? 'production' : 'development',
|
||||||
devtool: isProdBuild ? 'source-map' : 'cheap-module-eval-source-map',
|
devtool: isProdBuild ? 'source-map' : 'eval-cheap-module-source-map',
|
||||||
entry: {
|
entry: {
|
||||||
app: `${SRC_DIR}/index.js`,
|
app: `${SRC_DIR}/index.js`,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -273,6 +273,17 @@ development of OHIF Viewer:
|
|||||||
Leidos Biomedical Research under Task Order HHSN26100071 from NCI.
|
Leidos Biomedical Research under Task Order HHSN26100071 from NCI.
|
||||||
[IDC Viewer](https://learn.canceridc.dev/portal/visualization) is a customized
|
[IDC Viewer](https://learn.canceridc.dev/portal/visualization) is a customized
|
||||||
version of the OHIF Viewer.
|
version of the OHIF Viewer.
|
||||||
|
|
||||||
|
### Research notice
|
||||||
|
Please note that this repository is participating in a study into sustainability
|
||||||
|
of open source projects. Data will be gathered about this repository for
|
||||||
|
approximately the next 12 months, starting from June 2021.
|
||||||
|
|
||||||
|
Data collected will include number of contributors, number of PRs, time taken to
|
||||||
|
close/merge these PRs, and issues closed.
|
||||||
|
|
||||||
|
For more information, please visit
|
||||||
|
[our informational page](https://sustainable-open-science-and-software.github.io/) or download our [participant information sheet](https://sustainable-open-science-and-software.github.io/assets/PIS_sustainable_software.pdf).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,30 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [2.12.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.3...@ohif/extension-cornerstone@2.12.4) (2022-01-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.12.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.2...@ohif/extension-cornerstone@2.12.3) (2021-12-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.12.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.1...@ohif/extension-cornerstone@2.12.2) (2021-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [2.12.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.0...@ohif/extension-cornerstone@2.12.1) (2021-09-28)
|
## [2.12.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.0...@ohif/extension-cornerstone@2.12.1) (2021-09-28)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-cornerstone",
|
"name": "@ohif/extension-cornerstone",
|
||||||
"version": "2.12.1",
|
"version": "2.12.4",
|
||||||
"description": "OHIF extension for Cornerstone",
|
"description": "OHIF extension for Cornerstone",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -32,12 +32,12 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"@ohif/ui": "^0.50.0",
|
"@ohif/ui": "^0.50.0",
|
||||||
"cornerstone-core": "^2.5.0",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-math": "^0.1.9",
|
"cornerstone-math": "^0.1.9",
|
||||||
"cornerstone-tools": "^6.0.0",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"cornerstone-wado-image-loader": "^4.0.3",
|
"cornerstone-wado-image-loader": "^4.1.0",
|
||||||
"dcmjs": "0.18.9",
|
"dcmjs": "0.19.2",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.11",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [0.3.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.3.0...@ohif/extension-debugging@0.3.1) (2021-12-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-debugging
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.3.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.2.2...@ohif/extension-debugging@0.3.0) (2021-09-23)
|
# [0.3.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.2.2...@ohif/extension-debugging@0.3.0) (2021-09-23)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-debugging",
|
"name": "@ohif/extension-debugging",
|
||||||
"version": "0.3.0",
|
"version": "0.3.1",
|
||||||
"description": "OHIF extension for debugging.",
|
"description": "OHIF extension for debugging.",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -28,12 +28,12 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^2.6.0",
|
"@ohif/core": "^2.6.0",
|
||||||
"dicom-parser": "^1.8.9"
|
"dicom-parser": "^1.8.11"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.5.5",
|
||||||
"detect-browser": "5.1.1",
|
"detect-browser": "5.1.1",
|
||||||
"dicomweb-client": "^0.8.1",
|
"dicomweb-client": "^0.8.3",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"jszip": "^3.2.2"
|
"jszip": "^3.2.2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,38 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.3.15](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.14...@ohif/extension-dicom-html@1.3.15) (2022-01-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.3.14](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.13...@ohif/extension-dicom-html@1.3.14) (2021-12-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.3.13](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.12...@ohif/extension-dicom-html@1.3.13) (2021-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.3.12](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.11...@ohif/extension-dicom-html@1.3.12) (2021-10-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [1.3.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.10...@ohif/extension-dicom-html@1.3.11) (2021-09-28)
|
## [1.3.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.10...@ohif/extension-dicom-html@1.3.11) (2021-09-28)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-dicom-html
|
**Note:** Version bump only for package @ohif/extension-dicom-html
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-dicom-html",
|
"name": "@ohif/extension-dicom-html",
|
||||||
"version": "1.3.11",
|
"version": "1.3.15",
|
||||||
"description": "OHIF extension for rendering structured reports to HTML",
|
"description": "OHIF extension for rendering structured reports to HTML",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"dcmjs": "0.18.9",
|
"dcmjs": "0.19.2",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.8.6"
|
"react-dom": "^16.8.6"
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ const getContentSequence = (data, level = 1) => {
|
|||||||
|
|
||||||
const root = [];
|
const root = [];
|
||||||
if (header) {
|
if (header) {
|
||||||
const HeaderDynamicLevel = `h${level}`;
|
const HeaderDynamicLevel = `h${Math.min(level, 6)}`;
|
||||||
|
|
||||||
root.push(<HeaderDynamicLevel key={header}>{header}</HeaderDynamicLevel>);
|
root.push(<HeaderDynamicLevel key={header}>{header}</HeaderDynamicLevel>);
|
||||||
}
|
}
|
||||||
@@ -170,7 +170,7 @@ const getContentSequence = (data, level = 1) => {
|
|||||||
|
|
||||||
if (key === '_meta') {
|
if (key === '_meta') {
|
||||||
const HeaderDynamicLevel = `h3`;
|
const HeaderDynamicLevel = `h3`;
|
||||||
root.push(<hr />);
|
root.push(<hr key={root.length} />);
|
||||||
root.push(
|
root.push(
|
||||||
<HeaderDynamicLevel key="Metadata">
|
<HeaderDynamicLevel key="Metadata">
|
||||||
DICOM File Meta Information
|
DICOM File Meta Information
|
||||||
@@ -217,7 +217,7 @@ class DicomHtmlViewport extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const dataSet = this.setContentFromByteArray(this.props.byteArray);
|
this.setContentFromByteArray(this.props.byteArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
setContentFromByteArray(byteArray) {
|
setContentFromByteArray(byteArray) {
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.1.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-pdf@1.1.1...@ohif/extension-dicom-pdf@1.1.2) (2022-01-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-pdf
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.1.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-pdf@1.1.0...@ohif/extension-dicom-pdf@1.1.1) (2021-12-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-pdf
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [1.1.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-pdf@1.0.6...@ohif/extension-dicom-pdf@1.1.0) (2021-09-23)
|
# [1.1.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-pdf@1.0.6...@ohif/extension-dicom-pdf@1.1.0) (2021-09-23)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-dicom-pdf",
|
"name": "@ohif/extension-dicom-pdf",
|
||||||
"version": "1.1.0",
|
"version": "1.1.2",
|
||||||
"description": "OHIF extension for Dicom PDF",
|
"description": "OHIF extension for Dicom PDF",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.11",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.8.6"
|
"react-dom": "^16.8.6"
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class DicomPDFViewport extends Component {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
byteArray: TypedArrayProp.uint8,
|
byteArray: TypedArrayProp.uint8,
|
||||||
|
rawPdf: PropTypes.bool,
|
||||||
useNative: PropTypes.bool,
|
useNative: PropTypes.bool,
|
||||||
viewportData: PropTypes.object,
|
viewportData: PropTypes.object,
|
||||||
activeViewportIndex: PropTypes.number,
|
activeViewportIndex: PropTypes.number,
|
||||||
@@ -45,7 +46,8 @@ class DicomPDFViewport extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const dataSet = this.parseByteArray(this.props.byteArray);
|
const { rawPdf } = this.props
|
||||||
|
const dataSet = !rawPdf && this.parseByteArray(this.props.byteArray);
|
||||||
const fileURL = this.getPDFFileUrl(dataSet, this.props.byteArray);
|
const fileURL = this.getPDFFileUrl(dataSet, this.props.byteArray);
|
||||||
|
|
||||||
this.setState(state => ({ ...state, fileURL }));
|
this.setState(state => ({ ...state, fileURL }));
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import OHIF from '@ohif/core';
|
import OHIF from '@ohif/core';
|
||||||
import OHIFComponentPlugin from './OHIFComponentPlugin.js';
|
import OHIFComponentPlugin from './OHIFComponentPlugin.js';
|
||||||
import DicomPDFViewport from './DicomPDFViewport';
|
import DicomPDFViewport from './DicomPDFViewport';
|
||||||
|
import { str2ab } from '@ohif/core';
|
||||||
|
|
||||||
const { DicomLoaderService } = OHIF.utils;
|
const { DicomLoaderService } = OHIF.utils;
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ class OHIFDicomPDFViewport extends Component {
|
|||||||
|
|
||||||
state = {
|
state = {
|
||||||
byteArray: null,
|
byteArray: null,
|
||||||
|
rawPdf: false,
|
||||||
error: null,
|
error: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -34,6 +36,15 @@ class OHIFDicomPDFViewport extends Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { displaySet, studies } = this.props.viewportData;
|
const { displaySet, studies } = this.props.viewportData;
|
||||||
|
|
||||||
|
if (displaySet.metadata && displaySet.metadata.EncapsulatedDocument) {
|
||||||
|
const { InlineBinary, BulkDataURI } = displaySet.metadata.EncapsulatedDocument;
|
||||||
|
if (InlineBinary) {
|
||||||
|
const inlineBinaryData = atob(InlineBinary);
|
||||||
|
const byteArray = str2ab(inlineBinaryData);
|
||||||
|
this.setState({ byteArray, rawPdf: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
DicomLoaderService.findDicomDataPromise(displaySet, studies).then(
|
DicomLoaderService.findDicomDataPromise(displaySet, studies).then(
|
||||||
data => this.setState({ byteArray: new Uint8Array(data) }),
|
data => this.setState({ byteArray: new Uint8Array(data) }),
|
||||||
error => {
|
error => {
|
||||||
@@ -49,15 +60,16 @@ class OHIFDicomPDFViewport extends Component {
|
|||||||
viewportIndex,
|
viewportIndex,
|
||||||
activeViewportIndex,
|
activeViewportIndex,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { byteArray, error } = this.state;
|
const { byteArray, error, rawPdf } = this.state;
|
||||||
const { id, init, destroy } = OHIFDicomPDFViewport;
|
const { id, init, destroy } = OHIFDicomPDFViewport;
|
||||||
const pluginProps = { id, init, destroy };
|
const pluginProps = { id, init, destroy };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OHIFComponentPlugin {...pluginProps}>
|
<OHIFComponentPlugin {...pluginProps}>
|
||||||
{byteArray && (
|
{(byteArray) && (
|
||||||
<DicomPDFViewport
|
<DicomPDFViewport
|
||||||
byteArray={byteArray}
|
byteArray={byteArray}
|
||||||
|
rawPdf={rawPdf}
|
||||||
setViewportActive={setViewportActive}
|
setViewportActive={setViewportActive}
|
||||||
viewportIndex={viewportIndex}
|
viewportIndex={viewportIndex}
|
||||||
activeViewportIndex={activeViewportIndex}
|
activeViewportIndex={activeViewportIndex}
|
||||||
|
|||||||
@@ -3,6 +3,38 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [0.7.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.5...@ohif/extension-dicom-rt@0.7.6) (2022-01-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-rt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.7.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.4...@ohif/extension-dicom-rt@0.7.5) (2022-01-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-rt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.7.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.3...@ohif/extension-dicom-rt@0.7.4) (2021-12-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-rt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.7.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.2...@ohif/extension-dicom-rt@0.7.3) (2021-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-rt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.7.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.1...@ohif/extension-dicom-rt@0.7.2) (2021-10-06)
|
## [0.7.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.1...@ohif/extension-dicom-rt@0.7.2) (2021-10-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-dicom-rt
|
**Note:** Version bump only for package @ohif/extension-dicom-rt
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-dicom-rt",
|
"name": "@ohif/extension-dicom-rt",
|
||||||
"version": "0.7.2",
|
"version": "0.7.6",
|
||||||
"description": "OHIF extension for rendering DICOM RTSTRUCTs on top of cornerstone images.",
|
"description": "OHIF extension for rendering DICOM RTSTRUCTs on top of cornerstone images.",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -29,9 +29,9 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"cornerstone-core": "^2.5.0",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-tools": "^6.0.0",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"dcmjs": "0.18.9",
|
"dcmjs": "0.19.2",
|
||||||
"gl-matrix": "^3.3.0",
|
"gl-matrix": "^3.3.0",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
|
|||||||
@@ -81,13 +81,10 @@ const RTPanel = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateStructureSets();
|
updateStructureSets();
|
||||||
|
|
||||||
document.addEventListener('extensiondicomrtrtloaded', updateStructureSets);
|
document.addEventListener('rt-panel-tab-updated', updateStructureSets);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener(
|
document.removeEventListener('rt-panel-tab-updated', updateStructureSets);
|
||||||
'extensiondicomrtrtloaded',
|
|
||||||
updateStructureSets
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|||||||
@@ -91,17 +91,12 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (activeViewport) {
|
if (activeViewport) {
|
||||||
const study = studies.find(
|
|
||||||
s => s.StudyInstanceUID === activeViewport.StudyInstanceUID
|
|
||||||
);
|
|
||||||
const ds = study.displaySets.find(
|
|
||||||
ds =>
|
|
||||||
ds.displaySetInstanceUID ===
|
|
||||||
activeViewport.displaySetInstanceUID
|
|
||||||
);
|
|
||||||
const studyMetadata = studyMetadataManager.get(
|
const studyMetadata = studyMetadataManager.get(
|
||||||
activeViewport.StudyInstanceUID
|
activeViewport.StudyInstanceUID
|
||||||
);
|
);
|
||||||
|
if (!studyMetadata) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const referencedDisplaySets = studyMetadata.getDerivedDatasets({
|
const referencedDisplaySets = studyMetadata.getDerivedDatasets({
|
||||||
referencedSeriesInstanceUID: activeViewport.SeriesInstanceUID,
|
referencedSeriesInstanceUID: activeViewport.SeriesInstanceUID,
|
||||||
Modality: 'RTSTRUCT',
|
Modality: 'RTSTRUCT',
|
||||||
|
|||||||
@@ -3,6 +3,38 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [0.7.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.5...@ohif/extension-dicom-segmentation@0.7.6) (2022-01-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.7.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.4...@ohif/extension-dicom-segmentation@0.7.5) (2021-12-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.7.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.3...@ohif/extension-dicom-segmentation@0.7.4) (2021-10-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.7.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.2...@ohif/extension-dicom-segmentation@0.7.3) (2021-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.7.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.1...@ohif/extension-dicom-segmentation@0.7.2) (2021-10-06)
|
## [0.7.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.1...@ohif/extension-dicom-segmentation@0.7.2) (2021-10-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-dicom-segmentation",
|
"name": "@ohif/extension-dicom-segmentation",
|
||||||
"version": "0.7.2",
|
"version": "0.7.6",
|
||||||
"description": "OHIF extension for viewing segmentations in the 2D MPR view",
|
"description": "OHIF extension for viewing segmentations in the 2D MPR view",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -29,9 +29,9 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"cornerstone-core": "^2.5.0",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-tools": "^6.0.0",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"dcmjs": "0.18.9",
|
"dcmjs": "0.19.2",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.8.6"
|
"react-dom": "^16.8.6"
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const SegmentItem = ({
|
|||||||
onClick,
|
onClick,
|
||||||
itemClass,
|
itemClass,
|
||||||
color,
|
color,
|
||||||
|
labelmap3D,
|
||||||
visible,
|
visible,
|
||||||
onVisibilityChange,
|
onVisibilityChange,
|
||||||
}) => {
|
}) => {
|
||||||
@@ -39,7 +40,7 @@ const SegmentItem = ({
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const newVisibility = !isVisible;
|
const newVisibility = !isVisible;
|
||||||
setIsVisible(newVisibility);
|
setIsVisible(newVisibility);
|
||||||
onVisibilityChange(newVisibility, index);
|
onVisibilityChange(newVisibility, index, labelmap3D);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
+36
-15
@@ -431,23 +431,43 @@ const SegmentationPanel = ({
|
|||||||
return enabledElements[activeIndex].element;
|
return enabledElements[activeIndex].element;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSegmentVisibilityChangeHandler = (isVisible, segmentNumber) => {
|
const onSegmentVisibilityChangeHandler = (
|
||||||
/** Get all labelmaps with this segmentNumber (overlapping segments) */
|
isVisible,
|
||||||
const { labelmaps3D } = getBrushStackState();
|
segmentNumber,
|
||||||
const possibleLabelMaps3D = labelmaps3D.filter(({ labelmaps2D }) => {
|
labelmap3D
|
||||||
return labelmaps2D.some(({ segmentsOnLabelmap }) =>
|
) => {
|
||||||
segmentsOnLabelmap.includes(segmentNumber)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
let segmentsHidden = [];
|
let segmentsHidden = [];
|
||||||
possibleLabelMaps3D.forEach(labelmap3D => {
|
if (labelmap3D.metadata.hasOverlapping) {
|
||||||
labelmap3D.segmentsHidden[segmentNumber] = !isVisible;
|
/** Get all labelmaps with this segmentNumber and that
|
||||||
|
* are from the same series (overlapping segments) */
|
||||||
|
const { labelmaps3D } = getBrushStackState();
|
||||||
|
|
||||||
segmentsHidden = [
|
const sameSeriesLabelMaps3D = labelmaps3D.filter(({ metadata }) => {
|
||||||
...new Set([...segmentsHidden, ...labelmap3D.segmentsHidden]),
|
return (
|
||||||
];
|
labelmap3D.metadata.segmentationSeriesInstanceUID ===
|
||||||
});
|
metadata.segmentationSeriesInstanceUID
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const possibleLabelMaps3D = sameSeriesLabelMaps3D.filter(
|
||||||
|
({ labelmaps2D }) => {
|
||||||
|
return labelmaps2D.some(({ segmentsOnLabelmap }) =>
|
||||||
|
segmentsOnLabelmap.includes(segmentNumber)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
possibleLabelMaps3D.forEach(labelmap3D => {
|
||||||
|
labelmap3D.segmentsHidden[segmentNumber] = !isVisible;
|
||||||
|
|
||||||
|
segmentsHidden = [
|
||||||
|
...new Set([...segmentsHidden, ...labelmap3D.segmentsHidden]),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
labelmap3D.segmentsHidden[segmentNumber] = !isVisible;
|
||||||
|
segmentsHidden = [...labelmap3D.segmentsHidden];
|
||||||
|
}
|
||||||
|
|
||||||
setState(state => ({ ...state, segmentsHidden }));
|
setState(state => ({ ...state, segmentsHidden }));
|
||||||
|
|
||||||
@@ -514,6 +534,7 @@ const SegmentationPanel = ({
|
|||||||
label={segmentLabel}
|
label={segmentLabel}
|
||||||
index={segmentNumber}
|
index={segmentNumber}
|
||||||
color={color}
|
color={color}
|
||||||
|
labelmap3D={labelmap3D}
|
||||||
visible={!labelmap3D.segmentsHidden[segmentIndex]}
|
visible={!labelmap3D.segmentsHidden[segmentIndex]}
|
||||||
onVisibilityChange={onSegmentVisibilityChangeHandler}
|
onVisibilityChange={onSegmentVisibilityChangeHandler}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -64,8 +64,17 @@ export default function getSopClassHandlerModule({ servicesManager }) {
|
|||||||
metadata,
|
metadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
segDisplaySet.getSourceDisplaySet = function(studies, activateLabelMap = true, onDisplaySetLoadFailureHandler) {
|
segDisplaySet.getSourceDisplaySet = function(
|
||||||
return getSourceDisplaySet(studies, segDisplaySet, activateLabelMap, onDisplaySetLoadFailureHandler);
|
studies,
|
||||||
|
activateLabelMap = true,
|
||||||
|
onDisplaySetLoadFailureHandler
|
||||||
|
) {
|
||||||
|
return getSourceDisplaySet(
|
||||||
|
studies,
|
||||||
|
segDisplaySet,
|
||||||
|
activateLabelMap,
|
||||||
|
onDisplaySetLoadFailureHandler
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
segDisplaySet.load = async function(referencedDisplaySet, studies) {
|
segDisplaySet.load = async function(referencedDisplaySet, studies) {
|
||||||
@@ -98,6 +107,9 @@ export default function getSopClassHandlerModule({ servicesManager }) {
|
|||||||
if (labelmapBufferArray.length > 1) {
|
if (labelmapBufferArray.length > 1) {
|
||||||
let labelmapIndexes = [];
|
let labelmapIndexes = [];
|
||||||
for (let i = 0; i < labelmapBufferArray.length; ++i) {
|
for (let i = 0; i < labelmapBufferArray.length; ++i) {
|
||||||
|
segMetadata.segmentationSeriesInstanceUID =
|
||||||
|
segDisplaySet.SeriesInstanceUID;
|
||||||
|
segMetadata.hasOverlapping = true;
|
||||||
labelmapIndexes.push(
|
labelmapIndexes.push(
|
||||||
await loadSegmentation(
|
await loadSegmentation(
|
||||||
imageIds,
|
imageIds,
|
||||||
@@ -118,6 +130,9 @@ export default function getSopClassHandlerModule({ servicesManager }) {
|
|||||||
labelmapIndex = labelmapIndexes[0];
|
labelmapIndex = labelmapIndexes[0];
|
||||||
console.warn('Overlapping segments!');
|
console.warn('Overlapping segments!');
|
||||||
} else {
|
} else {
|
||||||
|
segMetadata.segmentationSeriesInstanceUID =
|
||||||
|
segDisplaySet.SeriesInstanceUID;
|
||||||
|
segMetadata.hasOverlapping = false;
|
||||||
labelmapIndex = await loadSegmentation(
|
labelmapIndex = await loadSegmentation(
|
||||||
imageIds,
|
imageIds,
|
||||||
segDisplaySet,
|
segDisplaySet,
|
||||||
|
|||||||
@@ -143,6 +143,9 @@ export default {
|
|||||||
const studyMetadata = studyMetadataManager.get(
|
const studyMetadata = studyMetadataManager.get(
|
||||||
activeViewport.StudyInstanceUID
|
activeViewport.StudyInstanceUID
|
||||||
);
|
);
|
||||||
|
if (!studyMetadata) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const referencedDS = studyMetadata.getDerivedDatasets({
|
const referencedDS = studyMetadata.getDerivedDatasets({
|
||||||
referencedSeriesInstanceUID:
|
referencedSeriesInstanceUID:
|
||||||
activeViewport.SeriesInstanceUID,
|
activeViewport.SeriesInstanceUID,
|
||||||
|
|||||||
@@ -3,6 +3,46 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [0.2.17](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.16...@ohif/extension-dicom-tag-browser@0.2.17) (2022-01-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.2.16](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.15...@ohif/extension-dicom-tag-browser@0.2.16) (2021-12-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.2.15](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.14...@ohif/extension-dicom-tag-browser@0.2.15) (2021-12-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.2.14](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.13...@ohif/extension-dicom-tag-browser@0.2.14) (2021-11-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.2.13](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.12...@ohif/extension-dicom-tag-browser@0.2.13) (2021-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.2.12](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.11...@ohif/extension-dicom-tag-browser@0.2.12) (2021-09-28)
|
## [0.2.12](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.11...@ohif/extension-dicom-tag-browser@0.2.12) (2021-09-28)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
|
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-dicom-tag-browser",
|
"name": "@ohif/extension-dicom-tag-browser",
|
||||||
"version": "0.2.12",
|
"version": "0.2.17",
|
||||||
"description": "OHIF extension for checking DICOM headers.",
|
"description": "OHIF extension for checking DICOM headers.",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -28,12 +28,12 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^2.6.0",
|
"@ohif/core": "^2.6.0",
|
||||||
"dcmjs": "0.18.9",
|
"dcmjs": "0.19.2",
|
||||||
"react": "^16.8.6"
|
"react": "^16.8.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.5.5",
|
||||||
"dicomweb-client": "^0.8.1",
|
"dicomweb-client": "^0.8.3",
|
||||||
"moment": "2.24.0",
|
"moment": "2.24.0",
|
||||||
"react-select": "^3.0.8"
|
"react-select": "^3.0.8"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const DicomTagBrowser = ({ displaySets, displaySetInstanceUID }) => {
|
|||||||
activeDisplaySetInstanceUID,
|
activeDisplaySetInstanceUID,
|
||||||
setActiveDisplaySetInstanceUID,
|
setActiveDisplaySetInstanceUID,
|
||||||
] = useState(displaySetInstanceUID);
|
] = useState(displaySetInstanceUID);
|
||||||
const [activeInstance, setActiveInstance] = useState(0);
|
const [activeInstance, setActiveInstance] = useState(1);
|
||||||
const [tags, setTags] = useState([]);
|
const [tags, setTags] = useState([]);
|
||||||
const [meta, setMeta] = useState('');
|
const [meta, setMeta] = useState('');
|
||||||
const [instanceList, setInstanceList] = useState([]);
|
const [instanceList, setInstanceList] = useState([]);
|
||||||
@@ -51,20 +51,21 @@ const DicomTagBrowser = ({ displaySets, displaySetInstanceUID }) => {
|
|||||||
description: displayDate,
|
description: displayDate,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setActiveDisplaySetInstanceUID(displaySetInstanceUID);
|
setActiveDisplaySetInstanceUID(displaySetInstanceUID);
|
||||||
setActiveInstance(0);
|
setActiveInstance(1);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
let metadata;
|
let metadata;
|
||||||
const isImageStack = activeDisplaySet instanceof ImageSet;
|
const isImageStack =
|
||||||
|
activeDisplaySet instanceof ImageSet &&
|
||||||
|
activeDisplaySet.isModalitySupported === true;
|
||||||
|
|
||||||
let selectedInstanceValue;
|
|
||||||
let instanceList;
|
let instanceList;
|
||||||
|
|
||||||
if (isImageStack) {
|
if (isImageStack) {
|
||||||
const { images } = activeDisplaySet;
|
const { images } = activeDisplaySet;
|
||||||
const image = images[activeInstance];
|
const image = images[activeInstance - 1];
|
||||||
|
|
||||||
instanceList = images.map((image, index) => {
|
instanceList = images.map((image, index) => {
|
||||||
const metadata = image.getData().metadata;
|
const metadata = image.getData().metadata;
|
||||||
@@ -91,7 +92,7 @@ const DicomTagBrowser = ({ displaySets, displaySetInstanceUID }) => {
|
|||||||
setInstanceList(instanceList);
|
setInstanceList(instanceList);
|
||||||
setDisplaySetList(newDisplaySetList);
|
setDisplaySetList(newDisplaySetList);
|
||||||
setIsImageStack(isImageStack);
|
setIsImageStack(isImageStack);
|
||||||
}, [activeDisplaySetInstanceUID, activeInstance]);
|
}, [activeDisplaySetInstanceUID, activeInstance, displaySets]);
|
||||||
|
|
||||||
const selectedDisplaySetValue = displaySetList.find(
|
const selectedDisplaySetValue = displaySetList.find(
|
||||||
ds => ds.value === activeDisplaySetInstanceUID
|
ds => ds.value === activeDisplaySetInstanceUID
|
||||||
@@ -106,7 +107,7 @@ const DicomTagBrowser = ({ displaySets, displaySetInstanceUID }) => {
|
|||||||
showValue
|
showValue
|
||||||
step={1}
|
step={1}
|
||||||
min={1}
|
min={1}
|
||||||
max={instanceList.length - 1}
|
max={instanceList.length}
|
||||||
value={activeInstance}
|
value={activeInstance}
|
||||||
valueRenderer={value => <p>Instance Number: {value}</p>}
|
valueRenderer={value => <p>Instance Number: {value}</p>}
|
||||||
onChange={({ target }) => {
|
onChange={({ target }) => {
|
||||||
|
|||||||
@@ -3,6 +3,78 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.12.12](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.11...@ohif/extension-vtk@1.12.12) (2022-01-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.10...@ohif/extension-vtk@1.12.11) (2022-01-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.10](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.9...@ohif/extension-vtk@1.12.10) (2022-01-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.8...@ohif/extension-vtk@1.12.9) (2021-12-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.7...@ohif/extension-vtk@1.12.8) (2021-12-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.6...@ohif/extension-vtk@1.12.7) (2021-12-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.5...@ohif/extension-vtk@1.12.6) (2021-11-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.4...@ohif/extension-vtk@1.12.5) (2021-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.3...@ohif/extension-vtk@1.12.4) (2021-10-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [1.12.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.2...@ohif/extension-vtk@1.12.3) (2021-10-04)
|
## [1.12.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.2...@ohif/extension-vtk@1.12.3) (2021-10-04)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-vtk
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|||||||
+11
-11
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-vtk",
|
"name": "@ohif/extension-vtk",
|
||||||
"version": "1.12.3",
|
"version": "1.12.12",
|
||||||
"description": "OHIF extension for VTK.js",
|
"description": "OHIF extension for VTK.js",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -32,11 +32,11 @@
|
|||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"@ohif/i18n": "^0.50.0",
|
"@ohif/i18n": "^0.50.0",
|
||||||
"@ohif/ui": "^0.50.0",
|
"@ohif/ui": "^0.50.0",
|
||||||
"cornerstone-core": "^2.5.0",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-tools": "^6.0.0",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"cornerstone-wado-image-loader": "^4.0.3",
|
"cornerstone-wado-image-loader": "^4.1.0",
|
||||||
"dcmjs": "0.18.9",
|
"dcmjs": "0.19.2",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.11",
|
||||||
"i18next": "^17.0.3",
|
"i18next": "^17.0.3",
|
||||||
"i18next-browser-languagedetector": "^3.0.1",
|
"i18next-browser-languagedetector": "^3.0.1",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
@@ -53,11 +53,11 @@
|
|||||||
"react-vtkjs-viewport": "^0.14.4"
|
"react-vtkjs-viewport": "^0.14.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ohif/core": "^2.16.0",
|
"@ohif/core": "^2.16.8",
|
||||||
"@ohif/ui": "^1.10.2",
|
"@ohif/ui": "^1.10.5",
|
||||||
"cornerstone-tools": "^6.0.0",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"cornerstone-wado-image-loader": "^4.0.3",
|
"cornerstone-wado-image-loader": "^4.1.0",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.11",
|
||||||
"gh-pages": "^2.0.1",
|
"gh-pages": "^2.0.1",
|
||||||
"i18next": "^17.0.3",
|
"i18next": "^17.0.3",
|
||||||
"i18next-browser-languagedetector": "^3.0.1",
|
"i18next-browser-languagedetector": "^3.0.1",
|
||||||
|
|||||||
+4
-2
@@ -56,6 +56,7 @@
|
|||||||
"@babel/preset-env": "^7.5.0",
|
"@babel/preset-env": "^7.5.0",
|
||||||
"@babel/preset-react": "^7.0.0",
|
"@babel/preset-react": "^7.0.0",
|
||||||
"@percy/cypress": "^2.2.0",
|
"@percy/cypress": "^2.2.0",
|
||||||
|
"@webpack-cli/serve": "^1.6.1",
|
||||||
"babel-eslint": "9.x",
|
"babel-eslint": "9.x",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.0.6",
|
||||||
"babel-plugin-inline-react-svg": "1.1.0",
|
"babel-plugin-inline-react-svg": "1.1.0",
|
||||||
@@ -104,8 +105,8 @@
|
|||||||
"stylus-loader": "^3.0.2",
|
"stylus-loader": "^3.0.2",
|
||||||
"terser-webpack-plugin": "^2.1.0",
|
"terser-webpack-plugin": "^2.1.0",
|
||||||
"webpack": "^4.35.2",
|
"webpack": "^4.35.2",
|
||||||
"webpack-cli": "^3.3.5",
|
"webpack-cli": "^4.9.2",
|
||||||
"webpack-dev-server": "^3.7.2",
|
"webpack-dev-server": "^4.7.3",
|
||||||
"webpack-hot-middleware": "^2.25.0",
|
"webpack-hot-middleware": "^2.25.0",
|
||||||
"webpack-merge": "^4.2.1",
|
"webpack-merge": "^4.2.1",
|
||||||
"workbox-webpack-plugin": "^5.0.0-beta.1",
|
"workbox-webpack-plugin": "^5.0.0-beta.1",
|
||||||
@@ -123,6 +124,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
"**/node-gyp": "8.4.1",
|
||||||
"**/@babel/runtime": "7.5.5"
|
"**/@babel/runtime": "7.5.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,76 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [2.16.8](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.7...@ohif/core@2.16.8) (2022-01-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.7](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.6...@ohif/core@2.16.7) (2022-01-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.6](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.5...@ohif/core@2.16.6) (2022-01-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.5](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.4...@ohif/core@2.16.5) (2021-12-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* DICOMFileLoadingListener typo in method name ([#2647](https://github.com/OHIF/Viewers/issues/2647)) ([761d54f](https://github.com/OHIF/Viewers/commit/761d54fbbfb376c20ee15794ef7bb7111f64a06f))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.4](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.3...@ohif/core@2.16.4) (2021-12-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* SeriesTime and SeriesDate are only set for the first series and undefined for the remaining ones ([#2476](https://github.com/OHIF/Viewers/issues/2476)) ([6a401c9](https://github.com/OHIF/Viewers/commit/6a401c9e5204cb4f7af6aa33190ad5a8d0879de6))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.3](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.2...@ohif/core@2.16.3) (2021-12-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.2](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.1...@ohif/core@2.16.2) (2021-11-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.1](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.0...@ohif/core@2.16.1) (2021-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [2.16.0](https://github.com/OHIF/Viewers/compare/@ohif/core@2.15.1...@ohif/core@2.16.0) (2021-10-04)
|
# [2.16.0](https://github.com/OHIF/Viewers/compare/@ohif/core@2.15.1...@ohif/core@2.16.0) (2021-10-04)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/core",
|
"name": "@ohif/core",
|
||||||
"version": "2.16.0",
|
"version": "2.16.8",
|
||||||
"description": "Generic business logic for web-based medical imaging applications",
|
"description": "Generic business logic for web-based medical imaging applications",
|
||||||
"author": "OHIF Core Team",
|
"author": "OHIF Core Team",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -31,16 +31,16 @@
|
|||||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage"
|
"test:unit:ci": "jest --ci --runInBand --collectCoverage"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"cornerstone-core": "^2.5.0",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-tools": "^6.0.0",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"cornerstone-wado-image-loader": "^4.0.3",
|
"cornerstone-wado-image-loader": "^4.1.0",
|
||||||
"dicom-parser": "^1.8.9"
|
"dicom-parser": "^1.8.11"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.5.5",
|
||||||
"ajv": "^6.10.0",
|
"ajv": "^6.10.0",
|
||||||
"dcmjs": "0.18.9",
|
"dcmjs": "0.19.2",
|
||||||
"dicomweb-client": "^0.8.1",
|
"dicomweb-client": "^0.8.3",
|
||||||
"immer": "6.0.2",
|
"immer": "6.0.2",
|
||||||
"isomorphic-base64": "^1.0.2",
|
"isomorphic-base64": "^1.0.2",
|
||||||
"lodash.clonedeep": "^4.5.0",
|
"lodash.clonedeep": "^4.5.0",
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class DICOMFileLoadingListener extends BaseLoadingListener {
|
|||||||
constructor(stack, options) {
|
constructor(stack, options) {
|
||||||
super(stack, options);
|
super(stack, options);
|
||||||
|
|
||||||
this.imageLoadProgressEventHandler = this._imageLoadProgressEventHandle.bind(
|
this.imageLoadProgressEventHandler = this._imageLoadProgressEventHandler.bind(
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from 'cornerstone-core';
|
||||||
import cornerstoneTools from 'cornerstone-tools';
|
|
||||||
|
|
||||||
import getImageId from '../utils/getImageId.js';
|
import getImageId from '../utils/getImageId.js';
|
||||||
|
|
||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
@@ -13,6 +11,7 @@ export class StudyPrefetcher {
|
|||||||
requestType: 'prefetch',
|
requestType: 'prefetch',
|
||||||
preventCache: false,
|
preventCache: false,
|
||||||
prefetchDisplaySetsTimeout: 300,
|
prefetchDisplaySetsTimeout: 300,
|
||||||
|
maxNumPrefetchRequests: 100,
|
||||||
includeActiveDisplaySet: false,
|
includeActiveDisplaySet: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -94,7 +93,11 @@ export class StudyPrefetcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.element = element;
|
this.element = element;
|
||||||
this.enabledElement = cornerstone.getEnabledElement(element);
|
try {
|
||||||
|
this.enabledElement = cornerstone.getEnabledElement(element);
|
||||||
|
} catch {
|
||||||
|
throw new Error('Failed to find the enabled element');
|
||||||
|
}
|
||||||
|
|
||||||
this.stopPrefetching();
|
this.stopPrefetching();
|
||||||
this.prefetchDisplaySets(displaySetInstanceUID);
|
this.prefetchDisplaySets(displaySetInstanceUID);
|
||||||
@@ -114,7 +117,11 @@ export class StudyPrefetcher {
|
|||||||
* @param {number} timeout
|
* @param {number} timeout
|
||||||
*/
|
*/
|
||||||
prefetchDisplaySetsAsync(element, timeout) {
|
prefetchDisplaySetsAsync(element, timeout) {
|
||||||
this.enabledElement = cornerstone.getEnabledElement(element);
|
try {
|
||||||
|
this.enabledElement = cornerstone.getEnabledElement(element);
|
||||||
|
} catch {
|
||||||
|
throw new Error('Failed to find the enabled element');
|
||||||
|
}
|
||||||
timeout = timeout || this.options.prefetchDisplaySetsTimeout;
|
timeout = timeout || this.options.prefetchDisplaySetsTimeout;
|
||||||
clearTimeout(this.prefetchDisplaySetsHandler);
|
clearTimeout(this.prefetchDisplaySetsHandler);
|
||||||
this.prefetchDisplaySetsHandler = setTimeout(() => {
|
this.prefetchDisplaySetsHandler = setTimeout(() => {
|
||||||
@@ -145,6 +152,11 @@ export class StudyPrefetcher {
|
|||||||
const nonCachedImageIds = this.filterCachedImageIds(imageIds);
|
const nonCachedImageIds = this.filterCachedImageIds(imageIds);
|
||||||
const imageLoadPoolManager = cornerstone.imageLoadPoolManager;
|
const imageLoadPoolManager = cornerstone.imageLoadPoolManager;
|
||||||
|
|
||||||
|
imageLoadPoolManager.maxNumRequests = {
|
||||||
|
...imageLoadPoolManager.maxNumRequests,
|
||||||
|
prefetch: this.options.maxNumPrefetchRequests,
|
||||||
|
};
|
||||||
|
|
||||||
let requestFn;
|
let requestFn;
|
||||||
if (this.options.preventCache) {
|
if (this.options.preventCache) {
|
||||||
requestFn = id => cornerstone.loadImage(id);
|
requestFn = id => cornerstone.loadImage(id);
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ import { SeriesMetadata } from './SeriesMetadata';
|
|||||||
import { api } from 'dicomweb-client';
|
import { api } from 'dicomweb-client';
|
||||||
// - createStacks
|
// - createStacks
|
||||||
import { isImage } from '../../utils/isImage';
|
import { isImage } from '../../utils/isImage';
|
||||||
import { isDisplaySetReconstructable, isSpacingUniform } from '../../utils/isDisplaySetReconstructable';
|
import {
|
||||||
|
isDisplaySetReconstructable,
|
||||||
|
isSpacingUniform,
|
||||||
|
} from '../../utils/isDisplaySetReconstructable';
|
||||||
import errorHandler from '../../errorHandler';
|
import errorHandler from '../../errorHandler';
|
||||||
import isLowPriorityModality from '../../utils/isLowPriorityModality';
|
import isLowPriorityModality from '../../utils/isLowPriorityModality';
|
||||||
import getXHRRetryRequestHook from '../../utils/xhrRetryRequestHook';
|
import getXHRRetryRequestHook from '../../utils/xhrRetryRequestHook';
|
||||||
@@ -159,41 +162,64 @@ class StudyMetadata extends Metadata {
|
|||||||
// series into another display set.
|
// series into another display set.
|
||||||
const stackableInstances = [];
|
const stackableInstances = [];
|
||||||
series.forEachInstance(instance => {
|
series.forEachInstance(instance => {
|
||||||
|
let displaySet;
|
||||||
|
|
||||||
// All imaging modalities must have a valid value for SOPClassUID (x00080016) or Rows (x00280010)
|
// All imaging modalities must have a valid value for SOPClassUID (x00080016) or Rows (x00280010)
|
||||||
if (
|
if (
|
||||||
!isImage(instance.getTagValue('SOPClassUID')) &&
|
!isImage(instance.getTagValue('SOPClassUID')) &&
|
||||||
!instance.getTagValue('Rows')
|
!instance.getTagValue('Rows')
|
||||||
) {
|
) {
|
||||||
return;
|
// we set an empty display and we add a isModalitySupported variable to
|
||||||
}
|
// print a warning that the modality is not supported in the thumbnail.
|
||||||
|
const displaySet = new ImageSet([]);
|
||||||
let displaySet;
|
const seriesData = series.getData();
|
||||||
|
|
||||||
if (isMultiFrame(instance)) {
|
|
||||||
displaySet = makeDisplaySet(series, [instance]);
|
|
||||||
|
|
||||||
displaySet.setAttributes({
|
displaySet.setAttributes({
|
||||||
sopClassUIDs,
|
displaySetInstanceUID: displaySet.uid,
|
||||||
isClip: true,
|
SeriesDate: seriesData.SeriesDate,
|
||||||
|
SeriesTime: seriesData.SeriesTime,
|
||||||
SeriesInstanceUID: series.getSeriesInstanceUID(),
|
SeriesInstanceUID: series.getSeriesInstanceUID(),
|
||||||
StudyInstanceUID: study.getStudyInstanceUID(), // Include the study instance UID for drag/drop purposes
|
SeriesNumber: instance.getTagValue('SeriesNumber'),
|
||||||
numImageFrames: instance.getTagValue('NumberOfFrames'), // Override the default value of instances.length
|
SeriesDescription: instance.getTagValue('SeriesDescription'),
|
||||||
InstanceNumber: instance.getTagValue('InstanceNumber'), // Include the instance number
|
numImageFrames: instance.getTagValue('NumberOfFrames'),
|
||||||
AcquisitionDatetime: instance.getTagValue('AcquisitionDateTime'), // Include the acquisition datetime
|
frameRate: instance.getTagValue('FrameTime'),
|
||||||
});
|
Modality: instance.getTagValue('Modality'),
|
||||||
displaySets.push(displaySet);
|
isMultiFrame: false,
|
||||||
} else if (isSingleImageModality(instance.Modality)) {
|
|
||||||
displaySet = makeDisplaySet(series, [instance]);
|
|
||||||
displaySet.setAttributes({
|
|
||||||
sopClassUIDs,
|
|
||||||
StudyInstanceUID: study.getStudyInstanceUID(), // Include the study instance UID
|
StudyInstanceUID: study.getStudyInstanceUID(), // Include the study instance UID
|
||||||
SeriesInstanceUID: series.getSeriesInstanceUID(),
|
|
||||||
InstanceNumber: instance.getTagValue('InstanceNumber'), // Include the instance number
|
InstanceNumber: instance.getTagValue('InstanceNumber'), // Include the instance number
|
||||||
AcquisitionDatetime: instance.getTagValue('AcquisitionDateTime'), // Include the acquisition datetime
|
AcquisitionDatetime: instance.getTagValue('AcquisitionDateTime'), // Include the acquisition datetime
|
||||||
|
isReconstructable: false,
|
||||||
|
isModalitySupported: false,
|
||||||
|
metadata: instance.getData().metadata,
|
||||||
});
|
});
|
||||||
|
|
||||||
displaySets.push(displaySet);
|
displaySets.push(displaySet);
|
||||||
} else {
|
} else {
|
||||||
stackableInstances.push(instance);
|
if (isMultiFrame(instance)) {
|
||||||
|
displaySet = makeDisplaySet(series, [instance]);
|
||||||
|
|
||||||
|
displaySet.setAttributes({
|
||||||
|
sopClassUIDs,
|
||||||
|
isClip: true,
|
||||||
|
SeriesInstanceUID: series.getSeriesInstanceUID(),
|
||||||
|
StudyInstanceUID: study.getStudyInstanceUID(), // Include the study instance UID for drag/drop purposes
|
||||||
|
numImageFrames: instance.getTagValue('NumberOfFrames'), // Override the default value of instances.length
|
||||||
|
InstanceNumber: instance.getTagValue('InstanceNumber'), // Include the instance number
|
||||||
|
AcquisitionDatetime: instance.getTagValue('AcquisitionDateTime'), // Include the acquisition datetime
|
||||||
|
});
|
||||||
|
displaySets.push(displaySet);
|
||||||
|
} else if (isSingleImageModality(instance.Modality)) {
|
||||||
|
displaySet = makeDisplaySet(series, [instance]);
|
||||||
|
displaySet.setAttributes({
|
||||||
|
sopClassUIDs,
|
||||||
|
StudyInstanceUID: study.getStudyInstanceUID(), // Include the study instance UID
|
||||||
|
SeriesInstanceUID: series.getSeriesInstanceUID(),
|
||||||
|
InstanceNumber: instance.getTagValue('InstanceNumber'), // Include the instance number
|
||||||
|
AcquisitionDatetime: instance.getTagValue('AcquisitionDateTime'), // Include the acquisition datetime
|
||||||
|
});
|
||||||
|
displaySets.push(displaySet);
|
||||||
|
} else {
|
||||||
|
stackableInstances.push(instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -227,7 +253,6 @@ class StudyMetadata extends Metadata {
|
|||||||
displaySets.map(displaySet => this._derivedDisplaySets.push(displaySet));
|
displaySets.map(displaySet => this._derivedDisplaySets.push(displaySet));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the source display set of the derivated display set.
|
* Returns the source display set of the derivated display set.
|
||||||
* @param {object} derivatedDisplaySet
|
* @param {object} derivatedDisplaySet
|
||||||
@@ -242,40 +267,45 @@ class StudyMetadata extends Metadata {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const otherDisplaySets = allDisplaySets.filter(
|
const otherDisplaySets = allDisplaySets.filter(
|
||||||
ds => ds.displaySetInstanceUID !== derivatedDisplaySet.displaySetInstanceUID
|
ds =>
|
||||||
|
ds.displaySetInstanceUID !== derivatedDisplaySet.displaySetInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
const { metadata } = derivatedDisplaySet;
|
const { metadata } = derivatedDisplaySet;
|
||||||
|
|
||||||
let referencedSeriesInstanceUIDs = _findReferencedSeriesInstanceUIDsFromSourceImageSequence
|
let referencedSeriesInstanceUIDs = _findReferencedSeriesInstanceUIDsFromSourceImageSequence(
|
||||||
(metadata, otherDisplaySets);
|
metadata,
|
||||||
|
otherDisplaySets
|
||||||
|
);
|
||||||
|
|
||||||
let noReferencedSeriesAvailable = !referencedSeriesInstanceUIDs ||
|
let noReferencedSeriesAvailable =
|
||||||
|
!referencedSeriesInstanceUIDs ||
|
||||||
referencedSeriesInstanceUIDs.length === 0;
|
referencedSeriesInstanceUIDs.length === 0;
|
||||||
if (noReferencedSeriesAvailable) {
|
if (noReferencedSeriesAvailable) {
|
||||||
referencedSeriesInstanceUIDs =
|
referencedSeriesInstanceUIDs = _findReferencedSeriesInstanceUIDsFromReferencedSeriesSequence(
|
||||||
_findReferencedSeriesInstanceUIDsFromReferencedSeriesSequence
|
metadata
|
||||||
(metadata);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
noReferencedSeriesAvailable = !referencedSeriesInstanceUIDs ||
|
noReferencedSeriesAvailable =
|
||||||
|
!referencedSeriesInstanceUIDs ||
|
||||||
referencedSeriesInstanceUIDs.length === 0;
|
referencedSeriesInstanceUIDs.length === 0;
|
||||||
if (noReferencedSeriesAvailable) {
|
if (noReferencedSeriesAvailable) {
|
||||||
referencedSeriesInstanceUIDs =
|
referencedSeriesInstanceUIDs = _findReferencedSeriesInstanceUIDsFromReferencedImageSequence(
|
||||||
_findReferencedSeriesInstanceUIDsFromReferencedImageSequence
|
metadata,
|
||||||
(metadata, otherDisplaySets);
|
otherDisplaySets
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const referencedSeriesAvailable = referencedSeriesInstanceUIDs &&
|
const referencedSeriesAvailable =
|
||||||
referencedSeriesInstanceUIDs.length !== 0;
|
referencedSeriesInstanceUIDs && referencedSeriesInstanceUIDs.length !== 0;
|
||||||
if (referencedSeriesAvailable) {
|
if (referencedSeriesAvailable) {
|
||||||
const referencedDisplaySet = otherDisplaySets.find(ds =>
|
const referencedDisplaySet = otherDisplaySets.find(ds =>
|
||||||
referencedSeriesInstanceUIDs.includes(ds.SeriesInstanceUID)
|
referencedSeriesInstanceUIDs.includes(ds.SeriesInstanceUID)
|
||||||
);
|
);
|
||||||
;
|
|
||||||
return referencedDisplaySet;
|
return referencedDisplaySet;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of derived datasets in the study, filtered by the given filter.
|
* Returns a list of derived datasets in the study, filtered by the given filter.
|
||||||
@@ -303,7 +333,10 @@ class StudyMetadata extends Metadata {
|
|||||||
if (referencedSeriesInstanceUID) {
|
if (referencedSeriesInstanceUID) {
|
||||||
filteredDerivedDisplaySets = filteredDerivedDisplaySets.filter(
|
filteredDerivedDisplaySets = filteredDerivedDisplaySets.filter(
|
||||||
displaySet => {
|
displaySet => {
|
||||||
return StudyMetadata.getReferencedDisplaySet(displaySet, [this]).SeriesInstanceUID === referencedSeriesInstanceUID;
|
return (
|
||||||
|
StudyMetadata.getReferencedDisplaySet(displaySet, [this])
|
||||||
|
.SeriesInstanceUID === referencedSeriesInstanceUID
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -311,8 +344,7 @@ class StudyMetadata extends Metadata {
|
|||||||
if (referencedFrameOfReferenceUID) {
|
if (referencedFrameOfReferenceUID) {
|
||||||
filteredDerivedDisplaySets = filteredDerivedDisplaySets.filter(
|
filteredDerivedDisplaySets = filteredDerivedDisplaySets.filter(
|
||||||
displaySet =>
|
displaySet =>
|
||||||
displaySet.FrameOfReferenceUID ===
|
displaySet.FrameOfReferenceUID === referencedFrameOfReferenceUID
|
||||||
referencedFrameOfReferenceUID
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,8 +529,10 @@ class StudyMetadata extends Metadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._displaySets.some(ds =>
|
if (
|
||||||
ds.displaySetInstanceUID === displaySet.displaySetInstanceUID)
|
this._displaySets.some(
|
||||||
|
ds => ds.displaySetInstanceUID === displaySet.displaySetInstanceUID
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -867,8 +901,9 @@ const makeDisplaySet = (series, instances) => {
|
|||||||
imageSet.sortByImagePositionPatient();
|
imageSet.sortByImagePositionPatient();
|
||||||
|
|
||||||
// check if the spacing is uniform and update isReconstructable
|
// check if the spacing is uniform and update isReconstructable
|
||||||
const datasetIs4D = displayReconstructableInfo.reconstructionIssues.find
|
const datasetIs4D = displayReconstructableInfo.reconstructionIssues.find(
|
||||||
(issue => issue === ReconstructionIssues.DATASET_4D);
|
issue => issue === ReconstructionIssues.DATASET_4D
|
||||||
|
);
|
||||||
displaySpacingInfo = isSpacingUniform(imageSet.images, datasetIs4D);
|
displaySpacingInfo = isSpacingUniform(imageSet.images, datasetIs4D);
|
||||||
imageSet.isReconstructable = displaySpacingInfo.isUniform;
|
imageSet.isReconstructable = displaySpacingInfo.isUniform;
|
||||||
|
|
||||||
@@ -881,11 +916,15 @@ const makeDisplaySet = (series, instances) => {
|
|||||||
|
|
||||||
if (!imageSet.displayReconstructableInfo) {
|
if (!imageSet.displayReconstructableInfo) {
|
||||||
// It is not reconstrabale Save type of warning
|
// It is not reconstrabale Save type of warning
|
||||||
imageSet.reconstructionIssues = displaySpacingInfo ?
|
imageSet.reconstructionIssues = displaySpacingInfo
|
||||||
displayReconstructableInfo.reconstructionIssues.concat(displaySpacingInfo.reconstructionIssues) :
|
? displayReconstructableInfo.reconstructionIssues.concat(
|
||||||
displayReconstructableInfo.reconstructionIssues;
|
displaySpacingInfo.reconstructionIssues
|
||||||
|
)
|
||||||
|
: displayReconstructableInfo.reconstructionIssues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imageSet.isModalitySupported = true;
|
||||||
|
|
||||||
return imageSet;
|
return imageSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -963,38 +1002,36 @@ function _getDisplaySetFromSopClassModule(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the referenced series instance UIDs by searching the information in the
|
* Returns the referenced series instance UIDs by searching the information in the
|
||||||
* ReferencedSeriesSequence.
|
* ReferencedSeriesSequence.
|
||||||
* @param {object} derivatedDisplaySet.metadata
|
* @param {object} derivatedDisplaySet.metadata
|
||||||
* @return {array[string]} referenced series instance UIDs.
|
* @return {array[string]} referenced series instance UIDs.
|
||||||
*/
|
*/
|
||||||
function _findReferencedSeriesInstanceUIDsFromReferencedSeriesSequence (
|
function _findReferencedSeriesInstanceUIDsFromReferencedSeriesSequence(
|
||||||
metadata,
|
metadata
|
||||||
) {
|
) {
|
||||||
if (!metadata.ReferencedSeriesSequence) {
|
if (!metadata.ReferencedSeriesSequence) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let referencedSeriesInstanceUIDs;
|
let referencedSeriesInstanceUIDs;
|
||||||
const ReferencedSeriesSequence = _toArray(
|
const ReferencedSeriesSequence = _toArray(metadata.ReferencedSeriesSequence);
|
||||||
metadata.ReferencedSeriesSequence
|
|
||||||
);
|
|
||||||
|
|
||||||
referencedSeriesInstanceUIDs = ReferencedSeriesSequence.map(
|
referencedSeriesInstanceUIDs = ReferencedSeriesSequence.map(
|
||||||
ReferencedSeries => ReferencedSeries.SeriesInstanceUID
|
ReferencedSeries => ReferencedSeries.SeriesInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
return referencedSeriesInstanceUIDs;
|
return referencedSeriesInstanceUIDs;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the referenced series instance UIDs by searching the information in the
|
* Returns the referenced series instance UIDs by searching the information in the
|
||||||
* ReferencedImageSequence.
|
* ReferencedImageSequence.
|
||||||
* @param {object} derivatedDisplaySet.metadata
|
* @param {object} derivatedDisplaySet.metadata
|
||||||
* @param {array[object]} displaysets
|
* @param {array[object]} displaysets
|
||||||
* @return {array[string]} referenced series instance UIDs.
|
* @return {array[string]} referenced series instance UIDs.
|
||||||
*/
|
*/
|
||||||
function _findReferencedSeriesInstanceUIDsFromReferencedImageSequence (
|
function _findReferencedSeriesInstanceUIDsFromReferencedImageSequence(
|
||||||
metadata,
|
metadata,
|
||||||
displaySets
|
displaySets
|
||||||
) {
|
) {
|
||||||
@@ -1015,22 +1052,25 @@ function _findReferencedSeriesInstanceUIDsFromReferencedImageSequence (
|
|||||||
ReferencedSOPInstanceUID
|
ReferencedSOPInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
if (referencedSeriesInstanceUIDs && referencedSeriesInstanceUIDs.length !== 0) {
|
if (
|
||||||
|
referencedSeriesInstanceUIDs &&
|
||||||
|
referencedSeriesInstanceUIDs.length !== 0
|
||||||
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return referencedSeriesInstanceUIDs;
|
return referencedSeriesInstanceUIDs;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the referenced series instance UIDs by searching the information in the
|
* Returns the referenced series instance UIDs by searching the information in the
|
||||||
* SourceImageSequence.
|
* SourceImageSequence.
|
||||||
* @param {object} derivatedDisplaySet.metadata
|
* @param {object} derivatedDisplaySet.metadata
|
||||||
* @param {array[object]} displaysets
|
* @param {array[object]} displaysets
|
||||||
* @return {array[string]} referenced series instance UIDs.
|
* @return {array[string]} referenced series instance UIDs.
|
||||||
*/
|
*/
|
||||||
function _findReferencedSeriesInstanceUIDsFromSourceImageSequence (
|
function _findReferencedSeriesInstanceUIDsFromSourceImageSequence(
|
||||||
metadata,
|
metadata,
|
||||||
displaySets
|
displaySets
|
||||||
) {
|
) {
|
||||||
@@ -1040,9 +1080,7 @@ function _findReferencedSeriesInstanceUIDsFromSourceImageSequence (
|
|||||||
SourceImageSequence = metadata.SourceImageSequence;
|
SourceImageSequence = metadata.SourceImageSequence;
|
||||||
} else {
|
} else {
|
||||||
const { PerFrameFunctionalGroupsSequence } = metadata;
|
const { PerFrameFunctionalGroupsSequence } = metadata;
|
||||||
const firstFunctionalGroups = _toArray(
|
const firstFunctionalGroups = _toArray(PerFrameFunctionalGroupsSequence)[0];
|
||||||
PerFrameFunctionalGroupsSequence
|
|
||||||
)[0];
|
|
||||||
if (firstFunctionalGroups) {
|
if (firstFunctionalGroups) {
|
||||||
const { DerivationImageSequence } = firstFunctionalGroups;
|
const { DerivationImageSequence } = firstFunctionalGroups;
|
||||||
SourceImageSequence = DerivationImageSequence;
|
SourceImageSequence = DerivationImageSequence;
|
||||||
@@ -1062,22 +1100,25 @@ function _findReferencedSeriesInstanceUIDsFromSourceImageSequence (
|
|||||||
displaySets,
|
displaySets,
|
||||||
ReferencedSOPInstanceUID
|
ReferencedSOPInstanceUID
|
||||||
);
|
);
|
||||||
if (referencedSeriesInstanceUIDs && referencedSeriesInstanceUIDs.length !== 0) {
|
if (
|
||||||
|
referencedSeriesInstanceUIDs &&
|
||||||
|
referencedSeriesInstanceUIDs.length !== 0
|
||||||
|
) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return referencedSeriesInstanceUIDs;
|
return referencedSeriesInstanceUIDs;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the referenced series instance UIDs by searching the information in the
|
* Returns the referenced series instance UIDs by searching the information in the
|
||||||
* SOPInstanceUID of the displaySets.
|
* SOPInstanceUID of the displaySets.
|
||||||
* @param {array[object]} displaysets
|
* @param {array[object]} displaysets
|
||||||
* @param {string} SOPInstanceUID
|
* @param {string} SOPInstanceUID
|
||||||
* @return {array[string]} referenced series instance UIDs.
|
* @return {array[string]} referenced series instance UIDs.
|
||||||
*/
|
*/
|
||||||
function _findReferencedSeriesInstanceUIDsFromSOPInstanceUID (
|
function _findReferencedSeriesInstanceUIDsFromSOPInstanceUID(
|
||||||
displaySets,
|
displaySets,
|
||||||
SOPInstanceUID
|
SOPInstanceUID
|
||||||
) {
|
) {
|
||||||
@@ -1098,10 +1139,10 @@ function _findReferencedSeriesInstanceUIDsFromSOPInstanceUID (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function _toArray(arrayOrObject) {
|
function _toArray(arrayOrObject) {
|
||||||
return Array.isArray(arrayOrObject) ? arrayOrObject : [arrayOrObject];
|
return Array.isArray(arrayOrObject) ? arrayOrObject : [arrayOrObject];
|
||||||
}
|
}
|
||||||
|
|
||||||
export {StudyMetadata};
|
export { StudyMetadata };
|
||||||
@@ -20,6 +20,7 @@ import ui from './ui';
|
|||||||
import user from './user.js';
|
import user from './user.js';
|
||||||
import errorHandler from './errorHandler.js';
|
import errorHandler from './errorHandler.js';
|
||||||
import utils, { hotkeys } from './utils/';
|
import utils, { hotkeys } from './utils/';
|
||||||
|
import str2ab from './utils/str2ab';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
UINotificationService,
|
UINotificationService,
|
||||||
@@ -96,6 +97,8 @@ export {
|
|||||||
UIDialogService,
|
UIDialogService,
|
||||||
MeasurementService,
|
MeasurementService,
|
||||||
LoggerService,
|
LoggerService,
|
||||||
|
|
||||||
|
str2ab,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { OHIF };
|
export { OHIF };
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ describe('Top level exports', () => {
|
|||||||
'cornerstone',
|
'cornerstone',
|
||||||
'default', //
|
'default', //
|
||||||
'errorHandler',
|
'errorHandler',
|
||||||
|
'str2ab',
|
||||||
'string',
|
'string',
|
||||||
'ui',
|
'ui',
|
||||||
'user',
|
'user',
|
||||||
|
|||||||
@@ -9,38 +9,27 @@ import { api } from 'dicomweb-client';
|
|||||||
*/
|
*/
|
||||||
export default class StaticWadoClient extends api.DICOMwebClient {
|
export default class StaticWadoClient extends api.DICOMwebClient {
|
||||||
static filterKeys = {
|
static filterKeys = {
|
||||||
StudyInstanceUID: '0020000D',
|
"StudyInstanceUID": "0020000D",
|
||||||
PatientName: '00100010',
|
"PatientName": "00100010",
|
||||||
PatientID: '00100020',
|
"00100020": "mrn",
|
||||||
StudyDescription: '00081030',
|
"PatientID": "00100020",
|
||||||
ModalitiesInStudy: '00080061',
|
"StudyDescription": "00081030",
|
||||||
|
"StudyDate": "00080020",
|
||||||
|
"ModalitiesInStudy": "00080061",
|
||||||
|
AccessionNumber: "00080050",
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(qidoConfig) {
|
constructor(qidoConfig) {
|
||||||
super(qidoConfig);
|
super(qidoConfig);
|
||||||
this.staticWado = qidoConfig.staticWado;
|
this.staticWado = qidoConfig.staticWado;
|
||||||
this.extendMetadataWithInstances = qidoConfig.extendMetadataWithInstances;
|
|
||||||
}
|
|
||||||
|
|
||||||
async retrieveSeriesMetadata(options) {
|
|
||||||
if (!this.extendMetadataWithInstances)
|
|
||||||
return super.retrieveSeriesMetadata(options);
|
|
||||||
const results = await Promise.all([
|
|
||||||
super.retrieveSeriesMetadata(options),
|
|
||||||
this.searchForInstances(options),
|
|
||||||
]);
|
|
||||||
const metadata = results[0];
|
|
||||||
const instances = results[1];
|
|
||||||
return metadata.map(item => {
|
|
||||||
const sopUID = item['00080018'].Value[0];
|
|
||||||
const instance = instances.find(
|
|
||||||
instance => instance['00080018'].Value[0] == sopUID
|
|
||||||
);
|
|
||||||
Object.assign(item, instance);
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the search for studies remote query with a local version which
|
||||||
|
* retrieves a complete query list and then sub-selects from it locally.
|
||||||
|
* @param {*} options
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
async searchForStudies(options) {
|
async searchForStudies(options) {
|
||||||
if (!this.staticWado) return super.searchForStudies(options);
|
if (!this.staticWado) return super.searchForStudies(options);
|
||||||
|
|
||||||
@@ -56,6 +45,62 @@ export default class StaticWadoClient extends api.DICOMwebClient {
|
|||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares values, matching any instance of desired to any instance of
|
||||||
|
* actual by recursively go through the paired set of values. That is,
|
||||||
|
* this is O(m*n) where m is how many items in desired and n is the length of actual
|
||||||
|
* Then, at the individual item node, compares the Alphabetic name if present,
|
||||||
|
* and does a sub-string matching on string values, and otherwise does an
|
||||||
|
* exact match comparison.
|
||||||
|
*
|
||||||
|
* @param {*} desired
|
||||||
|
* @param {*} actual
|
||||||
|
* @returns true if the values match
|
||||||
|
*/
|
||||||
|
compareValues(desired, actual) {
|
||||||
|
if (Array.isArray(desired)) {
|
||||||
|
return desired.find(item => this.compareValues(item, actual));
|
||||||
|
}
|
||||||
|
if (Array.isArray(actual)) {
|
||||||
|
return actual.find(actualItem => this.compareValues(desired, actualItem));
|
||||||
|
}
|
||||||
|
if (actual && actual.Alphabetic) {
|
||||||
|
actual = actual.Alphabetic;
|
||||||
|
}
|
||||||
|
if (typeof (actual) == 'string') {
|
||||||
|
if (actual.length === 0) return true;
|
||||||
|
if (desired.length === 0 || desired === '*') return true;
|
||||||
|
if (desired[0] === '*' && desired[desired.length - 1] === '*') {
|
||||||
|
console.log(`Comparing ${actual} to ${desired.substring(1, desired.length - 1)}`)
|
||||||
|
return actual.indexOf(desired.substring(1, desired.length - 1)) != -1;
|
||||||
|
} else if (desired[desired.length - 1] === '*') {
|
||||||
|
return actual.indexOf(desired.substring(0, desired.length - 1)) != -1;
|
||||||
|
} else if (desired[0] === '*') {
|
||||||
|
return actual.indexOf(desired.substring(1)) === actual.length - desired.length + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return desired === actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Compares a pair of dates to see if the value is within the range */
|
||||||
|
compareDateRange(range, value) {
|
||||||
|
if (!value) return true;
|
||||||
|
const dash = range.indexOf('-');
|
||||||
|
if (dash === -1) return this.compareValues(range, value);
|
||||||
|
const start = range.substring(0, dash);
|
||||||
|
const end = range.substring(dash + 1);
|
||||||
|
return (!start || value >= start) &&
|
||||||
|
(!end || value <= end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the return list by the query parameters.
|
||||||
|
*
|
||||||
|
* @param {*} key
|
||||||
|
* @param {*} queryParams
|
||||||
|
* @param {*} study
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
filterItem(key, queryParams, study) {
|
filterItem(key, queryParams, study) {
|
||||||
const altKey = StaticWadoClient.filterKeys[key] || key;
|
const altKey = StaticWadoClient.filterKeys[key] || key;
|
||||||
if (!queryParams) return true;
|
if (!queryParams) return true;
|
||||||
@@ -63,23 +108,8 @@ export default class StaticWadoClient extends api.DICOMwebClient {
|
|||||||
if (!testValue) return true;
|
if (!testValue) return true;
|
||||||
const valueElem = study[key] || study[altKey];
|
const valueElem = study[key] || study[altKey];
|
||||||
if (!valueElem) return false;
|
if (!valueElem) return false;
|
||||||
|
if (valueElem.vr == 'DA') return this.compareDateRange(testValue, valueElem.Value[0]);
|
||||||
const value = valueElem.Value;
|
const value = valueElem.Value;
|
||||||
return this.eqItem(testValue, value);
|
return this.compareValues(testValue, value) && true;
|
||||||
}
|
|
||||||
|
|
||||||
eqItem(testValue, value) {
|
|
||||||
if (testValue.filter) {
|
|
||||||
return (
|
|
||||||
testValue.filter(testItem => this.eqItem(testItem, value)).length > 0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (value === testValue) return true;
|
|
||||||
if (typeof value == 'string') {
|
|
||||||
return value.indexOf(testValue) != -1;
|
|
||||||
}
|
|
||||||
if (value.Alphabetic) return this.eqItem(testValue, value.Alphabetic);
|
|
||||||
if (value.filter)
|
|
||||||
return value.filter(item => this.eqItem(testValue, item)).length > 0;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,6 +116,11 @@ async function makeSOPInstance(server, study, instance) {
|
|||||||
};
|
};
|
||||||
study.seriesMap[SeriesInstanceUID] = series;
|
study.seriesMap[SeriesInstanceUID] = series;
|
||||||
study.series.push(series);
|
study.series.push(series);
|
||||||
|
} else {
|
||||||
|
if (series.SeriesDate === undefined)
|
||||||
|
series.SeriesDate = naturalizedInstance.SeriesDate;
|
||||||
|
if (series.SeriesTime === undefined)
|
||||||
|
series.SeriesTime = naturalizedInstance.SeriesTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
const wadouri = buildInstanceWadoUrl(
|
const wadouri = buildInstanceWadoUrl(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ReconstructionIssues } from './../enums.js';
|
import { ReconstructionIssues } from './../enums.js';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a series is reconstructable to a 3D volume.
|
* Checks if a series is reconstructable to a 3D volume.
|
||||||
*
|
*
|
||||||
@@ -78,7 +77,9 @@ function processSingleframe(instances) {
|
|||||||
reconstructionIssues.push(ReconstructionIssues.VARYING_IMAGESDIMENSIONS);
|
reconstructionIssues.push(ReconstructionIssues.VARYING_IMAGESDIMENSIONS);
|
||||||
} else if (SamplesPerPixel !== firstImageSamplesPerPixel) {
|
} else if (SamplesPerPixel !== firstImageSamplesPerPixel) {
|
||||||
reconstructionIssues.push(ReconstructionIssues.VARYING_IMAGESCOMPONENTS);
|
reconstructionIssues.push(ReconstructionIssues.VARYING_IMAGESCOMPONENTS);
|
||||||
} else if (!_isSameArray(ImageOrientationPatient, firstImageOrientationPatient)) {
|
} else if (
|
||||||
|
!_isSameArray(ImageOrientationPatient, firstImageOrientationPatient)
|
||||||
|
) {
|
||||||
reconstructionIssues.push(ReconstructionIssues.VARYING_IMAGESORIENTATION);
|
reconstructionIssues.push(ReconstructionIssues.VARYING_IMAGESORIENTATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +93,10 @@ function processSingleframe(instances) {
|
|||||||
reconstructionIssues.push(ReconstructionIssues.DATASET_4D);
|
reconstructionIssues.push(ReconstructionIssues.DATASET_4D);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { value: reconstructionIssues.length === 0 ? true : false, reconstructionIssues };
|
return {
|
||||||
|
value: reconstructionIssues.length === 0 ? true : false,
|
||||||
|
reconstructionIssues,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -116,14 +120,12 @@ function isSpacingUniform(instances, datasetIs4D) {
|
|||||||
// If spacing is on a uniform grid but we are missing frames,
|
// If spacing is on a uniform grid but we are missing frames,
|
||||||
// Allow reconstruction, but pass back the number of missing frames.
|
// Allow reconstruction, but pass back the number of missing frames.
|
||||||
if (n > 2) {
|
if (n > 2) {
|
||||||
const lastIpp = instances[n - 1].getData().metadata
|
const lastIpp = instances[n - 1].getData().metadata.ImagePositionPatient;
|
||||||
.ImagePositionPatient;
|
|
||||||
|
|
||||||
// We can't reconstruct if we are missing ImagePositionPatient values
|
// We can't reconstruct if we are missing ImagePositionPatient values
|
||||||
if (firstImagePositionPatient && lastIpp) {
|
if (firstImagePositionPatient && lastIpp) {
|
||||||
const averageSpacingBetweenFrames =
|
const averageSpacingBetweenFrames =
|
||||||
_getPerpendicularDistance(firstImagePositionPatient, lastIpp) /
|
_getPerpendicularDistance(firstImagePositionPatient, lastIpp) / (n - 1);
|
||||||
(n - 1);
|
|
||||||
|
|
||||||
let previousImagePositionPatient = firstImagePositionPatient;
|
let previousImagePositionPatient = firstImagePositionPatient;
|
||||||
|
|
||||||
@@ -136,7 +138,7 @@ function isSpacingUniform(instances, datasetIs4D) {
|
|||||||
previousImagePositionPatient
|
previousImagePositionPatient
|
||||||
);
|
);
|
||||||
|
|
||||||
if (datasetIs4D && spacingBetweenFrames < 1.e-3) {
|
if (datasetIs4D && spacingBetweenFrames < 1e-3) {
|
||||||
// the dataset is 4D, if the distance is zero, means that we are
|
// the dataset is 4D, if the distance is zero, means that we are
|
||||||
// checking the 4th dimension. Do not return, since we want still to
|
// checking the 4th dimension. Do not return, since we want still to
|
||||||
// check the 3rd dimension spacing.
|
// check the 3rd dimension spacing.
|
||||||
@@ -164,10 +166,13 @@ function isSpacingUniform(instances, datasetIs4D) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { isUniform: reconstructionIssues.length === 0 ? true : false, missingFrames, reconstructionIssues };
|
return {
|
||||||
|
isUniform: reconstructionIssues.length === 0 ? true : false,
|
||||||
|
missingFrames,
|
||||||
|
reconstructionIssues,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if 4D dataset.
|
* Check if 4D dataset.
|
||||||
*
|
*
|
||||||
@@ -181,7 +186,7 @@ function isSpacingUniform(instances, datasetIs4D) {
|
|||||||
*
|
*
|
||||||
* @returns {boolean} dataset4D value.
|
* @returns {boolean} dataset4D value.
|
||||||
*/
|
*/
|
||||||
function _isDataset4D(instances) {
|
function _isDataset4D(instances) {
|
||||||
const n = instances.length;
|
const n = instances.length;
|
||||||
for (let ii = 0; ii < n; ++ii) {
|
for (let ii = 0; ii < n; ++ii) {
|
||||||
const instanceMetadataControl = instances[ii].getData().metadata;
|
const instanceMetadataControl = instances[ii].getData().metadata;
|
||||||
@@ -204,7 +209,12 @@ function isSpacingUniform(instances, datasetIs4D) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isSameArray(instanceMetadataControl.ImagePositionPatient, instanceMetadata.ImagePositionPatient)) {
|
if (
|
||||||
|
_isSameArray(
|
||||||
|
instanceMetadataControl.ImagePositionPatient,
|
||||||
|
instanceMetadata.ImagePositionPatient
|
||||||
|
)
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,11 +275,11 @@ function _getSpacingIssue(spacing, averageSpacing) {
|
|||||||
function _getPerpendicularDistance(a, b) {
|
function _getPerpendicularDistance(a, b) {
|
||||||
return Math.sqrt(
|
return Math.sqrt(
|
||||||
Math.pow(a[0] - b[0], 2) +
|
Math.pow(a[0] - b[0], 2) +
|
||||||
Math.pow(a[1] - b[1], 2) +
|
Math.pow(a[1] - b[1], 2) +
|
||||||
Math.pow(a[2] - b[2], 2)
|
Math.pow(a[2] - b[2], 2)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const constructableModalities = ['MR', 'CT', 'PT', 'NM'];
|
const constructableModalities = ['MR', 'CT', 'PT', 'NM'];
|
||||||
|
|
||||||
export {isDisplaySetReconstructable, isSpacingUniform};
|
export { isDisplaySetReconstructable, isSpacingUniform };
|
||||||
@@ -3,6 +3,30 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.10.5](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.10.4...@ohif/ui@1.10.5) (2021-11-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/ui
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.10.4](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.10.3...@ohif/ui@1.10.4) (2021-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/ui
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.10.3](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.10.2...@ohif/ui@1.10.3) (2021-10-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/ui
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [1.10.2](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.10.1...@ohif/ui@1.10.2) (2021-09-24)
|
## [1.10.2](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.10.1...@ohif/ui@1.10.2) (2021-09-24)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/ui",
|
"name": "@ohif/ui",
|
||||||
"version": "1.10.2",
|
"version": "1.10.5",
|
||||||
"description": "A set of React components for Medical Imaging Viewers",
|
"description": "A set of React components for Medical Imaging Viewers",
|
||||||
"author": "OHIF Contributors",
|
"author": "OHIF Contributors",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -25,11 +25,12 @@ function StudyBrowser(props) {
|
|||||||
altImageText,
|
altImageText,
|
||||||
displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
imageId,
|
imageId,
|
||||||
InstanceNumber,
|
derivedDisplaySetsNumber,
|
||||||
numImageFrames,
|
numImageFrames,
|
||||||
SeriesDescription,
|
SeriesDescription,
|
||||||
SeriesNumber,
|
SeriesNumber,
|
||||||
hasWarnings,
|
hasWarnings,
|
||||||
|
hasDerivedDisplaySets,
|
||||||
} = thumb;
|
} = thumb;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -48,12 +49,13 @@ function StudyBrowser(props) {
|
|||||||
// Thumb
|
// Thumb
|
||||||
altImageText={altImageText}
|
altImageText={altImageText}
|
||||||
imageId={imageId}
|
imageId={imageId}
|
||||||
InstanceNumber={InstanceNumber}
|
derivedDisplaySetsNumber={derivedDisplaySetsNumber}
|
||||||
displaySetInstanceUID={displaySetInstanceUID} // used by drop
|
displaySetInstanceUID={displaySetInstanceUID} // used by drop
|
||||||
numImageFrames={numImageFrames}
|
numImageFrames={numImageFrames}
|
||||||
SeriesDescription={SeriesDescription}
|
SeriesDescription={SeriesDescription}
|
||||||
SeriesNumber={SeriesNumber}
|
SeriesNumber={SeriesNumber}
|
||||||
hasWarnings={hasWarnings}
|
hasWarnings={hasWarnings}
|
||||||
|
hasDerivedDisplaySets={hasDerivedDisplaySets}
|
||||||
// Events
|
// Events
|
||||||
onClick={onThumbnailClick.bind(
|
onClick={onThumbnailClick.bind(
|
||||||
undefined,
|
undefined,
|
||||||
@@ -83,7 +85,7 @@ StudyBrowser.propTypes = {
|
|||||||
altImageText: PropTypes.string,
|
altImageText: PropTypes.string,
|
||||||
displaySetInstanceUID: PropTypes.string.isRequired,
|
displaySetInstanceUID: PropTypes.string.isRequired,
|
||||||
imageId: PropTypes.string,
|
imageId: PropTypes.string,
|
||||||
InstanceNumber: PropTypes.number,
|
derivedDisplaySetsNumber: PropTypes.number,
|
||||||
numImageFrames: PropTypes.number,
|
numImageFrames: PropTypes.number,
|
||||||
SeriesDescription: PropTypes.string,
|
SeriesDescription: PropTypes.string,
|
||||||
SeriesNumber: PropTypes.number,
|
SeriesNumber: PropTypes.number,
|
||||||
|
|||||||
@@ -15,11 +15,12 @@ const StudyLoadingListener = classes.StudyLoadingListener;
|
|||||||
function ThumbnailFooter({
|
function ThumbnailFooter({
|
||||||
SeriesDescription,
|
SeriesDescription,
|
||||||
SeriesNumber,
|
SeriesNumber,
|
||||||
InstanceNumber,
|
|
||||||
numImageFrames,
|
numImageFrames,
|
||||||
hasWarnings,
|
hasWarnings,
|
||||||
|
hasDerivedDisplaySets,
|
||||||
}) {
|
}) {
|
||||||
const [inconsistencyWarnings, inconsistencyWarningsSet] = useState([]);
|
const [inconsistencyWarnings, inconsistencyWarningsSet] = useState([]);
|
||||||
|
const [derivedDisplaySetsActive, derivedDisplaySetsActiveSet] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let unmounted = false;
|
let unmounted = false;
|
||||||
@@ -28,10 +29,15 @@ function ThumbnailFooter({
|
|||||||
inconsistencyWarningsSet(response);
|
inconsistencyWarningsSet(response);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
hasDerivedDisplaySets.then(response => {
|
||||||
|
if (!unmounted) {
|
||||||
|
derivedDisplaySetsActiveSet(response);
|
||||||
|
}
|
||||||
|
});
|
||||||
return () => {
|
return () => {
|
||||||
unmounted = true;
|
unmounted = true;
|
||||||
};
|
};
|
||||||
}, [hasWarnings]);
|
}, [hasWarnings, hasDerivedDisplaySets]);
|
||||||
|
|
||||||
const infoOnly = !SeriesDescription;
|
const infoOnly = !SeriesDescription;
|
||||||
|
|
||||||
@@ -88,20 +94,47 @@ function ThumbnailFooter({
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getDerivedInfo = derivedDisplaySetsActive => {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{derivedDisplaySetsActive ? (
|
||||||
|
<div className="derived">
|
||||||
|
<Icon name="link" />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<React.Fragment></React.Fragment>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const getSeriesInformation = (
|
const getSeriesInformation = (
|
||||||
SeriesNumber,
|
SeriesNumber,
|
||||||
InstanceNumber,
|
|
||||||
numImageFrames,
|
numImageFrames,
|
||||||
inconsistencyWarnings
|
inconsistencyWarnings,
|
||||||
|
derivedDisplaySetsActive
|
||||||
) => {
|
) => {
|
||||||
if (!SeriesNumber && !InstanceNumber && !numImageFrames) {
|
if (!SeriesNumber && !numImageFrames) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const seriesInformation = (
|
const seriesInformation = (
|
||||||
<div className="series-information">
|
<div className="series-information">
|
||||||
{getInfo(SeriesNumber, 'S:')}
|
<React.Fragment>
|
||||||
{getInfo(InstanceNumber, 'I:')}
|
{SeriesNumber !== undefined ? (
|
||||||
{getInfo(numImageFrames, '', 'image-frames')}
|
getInfo(SeriesNumber, 'S:')
|
||||||
|
) : (
|
||||||
|
<React.Fragment></React.Fragment>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
<React.Fragment>
|
||||||
|
{numImageFrames !== undefined ? (
|
||||||
|
getInfo(numImageFrames, '', 'image-frames')
|
||||||
|
) : (
|
||||||
|
<React.Fragment></React.Fragment>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
{getDerivedInfo(derivedDisplaySetsActive)}
|
||||||
{getWarningInfo(SeriesNumber, inconsistencyWarnings)}
|
{getWarningInfo(SeriesNumber, inconsistencyWarnings)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -114,9 +147,9 @@ function ThumbnailFooter({
|
|||||||
<div className="series-description">{SeriesDescription}</div>
|
<div className="series-description">{SeriesDescription}</div>
|
||||||
{getSeriesInformation(
|
{getSeriesInformation(
|
||||||
SeriesNumber,
|
SeriesNumber,
|
||||||
InstanceNumber,
|
|
||||||
numImageFrames,
|
numImageFrames,
|
||||||
inconsistencyWarnings
|
inconsistencyWarnings,
|
||||||
|
derivedDisplaySetsActive
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -130,11 +163,6 @@ function Thumbnail(props) {
|
|||||||
displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
imageId,
|
imageId,
|
||||||
imageSrc,
|
imageSrc,
|
||||||
InstanceNumber,
|
|
||||||
numImageFrames,
|
|
||||||
SeriesDescription,
|
|
||||||
SeriesNumber,
|
|
||||||
hasWarnings,
|
|
||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
onClick,
|
onClick,
|
||||||
onDoubleClick,
|
onDoubleClick,
|
||||||
@@ -232,8 +260,8 @@ Thumbnail.propTypes = {
|
|||||||
altImageText: PropTypes.string,
|
altImageText: PropTypes.string,
|
||||||
SeriesDescription: PropTypes.string,
|
SeriesDescription: PropTypes.string,
|
||||||
SeriesNumber: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
SeriesNumber: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
InstanceNumber: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
||||||
hasWarnings: PropTypes.instanceOf(Promise),
|
hasWarnings: PropTypes.instanceOf(Promise),
|
||||||
|
hasDerivedDisplaySets: PropTypes.instanceOf(Promise),
|
||||||
numImageFrames: PropTypes.number,
|
numImageFrames: PropTypes.number,
|
||||||
onDoubleClick: PropTypes.func,
|
onDoubleClick: PropTypes.func,
|
||||||
onClick: PropTypes.func,
|
onClick: PropTypes.func,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ const SnackbarProvider = ({ children, service }) => {
|
|||||||
LogManager.subscribe(LogManager.EVENTS.OnLog, onLogHandler);
|
LogManager.subscribe(LogManager.EVENTS.OnLog, onLogHandler);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
LogManager.subscribe(LogManager.EVENTS.OnLog, onLogHandler);
|
LogManager.unsubscribe(LogManager.EVENTS.OnLog, onLogHandler);
|
||||||
};
|
};
|
||||||
}, [show]);
|
}, [show]);
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,16 @@ const PROXY_TARGET = process.env.PROXY_TARGET;
|
|||||||
const PROXY_DOMAIN = process.env.PROXY_DOMAIN;
|
const PROXY_DOMAIN = process.env.PROXY_DOMAIN;
|
||||||
const ENTRY_TARGET = process.env.ENTRY_TARGET || `${SRC_DIR}/index.js`;
|
const ENTRY_TARGET = process.env.ENTRY_TARGET || `${SRC_DIR}/index.js`;
|
||||||
|
|
||||||
|
|
||||||
|
const setHeaders = (res, path) => {
|
||||||
|
res.setHeader('Content-Type', 'text/plain')
|
||||||
|
if (path.indexOf('.gz') !== -1) {
|
||||||
|
res.setHeader('Content-Encoding', 'gzip')
|
||||||
|
} else if (path.indexOf('.br') !== -1) {
|
||||||
|
res.setHeader('Content-Encoding', 'br')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = (env, argv) => {
|
module.exports = (env, argv) => {
|
||||||
const baseConfig = webpackBase(env, argv, { SRC_DIR, DIST_DIR });
|
const baseConfig = webpackBase(env, argv, { SRC_DIR, DIST_DIR });
|
||||||
const isProdBuild = process.env.NODE_ENV === 'production';
|
const isProdBuild = process.env.NODE_ENV === 'production';
|
||||||
@@ -134,11 +144,40 @@ module.exports = (env, argv) => {
|
|||||||
hot: true,
|
hot: true,
|
||||||
open: true,
|
open: true,
|
||||||
port: 3000,
|
port: 3000,
|
||||||
host: '0.0.0.0',
|
client: {
|
||||||
public: 'http://localhost:' + 3000,
|
overlay: { errors: true, warnings: false },
|
||||||
|
},
|
||||||
|
'static': [
|
||||||
|
{
|
||||||
|
directory: path.join(require('os').homedir(), 'dicomweb'),
|
||||||
|
staticOptions: {
|
||||||
|
extensions: ['gz', 'br'],
|
||||||
|
index: "index.json.gz",
|
||||||
|
redirect: true,
|
||||||
|
setHeaders,
|
||||||
|
},
|
||||||
|
publicPath: '/dicomweb',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
directory: '../../testdata',
|
||||||
|
staticOptions: {
|
||||||
|
extensions: ['gz', 'br'],
|
||||||
|
index: "index.json.gz",
|
||||||
|
redirect: true,
|
||||||
|
setHeaders,
|
||||||
|
},
|
||||||
|
publicPath: '/testdata',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
//public: 'http://localhost:' + 3000,
|
||||||
|
//writeToDisk: true,
|
||||||
historyApiFallback: {
|
historyApiFallback: {
|
||||||
disableDotRule: true,
|
disableDotRule: true,
|
||||||
},
|
},
|
||||||
|
headers: {
|
||||||
|
'Cross-Origin-Embedder-Policy': 'require-corp',
|
||||||
|
'Cross-Origin-Opener-Policy': 'same-origin',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,102 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [4.12.13](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.12...@ohif/viewer@4.12.13) (2022-01-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.12](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.11...@ohif/viewer@4.12.12) (2022-01-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.11](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.10...@ohif/viewer@4.12.11) (2022-01-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.10](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.9...@ohif/viewer@4.12.10) (2022-01-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.9](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.8...@ohif/viewer@4.12.9) (2021-12-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.8](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.7...@ohif/viewer@4.12.8) (2021-12-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.7](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.6...@ohif/viewer@4.12.7) (2021-12-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.6](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.5...@ohif/viewer@4.12.6) (2021-11-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.5](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.4...@ohif/viewer@4.12.5) (2021-10-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.4](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.3...@ohif/viewer@4.12.4) (2021-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.3](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.2...@ohif/viewer@4.12.3) (2021-10-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.2](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.1...@ohif/viewer@4.12.2) (2021-10-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.12.1](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.0...@ohif/viewer@4.12.1) (2021-10-06)
|
## [4.12.1](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.0...@ohif/viewer@4.12.1) (2021-10-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/viewer
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ describe('OHIF Save Measurements', function() {
|
|||||||
// cy.get('.sb-closeIcon').click();
|
// cy.get('.sb-closeIcon').click();
|
||||||
// });
|
// });
|
||||||
|
|
||||||
it('checks if warning message is displayed on measurements of unsupported tools', function() {
|
/*it('checks if warning message is displayed on measurements of unsupported tools', function() {
|
||||||
// Add measurement for unsupported tool in the viewport
|
// Add measurement for unsupported tool in the viewport
|
||||||
cy.addAngleMeasurement();
|
cy.addAngleMeasurement();
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ describe('OHIF Save Measurements', function() {
|
|||||||
|
|
||||||
// Close Measurements panel
|
// Close Measurements panel
|
||||||
cy.get('@measurementsBtn').click();
|
cy.get('@measurementsBtn').click();
|
||||||
});
|
});*/
|
||||||
|
|
||||||
/*it('checks if measurements of unsupported tools were not saved', function() {
|
/*it('checks if measurements of unsupported tools were not saved', function() {
|
||||||
// Add measurement for supported tool in the viewport
|
// Add measurement for supported tool in the viewport
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import '@percy/cypress';
|
import '@percy/cypress';
|
||||||
|
import { enable } from 'cornerstone-core';
|
||||||
import 'cypress-file-upload';
|
import 'cypress-file-upload';
|
||||||
import { DragSimulator } from '../helpers/DragSimulator.js';
|
import { DragSimulator } from '../helpers/DragSimulator.js';
|
||||||
import {
|
import {
|
||||||
@@ -199,6 +200,11 @@ Cypress.Commands.add('waitDicomImage', (timeout = 50000) => {
|
|||||||
.its('cornerstone')
|
.its('cornerstone')
|
||||||
.then({ timeout }, $cornerstone => {
|
.then({ timeout }, $cornerstone => {
|
||||||
return new Cypress.Promise(resolve => {
|
return new Cypress.Promise(resolve => {
|
||||||
|
const onEnabled = enabledEvt => {
|
||||||
|
const element = enabledEvt.detail.element;
|
||||||
|
|
||||||
|
element.addEventListener('cornerstoneimagerendered', onEvent);
|
||||||
|
};
|
||||||
const onEvent = renderedEvt => {
|
const onEvent = renderedEvt => {
|
||||||
const element = renderedEvt.detail.element;
|
const element = renderedEvt.detail.element;
|
||||||
|
|
||||||
@@ -209,15 +215,17 @@ Cypress.Commands.add('waitDicomImage', (timeout = 50000) => {
|
|||||||
);
|
);
|
||||||
resolve();
|
resolve();
|
||||||
};
|
};
|
||||||
const onEnabled = enabledEvt => {
|
const enabledElements = $cornerstone.getEnabledElements();
|
||||||
const element = enabledEvt.detail.element;
|
if (enabledElements && enabledElements.length && !enabledElements[0].invalid) {
|
||||||
|
// Sometimes the page finishes rendering before this gets run,
|
||||||
element.addEventListener('cornerstoneimagerendered', onEvent);
|
// if so, just resolve immediately.
|
||||||
};
|
resolve();
|
||||||
$cornerstone.events.addEventListener(
|
} else {
|
||||||
'cornerstoneelementenabled',
|
$cornerstone.events.addEventListener(
|
||||||
onEnabled
|
'cornerstoneelementenabled',
|
||||||
);
|
onEnabled
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/viewer",
|
"name": "@ohif/viewer",
|
||||||
"version": "4.12.1",
|
"version": "4.12.13",
|
||||||
"description": "OHIF Viewer",
|
"description": "OHIF Viewer",
|
||||||
"author": "OHIF Contributors",
|
"author": "OHIF Contributors",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -22,8 +22,8 @@
|
|||||||
"build:viewer:ci": "cross-env NODE_ENV=production PUBLIC_URL=/pwa/ APP_CONFIG=config/netlify.js QUICK_BUILD=true node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --config .webpack/webpack.pwa.js",
|
"build:viewer:ci": "cross-env NODE_ENV=production PUBLIC_URL=/pwa/ APP_CONFIG=config/netlify.js QUICK_BUILD=true node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --config .webpack/webpack.pwa.js",
|
||||||
"build:viewer:demo": "cross-env NODE_ENV=production APP_CONFIG=config/demo.js HTML_TEMPLATE=rollbar.html QUICK_BUILD=true node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --progress --config .webpack/webpack.pwa.js",
|
"build:viewer:demo": "cross-env NODE_ENV=production APP_CONFIG=config/demo.js HTML_TEMPLATE=rollbar.html QUICK_BUILD=true node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --progress --config .webpack/webpack.pwa.js",
|
||||||
"build:viewer:package": "yarn run build:package",
|
"build:viewer:package": "yarn run build:package",
|
||||||
"dev": "cross-env NODE_ENV=development webpack-dev-server --config .webpack/webpack.pwa.js --watch",
|
"dev": "cross-env NODE_ENV=development webpack-dev-server --config .webpack/webpack.pwa.js",
|
||||||
"dev:orthanc": "cross-env NODE_ENV=development PROXY_TARGET=/dicom-web PROXY_DOMAIN=http://localhost:8042 APP_CONFIG=config/docker_nginx-orthanc.js webpack-dev-server --config .webpack/webpack.pwa.js --watch",
|
"dev:orthanc": "cross-env NODE_ENV=development PROXY_TARGET=/dicom-web PROXY_DOMAIN=http://localhost:8042 APP_CONFIG=config/docker_nginx-orthanc.js webpack-dev-server --config .webpack/webpack.pwa.js",
|
||||||
"dev:viewer": "yarn run dev",
|
"dev:viewer": "yarn run dev",
|
||||||
"start": "yarn run dev",
|
"start": "yarn run dev",
|
||||||
"test:e2e": "cypress open",
|
"test:e2e": "cypress open",
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"test:e2e:script-tag": "cypress run --config video=false --browser chrome --spec 'cypress/integration/common/**/*,cypress/integration/script-tag/**/*'",
|
"test:e2e:script-tag": "cypress run --config video=false --browser chrome --spec 'cypress/integration/common/**/*,cypress/integration/script-tag/**/*'",
|
||||||
"test:e2e:local": "cypress run --config video=false --browser chrome --spec 'cypress/integration/common/**/*,cypress/integration/pwa/**/*'",
|
"test:e2e:local": "cypress run --config video=false --browser chrome --spec 'cypress/integration/common/**/*,cypress/integration/pwa/**/*'",
|
||||||
"test:e2e:dist": "start-server-and-test test:e2e:serve http://localhost:3000 test:e2e:ci",
|
"test:e2e:dist": "start-server-and-test test:e2e:serve http://localhost:3000 test:e2e:ci",
|
||||||
"test:e2e:serve": "serve -n -l 3000 -s dist",
|
"test:e2e:serve": "cross-env APP_CONFIG=config/e2e.js yarn start",
|
||||||
"test:unit": "jest --watchAll",
|
"test:unit": "jest --watchAll",
|
||||||
"test:unit:ci": "jest --ci --runInBand --collectCoverage",
|
"test:unit:ci": "jest --ci --runInBand --collectCoverage",
|
||||||
"prepublishOnly": "yarn run build:package",
|
"prepublishOnly": "yarn run build:package",
|
||||||
@@ -47,28 +47,28 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.5.5",
|
||||||
"@ohif/core": "^2.16.0",
|
"@ohif/core": "^2.16.8",
|
||||||
"@ohif/extension-cornerstone": "^2.12.1",
|
"@ohif/extension-cornerstone": "^2.12.4",
|
||||||
"@ohif/extension-debugging": "^0.3.0",
|
"@ohif/extension-debugging": "^0.3.1",
|
||||||
"@ohif/extension-dicom-html": "^1.3.11",
|
"@ohif/extension-dicom-html": "^1.3.15",
|
||||||
"@ohif/extension-dicom-microscopy": "^0.52.0",
|
"@ohif/extension-dicom-microscopy": "^0.52.0",
|
||||||
"@ohif/extension-dicom-pdf": "^1.1.0",
|
"@ohif/extension-dicom-pdf": "^1.1.2",
|
||||||
"@ohif/extension-dicom-rt": "^0.7.2",
|
"@ohif/extension-dicom-rt": "^0.7.6",
|
||||||
"@ohif/extension-dicom-segmentation": "^0.7.2",
|
"@ohif/extension-dicom-segmentation": "^0.7.6",
|
||||||
"@ohif/extension-lesion-tracker": "^0.2.1",
|
"@ohif/extension-lesion-tracker": "^0.2.1",
|
||||||
"@ohif/extension-vtk": "^1.12.3",
|
"@ohif/extension-vtk": "^1.12.12",
|
||||||
"@ohif/i18n": "^0.53.0",
|
"@ohif/i18n": "^0.53.0",
|
||||||
"@ohif/ui": "^1.10.2",
|
"@ohif/ui": "^1.10.5",
|
||||||
"@tanem/react-nprogress": "^1.1.25",
|
"@tanem/react-nprogress": "^1.1.25",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"core-js": "^3.2.1",
|
"core-js": "^3.2.1",
|
||||||
"cornerstone-core": "^2.5.0",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-math": "^0.1.9",
|
"cornerstone-math": "^0.1.9",
|
||||||
"cornerstone-tools": "^6.0.0",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"cornerstone-wado-image-loader": "^4.0.3",
|
"cornerstone-wado-image-loader": "^4.1.0",
|
||||||
"dcmjs": "0.18.9",
|
"dcmjs": "0.19.2",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.11",
|
||||||
"dicomweb-client": "^0.8.1",
|
"dicomweb-client": "^0.8.3",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"i18next": "^17.0.3",
|
"i18next": "^17.0.3",
|
||||||
"i18next-browser-languagedetector": "^3.0.1",
|
"i18next-browser-languagedetector": "^3.0.1",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ window.config = {
|
|||||||
displaySetCount: 3,
|
displaySetCount: 3,
|
||||||
preventCache: false,
|
preventCache: false,
|
||||||
prefetchDisplaySetsTimeout: 300,
|
prefetchDisplaySetsTimeout: 300,
|
||||||
|
maxNumPrefetchRequests: 100,
|
||||||
displayProgress: true,
|
displayProgress: true,
|
||||||
includeActiveDisplaySet: true,
|
includeActiveDisplaySet: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
window.config = {
|
||||||
|
routerBasename: '/',
|
||||||
|
showStudyList: true,
|
||||||
|
servers: {
|
||||||
|
dicomWeb: [
|
||||||
|
{
|
||||||
|
name: 'LocalStatic',
|
||||||
|
wadoUriRoot: '/testdata',
|
||||||
|
qidoRoot: '/testdata',
|
||||||
|
wadoRoot: '/testdata',
|
||||||
|
qidoSupportsIncludeField: false,
|
||||||
|
imageRendering: 'wadors',
|
||||||
|
enableStudyLazyLoad: true,
|
||||||
|
supportsFuzzyMatching: false,
|
||||||
|
staticWado: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Extensions should be able to suggest default values for these?
|
||||||
|
// Or we can require that these be explicitly set
|
||||||
|
hotkeys: [
|
||||||
|
// ~ Global
|
||||||
|
{
|
||||||
|
commandName: 'incrementActiveViewport',
|
||||||
|
label: 'Next Viewport',
|
||||||
|
keys: ['right'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'decrementActiveViewport',
|
||||||
|
label: 'Previous Viewport',
|
||||||
|
keys: ['left'],
|
||||||
|
},
|
||||||
|
// Supported Keys: https://craig.is/killing/mice
|
||||||
|
// ~ Cornerstone Extension
|
||||||
|
{ commandName: 'rotateViewportCW', label: 'Rotate Right', keys: ['r'] },
|
||||||
|
{ commandName: 'rotateViewportCCW', label: 'Rotate Left', keys: ['l'] },
|
||||||
|
{ commandName: 'invertViewport', label: 'Invert', keys: ['i'] },
|
||||||
|
{
|
||||||
|
commandName: 'flipViewportVertical',
|
||||||
|
label: 'Flip Horizontally',
|
||||||
|
keys: ['h'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'flipViewportHorizontal',
|
||||||
|
label: 'Flip Vertically',
|
||||||
|
keys: ['v'],
|
||||||
|
},
|
||||||
|
{ commandName: 'scaleUpViewport', label: 'Zoom In', keys: ['+'] },
|
||||||
|
{ commandName: 'scaleDownViewport', label: 'Zoom Out', keys: ['-'] },
|
||||||
|
{ commandName: 'fitViewportToWindow', label: 'Zoom to Fit', keys: ['='] },
|
||||||
|
{ commandName: 'resetViewport', label: 'Reset', keys: ['space'] },
|
||||||
|
// clearAnnotations
|
||||||
|
{ commandName: 'nextImage', label: 'Next Image', keys: ['down'] },
|
||||||
|
{ commandName: 'previousImage', label: 'Previous Image', keys: ['up'] },
|
||||||
|
// firstImage
|
||||||
|
// lastImage
|
||||||
|
{
|
||||||
|
commandName: 'previousViewportDisplaySet',
|
||||||
|
label: 'Previous Series',
|
||||||
|
keys: ['pagedown'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'nextViewportDisplaySet',
|
||||||
|
label: 'Next Series',
|
||||||
|
keys: ['pageup'],
|
||||||
|
},
|
||||||
|
// ~ Cornerstone Tools
|
||||||
|
{ commandName: 'setZoomTool', label: 'Zoom', keys: ['z'] },
|
||||||
|
// ~ Window level presets
|
||||||
|
{
|
||||||
|
commandName: 'windowLevelPreset1',
|
||||||
|
label: 'W/L Preset 1',
|
||||||
|
keys: ['1'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'windowLevelPreset2',
|
||||||
|
label: 'W/L Preset 2',
|
||||||
|
keys: ['2'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'windowLevelPreset3',
|
||||||
|
label: 'W/L Preset 3',
|
||||||
|
keys: ['3'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'windowLevelPreset4',
|
||||||
|
label: 'W/L Preset 4',
|
||||||
|
keys: ['4'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'windowLevelPreset5',
|
||||||
|
label: 'W/L Preset 5',
|
||||||
|
keys: ['5'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'windowLevelPreset6',
|
||||||
|
label: 'W/L Preset 6',
|
||||||
|
keys: ['6'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'windowLevelPreset7',
|
||||||
|
label: 'W/L Preset 7',
|
||||||
|
keys: ['7'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'windowLevelPreset8',
|
||||||
|
label: 'W/L Preset 8',
|
||||||
|
keys: ['8'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'windowLevelPreset9',
|
||||||
|
label: 'W/L Preset 9',
|
||||||
|
keys: ['9'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -5,9 +5,9 @@ window.config = {
|
|||||||
dicomWeb: [
|
dicomWeb: [
|
||||||
{
|
{
|
||||||
name: 'LocalStatic',
|
name: 'LocalStatic',
|
||||||
wadoUriRoot: 'http://localhost:5000/',
|
wadoUriRoot: '/dicomweb',
|
||||||
qidoRoot: 'http://localhost:5000',
|
qidoRoot: '/dicomweb',
|
||||||
wadoRoot: 'http://localhost:5000/',
|
wadoRoot: '/dicomweb',
|
||||||
qidoSupportsIncludeField: false,
|
qidoSupportsIncludeField: false,
|
||||||
imageRendering: 'wadors',
|
imageRendering: 'wadors',
|
||||||
thumbnailRendering: 'thumbnail',
|
thumbnailRendering: 'thumbnail',
|
||||||
|
|||||||
@@ -14,13 +14,11 @@ const mapDispatchToProps = (dispatch, ownProps) => {
|
|||||||
displaySetInstanceUID
|
displaySetInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { LoggerService, UINotificationService } = servicesManager.services;
|
||||||
|
|
||||||
if (displaySet.isDerived) {
|
if (displaySet.isDerived) {
|
||||||
const { Modality } = displaySet;
|
const { Modality } = displaySet;
|
||||||
if (Modality === 'SEG' && servicesManager) {
|
if (Modality === 'SEG' && servicesManager) {
|
||||||
const {
|
|
||||||
LoggerService,
|
|
||||||
UINotificationService,
|
|
||||||
} = servicesManager.services;
|
|
||||||
const onDisplaySetLoadFailureHandler = error => {
|
const onDisplaySetLoadFailureHandler = error => {
|
||||||
LoggerService.error({ error, message: error.message });
|
LoggerService.error({ error, message: error.message });
|
||||||
UINotificationService.show({
|
UINotificationService.show({
|
||||||
@@ -55,14 +53,42 @@ const mapDispatchToProps = (dispatch, ownProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!displaySet) {
|
if (!displaySet) {
|
||||||
throw new Error(
|
const error = new Error(
|
||||||
`Referenced series for ${Modality} dataset not present.`
|
`Referenced series for ${Modality} dataset not present.`
|
||||||
);
|
);
|
||||||
|
const message = `Referenced series for ${Modality} dataset not present.`;
|
||||||
|
LoggerService.error({ error, message });
|
||||||
|
UINotificationService.show({
|
||||||
|
autoClose: false,
|
||||||
|
title: 'Fail to load series',
|
||||||
|
message,
|
||||||
|
type: 'error',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!displaySet) {
|
if (!displaySet) {
|
||||||
throw new Error('Source data not present');
|
const error = new Error('Source data not present');
|
||||||
}
|
const message = 'Source data not present';
|
||||||
|
LoggerService.error({ error, message });
|
||||||
|
UINotificationService.show({
|
||||||
|
autoClose: false,
|
||||||
|
title: 'Fail to load series',
|
||||||
|
message,
|
||||||
|
type: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displaySet.isModalitySupported === false) {
|
||||||
|
const error = new Error('Modality not supported');
|
||||||
|
const message = 'Modality not supported';
|
||||||
|
LoggerService.error({ error, message });
|
||||||
|
UINotificationService.show({
|
||||||
|
autoClose: false,
|
||||||
|
title: 'Fail to load series',
|
||||||
|
message,
|
||||||
|
type: 'error',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(setActiveViewportSpecificData(displaySet));
|
dispatch(setActiveViewportSpecificData(displaySet));
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import './Viewer.css';
|
|||||||
import StudyPrefetcher from '../components/StudyPrefetcher.js';
|
import StudyPrefetcher from '../components/StudyPrefetcher.js';
|
||||||
import StudyLoadingMonitor from '../components/StudyLoadingMonitor';
|
import StudyLoadingMonitor from '../components/StudyLoadingMonitor';
|
||||||
|
|
||||||
|
const { studyMetadataManager } = OHIF.utils;
|
||||||
|
|
||||||
class Viewer extends Component {
|
class Viewer extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
studies: PropTypes.arrayOf(
|
studies: PropTypes.arrayOf(
|
||||||
@@ -429,6 +431,31 @@ class Viewer extends Component {
|
|||||||
|
|
||||||
export default withDialog(Viewer);
|
export default withDialog(Viewer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Async function to check if the displaySet has any derived one
|
||||||
|
*
|
||||||
|
* @param {*object} displaySet
|
||||||
|
* @param {*object} study
|
||||||
|
* @returns {bool}
|
||||||
|
*/
|
||||||
|
const _checkForDerivedDisplaySets = async function(displaySet, study) {
|
||||||
|
let derivedDisplaySetsNumber = 0;
|
||||||
|
if (
|
||||||
|
displaySet.Modality &&
|
||||||
|
!['SEG', 'SR', 'RTSTRUCT', 'RTDOSE'].includes(displaySet.Modality)
|
||||||
|
) {
|
||||||
|
const studyMetadata = studyMetadataManager.get(study.StudyInstanceUID);
|
||||||
|
|
||||||
|
const derivedDisplaySets = studyMetadata.getDerivedDatasets({
|
||||||
|
referencedSeriesInstanceUID: displaySet.SeriesInstanceUID,
|
||||||
|
});
|
||||||
|
|
||||||
|
derivedDisplaySetsNumber = derivedDisplaySets.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return derivedDisplaySetsNumber > 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Async function to check if there are any inconsistences in the series.
|
* Async function to check if there are any inconsistences in the series.
|
||||||
*
|
*
|
||||||
@@ -513,6 +540,10 @@ const _checkForSeriesInconsistencesWarnings = async function(
|
|||||||
'The datasets is missing frames: ' + displaySet.missingFrames + '.'
|
'The datasets is missing frames: ' + displaySet.missingFrames + '.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (displaySet.isModalitySupported === false) {
|
||||||
|
inconsistencyWarnings.push('The datasets modality is not supported.');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const segMetadata = displaySet.metadata;
|
const segMetadata = displaySet.metadata;
|
||||||
if (!segMetadata) {
|
if (!segMetadata) {
|
||||||
@@ -684,7 +715,6 @@ const _mapStudiesToThumbnails = function(studies, activeDisplaySetInstanceUID) {
|
|||||||
const {
|
const {
|
||||||
displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
SeriesDescription,
|
SeriesDescription,
|
||||||
InstanceNumber,
|
|
||||||
numImageFrames,
|
numImageFrames,
|
||||||
SeriesNumber,
|
SeriesNumber,
|
||||||
} = displaySet;
|
} = displaySet;
|
||||||
@@ -709,6 +739,11 @@ const _mapStudiesToThumbnails = function(studies, activeDisplaySetInstanceUID) {
|
|||||||
studies
|
studies
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const hasDerivedDisplaySets = _checkForDerivedDisplaySets(
|
||||||
|
displaySet,
|
||||||
|
study
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
active: _isDisplaySetActive(
|
active: _isDisplaySetActive(
|
||||||
displaySet,
|
displaySet,
|
||||||
@@ -719,10 +754,10 @@ const _mapStudiesToThumbnails = function(studies, activeDisplaySetInstanceUID) {
|
|||||||
altImageText,
|
altImageText,
|
||||||
displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
SeriesDescription,
|
SeriesDescription,
|
||||||
InstanceNumber,
|
|
||||||
numImageFrames,
|
numImageFrames,
|
||||||
SeriesNumber,
|
SeriesNumber,
|
||||||
hasWarnings,
|
hasWarnings,
|
||||||
|
hasDerivedDisplaySets,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -139,10 +139,11 @@ class ViewerMain extends Component {
|
|||||||
displaySetInstanceUID
|
displaySetInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { LoggerService, UINotificationService } = servicesManager.services;
|
||||||
|
|
||||||
if (displaySet.isDerived) {
|
if (displaySet.isDerived) {
|
||||||
const { Modality } = displaySet;
|
const { Modality } = displaySet;
|
||||||
if (Modality === 'SEG' && servicesManager) {
|
if (Modality === 'SEG' && servicesManager) {
|
||||||
const {LoggerService, UINotificationService} = servicesManager.services;
|
|
||||||
const onDisplaySetLoadFailureHandler = error => {
|
const onDisplaySetLoadFailureHandler = error => {
|
||||||
LoggerService.error({ error, message: error.message });
|
LoggerService.error({ error, message: error.message });
|
||||||
UINotificationService.show({
|
UINotificationService.show({
|
||||||
@@ -153,24 +154,41 @@ class ViewerMain extends Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const {referencedDisplaySet} = displaySet.getSourceDisplaySet(
|
const { referencedDisplaySet } = displaySet.getSourceDisplaySet(
|
||||||
this.props.studies,
|
this.props.studies,
|
||||||
true,
|
true,
|
||||||
onDisplaySetLoadFailureHandler
|
onDisplaySetLoadFailureHandler
|
||||||
);
|
);
|
||||||
displaySet = referencedDisplaySet;
|
displaySet = referencedDisplaySet;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
displaySet = displaySet.getSourceDisplaySet(this.props.studies);
|
displaySet = displaySet.getSourceDisplaySet(this.props.studies);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!displaySet) {
|
if (!displaySet) {
|
||||||
throw new Error(
|
const error = new Error('Source data not present');
|
||||||
`Referenced series for ${Modality} dataset not present.`
|
const message = 'Source data not present';
|
||||||
);
|
LoggerService.error({ error, message });
|
||||||
|
UINotificationService.show({
|
||||||
|
autoClose: false,
|
||||||
|
title: 'Fail to load series',
|
||||||
|
message,
|
||||||
|
type: 'error',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (displaySet.isModalitySupported === false) {
|
||||||
|
const error = new Error('Modality not supported');
|
||||||
|
const message = 'Modality not supported';
|
||||||
|
LoggerService.error({ error, message });
|
||||||
|
UINotificationService.show({
|
||||||
|
autoClose: false,
|
||||||
|
title: 'Fail to load series',
|
||||||
|
message,
|
||||||
|
type: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.props.setViewportSpecificData(viewportIndex, displaySet);
|
this.props.setViewportSpecificData(viewportIndex, displaySet);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
3.7
|
||||||
Submodule
+1
Submodule testdata added at 47d51e15a0.
Reference in new issue
Block a user