Compare commits

..
Author SHA1 Message Date
ohif-bot eaa423c64e chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.36
 - @ohif/core@2.16.30
 - @ohif/viewer@4.12.42
2022-10-25 14:09:04 +00:00
Gitanjali f7db74a843 fix: 2965 Correct Parsing Logic for Qualitative Instance Level SR (#2972)
* fix: 2965 Correct Parsing Logic for Qualitative Instance Level SR

* fix: 2965 Correct Parsing Logic for Qualitative Instance Level SR

* fix: 2965 Correct Parsing Logic for Qualitative Instance Level SR
2022-10-25 10:06:59 -04:00
ohif-bot 7aba01f534 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.35
 - @ohif/viewer@4.12.41
2022-09-26 14:42:01 +00:00
GitanjaliChhetri c5ebeaa127 Re IDC #2847: Fix 2d MPR rendering issue for the sagittal view (#2960) 2022-09-26 08:39:55 -06:00
ohif-bot d7e1d2c975 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.15
 - @ohif/extension-vtk@1.12.34
 - @ohif/core@2.16.29
 - @ohif/viewer@4.12.40
2022-09-20 11:26:05 +00:00
Davide Punzo eb7eb56d7e Re IDC #2934: update cornerstoneWADOImageLoader to v 4.2.1 (#2944) 2022-09-20 13:24:17 +02:00
ohif-bot c5ee092bf2 chore(release): publish [skip ci]
- @ohif/extension-dicom-segmentation@0.7.15
 - @ohif/extension-vtk@1.12.33
 - @ohif/core@2.16.28
 - @ohif/viewer@4.12.39
2022-09-19 10:32:07 +00:00
Davide Punzo e2f4f95222 Re IDC #2935: fix parsing of Instance-level qualitative annotations (#2940) 2022-09-19 12:29:28 +02:00
ohif-bot 4546ede9bb chore(release): publish [skip ci]
- @ohif/extension-dicom-segmentation@0.7.14
 - @ohif/viewer@4.12.38
2022-09-12 12:24:25 +00:00
Davide Punzo e0fb439e98 Fix IDC Re #2918: Runtime tolerance for SEGs loading (#2924) 2022-09-12 14:22:32 +02:00
ohif-bot ebbc9e0d6d chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.32
 - @ohif/core@2.16.27
 - @ohif/viewer@4.12.37
2022-09-12 08:27:33 +00:00
Davide Punzo 47a6130fd5 Re IDC #2919: fix popup notifications behavior (#2923) 2022-09-12 10:25:19 +02:00
ohif-bot 80dfdcc37c chore(release): publish [skip ci]
- @ohif/viewer@4.12.36
2022-09-08 14:48:41 +00:00
Doug Horner d74ad370e0 fix: hotkey page up/down did not work (#2910) 2022-09-08 10:46:26 -04:00
ohif-bot ddfde9279e chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.31
 - @ohif/core@2.16.26
 - @ohif/viewer@4.12.35
2022-09-02 13:49:07 +00:00
Davide Punzo aaab6d2622 Re IDC #2849: raise error if dicom request is not conforming with the UID (DICOM UI VR) character repertoire. (#2908) 2022-09-02 15:47:28 +02:00
ohif-bot d2921083e7 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.14
 - @ohif/extension-dicom-html@1.3.23
 - @ohif/extension-dicom-rt@0.7.13
 - @ohif/extension-dicom-segmentation@0.7.13
 - @ohif/extension-dicom-tag-browser@0.2.24
 - @ohif/extension-vtk@1.12.30
 - @ohif/core@2.16.25
 - @ohif/viewer@4.12.34
2022-09-01 18:14:46 +00:00
Davide Punzo a6338ea266 Re IDC #2869: update dcmjs for fixing eps in nearly equal condition (#2906) 2022-09-01 20:12:30 +02:00
ohif-bot fe9551b9b1 chore(release): publish [skip ci]
- @ohif/extension-dicom-rt@0.7.12
 - @ohif/extension-dicom-segmentation@0.7.12
 - @ohif/extension-vtk@1.12.29
 - @ohif/core@2.16.24
 - @ohif/viewer@4.12.33
2022-08-31 12:59:14 +00:00
Davide Punzo ef60156a47 Fix minor issues IDC (#2903) 2022-08-31 14:57:14 +02:00
ohif-bot 850de2903a chore(release): publish [skip ci]
- @ohif/viewer@4.12.32
2022-08-25 09:50:05 +00:00
Davide Punzo f26ed5539b IDC2859 (#2891)
* Re #2859 IDC: disable jump to for measurements in MPR mode
2022-08-25 11:48:20 +02:00
ohif-bot 21aeaa63c7 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.28
 - @ohif/core@2.16.23
 - @ohif/ui@1.10.10
 - @ohif/viewer@4.12.31
2022-08-24 10:38:46 +00:00
Davide Punzo 2ac0d3f017 Re #2852 IDC: fix parsing of qualitative slice annotation (#2888) 2022-08-24 12:37:21 +02:00
ohif-bot efdbe8e7b4 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.13
 - @ohif/extension-debugging@0.3.3
 - @ohif/extension-dicom-html@1.3.22
 - @ohif/extension-vtk@1.12.27
 - @ohif/core@2.16.22
 - @ohif/viewer@4.12.30
2022-06-30 10:07:05 +00:00
Davide Punzo 67b70eaa98 IDC2797: add linking and report UI for SR displaySets (#2834) 2022-06-30 12:05:47 +02:00
ohif-bot 5150ed9427 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.12
 - @ohif/extension-lesion-tracker@0.2.2
 - @ohif/extension-vtk@1.12.26
 - @ohif/core@2.16.21
 - @ohif/ui@1.10.9
 - @ohif/viewer@4.12.29
2022-06-29 02:26:24 +00:00
Davide Punzo 1bcb0acf9f IDC2797: improving UI for SR qualitative measurements and bug fixes (#2832) 2022-06-29 04:24:35 +02:00
ohif-bot 5d6cf2a609 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.25
 - @ohif/core@2.16.20
 - @ohif/viewer@4.12.28
2022-06-28 11:18:54 +00:00
Davide Punzo 9f813e0ea0 fix: Re IDC2797, fix double parsing of SR qualitative annotations (#2830) 2022-06-28 13:17:16 +02:00
ohif-bot 49de44ba34 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.11
 - @ohif/extension-vtk@1.12.24
 - @ohif/core@2.16.19
 - @ohif/viewer@4.12.27
2022-06-14 12:14:35 +00:00
Davide Punzo b04e186274 feat IDC #2797: add support for SR qualitative annotation per instance (#2822) 2022-06-14 14:12:27 +02:00
ohif-bot c59d66412f chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.23
 - @ohif/core@2.16.18
 - @ohif/viewer@4.12.26
2022-04-22 08:54:26 +00:00
Davide Punzo f8b4ccbb59 IDC: Fix undefined return in getDerivedDatasets (#2784) 2022-04-22 10:53:01 +02:00
ohif-bot 5426773ffc chore(release): publish [skip ci]
- @ohif/extension-dicom-tag-browser@0.2.23
 - @ohif/extension-vtk@1.12.22
 - @ohif/core@2.16.17
 - @ohif/ui@1.10.8
 - @ohif/viewer@4.12.25
2022-04-06 16:24:23 +00:00
Davide Punzo a507a00f59 Fix thumbnail loading bar (#2772) 2022-04-06 18:23:02 +02:00
Davide Punzo cedeb756c0 Re IDC #2762: fix thumbnail series type for unsupported SOPClassUID (#2770) 2022-04-06 17:10:00 +02:00
ohif-bot 64385485b6 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.10
 - @ohif/extension-dicom-html@1.3.21
 - @ohif/extension-dicom-rt@0.7.11
 - @ohif/extension-dicom-segmentation@0.7.11
 - @ohif/extension-dicom-tag-browser@0.2.22
 - @ohif/extension-vtk@1.12.21
 - @ohif/core@2.16.16
 - @ohif/viewer@4.12.24
2022-04-05 07:40:48 +00:00
Davide Punzo 32828d9a6e Re IDC #2765: fix loading of segmentations at first startup (#2768)
Re IDC #2761: fix loading of segmentations

update dcmjs to 0.19.9
2022-04-05 09:39:22 +02:00
ohif-bot b94d4782d1 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.9
 - @ohif/extension-dicom-html@1.3.20
 - @ohif/extension-dicom-rt@0.7.10
 - @ohif/extension-dicom-segmentation@0.7.10
 - @ohif/extension-dicom-tag-browser@0.2.21
 - @ohif/extension-vtk@1.12.20
 - @ohif/core@2.16.15
 - @ohif/viewer@4.12.23
2022-03-25 11:17:54 +00:00
Igor Octaviano 36b47ce3a3 Merge pull request #2750 from OHIF/igoroctaviano/dcmjs-0.19.8
Update dependency: dcmjs@0.19.8
2022-03-25 08:16:36 -03:00
igoroctaviano fe57c00577 Update dependency: dcmjs@0.19.8
dcmjs
  * @ohif/core: 0.19.7 → 0.19.8
  * @ohif/extension-cornerstone: 0.19.7 → 0.19.8
  * @ohif/extension-dicom-html: 0.19.7 → 0.19.8
  * @ohif/extension-dicom-rt: 0.19.7 → 0.19.8
  * @ohif/extension-dicom-segmentation: 0.19.7 → 0.19.8
  * @ohif/extension-dicom-tag-browser: 0.19.7 → 0.19.8
  * @ohif/extension-vtk: 0.19.7 → 0.19.8
  * @ohif/viewer: 0.19.7 → 0.19.8
2022-03-25 07:45:50 -03:00
ohif-bot 21a3bc2ded chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.8
 - @ohif/extension-dicom-html@1.3.19
 - @ohif/extension-dicom-rt@0.7.9
 - @ohif/extension-dicom-segmentation@0.7.9
 - @ohif/extension-dicom-tag-browser@0.2.20
 - @ohif/extension-vtk@1.12.19
 - @ohif/core@2.16.14
 - @ohif/viewer@4.12.22
2022-03-14 17:19:00 +00:00
Davide Punzo b6b09f22fc IDC2733: update dcmjs to version 0.19.7 (#2745) 2022-03-14 18:17:28 +01:00
ohif-bot 64a4d60e52 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.18
 - @ohif/core@2.16.13
 - @ohif/viewer@4.12.21
2022-03-14 16:26:55 +00:00
0ba796c73c fix: Update fetchPaletteColorLookupTableData: LUT Entries shall be 0 if the table entries value is 2^16 (#2395)
Opened issue https://github.com/OHIF/Viewers/issues/2366. 

Following http://dicom.nema.org/medical/Dicom/2018d/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.5, LUT Entries shall be 0 if the table entries value is 2^16.

If numLutEntries is 0, there is no for loop and return empty lut array.

Solution:

const numLutEntries = lutDescriptor[0] ? lutDescriptor[0] : 65536;

This is often used by Philips Ultrasound equipments.

Co-authored-by: Alireza <ar.sedghi@gmail.com>
Co-authored-by: Erik Ziegler <erik.sweed@gmail.com>
2022-03-14 17:25:19 +01:00
ohif-bot cb7fafb1d6 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.17
 - @ohif/ui@1.10.7
 - @ohif/viewer@4.12.20
2022-03-14 16:20:31 +00:00
ladeirarodolfo 7164d1a654 fix: remove docz + node version fix on docker (#2743)
* fix: docz uses too outdated packages and current documentation hasnt being updated oftenly. removing it

* fix: node docker version to prevent node req "^12.13.0 || ^14.15.0 || >=16" issue
2022-03-14 17:18:26 +01:00
ohif-bot 383a0ef167 chore(release): publish [skip ci]
- @ohif/extension-debugging@0.3.2
 - @ohif/viewer@4.12.19
2022-03-10 13:26:11 +00:00
Davide Punzo 56bd49a0cd Re IDC #2698 : fix overflow text and adding referenced Segs and RTSTRUCT series info in the debug dialog (#2735) 2022-03-10 14:23:01 +01:00
ohif-bot 755b283574 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.16
 - @ohif/core@2.16.12
 - @ohif/viewer@4.12.18
2022-02-15 10:41:51 +00:00
Igor Octaviano a8a4fcee40 Merge pull request #2708 from OHIF/igoroctaviano/bump-libs
refactor: 💡 Bump lodash and immer to avoid vulnerabilities
2022-02-15 07:38:15 -03:00
igoroctaviano 9892320ffb refactor: 💡 Bump lodash and immer to avoid vulnerabilities
Bump lodash and immer to avoid vulnerabilities
2022-02-14 18:50:14 -03:00
ohif-bot 28befb1ea6 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.7
 - @ohif/extension-dicom-html@1.3.18
 - @ohif/extension-dicom-rt@0.7.8
 - @ohif/extension-dicom-segmentation@0.7.8
 - @ohif/extension-dicom-tag-browser@0.2.19
 - @ohif/extension-vtk@1.12.15
 - @ohif/core@2.16.11
 - @ohif/viewer@4.12.17
2022-02-03 17:12:08 +00:00
Davide Punzo c554c5fac2 IDC Re #2656: update dcmjs 0.19.4 and change tol to 0.01. + fix boundary cases in parseSCOORD3D (#2699)
* IDC: update dcmjs to version 0.19.4

* IDC Re #2656: change tol to 0.01 for segs in dcmjs. + fix boundary cases in parseSCOORD3D
2022-02-03 18:08:05 +01:00
ohif-bot 6e3a58931a chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.6
 - @ohif/extension-dicom-html@1.3.17
 - @ohif/extension-vtk@1.12.14
 - @ohif/core@2.16.10
 - @ohif/ui@1.10.6
 - @ohif/viewer@4.12.16
2022-02-03 08:37:00 +00:00
Davide Punzoandigoroctaviano 5beb12a7fc IDC (Re #1215): Feat/v2 annotations (#2658)
* Add scoord3d parse / display tool to v2

* Update measurement panel with sr measurements

* Update measurement panel to display read only items

* Cleanup debugger statement

* Check for empty measurement

* fix SCOORD3D coordinates

* Update getRenderableData.js

* fix scoord3d coordinate transformation

* implement logic to detect the ReferencedSOPInstanceUID if missing in the measurement. Fix also world to IJ coordinates.

* Fix broken unit test / import

* fix comment style

* Init tools only once

* restore default config dcmjs server

Co-authored-by: igoroctaviano <igoroctaviano@gmail.com>
2022-02-03 09:33:02 +01:00
ohif-bot 1953118c8a chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.5
 - @ohif/extension-dicom-html@1.3.16
 - @ohif/extension-dicom-rt@0.7.7
 - @ohif/extension-dicom-segmentation@0.7.7
 - @ohif/extension-dicom-tag-browser@0.2.18
 - @ohif/extension-vtk@1.12.13
 - @ohif/core@2.16.9
 - @ohif/viewer@4.12.15
2022-02-02 15:09:29 +00:00
Davide Punzo 7807f849f2 IDC: update dcmjs to version 0.19.3 (#2697) 2022-02-02 16:06:14 +01:00
ohif-bot b426256df5 chore(release): publish [skip ci]
- @ohif/viewer@4.12.14
2022-01-31 15:05:24 +00:00
Josiah VinsonandJosiah Vinson c9b7e97f9c Fixing broken OpenResty / Orthanc recipes and updating doc (#2652)
* Updating docker files and documentation for OpenResty / Orthanc recipes.

* fixing link formatting

Co-authored-by: Josiah Vinson <jovinson@microsoft.com>
2022-01-31 10:02:18 -05:00
ohif-bot 0fc7d93d73 chore(release): publish [skip ci]
- @ohif/extension-dicom-pdf@1.1.2
 - @ohif/extension-vtk@1.12.12
 - @ohif/core@2.16.8
 - @ohif/viewer@4.12.13
2022-01-29 01:06:23 +00:00
Bill Wallace 33307d3cd2 Feat/v2 e2e static tests (#2684)
Use the static data for hte e2e tests
2022-01-28 20:02:30 -05:00
ohif-bot c3ce909434 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.4
 - @ohif/extension-dicom-html@1.3.15
 - @ohif/extension-dicom-rt@0.7.6
 - @ohif/extension-dicom-segmentation@0.7.6
 - @ohif/extension-dicom-tag-browser@0.2.17
 - @ohif/extension-vtk@1.12.11
 - @ohif/core@2.16.7
 - @ohif/viewer@4.12.12
2022-01-20 09:18:41 +00:00
Davide Punzo ad2c750503 IDC update dcmjs to v0.19.2 (#2672)
* IDC: update dcmjs with SEG loading regression fix
2022-01-20 10:15:19 +01:00
ohif-bot cceb61f123 chore(release): publish [skip ci]
- @ohif/extension-dicom-rt@0.7.5
 - @ohif/viewer@4.12.11
2022-01-19 09:29:16 +00:00
Davide Punzo 13bcba8c39 IDC #2657: fix rt struct panel update (#2666)
* Fix observation in RT panel
2022-01-19 10:25:42 +01:00
ohif-bot d2db026158 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.10
 - @ohif/core@2.16.6
 - @ohif/viewer@4.12.10
2022-01-13 13:21:38 +00:00
Ștefan Silviu-AlexandruandStefan Silviu e4b0552db4 feature: configurable max prefetch request count (#2632)
* feature: configurable max prefetch request count

* update name and default value for prefetch number

Co-authored-by: Stefan Silviu <silviu.stefan@atta.systems>
2022-01-13 08:18:29 -05:00
ohif-bot d7ba2fac69 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.9
 - @ohif/core@2.16.5
 - @ohif/viewer@4.12.9
2021-12-23 22:25:30 +00:00
Alireza 761d54fbbf fix: DICOMFileLoadingListener typo in method name (#2647) 2021-12-23 17:22:35 -05:00
ohif-bot 79548d2380 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.8
 - @ohif/core@2.16.4
 - @ohif/viewer@4.12.8
2021-12-23 20:38:37 +00:00
6a401c9e52 fix: SeriesTime and SeriesDate are only set for the first series and undefined for the remaining ones (#2476)
* set SeriesDate and SeriesTime for all series, instead of only for the first series

* set SeriesDate and SeriesTime only when they are undefined

* fix: equality operator

Co-authored-by: Christian El Salloum <christian.elsalloum@emtensor.com>
Co-authored-by: Alireza <ar.sedghi@gmail.com>
2021-12-23 15:35:37 -05:00
Yo Yehudi 23376d279d chore: Add research notice (#2458) 2021-12-23 12:01:07 -05:00
ohif-bot 4110b0422c chore(release): publish [skip ci]
- @ohif/extension-dicom-tag-browser@0.2.16
2021-12-10 09:38:52 +00:00
Davide Punzo ed501bb462 IDC Re #2633: fix slider min and max (#2634)
* IDC Re #2633: fix slider min and max
2021-12-10 10:33:30 +01:00
Davide Punzo abf050e162 update docker remote version for CI (#2629) 2021-12-02 13:56:59 +01:00
ohif-bot 35ed82e161 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.3
 - @ohif/extension-debugging@0.3.1
 - @ohif/extension-dicom-html@1.3.14
 - @ohif/extension-dicom-pdf@1.1.1
 - @ohif/extension-dicom-rt@0.7.4
 - @ohif/extension-dicom-segmentation@0.7.5
 - @ohif/extension-dicom-tag-browser@0.2.15
 - @ohif/extension-vtk@1.12.7
 - @ohif/core@2.16.3
 - @ohif/viewer@4.12.7
2021-12-02 11:57:19 +00:00
Davide Punzo d0ccc22fd9 Update cornerstone deps (#2628)
* update cornerstone deps
2021-12-02 12:53:41 +01:00
ohif-bot 31841c495f chore(release): publish [skip ci]
- @ohif/extension-dicom-tag-browser@0.2.14
 - @ohif/extension-vtk@1.12.6
 - @ohif/core@2.16.2
 - @ohif/ui@1.10.5
 - @ohif/viewer@4.12.6
2021-11-30 14:20:06 +00:00
Davide Punzo 65505d9bce Re IDC #2604: show series (with unsupported modalities) on slides panel and on tag explorer (#2621)
* Re IDC #2604: show series (with unsupported modalities) on slides panel and on tag explorer
2021-11-30 15:15:51 +01:00
ohif-bot 460fdeb534 chore(release): publish [skip ci]
- @ohif/extension-dicom-segmentation@0.7.4
 - @ohif/viewer@4.12.5
2021-10-27 13:10:24 +00:00
Igor Octaviano f4b7091ae4 Merge pull request #2596 from OHIF/fix/ohif-2590
Re #2590: Fix segments visibility handler
2021-10-27 10:06:35 -03:00
Davide Punzo 1e72684455 Re #2590: Fix segments visibility handler 2021-10-26 13:00:01 +02:00
ohif-bot 5b0b6301b9 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.2
 - @ohif/extension-dicom-html@1.3.13
 - @ohif/extension-dicom-rt@0.7.3
 - @ohif/extension-dicom-segmentation@0.7.3
 - @ohif/extension-dicom-tag-browser@0.2.13
 - @ohif/extension-vtk@1.12.5
 - @ohif/core@2.16.1
 - @ohif/ui@1.10.4
 - @ohif/viewer@4.12.4
2021-10-26 08:23:03 +00:00
Igor OctavianoandDavide Punzo 03a34a75a1 Add checks for study metadata in rt and seg panels + bump dcmjs to fix circular references issues naturalizing datasets (#2588)
Co-authored-by: Davide Punzo <punzodavide@hotmail.it>
2021-10-26 10:19:12 +02:00
ohif-bot 729272a985 chore(release): publish [skip ci]
- @ohif/extension-dicom-html@1.3.12
 - @ohif/viewer@4.12.3
2021-10-25 15:11:00 +00:00
Bill Wallace 9194ec2404 fix(OHIF):The header depth was too deep for display SR files. (#2594) 2021-10-25 17:08:10 +02:00
ohif-bot 52c95a1209 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.4
 - @ohif/ui@1.10.3
 - @ohif/viewer@4.12.2
2021-10-15 11:37:07 +00:00
Davide Punzo 8903adaea7 Re #2571: thumbnail footer remove instance number and add link icon if any derived display set is present (#2582)
* Re #2571, thumbnail footer layout modifications: remove instance number and add link icon if any derived display set is present.
2021-10-15 13:29:36 +02:00
ohif-bot 9481e2a99e chore(release): publish [skip ci]
- @ohif/extension-dicom-rt@0.7.2
 - @ohif/extension-dicom-segmentation@0.7.2
 - @ohif/viewer@4.12.1
2021-10-06 21:01:00 +00:00
Igor Octaviano f783fd7650 Merge pull request #2575 from OHIF/fix/ohif-2570
OHIF-2570: Update badge number based on active ds
2021-10-06 17:53:07 -03:00
Igor Octaviano 79afee7615 Merge branch 'master' into fix/ohif-2570 2021-10-05 09:40:49 -03:00
ohif-bot 539141fe5a chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.3
 - @ohif/core@2.16.0
 - @ohif/viewer@4.12.0
2021-10-04 07:36:45 +00:00
Bill Wallace a046c6c901 feat: Added support for WADO servers built with static hosting (e.g. S3) (#2566) 2021-10-04 09:30:36 +02:00
igoroctaviano 073be065cf Update badge number based on active ds 2021-10-01 18:09:48 -03:00
ohif-bot 252536a1e6 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.1
 - @ohif/extension-dicom-html@1.3.11
 - @ohif/extension-dicom-rt@0.7.1
 - @ohif/extension-dicom-segmentation@0.7.1
 - @ohif/extension-dicom-tag-browser@0.2.12
 - @ohif/extension-vtk@1.12.2
 - @ohif/core@2.15.1
 - @ohif/viewer@4.11.2
2021-09-28 12:14:17 +00:00
Davide Punzo 53b1d71d56 fix regression not showing warnings list on thumbnail for segmentations (#2563)
* fix regression not showing warnings list on thumbnail for segmentations

* update dcmjs version
2021-09-28 14:07:29 +02:00
Erik Ziegler 702d99cb93 Add FUNDING.yml 2021-09-27 14:23:37 +02:00
Alireza bb7b78bf33 chore(github): Create config.yml for issues (#2561)
* chore(github): Create config.yml for issues

* Delete ---support-question.md
2021-09-27 14:20:38 +02:00
ohif-bot b796fc9c62 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.12.1
 - @ohif/ui@1.10.2
 - @ohif/viewer@4.11.1
2021-09-24 11:04:33 +00:00
Erik Ziegler 66c587b139 fix: throttle thumbnail progress updates (#2557) 2021-09-24 12:58:30 +02:00
ohif-bot f6e2e58aad chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.12.0
 - @ohif/extension-debugging@0.3.0
 - @ohif/extension-dicom-pdf@1.1.0
 - @ohif/extension-dicom-rt@0.7.0
 - @ohif/extension-dicom-segmentation@0.7.0
 - @ohif/extension-vtk@1.12.0
 - @ohif/core@2.15.0
 - @ohif/viewer@4.11.0
2021-09-23 16:42:56 +00:00
Erik ZieglerandAlireza 489d4b0584 feat: Update to WADO Image Loader 4.0.3 to add dynamically imported WebAssembly codec support 🚀 (#2537)
* feat: bump to prerelease of WADO Image Loader for testing

* switch to released versions

* update react-vtkjs-viewport and fix requestpool usage in StudyPrefetcher

* attempt to fix e2e tests for script-tag usage

* fix e2e test error

* switch to using webpack alias in PWA to use dynamic import version of OHIF

* fix copy plugin usage

* try to fix publicpath issue

* bump to 4.0.3

Co-authored-by: Alireza <ar.sedghi@gmail.com>
2021-09-23 18:37:29 +02:00
ohif-bot 36019156da chore(release): publish [skip ci]
- @ohif/extension-vtk@1.11.18
 - @ohif/core@2.14.1
 - @ohif/ui@1.10.1
 - @ohif/viewer@4.10.1
2021-09-13 13:10:07 +00:00
Igor Octaviano f2a371fc2d Display warning messages if fails to parse sr report (#2543) 2021-09-13 15:06:30 +02:00
ohif-bot ad2f038817 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.11.0
 - @ohif/extension-vtk@1.11.17
 - @ohif/core@2.14.0
 - @ohif/ui@1.10.0
 - @ohif/viewer@4.10.0
2021-09-09 08:02:24 +00:00
Igor OctavianoandAlireza 8f2604509d feat: OHIF-1000: Study prefetcher (#2466)
* Enable study prefetcher and expose configs

* Fix progress for all images

* Enable study loading listener

* Add new default for displaying progress bar for series

* Use events instead of redux to improve performance

* Add documentation, resolve issues with different datasets

* CR Updates

* CR Updates

* CR Updates & Resolve issue when activating both stack and study prefetch

* Add upward and update display set logic

* Add new behavior to prefetching orders

* Rollback display set check and activate cache check

* Remove prefetch check

* Check if displayset has images

* Debounce check cache events

* Remove usued debounce flags

* Ignore prefetching same image

* Use new image instead of image rendered

* Continue prefetch after cache check

* Update prefetch logic after checking cache

* Remove log

* Update displayset count default to 3

* Update netlify config

Co-authored-by: Alireza <ar.sedghi@gmail.com>
2021-09-09 09:58:24 +02:00
ohif-bot ea0963d75f chore(release): publish [skip ci]
- @ohif/extension-dicom-rt@0.6.14
 - @ohif/extension-dicom-segmentation@0.6.11
 - @ohif/extension-vtk@1.11.16
 - @ohif/core@2.13.15
 - @ohif/ui@1.9.3
 - @ohif/viewer@4.9.24
2021-09-03 21:01:01 +00:00
Igor Octaviano 46d5718011 Merge pull request #2491 from OHIF/feat/ohif-2482
OHIF-2482: Add badge numbers for seg and rtstruct
2021-09-03 17:57:42 -03:00
Davide Punzo f8740e04f3 Merge branch 'master' into feat/ohif-2482 2021-09-02 16:08:37 +02:00
ohif-bot 669717d27b chore(release): publish [skip ci]
- @ohif/extension-vtk@1.11.15
 - @ohif/core@2.13.14
 - @ohif/viewer@4.9.23
2021-08-30 13:04:58 +00:00
Alireza 715dfc556a fix: MPR metadata parsing for spacings (#2517)
* fix: MPR metadata parsing for spacings

* fix: OHIF Metadata provider for validNumbers for imagePlaneModule
2021-08-30 09:01:46 -04:00
ohif-bot cafb7d3f7b chore(release): publish [skip ci]
- @ohif/viewer@4.9.22
2021-08-19 13:05:04 +00:00
matthiasg 5f92f6ec7f fix: Remove internet dependency for workbox (addressing #2109) (#2151)
* Ignoring *.js.map files as generated in the extensions directories for example

* Fix for #2109. Removed internet dependency to google workbox
2021-08-19 15:00:20 +02:00
Matthias SchmiederandMatthias Schmieder eea610dfe8 fix CVE-2019-5021 caused by nginx-apline (#2514)
Co-authored-by: Matthias Schmieder <matthias.schmieder@stryker.com>
2021-08-19 13:42:04 +02:00
Erik Ziegler e8733a9bd9 Update CITATION.cff (#2504) 2021-08-04 17:16:35 +02:00
Erik Ziegler d292931073 Create CITATION.cff (#2503) 2021-08-04 15:43:10 +02:00
igoroctaviano f6a0db753a Merge branch 'master' of github.com:OHIF/Viewers into feat/ohif-2482 2021-07-29 09:19:42 -03:00
igoroctaviano 8518e179ee Extract event 2021-07-29 09:18:31 -03:00
igoroctaviano 3f40cdced7 Add badge numbers for seg and rtstruct 2021-07-28 22:15:05 -03:00
ohif-bot 4cf17185da chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.10.10
 - @ohif/viewer@4.9.21
2021-07-26 11:44:06 +00:00
b8ae92c2d4 fix: changed new image handler conditional for 0 edge case (#2338)
Co-authored-by: Michael Andersen <Michael.Andersen@rmp.uhn.ca>
Co-authored-by: Erik Ziegler <erik.sweed@gmail.com>
2021-07-26 13:35:37 +02:00
Woonchan Cho bad67020cc chore(#2483) make client-side code debuggable right from the source code (#2484) 2021-07-26 13:34:55 +02:00
ohif-bot 2afcd498f3 chore(release): publish [skip ci]
- @ohif/extension-debugging@0.2.2
 - @ohif/extension-dicom-tag-browser@0.2.11
 - @ohif/extension-vtk@1.11.14
 - @ohif/core@2.13.13
 - @ohif/viewer@4.9.20
2021-06-03 20:56:43 +00:00
Igor Octaviano ce4c3d5360 Merge pull request #2408 from OHIF/feat/idc-2374
IDC-2374: Exponential backoff and retry after 500 error
2021-06-03 17:52:49 -03:00
igoroctaviano d575e36879 Expose retryable option 2021-06-03 17:24:39 -03:00
igoroctaviano 98fcabfcb5 Resolve opening connection before previsouly setting headers 2021-06-03 17:05:45 -03:00
Davide Punzo 1e2773345a Merge branch 'feat/idc-2374' of https://github.com/OHIF/Viewers into feat/idc-2374 2021-06-03 16:25:29 +02:00
Davide Punzo f847633cf3 update dicomweb-client to version 0.8.1 2021-06-03 16:25:06 +02:00
igoroctaviano bd2ddd7702 Remove metadata check 2021-06-03 07:20:49 -03:00
igoroctaviano 26b7b34bd4 Add check for metadata 2021-06-03 07:10:33 -03:00
Davide Punzo 6f3e446a79 Merge branch 'master' into feat/idc-2374 2021-06-03 10:11:45 +02:00
ohif-bot f0d7f2e6c7 chore(release): publish [skip ci]
- @ohif/viewer@4.9.19
2021-06-03 08:07:04 +00:00
Davide Punzo c8f7abfd53 Merge branch 'master' into feat/idc-2374 2021-06-03 10:04:02 +02:00
Davide Punzo 2b29ff1820 clean back default config (#2438) 2021-06-03 10:03:49 +02:00
Davide Punzo 5627e9c919 update dicomweb-client to version 0.8.0 2021-06-03 09:37:57 +02:00
Davide Punzo 582b713b84 Merge branch 'master' into feat/idc-2374 2021-06-03 09:25:50 +02:00
ohif-bot 5eb8e58b65 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.10.9
 - @ohif/extension-dicom-html@1.3.10
 - @ohif/extension-dicom-rt@0.6.13
 - @ohif/extension-dicom-segmentation@0.6.10
 - @ohif/extension-dicom-tag-browser@0.2.10
 - @ohif/extension-vtk@1.11.13
 - @ohif/core@2.13.12
 - @ohif/viewer@4.9.18
2021-06-02 14:01:32 +00:00
Igor Octaviano 403688b18c fix(dicom-html): Add parsed dicom meta info section (#2419)
* Add dicom meta info section to dicom sr html
* Update dependency: dcmjs@0.18.8
2021-06-02 15:57:56 +02:00
ohif-bot f0d13a7acd chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.10.8
 - @ohif/extension-dicom-rt@0.6.12
 - @ohif/extension-dicom-segmentation@0.6.9
 - @ohif/extension-vtk@1.11.12
 - @ohif/core@2.13.11
 - @ohif/ui@1.9.2
 - @ohif/viewer@4.9.17
2021-05-17 16:51:58 +00:00
Davide Punzo 78f1a7f3e5 Re #2259: UI refinements for warnings (#2397)
* Re #2259: highlight series thumbnails border for active series (series in the active viewport)
* Re #2259: add the warning icon also on the active viewport as an overlay
2021-05-17 18:48:32 +02:00
ohif-bot a57ab4d12a chore(release): publish [skip ci]
- @ohif/viewer@4.9.16
2021-05-14 01:18:42 +00:00
Igor Octaviano 3b6c6374e3 Merge pull request #2409 from OHIF/feat/add-option-to-disable-servers-cache
IDC: Add option to disable local storage of servers
2021-05-13 22:15:59 -03:00
igoroctaviano 4b508b0c25 Update config property 2021-05-13 21:56:19 -03:00
igoroctaviano 1cbef867ce Add option to disable local storage cache of servers 2021-05-13 21:42:46 -03:00
igoroctaviano 05444f48d4 Improve docs remove env variables 2021-05-13 09:30:52 -03:00
igoroctaviano 2ea227ca06 Extract hook and add config and documentation 2021-05-13 09:06:11 -03:00
igoroctaviano 35aaad175c Update naming 2021-05-13 08:11:09 -03:00
igoroctaviano 863fe05907 Update naming 2021-05-13 08:11:03 -03:00
igoroctaviano 1c9560044f Implement handlers to retry metadata requests 2021-05-13 08:10:53 -03:00
ohif-bot 343f06c57d chore(release): publish [skip ci]
- @ohif/extension-dicom-html@1.3.9
 - @ohif/extension-dicom-rt@0.6.11
 - @ohif/extension-dicom-segmentation@0.6.8
 - @ohif/extension-dicom-tag-browser@0.2.9
 - @ohif/extension-vtk@1.11.11
 - @ohif/core@2.13.10
 - @ohif/viewer@4.9.15
2021-04-22 03:42:37 +00:00
dannyrb e2bb647386 Merge branch 'master' of github.com:OHIF/Viewers into ups-master 2021-04-21 23:29:54 -04:00
dannyrb a3cb9dab57 remove sitemap dep from older version 2021-04-21 23:29:41 -04:00
ohif-bot 410ab028c7 chore(release): publish [skip ci]
- @ohif/extension-dicom-html@1.3.8
 - @ohif/extension-dicom-rt@0.6.10
 - @ohif/extension-dicom-segmentation@0.6.7
 - @ohif/extension-dicom-tag-browser@0.2.8
 - @ohif/extension-vtk@1.11.10
 - @ohif/core@2.13.9
 - @ohif/viewer@4.9.14
2021-04-22 03:27:52 +00:00
dannyrb 54dd738f61 Merge branch 'master' of github.com:OHIF/Viewers into ups-master 2021-04-21 23:24:39 -04:00
dannyrb 6f16c7e48d Remove broken plugin? Seems to have broken child dep 2021-04-21 23:24:28 -04:00
ohif-bot 82ddd95cf0 chore(release): publish [skip ci]
- @ohif/extension-dicom-html@1.3.7
 - @ohif/extension-dicom-rt@0.6.9
 - @ohif/extension-dicom-segmentation@0.6.6
 - @ohif/extension-dicom-tag-browser@0.2.7
 - @ohif/extension-vtk@1.11.9
 - @ohif/core@2.13.8
 - @ohif/viewer@4.9.13
2021-04-21 14:14:00 +00:00
Davide Punzo 2b658fae7e IDC2345: update dcmjs to version 0.18.5 (#2378) 2021-04-21 16:10:49 +02:00
ohif-bot a822151e92 chore(release): publish [skip ci]
- @ohif/extension-dicom-html@1.3.6
 - @ohif/extension-vtk@1.11.8
 - @ohif/core@2.13.7
 - @ohif/viewer@4.9.12
2021-04-21 11:17:09 +00:00
Igor Octaviano 0ae49c6fdc IDC-2348: Add acquisition storage sr sopclass to sr html ext (#2352)
* Add acquisition context storage sr sop to html ext
2021-04-21 13:12:54 +02:00
ohif-bot 1d069d2da3 chore(release): publish [skip ci]
- @ohif/extension-dicom-segmentation@0.6.5
 - @ohif/extension-vtk@1.11.7
 - @ohif/core@2.13.6
 - @ohif/viewer@4.9.11
2021-04-21 10:22:55 +00:00
Igor Octaviano 274342a5e1 Merge pull request #2369 from Punzo/IDC2361
Re #2361: fix seg combobox filling
2021-04-21 07:19:32 -03:00
Davide Punzo 21a5d1bfc4 update 2021-04-21 10:40:02 +02:00
Davide Punzo e421bc7df9 update 2021-04-20 16:39:04 +02:00
Davide Punzo e41ba2bfde IDC2361: fix seg combobox filling 2021-04-19 19:42:30 +02:00
ohif-bot d2e75b0f20 chore(release): publish [skip ci]
- @ohif/extension-dicom-segmentation@0.6.4
 - @ohif/extension-vtk@1.11.6
 - @ohif/core@2.13.5
 - @ohif/viewer@4.9.10
2021-04-16 18:18:27 +00:00
Davide Punzo 07b272e024 IDC2345: implement thumbnails footnotes UI for segmentation series inconsistencies warning (#2364)
* IDC2345: implement thumbnails footnotes UI for segmentation series inconsistencies warning
2021-04-16 20:14:04 +02:00
ohif-bot a08caa9bdb chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.10.7
 - @ohif/extension-dicom-html@1.3.5
 - @ohif/extension-dicom-rt@0.6.8
 - @ohif/extension-dicom-segmentation@0.6.3
 - @ohif/extension-dicom-tag-browser@0.2.6
 - @ohif/extension-vtk@1.11.5
 - @ohif/core@2.13.4
 - @ohif/viewer@4.9.9
2021-04-15 13:13:50 +00:00
Igor Octaviano 29afddb3a6 Merge pull request #2363 from OHIF/fix/window-level-issues
fix(MetadataProvider): Update metadata provider to resolve issues after dicomweb update/new return value
2021-04-15 10:10:48 -03:00
igoroctaviano f85f856734 Comment cache 2021-04-15 09:40:37 -03:00
igoroctaviano c6bc19c002 Rollback circle ci test 2021-04-15 09:29:50 -03:00
igoroctaviano 538555f000 Merge branch 'master' of github.com:OHIF/Viewers into fix/window-level-issues 2021-04-15 09:17:54 -03:00
igoroctaviano 8681036b21 fix(wl): fix metadata provider window level issues after dicomweb update (string vs number) 2021-04-15 09:15:42 -03:00
Davide Punzo e55b909ca6 IDC2345: Update dcmjs to version 0.18.4 (#2362) 2021-04-15 13:33:13 +02:00
Davide Punzo 4bb36704ee IDC2346: fix images sorting (#2358) 2021-04-14 19:43:58 +02:00
Davide Punzo 9bbdb35d88 IDC2259: do not check uniform spacing in the 4th dimension for 4D datasets (#2356) 2021-04-13 12:57:28 +02:00
qqalexqq 2f443fa2ef fix: Update Dockerfile node version - fix missing dependencies (#2349)
There were some utilities missing: python, make, g++. Also node version was too old - current node builds without problems.
2021-04-05 09:47:57 +02:00
ohif-bot 6d7d7da287 chore(release): publish [skip ci]
- @ohif/extension-dicom-segmentation@0.6.2
 - @ohif/viewer@4.9.8
2021-03-31 10:24:08 +00:00
Davide Punzo 1f6751f95b IDC2332 (#2341)
1) fix the loading of the segmentations when filtering study with ?seriesInstanceUID= syntax
2) add time in the dates of the items of the segmentation combobox list
3) order segmentation combobox list in reverse time order
2021-03-31 12:20:34 +02:00
ohif-bot 92081a097d chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.10.6
 - @ohif/viewer@4.9.7
2021-03-26 18:38:58 +00:00
Igor Octaviano ba1a33c3ac Merge pull request #2335 from OHIF/idc-2334
IDC-2334: Resolve choppy scrolling in 2D mode
2021-03-26 15:36:07 -03:00
igoroctaviano 193ff12b6e Fix scroll speed 2021-03-26 13:27:51 -03:00
ohif-bot 3296ffaa07 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.11.4
 - @ohif/core@2.13.3
 - @ohif/ui@1.9.1
 - @ohif/viewer@4.9.6
2021-03-26 10:35:50 +00:00
Davide Punzo 0456d92462 IDC 2259: add warning UI for series inconsistencies (#2331)
IDC 2259: add warning UI for series inconsistencies

remove VTKMPRToolbarButton component memoization (it is not anymore necessary)
2021-03-26 11:32:10 +01:00
ohif-bot db3b15e537 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.11.3
 - @ohif/core@2.13.2
 - @ohif/viewer@4.9.5
2021-03-25 16:16:14 +00:00
Igor OctavianoandDavide Punzo 6e723ebced fix: IDC-2288: Update toolbar tabs after derived displayset loaded (#2307)
* Update toolbar tabs after derived displayset loaded

* trigger CI

Co-authored-by: Davide Punzo <punzodavide@hotmail.it>
2021-03-25 17:12:20 +01:00
ohif-bot a6a231c81e chore(release): publish [skip ci]
- @ohif/extension-debugging@0.2.1
 - @ohif/viewer@4.9.4
2021-03-19 18:54:21 +00:00
Igor Octaviano 7c2bd9b76a Merge pull request #2321 from OHIF/bugfix/idc-2006
bug(IDC-2006): Fix bug introduced with new logger service which broke debugger mailto functionality
2021-03-19 15:51:01 -03:00
igoroctaviano 5dfa8d465d Force pipeline 2021-03-19 15:12:37 -03:00
igoroctaviano fc5301e904 bug(debugger):Fix bug that breaks mailto introduced by logger service 2021-03-18 07:40:59 -03:00
ohif-bot 88e5a7e54a chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.10.5
 - @ohif/viewer@4.9.3
2021-03-15 20:12:36 +00:00
Igor Octaviano 5d24bb4b73 Merge pull request #2315 from OHIF/igoroctaviano/react-cornerstone-viewport-4.0.5
Update dependency: react-cornerstone-viewport@4.0.5
2021-03-15 17:09:16 -03:00
igoroctaviano 03a4056179 Update dependency: react-cornerstone-viewport@4.0.5
react-cornerstone-viewport
  * @ohif/extension-cornerstone: 4.0.4 → 4.0.5
2021-03-15 16:42:24 -03:00
ohif-bot ec76bc3b0b chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.10.4
 - @ohif/extension-dicom-html@1.3.4
 - @ohif/extension-dicom-rt@0.6.7
 - @ohif/extension-dicom-segmentation@0.6.1
 - @ohif/extension-dicom-tag-browser@0.2.5
 - @ohif/extension-vtk@1.11.2
 - @ohif/core@2.13.1
 - @ohif/viewer@4.9.2
2021-03-09 19:43:21 +00:00
Davide Punzo b1070acaca Update dependency: dcmjs@0.18.3 (#2302) 2021-03-09 20:38:19 +01:00
ohif-bot 7b5beb8f98 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.11.1
 - @ohif/viewer@4.9.1
2021-03-09 15:55:47 +00:00
97410e12b9 Added memoization on VTKMPRToolbarButton component to avoid unnecesary rebuilds (#2274)
* Added memoization on VTKMPRToolbarButton component to avoid unnecessary rebuilds

* update isDisplaySetReconstructable for float precision

Co-authored-by: Rodrigo Cáceres Vicencio <rcaceres@nursoft.cl>
Co-authored-by: Davide Punzo <punzodavide@hotmail.it>
2021-03-09 16:52:56 +01:00
ohif-bot bdecbfeee3 chore(release): publish [skip ci]
- @ohif/extension-debugging@0.2.0
 - @ohif/extension-dicom-microscopy@0.52.0
 - @ohif/extension-dicom-segmentation@0.6.0
 - @ohif/extension-vtk@1.11.0
 - @ohif/core@2.13.0
 - @ohif/ui@1.9.0
 - @ohif/viewer@4.9.0
2021-03-04 21:44:04 +00:00
Igor Octaviano 5a970056ae Merge pull request #2283 from OHIF/IDC-2223-update
feat(IDC-2223): add new log service to be used by debugger extension
2021-03-04 18:41:04 -03:00
igoroctaviano 8581405352 Add logger to viewport grid 2021-03-04 18:20:57 -03:00
igoroctaviano df8c4db2ed Update broken test 2021-03-03 20:06:58 -03:00
igoroctaviano ea62bdaddf Merge branch 'master' of github.com:OHIF/Viewers into IDC-2223-update 2021-03-03 19:18:36 -03:00
igoroctaviano e983b02677 Add onerror event to cover all other unhandled errors 2021-03-03 19:16:49 -03:00
ohif-bot 1e4b78d78d chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.10.3
 - @ohif/extension-dicom-html@1.3.3
 - @ohif/extension-dicom-rt@0.6.6
 - @ohif/extension-dicom-segmentation@0.5.4
 - @ohif/extension-dicom-tag-browser@0.2.4
 - @ohif/extension-vtk@1.10.6
 - @ohif/core@2.12.5
 - @ohif/viewer@4.8.12
2021-03-03 18:31:51 +00:00
igoroctaviano ee6131f98e Merge branch 'master' of github.com:OHIF/Viewers into IDC-2223-update 2021-03-03 15:28:23 -03:00
Igor Octaviano a56bdd035b Merge pull request #2290 from OHIF/bump-dcmjs
Update dependency: dcmjs@0.18.2
2021-03-03 15:27:54 -03:00
igoroctaviano 04901c296e Update dependency: dcmjs@0.18.2
dcmjs
  * @ohif/core: 0.18.1 → 0.18.2
  * @ohif/extension-cornerstone: 0.18.1 → 0.18.2
  * @ohif/extension-dicom-html: 0.18.1 → 0.18.2
  * @ohif/extension-dicom-rt: 0.18.1 → 0.18.2
  * @ohif/extension-dicom-segmentation: 0.18.1 → 0.18.2
  * @ohif/extension-dicom-tag-browser: 0.18.1 → 0.18.2
  * @ohif/extension-vtk: 0.18.1 → 0.18.2
  * @ohif/viewer: 0.18.1 → 0.18.2
2021-03-03 14:35:06 -03:00
ohif-bot 59cadad98c chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.10.2
 - @ohif/extension-dicom-html@1.3.2
 - @ohif/extension-dicom-rt@0.6.5
 - @ohif/extension-dicom-segmentation@0.5.3
 - @ohif/extension-dicom-tag-browser@0.2.3
 - @ohif/extension-vtk@1.10.5
 - @ohif/core@2.12.4
 - @ohif/viewer@4.8.11
2021-02-25 21:31:47 +00:00
igoroctaviano 14d6454eaf feat(log): add new log service 2021-02-25 18:29:28 -03:00
Igor Octaviano 64f87d2c93 Merge pull request #2281 from OHIF/fix/bump-dcmjs
Update dependency: dcmjs@0.18.1
2021-02-25 18:28:37 -03:00
igoroctaviano cfd66e5ef7 Update dependency: dcmjs@0.18.1
dcmjs
  * @ohif/core: 0.17.2 → 0.18.1
  * @ohif/extension-cornerstone: 0.17.2 → 0.18.1
  * @ohif/extension-dicom-html: 0.17.2 → 0.18.1
  * @ohif/extension-dicom-rt: 0.17.2 → 0.18.1
  * @ohif/extension-dicom-segmentation: 0.17.2 → 0.18.1
  * @ohif/extension-dicom-tag-browser: 0.17.2 → 0.18.1
  * @ohif/extension-vtk: 0.17.2 → 0.18.1
  * @ohif/viewer: 0.17.2 → 0.18.1
2021-02-25 17:05:24 -03:00
Andrey Fedorovandigoroctaviano 6480389778 chore: add acknowledgment of IDC (#2255)
* add acknowldgment of IDC

resolves #1136

* Fix typo + remove IDC ack example

Co-authored-by: igoroctaviano <igoroctaviano@gmail.com>
2021-02-12 12:08:43 +01:00
ohif-bot 0e736e7a56 chore(release): publish [skip ci]
- @ohif/viewer@4.8.10
2021-02-08 11:56:46 +00:00
Igor Octaviano d246cd9842 Merge pull request #2267 from OHIF/IDC-2251
IDC-2251: Add error page and not found pages if failed to retrieve study data
2021-02-08 08:53:35 -03:00
igoroctaviano 4fa1eb683d Merge branch 'master' of github.com:OHIF/Viewers into IDC-2251 2021-02-07 22:29:45 -03:00
ohif-bot ea6842a276 chore(release): publish [skip ci]
- @ohif/extension-dicom-tag-browser@0.2.2
 - @ohif/extension-vtk@1.10.4
 - @ohif/core@2.12.3
 - @ohif/ui@1.8.2
 - @ohif/viewer@4.8.9
2021-02-05 20:03:45 +00:00
igoroctaviano d97270f995 Merge branch 'master' of github.com:OHIF/Viewers into IDC-2251 2021-02-05 17:00:06 -03:00
Igor Octaviano 0ef76f8b66 Merge pull request #2260 from OHIF/IDC-2258
IDC-2258: Replace instance dropdown to slider for dicom tag browser
2021-02-05 16:59:38 -03:00
igoroctaviano 05b5a10af9 Merge branch 'master' of github.com:OHIF/Viewers into IDC-2258 2021-02-05 16:15:29 -03:00
ohif-bot e1150acaf6 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.10.1
 - @ohif/extension-dicom-html@1.3.1
 - @ohif/extension-dicom-rt@0.6.4
 - @ohif/extension-dicom-segmentation@0.5.2
 - @ohif/extension-dicom-tag-browser@0.2.1
 - @ohif/extension-vtk@1.10.3
 - @ohif/core@2.12.2
 - @ohif/viewer@4.8.8
2021-02-05 18:42:46 +00:00
Igor Octaviano 4abdbe0584 Merge branch 'master' into IDC-2258 2021-02-05 15:40:40 -03:00
Igor Octaviano 9223a52af9 Merge pull request #2268 from OHIF/IDC-2252
Update dependency: dcmjs@0.17.2 to fix Failure to load a valid SEG object due to incorrect expectations about ReferencedSegmentNumber
2021-02-05 15:40:09 -03:00
igoroctaviano 06f58d18bf Bump dcmjs 2021-02-03 17:38:20 -03:00
igoroctaviano 7c5f9c44b6 Add error page and not found pages if failed to retrieve study data 2021-02-03 13:58:46 -03:00
igoroctaviano ef341d1518 Replace instance dropdown to slider for dicom tag browser 2021-01-28 15:43:51 -03:00
ohif-bot d956963ef0 chore(release): publish [skip ci]
- @ohif/viewer@4.8.7
2021-01-28 14:32:43 +00:00
noerog 83b7d9e8b4 fix(config): Update Google Healthcare API endpoint from v1beta1 to v1 (#2256) 2021-01-28 15:29:53 +01:00
ohif-bot 12e73228d1 chore(release): publish [skip ci]
- @ohif/viewer@4.8.6
2021-01-26 12:43:46 +00:00
Jason Klotzer 4002401c66 fixes #2249 2021-01-26 13:39:48 +01:00
ohif-bot 18a8e059b6 chore(release): publish [skip ci]
- @ohif/extension-dicom-rt@0.6.3
 - @ohif/viewer@4.8.5
2021-01-21 17:33:28 +00:00
Igor Octaviano f3582e514e Merge pull request #2244 from OHIF/IDC-2123
feat(IDC-2123): When RTSTRUCT does not apply to the specific image series, the button and the panel should not be shown
2021-01-21 14:30:41 -03:00
igoroctaviano c76bfd4a58 Merge branch 'IDC-2123' of github.com:OHIF/Viewers into IDC-2123 2021-01-21 14:15:25 -03:00
igoroctaviano 7f8cf5f5da :wq
erge branch 'master' of github.com:OHIF/Viewers into IDC-2123
2021-01-21 14:15:13 -03:00
Igor Octaviano 5ef926477c Merge pull request #2240 from OHIF/IDC-1136
docs(IDC-1136): Add funding acknowledgment of the IDC project
2021-01-21 13:59:34 -03:00
igoroctaviano 87f5b97983 Merge branch 'master' of github.com:OHIF/Viewers into IDC-1136 2021-01-21 13:12:00 -03:00
ohif-bot 4c7b2b4ae0 chore(release): publish [skip ci]
- @ohif/extension-dicom-microscopy@0.51.4
 - @ohif/viewer@4.8.4
2021-01-21 14:59:06 +00:00
igoroctaviano d1e52dd6a6 Merge branch 'master' of github.com:OHIF/Viewers into IDC-1136 2021-01-21 11:55:17 -03:00
Igor Octaviano cb147dfc69 Merge pull request #2241 from OHIF/IDC-2223
feat(IDC-2223): Add error notification on microscopy viewport initialization errors
2021-01-21 11:54:51 -03:00
igoroctaviano a5fdeddfb4 Merge branch 'master' of github.com:OHIF/Viewers into IDC-2223 2021-01-21 10:42:41 -03:00
ohif-bot e0e5f6000f chore(release): publish [skip ci]
- @ohif/extension-dicom-rt@0.6.2
 - @ohif/extension-dicom-segmentation@0.5.1
 - @ohif/viewer@4.8.3
2021-01-21 13:36:40 +00:00
igoroctaviano cffb7d6f2f Merge branch 'master' of github.com:OHIF/Viewers into IDC-2223 2021-01-21 10:29:15 -03:00
Igor Octaviano 360616be13 Merge pull request #2243 from OHIF/IDC-1801
feat(IDC-1801): Improve/harmonize segmentations panel with rtstruct and add new visibility toggles
2021-01-21 10:28:40 -03:00
igoroctaviano d8fe8929b6 Merge branch 'IDC-1801' of github.com:OHIF/Viewers into IDC-1801 2021-01-21 09:37:50 -03:00
igoroctaviano 6b99a21227 Merge branch 'master' of github.com:OHIF/Viewers into IDC-1801 2021-01-21 09:37:39 -03:00
Igor Octaviano 16631e1fc4 Merge branch 'master' into IDC-1801 2021-01-21 09:36:51 -03:00
ohif-bot 587de94cea chore(release): publish [skip ci]
- @ohif/extension-vtk@1.10.2
 - @ohif/core@2.12.1
 - @ohif/ui@1.8.1
 - @ohif/viewer@4.8.2
2021-01-21 12:35:41 +00:00
Igor Octaviano 0ebe8a67d2 Merge branch 'master' into IDC-2123 2021-01-21 09:31:29 -03:00
Igor Octaviano 39a988dac7 Merge branch 'master' into IDC-1136 2021-01-21 09:31:26 -03:00
Igor Octaviano f95928bcdd Merge branch 'master' into IDC-2223 2021-01-21 09:31:22 -03:00
Igor Octaviano 0f736bd294 Merge branch 'master' into IDC-1801 2021-01-21 09:31:17 -03:00
Igor Octaviano 6cbd9839c6 Merge pull request #2246 from OHIF/IDC-2192
feat(IDC-2192): Notify buffer allocation failure trying to do MPR for a large series
2021-01-21 09:31:07 -03:00
igoroctaviano 649bc5825a Trigger netlify deploy 2021-01-21 09:06:29 -03:00
igoroctaviano 8038009afd Add exit mpr action 2021-01-20 20:59:03 -03:00
igoroctaviano f07f21117d Notify user of buffer errors from vtk / add possibility to add actions to notifications 2021-01-20 18:05:20 -03:00
igoroctaviano 77c7463c53 RTSTRUCT does not apply to the specific image series, the button and the panel should not be shown 2021-01-19 17:56:41 -03:00
igoroctaviano 449e8f25f6 Toggle visibility for cornerstone by default 2021-01-19 14:22:52 -03:00
igoroctaviano 437c01511e Toggle visibility for multiple labelmaps (overlapping) 2021-01-19 14:10:40 -03:00
igoroctaviano 00fddc1550 Improve/harmonize segmentations panel and add bulk visibility toggles 2021-01-16 01:19:12 -03:00
igoroctaviano 00b5cccae5 Add error message on microscopy viewport errors 2021-01-15 15:23:43 -03:00
igoroctaviano e545dd5b28 Add funding acknowledgment of the IDC project 2021-01-15 09:53:32 -03:00
ohif-bot efde6ed20e chore(release): publish [skip ci]
- @ohif/extension-dicom-rt@0.6.1
 - @ohif/extension-vtk@1.10.1
 - @ohif/viewer@4.8.1
2020-12-10 16:49:23 +00:00
Igor Octaviano 32022f51f2 fix: panel issues and mpr button (IDC2122-IDC2117) 2020-12-10 17:44:44 +01:00
ohif-bot d282f72d75 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.10.0
 - @ohif/extension-dicom-html@1.3.0
 - @ohif/extension-dicom-rt@0.6.0
 - @ohif/extension-dicom-segmentation@0.5.0
 - @ohif/extension-dicom-tag-browser@0.2.0
 - @ohif/extension-vtk@1.10.0
 - @ohif/core@2.12.0
 - @ohif/ui@1.8.0
 - @ohif/viewer@4.8.0
2020-12-10 10:09:50 +00:00
Davide PunzoandIgor Octaviano 29fceacee9 feat: visualize overlapping segments in cornerstone (#2185)
* feat: visualize overlapping segments

load multiple labelMaps (splitted by dcmjs because overlapping) in a segmentations [IDC2164]

Dynamically update active labelmap [IDC2164]

Co-authored-by: Davide Punzo <punzodavide@hotmail.it>
Co-authored-by: Igor Octaviano <igoroctaviano@gmail.com>
2020-12-10 11:04:27 +01:00
Igor Octaviano a7a5a359dc Use runtime values for version (#2204) 2020-12-10 09:56:30 +01:00
ohif-bot e362e895d4 chore(release): publish [skip ci]
- @ohif/viewer@4.7.2
2020-12-03 20:45:12 +00:00
Nikola Mijajlović 45a07dfa19 refactor: Update SidePanel.js to use a functional component (#2179) 2020-12-03 21:39:14 +01:00
ohif-bot 7323e63608 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.9.4
 - @ohif/viewer@4.7.1
2020-12-03 17:20:07 +00:00
Igor OctavianoandDavide Punzo 0baf18dcb2 fix: reset VOI on mpr reset (#2115)
Co-authored-by: Davide Punzo <punzodavide@hotmail.it>
2020-12-03 18:11:14 +01:00
ohif-bot cca3d6bff2 chore(release): publish [skip ci]
- @ohif/extension-dicom-rt@0.5.0
 - @ohif/viewer@4.7.0
2020-12-03 16:47:50 +00:00
Igor OctavianoandDavide Punzo f3cecf129b feat: Update approach to better handle rtdose instead of disabling panel
Co-authored-by: Davide Punzo <punzodavide@hotmail.it>
2020-12-03 17:36:02 +01:00
ohif-bot fe03fc6f55 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.9.3
 - @ohif/viewer@4.6.3
2020-12-03 16:11:30 +00:00
Davide Punzo b59187c74d Re #2113: disable 2D MPR when datasets have multiple slices for the same ImagePositionPatient (#2160)
fix: disable 2D MPR when datasets are 4D
2020-12-03 17:08:38 +01:00
ohif-bot 5210c80369 chore(release): publish [skip ci]
- @ohif/extension-dicom-tag-browser@0.1.1
 - @ohif/extension-vtk@1.9.2
 - @ohif/core@2.11.1
 - @ohif/ui@1.7.1
 - @ohif/viewer@4.6.2
2020-12-03 15:19:00 +00:00
Igor OctavianoandDavide Punzo f57725ac8b fix: fallback to original dataset VR for XS
Co-authored-by: Davide Punzo <punzodavide@hotmail.it>
2020-12-03 16:15:27 +01:00
ohif-bot 138e0fb3bf chore(release): publish [skip ci]
- @ohif/extension-dicom-tag-browser@0.1.0
 - @ohif/extension-vtk@1.9.1
 - @ohif/core@2.11.0
 - @ohif/ui@1.7.0
 - @ohif/viewer@4.6.1
2020-12-03 13:13:18 +00:00
be494a7376 feat: add show scroll option to modal
Co-authored-by: Erik Ziegler <erik.sweed@gmail.com>
Co-authored-by: Davide Punzo <punzodavide@hotmail.it>
2020-12-03 14:09:45 +01:00
ohif-bot ab23feefbb chore(release): publish [skip ci]
- @ohif/extension-vtk@1.9.0
 - @ohif/ui@1.6.0
 - @ohif/viewer@4.6.0
2020-12-03 12:29:32 +00:00
Igor OctavianoandDavide Punzo 4c079044f6 feat: Add error boundary and retry logic for network failures during dynamic imports (#2145)
Co-authored-by: Davide Punzo <punzodavide@hotmail.it>
2020-12-03 13:23:43 +01:00
ohif-bot 81fcfc7370 chore(release): publish [skip ci]
- @ohif/extension-dicom-tag-browser@0.0.5
2020-12-03 11:09:11 +00:00
Davide Punzo 6ec6446787 Merge pull request #2187 from OHIF/fix/tag-viewer-broken
Tag viewer broken for RTSTRUCT series
2020-12-03 11:59:58 +01:00
Davide Punzo 4b5a43641a Merge branch 'master' into fix/tag-viewer-broken 2020-12-03 11:39:23 +01:00
Erik Ziegler 2fb0b01fe2 ci: Fix release workflow issues with Gitbook-cli and missing executors (#2196) 2020-12-03 11:04:34 +01:00
ohif-bot 3632e5d495 chore(release): publish [skip ci]
- @ohif/viewer@4.5.29
2020-12-03 09:29:55 +00:00
Erik Ziegleranddannyrb dfe566e2aa ci: Use containerized PACS for running end-to-end tests #1122 (#1290)
* ci: Use containerized PACS for running end-to-end tests

* Try to fix cypress test results

Co-authored-by: dannyrb <danny.ri.brown@gmail.com>
2020-12-03 10:26:22 +01:00
Danny Brown 6c5ad9e98d change our definition of stale 2020-12-02 09:00:03 -05:00
ohif-bot aeb7d5edcc chore(release): publish [skip ci]
- @ohif/extension-vtk@1.8.0
 - @ohif/i18n@0.53.0
 - @ohif/viewer@4.5.28
2020-11-30 13:09:54 +00:00
qqalexqq d5b89748c9 feat(i18n): Added Russian language localization.
Fixes in translation, also a few new words added.

Changed 'Study List' translation (spelling changed).
2020-11-30 14:08:11 +01:00
Erik Ziegler b161016edb fix: Add syncTranslations script 2020-11-30 14:08:11 +01:00
Matthias Goetzke 2fff2d511f feat(i18n): Added de (German) translations
improved translations

Update StudyList.json

Fixed typo
2020-11-30 14:08:11 +01:00
ohif-bot cc92f91c1f chore(release): publish [skip ci]
- @ohif/viewer@4.5.27
2020-11-30 12:19:35 +00:00
matthiasg d2e777bafc fix: added MAX_CONCURRENCY limit as each webworker costs RAM, and machines with e.g 24 cores crash the process (#2161) 2020-11-30 13:17:27 +01:00
igoroctaviano c0c3ab307d Add only valid sequences 2020-11-26 13:00:54 -03:00
ohif-bot 5121913ee6 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.7.16
 - @ohif/viewer@4.5.26
2020-11-19 11:28:20 +00:00
Davide Punzo 6ef2b19925 Update vtk crosshairs logic (#2177) 2020-11-19 12:26:56 +01:00
ohif-bot f2450be255 chore(release): publish [skip ci]
- @ohif/viewer@4.5.25
2020-11-13 14:57:31 +00:00
DanielandDaniel Schiffl 04ca32a93e chore: OpenID Connect: Remove hard-coded loadUserInfo to make it configurable (#2167)
* removed hard-coded loadUserInfo

* undo styling

Co-authored-by: Daniel Schiffl <daniel.schiffl@stryker.com>
2020-11-13 15:55:43 +01:00
ohif-bot c92de6c647 chore(release): publish [skip ci]
- @ohif/viewer@4.5.24
2020-11-02 10:40:06 +00:00
Orlando Brea 5b302843d4 fix issue #2130 - With config.showStudyList : false -> Still showing hyperlink to StudyList on Not Found Component 2020-11-02 11:37:55 +01:00
ohif-bot 7eb8c4c641 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.7.15
 - @ohif/ui@1.5.7
 - @ohif/viewer@4.5.23
2020-11-02 10:35:07 +00:00
matthiasg 619f361510 fix: Reordered definitions in providers to prevent uninitialized var access (#2108) 2020-11-02 11:33:16 +01:00
ohif-bot 330eeaa216 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.7.14
 - @ohif/viewer@4.5.22
2020-10-20 12:49:10 +00:00
James Petts d627dee3b2 Update crosshairs UI and fix bug where you could scroll offscreen. (#2126)
* Update crosshairs UI and fix bug where you could scroll offscreen.

* Update tests for removed rotate tool.
2020-10-20 14:45:52 +02:00
ohif-bot d8714ea9c4 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.7.13
 - @ohif/viewer@4.5.21
2020-10-15 14:17:26 +00:00
James Petts 3c05920705 [IDC-2098] Update RVTKJSV (#2107)
* Update RVTKJSV

* Update react-vtkjs-viewport

* Fix WWWC tool with new rvtkjsv version
2020-10-15 16:15:28 +02:00
ohif-bot c6629bda75 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.7.12
 - @ohif/viewer@4.5.20
2020-10-13 16:25:26 +00:00
James Petts 588bcc9d17 Throw error if data too large in WebGL 1 enabled browser (#2106) 2020-10-13 18:23:14 +02:00
ohif-bot c31f8f9d65 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.7.11
 - @ohif/viewer@4.5.19
2020-10-13 13:06:12 +00:00
James Petts c0280e28ca Bring in rotatable crosshairs. (#2101)
* Bring in rotatable crosshairs.

* Pull in react-vtkjs-viewport 0.13.1 fix.
2020-10-13 15:00:01 +02:00
ohif-bot 7c3ac387ef chore(release): publish [skip ci]
- @ohif/extension-dicom-rt@0.4.9
 - @ohif/viewer@4.5.18
2020-10-12 08:26:15 +00:00
James Petts d6f79d9ddf [IDC-2063] Harden RTSTRUCT import (#2102)
* WIP

* Fix RTSTRUCT import with missing ContourImageSequence
2020-10-12 10:24:28 +02:00
ohif-bot 9448993cf0 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.9.6
 - @ohif/extension-dicom-html@1.2.9
 - @ohif/extension-dicom-rt@0.4.8
 - @ohif/extension-dicom-segmentation@0.4.7
 - @ohif/extension-dicom-tag-browser@0.0.4
 - @ohif/extension-vtk@1.7.10
 - @ohif/core@2.10.7
 - @ohif/viewer@4.5.17
2020-10-07 10:54:55 +00:00
James Petts 1c556b4cc3 Update dcmjs version (#2094) 2020-10-07 12:53:30 +02:00
ohif-bot 94a9067fe3 chore(release): publish [skip ci]
- @ohif/extension-debugging@0.1.6
 - @ohif/extension-dicom-rt@0.4.7
 - @ohif/extension-vtk@1.7.9
 - @ohif/ui@1.5.6
 - @ohif/viewer@4.5.16
2020-10-06 09:51:18 +00:00
James Petts cfba4df70e IDC-2064 & IDC-2059 add more options to debug extension (#2069)
* Add more to debug extension.

* Update and comment out unit tests broke from v3.
2020-10-06 11:48:56 +02:00
ohif-bot 11c1d12872 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.7.8
 - @ohif/core@2.10.6
 - @ohif/viewer@4.5.15
2020-09-30 18:03:17 +00:00
Ștefan Silviu-AlexandruandStefan Silviu 91364db882 fix: use SeriesMetadata method instead of property in findMostRecentStructuredReport (#2038)
fixes #1714

Call getInstanceCount() instead of manually checking length (which does not work)

Co-authored-by: Stefan Silviu <silviu.stefan@ab4.systems>
2020-09-30 20:01:07 +02:00
Nicolas Byl bea31d5fec fix: Enable port changes for Docker image using the PORT variable (#2016) 2020-09-30 19:55:28 +02:00
ohif-bot 48ecbc261a chore(release): publish [skip ci]
- @ohif/viewer@4.5.14
2020-09-30 10:19:10 +00:00
Woonchan ChoandWoonchan Cho 8bc467fb07 [IDC-2052] PWA start url (#2070)
Change start_url in manifest.json from "./index.html" to "./"

Co-authored-by: Woonchan Cho <wcho24@wustl.edu>
2020-09-30 12:16:18 +02:00
ohif-bot cffc44f0f4 chore(release): publish [skip ci]
- @ohif/extension-cornerstone@2.9.5
 - @ohif/viewer@4.5.13
2020-09-29 10:42:25 +00:00
James Petts ea0fc07e30 Update react-cornerstone-viewport for performance improvements (#2062)
* Update react-cornerstone-viewport

* Bump react-cornerstone-viewport version.

* Comment out tests which always cause problems.
2020-09-29 12:40:27 +02:00
ohif-bot b8d241fa33 chore(release): publish [skip ci]
- @ohif/extension-dicom-tag-browser@0.0.3
 - @ohif/viewer@4.5.12
2020-09-24 10:35:44 +00:00
James Petts ccdfcd4a85 [IDC-2049] Sort Tags in Tag browser split items in sequences, add indent after space. (#2053)
* Sort tag browser, add items, add indent.

* Remove debugger.
2020-09-24 12:34:22 +02:00
ohif-bot 6cf72d1757 chore(release): publish [skip ci]
- @ohif/extension-dicom-rt@0.4.6
 - @ohif/extension-dicom-segmentation@0.4.6
 - @ohif/viewer@4.5.11
2020-09-17 19:11:25 +00:00
James Petts bb1cdbda3a [IDC-1905] Hover tooltips for Segmentation + RTSTRUCT extension (#2044)
* WIP debug dialog

* Rename the p10 downloader extension to debugger extension, add button to toolbar. Deactivate it by default.

* Fix unit tests

* WIP

* WIP

* Finish mailTo

* tooltop
2020-09-17 21:09:46 +02:00
ohif-bot fab122dd8f chore(release): publish [skip ci]
- @ohif/extension-debugging@0.1.5
 - @ohif/extension-vtk@1.7.7
 - @ohif/ui@1.5.5
 - @ohif/viewer@4.5.10
2020-09-17 18:31:52 +00:00
James Petts 42803b0ae8 [IDC-2006] - optional mailTo for debugging extension. (#2027)
* WIP debug dialog

* Rename the p10 downloader extension to debugger extension, add button to toolbar. Deactivate it by default.

* Fix unit tests

* WIP

* WIP

* Finish mailTo
2020-09-17 20:28:08 +02:00
ohif-bot 5a78da8ff6 chore(release): publish [skip ci]
- @ohif/extension-dicom-html@1.2.8
 - @ohif/extension-dicom-microscopy@0.51.3
 - @ohif/extension-dicom-pdf@1.0.6
 - @ohif/extension-dicom-rt@0.4.5
 - @ohif/extension-dicom-segmentation@0.4.5
 - @ohif/extension-dicom-tag-browser@0.0.2
 - @ohif/extension-vtk@1.7.6
 - @ohif/core@2.10.5
 - @ohif/ui@1.5.4
 - @ohif/viewer@4.5.9
2020-09-10 10:17:12 +00:00
James Petts 0ef88e88eb [IDC-1129] - DICOM Tag Viewer extension (#2022)
* WIP render top level tags.

* Add drop down to select series.

* Fix errors with type 2 sequences.

* WIP swap instance.

* Fix formatting and make fullscreen.

* Remove debuggers.

* Finish formatting.

* Fix error with double SeriesNumber deconstruction.

* Address reviewer comments.
2020-09-10 12:13:24 +02:00
ohif-bot a7b5f1847a chore(release): publish [skip ci]
- @ohif/extension-debugging@0.1.4
 - @ohif/extension-dicom-rt@0.4.4
 - @ohif/extension-dicom-segmentation@0.4.4
 - @ohif/viewer@4.5.8
2020-09-10 09:14:18 +00:00
James Petts 5cb6e63b88 [IDC-1672] Highlight SEG segment/ RT structure when click to jump. (#2034)
* Highlight for RTSTRUCT.

* SEG temp crosshairs.

* Disable RT highlighting for now.

* Remove TODO
2020-09-10 11:11:59 +02:00
ohif-bot 48eb4a9ec3 chore(release): publish [skip ci]
- @ohif/viewer@4.5.7
2020-09-09 13:00:24 +00:00
James Petts d9231fd431 Split query parameter calls. (#2035) 2020-09-09 14:59:07 +02:00
ohif-bot e5b578bd8e chore(release): publish [skip ci]
- @ohif/extension-vtk@1.7.5
 - @ohif/core@2.10.4
 - @ohif/viewer@4.5.6
2020-09-03 13:51:56 +00:00
James Petts f38979037d IDC-1532 multiple series search google (#2026)
* Multiple series search for google cloud adapter.

* Revert IDC config.

* fix: 🐛 Series filtering on multiple series for google

* Revert changes to default config.

* Address reviewers comments.

* Fixed spelling mistakes
2020-09-03 15:48:32 +02:00
477 changed files with 27840 additions and 10253 deletions

No files matched your search

+77 -46
View File
@@ -13,11 +13,21 @@ version: 2.1
##
orbs:
codecov: codecov/codecov@1.0.5
cypress: cypress-io/cypress@1.13.0
cypress: cypress-io/cypress@1.26.0
executors:
# Custom executor to override Cypress config
deploy-to-prod-executor:
docker:
- image: 'cypress/browsers:node14.15.0-chrome86-ff82'
environment:
CYPRESS_BASE_URL: https://ohif-staging.netlify.com/
chrome-and-pacs:
docker:
# Primary container image where all steps run.
- image: 'cypress/browsers:node14.15.0-chrome86-ff82'
defaults: &defaults
docker:
- image: circleci/node:12.9.1
- image: cimg/node:14.19
environment:
TERM: xterm # Enable colors in term
QUICK_BUILD: true
@@ -36,12 +46,12 @@ jobs:
- checkout:
post:
- git fetch --all
- restore_cache:
name: Restore Yarn and Cypress Package Cache
keys:
# when lock file changes, use increasingly general patterns to restore cache
- yarn-packages-{{ checksum "yarn.lock" }}
- yarn-packages-
# - restore_cache:
# name: Restore Yarn and Cypress Package Cache
# keys:
# # when lock file changes, use increasingly general patterns to restore cache
# - yarn-packages-{{ checksum "yarn.lock" }}
# - yarn-packages-
- run:
name: Install Dependencies
command: yarn install --frozen-lockfile
@@ -95,18 +105,19 @@ jobs:
post:
- git fetch --all
- restore_cache:
name: Restore Yarn and Cypress Package Cache
keys:
# when lock file changes, use increasingly general patterns to restore cache
- yarn-packages-{{ checksum "yarn.lock" }}
- yarn-packages-
# - restore_cache:
# name: Restore Yarn and Cypress Package Cache
# keys:
# # when lock file changes, use increasingly general patterns to restore cache
# - yarn-packages-{{ checksum "yarn.lock" }}
# - yarn-packages-
- run:
name: Install Dependencies
command: yarn install --frozen-lockfile
- setup_remote_docker:
version: 19.03.13
docker_layer_caching: false
- run:
@@ -131,12 +142,12 @@ jobs:
- checkout:
post:
- git fetch --all
- restore_cache:
name: Restore Yarn and Cypress Package Cache
keys:
# when lock file changes, use increasingly general patterns to restore cache
- yarn-packages-{{ checksum "yarn.lock" }}
- yarn-packages-
# - restore_cache:
# name: Restore Yarn and Cypress Package Cache
# keys:
# # when lock file changes, use increasingly general patterns to restore cache
# - yarn-packages-{{ checksum "yarn.lock" }}
# - yarn-packages-
- run:
name: Install Dependencies
command: yarn install --frozen-lockfile
@@ -170,7 +181,7 @@ jobs:
DEPLOY_TO_DEV:
docker:
- image: circleci/node:12.9.1
- image: circleci/node:14.15.0
environment:
TERM: xterm
NETLIFY_SITE_ID: 32708787-c9b0-4634-b50f-7ca41952da77
@@ -185,7 +196,7 @@ jobs:
DEPLOY_TO_STAGING:
docker:
- image: circleci/node:12.9.1
- image: circleci/node:14.15.0
environment:
TERM: xterm
NETLIFY_SITE_ID: c7502ae3-b150-493c-8422-05701e44a969
@@ -200,7 +211,7 @@ jobs:
DEPLOY_TO_PRODUCTION:
docker:
- image: circleci/node:12.9.1
- image: circleci/node:14.15.0
environment:
TERM: xterm
NETLIFY_SITE_ID: 79c4a5da-5c95-4dc9-84f7-45fd9dfe21b0
@@ -225,11 +236,11 @@ jobs:
post:
- git fetch --all
# Use increasingly general patterns to restore cache
- restore_cache:
name: Restore Yarn and Cypress Package Cache
keys:
- yarn-packages-{{ checksum "yarn.lock" }}
- yarn-packages-
# - restore_cache:
# name: Restore Yarn and Cypress Package Cache
# keys:
# - yarn-packages-{{ checksum "yarn.lock" }}
# - yarn-packages-
- run:
name: Install Dependencies
command: yarn install --frozen-lockfile
@@ -257,7 +268,12 @@ jobs:
paths: .
DOCS_PUBLISH:
<<: *defaults
docker:
# Gitbook fails due to graceful-fs updates above this node version :-(
- image: circleci/node:12.9.1
environment:
TERM: xterm # Enable colors in term
working_directory: ~/repo
steps:
- checkout
- run:
@@ -278,6 +294,7 @@ jobs:
- attach_workspace:
at: ~/repo
- setup_remote_docker:
version: 19.03.13
docker_layer_caching: false
- run:
name: Build and push Docker image
@@ -317,16 +334,21 @@ workflows:
# E2E: PWA
- cypress/run:
name: 'E2E: PWA'
executor: cypress/browsers-chrome76
executor: chrome-and-pacs
browser: chrome
pre-steps:
- run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v && yarn global
add wait-on' # Use yarn latest
- run: |
# Clear yarn cache; update to latest
rm -rf ~/.yarn
npm i -g yarn
yarn -v
yarn: true
record: false
store_artifacts: false
record: true
store_artifacts: true
working_directory: platform/viewer
build: npx cross-env QUICK_BUILD=true yarn run build
build:
git submodule update --init && npx cross-env QUICK_BUILD=true
APP_CONFIG=config/e2e.js yarn run build
start: yarn run test:e2e:serve
spec: 'cypress/integration/common/**/*,cypress/integration/pwa/**/*'
wait-on: 'http://localhost:3000'
@@ -337,21 +359,24 @@ workflows:
path: platform/viewer/cypress/screenshots
- store_artifacts:
path: platform/viewer/cypress/videos
- store_test_results:
path: platform/viewer/cypress/results
requires:
- UNIT_TESTS
# E2E: script-tag
- cypress/run:
name: 'E2E: Script Tag'
executor: cypress/browsers-chrome76
executor: chrome-and-pacs
browser: chrome
pre-steps:
- run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v && yarn global
add wait-on' # Use yarn latest
- run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v' # Use yarn latest
yarn: true
record: false
store_artifacts: false
record: true
store_artifacts: true
working_directory: platform/viewer
build: npx cross-env QUICK_BUILD=true yarn run build:package
build:
git submodule update --init && npx cross-env QUICK_BUILD=true
APP_CONFIG=config/e2e.js yarn run build:package
start: yarn run test:e2e:serve
spec: 'cypress/integration/common/**/*,cypress/integration/script-tag/**/*'
wait-on: 'http://localhost:3000'
@@ -362,6 +387,8 @@ workflows:
path: platform/viewer/cypress/screenshots
- store_artifacts:
path: platform/viewer/cypress/videos
- store_test_results:
path: platform/viewer/cypress/results
requires:
- UNIT_TESTS
@@ -372,7 +399,7 @@ workflows:
# Update hub.docker.org
- cypress/run:
name: 'Generate Percy Snapshots'
executor: cypress/browsers-chrome76
executor: chrome-and-pacs
browser: chrome
pre-steps:
- run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v && yarn global
@@ -380,7 +407,9 @@ workflows:
yarn: true
store_artifacts: false
working_directory: platform/viewer
build: npx cross-env QUICK_BUILD=true yarn run build
build:
git submodule update --init && npx cross-env QUICK_BUILD=true
APP_CONFIG=config/e2e.js yarn run build
# start server --> verify running --> percy + chrome + cypress
command: yarn run test:e2e:dist
cache-key: 'yarn-packages-{{ checksum "yarn.lock" }}'
@@ -449,7 +478,7 @@ workflows:
# and record a Cypress dashboard test run
- cypress/run:
name: 'Generate Percy Snapshots'
executor: cypress/browsers-chrome76
executor: chrome-and-pacs
browser: chrome
pre-steps:
- run: 'rm -rf ~/.yarn && npm i -g yarn && yarn -v && yarn global
@@ -457,7 +486,9 @@ workflows:
yarn: true
store_artifacts: false
working_directory: platform/viewer
build: npx cross-env QUICK_BUILD=true yarn run build
build:
git submodule update --init && npx cross-env QUICK_BUILD=true
APP_CONFIG=config/e2e.js yarn run build
# start server --> verify running --> percy + chrome + cypress
command: yarn run test:e2e:dist
cache-key: 'yarn-packages-{{ checksum "yarn.lock" }}'
+6
View File
@@ -28,6 +28,12 @@ if [ -n "$CLIENT_ID" ] || [ -n "$HEALTHCARE_API_ENDPOINT" ]
cp /usr/share/nginx/html/google.js /usr/share/nginx/html/app-config.js
fi
if [ -n "${PORT}" ]
then
echo "Changing port to ${PORT}..."
sed -i -e "s/listen 80/listen ${PORT}/g" /etc/nginx/conf.d/default.conf
fi
echo "Starting Nginx to serve the OHIF Viewer..."
exec "$@"
+1
View File
@@ -0,0 +1 @@
custom: https://giving.massgeneral.org/ohif
@@ -1,18 +0,0 @@
---
name: "\U0001F917 Support Question"
about: "I have a question \U0001F4AC"
title: ''
labels: 'Community: Question :question:, Triage :white_flag:'
assignees: ''
---
> :hand: We are a small team with limited resources. Your question is much more
> likely to be answered if it is
> [a good question](https://stackoverflow.com/help/how-to-ask)
**Description**
Questions can often be answered by our documentation. Unable to find an answer
in our docs? We'll try to help. In the meantime, if you answer your own
question, please respond with the answer here so that others may benefit as
well. Better yet, open a PR to expand our docs ^\_^
+5
View File
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: 🤗 Support Question
url: https://community.ohif.org/
about: Please use our forum if you have questions or need help.
+2 -2
View File
@@ -2,9 +2,9 @@
# https://github.com/apps/stale
#
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 21
daysUntilStale: 180
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
daysUntilClose: 9000
# Issues with these labels will never be considered stale
exemptLabels:
- 'Story :raised_hands:'
+4 -1
View File
@@ -8,7 +8,10 @@ docs/_book
src/version.js
junit.xml
coverage/
.docz/
*.js.map
.yarn
platform/docs/.docusaurus
platform/ui/storybook-static
# YALC (for Erik)
.yalc
+3
View File
@@ -0,0 +1,3 @@
[submodule "testdata"]
path = testdata
url = https://github.com/OHIF/viewer-testdata-dicomweb.git
-10
View File
@@ -22,16 +22,6 @@ mv platform/viewer/dist/* .netlify/www/pwa -v
# Build && Move script output
# yarn run build:package
# Build && Move Docz Output
# Using local yarn install to prevent Gatsby from needing to access
# node_modules above the platform/ui folder
cd platform/ui
yarn install
yarn run build
cd ../..
mkdir -p ./.netlify/www/ui
mv platform/ui/.docz/dist/* .netlify/www/ui -v
# Cache all of the node_module dependencies in
# extensions, modules, and platform packages
yarn run lerna:cache
+1
View File
@@ -0,0 +1 @@
14.18.0
+15
View File
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}"
}
]
}
+5 -3
View File
@@ -3,7 +3,6 @@ const dotenv = require('dotenv');
//
const path = require('path');
const webpack = require('webpack');
const PACKAGE = require('../platform/viewer/package.json');
// ~~ RULES
const loadShadersRule = require('./rules/loadShaders.js');
const loadWebWorkersRule = require('./rules/loadWebWorkers.js');
@@ -29,7 +28,7 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => {
const config = {
mode: isProdBuild ? 'production' : 'development',
devtool: isProdBuild ? 'source-map' : 'cheap-module-eval-source-map',
devtool: isProdBuild ? 'source-map' : 'eval-cheap-module-source-map',
entry: {
app: `${SRC_DIR}/index.js`,
},
@@ -77,7 +76,10 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => {
'process.env.DEBUG': JSON.stringify(process.env.DEBUG),
'process.env.APP_CONFIG': JSON.stringify(process.env.APP_CONFIG || ''),
'process.env.PUBLIC_URL': JSON.stringify(process.env.PUBLIC_URL || '/'),
'process.env.VERSION_NUMBER': JSON.stringify(PACKAGE.version || ''),
'process.env.VERSION_NUMBER': webpack.DefinePlugin.runtimeValue(() => {
const package = require('../platform/viewer/package.json');
return JSON.stringify(package.version || '');
}, ['../platform/viewer/package.json']),
'process.env.BUILD_NUM': JSON.stringify(BUILD_NUM),
/* i18n */
'process.env.USE_LOCIZE': JSON.stringify(process.env.USE_LOCIZE || ''),
+24
View File
@@ -0,0 +1,24 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."
authors:
- family-names: "Ziegler"
given-names: "Erik"
orcid: "https://orcid.org/0000-0003-1857-8129"
- family-names: "Urban"
given-names: "Trinity"
- family-names: "Brown"
given-names: "Danny"
- family-names: "Petts"
given-names: "James"
- family-names: "Pieper"
given-names: "Steve D"
- family-names: "Lewis"
given-names: "Rob"
- family-names: "Hafey"
given-names: "Chris"
- family-names: "Harris"
given-names: "Gordon J"
title: "Open Health Imaging Foundation Viewer: An Extensible Open-Source Framework for Building Web-Based Imaging Applications to Support Cancer Research"
doi: 10.1200/CCI.19.00131
version: 1.0.0
url: "https://github.com/OHIF/Viewers"
+4 -3
View File
@@ -21,7 +21,7 @@
# Stage 1: Build the application
# docker build -t ohif/viewer:latest .
FROM node:10.16.3-slim as builder
FROM node:14-slim as builder
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
@@ -39,9 +39,10 @@ COPY package.json /usr/src/app/package.json
COPY postcss.config.js /usr/src/app/postcss.config.js
COPY yarn.lock /usr/src/app/yarn.lock
RUN apt-get update && apt-get install -y python make g++
# Run the install before copying the rest of the files
RUN yarn config set workspaces-experimental true
RUN yarn install
RUN yarn install --verbose
ENV PATH /usr/src/app/node_modules/.bin:$PATH
ENV QUICK_BUILD true
@@ -52,7 +53,7 @@ RUN yarn run build
# Stage 2: Bundle the built application into a Docker container
# which runs Nginx using Alpine Linux
FROM nginx:1.15.5-alpine
FROM nginx:1.21.1-alpine
RUN apk add --no-cache bash
RUN rm -rf /etc/nginx/conf.d
COPY .docker/Viewer-v2.x /etc/nginx/conf.d
+28 -2
View File
@@ -121,8 +121,7 @@ window.config = {
};
```
- Install the viewer:
`window.OHIFViewer.installViewer(window.config);`
- Install the viewer: `window.OHIFViewer.installViewer(window.config);`
This exact setup is demonstrated in this
[CodeSandbox](https://codesandbox.io/s/viewer-script-tag-tprch) and in our
@@ -259,6 +258,33 @@ Cancer Institute, Informatics Technology for Cancer Research (ITCR) program,
under a
[grant to Dr. Gordon Harris at Massachusetts General Hospital (U24 CA199460)](https://projectreporter.nih.gov/project_info_description.cfm?aid=8971104).
## Projects that contributed to OHIF Viewer
The following is a (partial) list of projects that contributed resources towards
development of OHIF Viewer:
- [NCI Imaging Data Commons (IDC) project](https://imaging.datacommons.cancer.gov/)
supported development of new features and bug fixes marked with
["IDC:priority"](https://github.com/OHIF/Viewers/issues?q=is%3Aissue+is%3Aopen+label%3AIDC%3Apriority),
["IDC:candidate"](https://github.com/OHIF/Viewers/issues?q=is%3Aissue+is%3Aopen+label%3AIDC%3Acandidate)
or
["IDC:collaboration"](https://github.com/OHIF/Viewers/issues?q=is%3Aissue+is%3Aopen+label%3AIDC%3Acollaboration).
NCI Imaging Data Commons is supported by the contract number 19X037Q from
Leidos Biomedical Research under Task Order HHSN26100071 from NCI.
[IDC Viewer](https://learn.canceridc.dev/portal/visualization) is a customized
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
MIT © [OHIF](https://github.com/OHIF)
+2 -2
View File
@@ -8,7 +8,6 @@
"-fontsettings",
"github",
"ga",
"sitemap",
"anchors",
"versions"
],
@@ -24,7 +23,8 @@
"token": "UA-110573590-2"
},
"sitemap": {
"hostname": "https://docs.ohif.org"
"hostname": "https://docs.ohif.org",
"todo": "sitemap plugin removed; causing build errors"
},
"versions": {
"gitbookConfigURL": "https://raw.githubusercontent.com/OHIF/Viewers/master/docs/book.json",
@@ -8,7 +8,9 @@ OHIF Viewer and its medical imaging data. This post covers one of many potential
setups that accomplish that. Please note, noticably absent is user account
control.
Do not use this recipe to host sensitive medical data on the open web. Depending
> **Do not use this recipe to host sensitive medical data on the open web!**
Depending
on your company's policies, this may be an appropriate setup on an internal
network when protected with a server's basic authentication. For a more robust
setup, check out our [user account control recipe](./user-account-control.md)
@@ -23,13 +25,13 @@ Our two biggest hurdles when hosting our image archive and web client are:
### Handling Web Requests
We mittigate our first issue by allowing [Nginx][nginx] to handle incoming web
We mitigate our first issue by allowing [Nginx][nginx] to handle incoming web
requests. Nginx is open source software for web serving, reverse proxying,
caching, and more. It's designed for maximum performance and stability --
allowing us to more reliably serve content than Orthanc's built-in server can.
More specifically, we accomplish this by using a
[`reverse proxy`](https://en.wikipedia.org/wiki/Reverse_proxy) to retrieve
[`reverse proxy`](https://en.wikipedia.org/wiki/Reverse_proxy) to retrieve
resources from our image archive (Orthanc), and when accessing its web admin.
> A reverse proxy is a type of proxy server that retrieves resources on behalf
@@ -38,7 +40,7 @@ resources from our image archive (Orthanc), and when accessing its web admin.
### CORS Issues
Cross-Origin Resource Sharing (CORS) is a mechanism that uses HTTP headers to
[Cross-Origin Resource Sharing][understanding-cors] (CORS) is a mechanism that uses HTTP headers to
tell a browser which web applications have permission to access selected
resources from a server at a different origin (domain, protocol, port). IE. By
default, a Web App located at `http://my-website.com` can't access resources
@@ -51,9 +53,6 @@ We can solve this one of two ways:
**This solution uses the first approach.**
You can read more about CORS in this Medium article: [Understanding
CORS][understanding-cors]
### Diagram
This setup allows us to create a setup similar to the one pictured below:
@@ -73,6 +72,8 @@ This setup allows us to create a setup similar to the one pictured below:
- Docker
- [Docker for Mac](https://docs.docker.com/docker-for-mac/)
- [Docker for Windows](https://docs.docker.com/docker-for-windows/)
- Node 16.x with optional Python and Visual Studio Build Tools ([webpack 4 has an issue](https://github.com/webpack/webpack/issues/14532) with Node 17.x)
- [Node.js](https://nodejs.org/en/download/)
_Not sure if you have `docker` installed already? Try running `docker --version`
in command prompt or terminal_
@@ -81,7 +82,7 @@ in command prompt or terminal_
_Spin Things Up_
- Navigate to `<project-root>/docker/OpenResty-Orthanc` in your shell
- Navigate to `./platform/viewer/.recipes/OpenResty-Orthanc` in your shell
- Run `docker-compose up`
_Upload Your First Study_
@@ -94,16 +95,16 @@ _Upload Your First Study_
### Troubleshooting
_Exit code 137_
#### Exit code 137
This means Docker ran out of memory. Open Docker Desktop, go to the `advanced`
tab, and increase the amount of Memory available.
_Cannot create container for service X_
#### Cannot create container for service X
Use this one with caution: `docker system prune`
_X is already running_
#### X is already running
Stop running all containers:
@@ -120,15 +121,12 @@ likely want to update:
#### OHIF Viewer
The OHIF Viewer's configuration is imported from a static `.js` file. The
configuration we use is set to a specific file when we build the viewer, and
configuration we use is set to [a specific file][config-ohif] when we build the viewer, and
determined by the env variable: `APP_CONFIG`. You can see where we set its value
in the `dockerfile` for this solution:
`ENV APP_CONFIG=config/docker_openresty-orthanc.js`
You can find the configuration we're using here:
`/public/config/docker_openresty-orthanc.js`
To rebuild the `webapp` image created by our `dockerfile` after updating the
Viewer's configuration, you can run:
@@ -137,7 +135,7 @@ Viewer's configuration, you can run:
#### Other
All other files are found in: `/docker/OpenResty-Orthanc/`
All other files in this directory include
| Service | Configuration | Docs |
| ----------------- | --------------------------------- | ------------------------------------------- |
@@ -236,6 +234,8 @@ members put together:
[orthanc-docs]: http://book.orthanc-server.com/users/configuration.html#configuration
[lua-resty-openidc-docs]: https://github.com/zmartzone/lua-resty-openidc
<!-- SRC -->
[config-ohif]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/public/config/docker_openresty-orthanc.js
[dockerfile]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc/dockerfile
[config-nginx]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc/config/nginx.conf
[config-orthanc]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/OpenResty-Orthanc/config/orthanc.json
+39 -3
View File
@@ -67,6 +67,33 @@ window.config = {
extensions: [],
showStudyList: true,
filterQueryParam: false,
/**
* Disable caching of servers configuration.
*
* There will be no effect if you update the servers property of this config
* while your application is running because this property is cached in local storage.
*/
disableServersCache: false,
/**
* OHIF's study prefetcher configuration.
*
* @param {boolean} enabled Whether to enable/disable OHIF's study prefetcher
* @param {('all'|'closest'|'downward'|'upward'|'topdown')} order Fetching order: all display sets, the closest ones, downward or top down fashion based on the currently selected display set
* @param {number} displaySetCount How much display sets should be prefetched at once (note: this attribute is ignored if order was set to 'all')
* @param {boolean} preventCache Prevent images to be cached in Cornerstone Tools's request pool manager
* @param {number} prefetchDisplaySetsTimeout Prefetch timeout
* @param {boolean} displayProgress Whether to display or not the progress bar in the display set
* @param {boolean} includeActiveDisplaySet Include or not the active display set while prefetching
*/
studyPrefetcher: {
enabled: true,
order: 'all',
displaySetCount: 1,
preventCache: false,
prefetchDisplaySetsTimeout: 300,
displayProgress: false,
includeActiveDisplaySet: true,
},
servers: {
dicomWeb: [
{
@@ -81,7 +108,14 @@ window.config = {
},
],
},
// Supported Keys: https://craig.is/killing/mice
/**
* Hotkey definitions.
* Supported Keys: https://craig.is/killing/mice
*
* @param {string} commandName
* @param {string} label
* @param {array} keys
*/
hotkeys: [
{ commandName: 'rotateViewportCW', label: 'Rotate Right', keys: ['r'] },
{ commandName: 'rotateViewportCCW', label: 'Rotate Left', keys: ['l'] },
@@ -97,14 +131,16 @@ window.config = {
keys: ['v'],
},
],
/* Configuration passed to the bundled cornerstone extension
/**
* Configuration passed to the bundled cornerstone extension
*
* The cornerstone extension is currently tightly coupled to the platform.
* Until we're able to decouple it, this key will serve as a workaround to
* pass it configuration.
*
* @param {boolean} hideHandles Whether to show/hide annotation "handles"
*/
cornerstoneExtensionConfig: {
/* Whether to show/hide annotation "handles" */
hideHandles: true,
},
};
+37
View File
@@ -0,0 +1,37 @@
# Viewer: Study Prefetcher & Stack Prefetch
Prefetching the stack of images of the active viewport is enabled by default for
cornerstone viewports via cornerstone tools's stack prefetch functionality.
In order to have a more customizable alternative for prefetching, OHIF provides
a built-in study prefetcher functionality which allows the user to set the order
in which the display sets are prefetched, the granularity, the timeout and
whether or not display a progress bar in the display set (close to the thumbnail
image) in the study browser.
You can customize these options via the viewer's configuration:
```js
window.config = {
/**
* OHIF's study prefetcher configuration.
*
* @param {boolean} enabled Whether to enable/disable OHIF's study prefetcher
* @param {('all'|'closest'|'downward'|'upward'|'topdown')} order Fetching order: all display sets, the closest ones, downward or top down fashion based on the currently selected display set
* @param {number} displaySetCount How much display sets should be prefetched at once (note: this attribute is ignored if order was set to 'all')
* @param {boolean} preventCache Prevent images to be cached in Cornerstone Tools's request pool manager
* @param {number} prefetchDisplaySetsTimeout Prefetch timeout
* @param {boolean} displayProgress Whether to display or not the progress bar in the display set
* @param {boolean} includeActiveDisplaySet Include or not the active display set while prefetching
*/
studyPrefetcher: {
enabled: true,
order: 'all',
displaySetCount: 1,
preventCache: false,
prefetchDisplaySetsTimeout: 300,
displayProgress: false,
includeActiveDisplaySet: true,
},
};
```
+2 -2
View File
@@ -8,7 +8,6 @@
"-fontsettings",
"github",
"ga",
"sitemap",
"anchors",
"versions"
],
@@ -24,7 +23,8 @@
"token": "UA-110573590-2"
},
"sitemap": {
"hostname": "https://docs.ohif.org"
"hostname": "https://docs.ohif.org",
"todo": "sitemap plugin removed; causing build errors"
},
"versions": {
"gitbookConfigURL": "https://raw.githubusercontent.com/OHIF/Viewers/master/docs/book.json",
+255
View File
@@ -3,6 +3,261 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.12.15](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.14...@ohif/extension-cornerstone@2.12.15) (2022-09-20)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.12.14](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.13...@ohif/extension-cornerstone@2.12.14) (2022-09-01)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.12.13](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.12...@ohif/extension-cornerstone@2.12.13) (2022-06-30)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.12.12](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.11...@ohif/extension-cornerstone@2.12.12) (2022-06-29)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.12.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.10...@ohif/extension-cornerstone@2.12.11) (2022-06-14)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.12.10](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.9...@ohif/extension-cornerstone@2.12.10) (2022-04-05)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.12.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.8...@ohif/extension-cornerstone@2.12.9) (2022-03-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.12.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.7...@ohif/extension-cornerstone@2.12.8) (2022-03-14)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.12.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.6...@ohif/extension-cornerstone@2.12.7) (2022-02-03)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.12.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.5...@ohif/extension-cornerstone@2.12.6) (2022-02-03)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.12.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.4...@ohif/extension-cornerstone@2.12.5) (2022-02-02)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [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)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [2.12.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.11.0...@ohif/extension-cornerstone@2.12.0) (2021-09-23)
### Features
* Update to WADO Image Loader 4.0.3 to add dynamically imported WebAssembly codec support 🚀 ([#2537](https://github.com/OHIF/Viewers/issues/2537)) ([489d4b0](https://github.com/OHIF/Viewers/commit/489d4b0584f4657ceda1c5b9b68d5e9733827e47))
# [2.11.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.10.10...@ohif/extension-cornerstone@2.11.0) (2021-09-09)
### Features
* OHIF-1000: Study prefetcher ([#2466](https://github.com/OHIF/Viewers/issues/2466)) ([8f26045](https://github.com/OHIF/Viewers/commit/8f2604509d24092b721f1333289d838820d68cac))
## [2.10.10](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.10.9...@ohif/extension-cornerstone@2.10.10) (2021-07-26)
### Bug Fixes
* changed new image handler conditional for 0 edge case ([#2338](https://github.com/OHIF/Viewers/issues/2338)) ([b8ae92c](https://github.com/OHIF/Viewers/commit/b8ae92c2d4f733b3ca89826118029685650b396a))
## [2.10.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.10.8...@ohif/extension-cornerstone@2.10.9) (2021-06-02)
### Bug Fixes
* **dicom-html:** Add parsed dicom meta info section ([#2419](https://github.com/OHIF/Viewers/issues/2419)) ([403688b](https://github.com/OHIF/Viewers/commit/403688b18c52468fc1101166ec0c1734fb710039))
## [2.10.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.10.7...@ohif/extension-cornerstone@2.10.8) (2021-05-17)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.10.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.10.6...@ohif/extension-cornerstone@2.10.7) (2021-04-15)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.10.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.10.5...@ohif/extension-cornerstone@2.10.6) (2021-03-26)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.10.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.10.4...@ohif/extension-cornerstone@2.10.5) (2021-03-15)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.10.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.10.3...@ohif/extension-cornerstone@2.10.4) (2021-03-09)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.10.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.10.2...@ohif/extension-cornerstone@2.10.3) (2021-03-03)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.10.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.10.1...@ohif/extension-cornerstone@2.10.2) (2021-02-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.10.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.10.0...@ohif/extension-cornerstone@2.10.1) (2021-02-05)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [2.10.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.9.6...@ohif/extension-cornerstone@2.10.0) (2020-12-10)
### Features
* visualize overlapping segments in cornerstone ([#2185](https://github.com/OHIF/Viewers/issues/2185)) ([29fceac](https://github.com/OHIF/Viewers/commit/29fceacee97d51f1952a0f6b574c66596d32c201))
## [2.9.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.9.5...@ohif/extension-cornerstone@2.9.6) (2020-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.9.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.9.4...@ohif/extension-cornerstone@2.9.5) (2020-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone
## [2.9.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.9.3...@ohif/extension-cornerstone@2.9.4) (2020-09-03)
**Note:** Version bump only for package @ohif/extension-cornerstone
+23 -2
View File
@@ -85,12 +85,32 @@ Tools can be configured through extension configuration using the tools key:
...
```
## Stack prefetch configuration
Stack prefetch can be configured through extension configuration using the
stackPrefetch key:
```js
...
cornerstoneExtensionConfig: {
stackPrefetch: {
enabled: true,
maxImagesToPrefetch: Infinity,
preserveExistingPool: false,
maxSimultaneousRequests: 20,
},
},
...
```
## Annotate Tools Configuration
*We currently support one property for annotation tools.*
_We currently support one property for annotation tools._
### Hide handles
This extension configuration allows you to toggle on/off handle rendering for all annotate tools:
This extension configuration allows you to toggle on/off handle rendering for
all annotate tools:
```js
...
@@ -119,3 +139,4 @@ This extension configuration allows you to toggle on/off handle rendering for al
[cornerstone-tools]: https://github.com/cornerstonejs/cornerstoneTools
[cornerstone]: https://github.com/cornerstonejs/cornerstone
<!-- prettier-ignore-end -->
```
+10 -9
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone",
"version": "2.9.4",
"version": "2.12.15",
"description": "OHIF extension for Cornerstone",
"author": "OHIF",
"license": "MIT",
@@ -32,25 +32,26 @@
"peerDependencies": {
"@ohif/core": "^0.50.0",
"@ohif/ui": "^0.50.0",
"cornerstone-core": "^2.2.8",
"cornerstone-math": "^0.1.8",
"cornerstone-tools": "^4.20.1",
"cornerstone-wado-image-loader": "^3.1.0",
"dcmjs": "0.16.3",
"dicom-parser": "^1.8.3",
"cornerstone-core": "^2.6.1",
"cornerstone-math": "^0.1.9",
"cornerstone-tools": "^6.0.6",
"cornerstone-wado-image-loader": "^4.2.1",
"dcmjs": "0.24.10",
"dicom-parser": "^1.8.11",
"hammerjs": "^2.0.8",
"prop-types": "^15.6.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-redux": "^6.0.0",
"react-resize-detector": "^3.4.0",
"redux": "^4.0.1"
"redux": "^4.0.1",
"styled-components": "^5.3.5"
},
"dependencies": {
"@babel/runtime": "^7.5.5",
"classnames": "^2.2.6",
"lodash.merge": "^4.6.2",
"lodash.throttle": "^4.1.1",
"react-cornerstone-viewport": "4.0.2"
"react-cornerstone-viewport": "4.1.1"
}
}
@@ -3,6 +3,7 @@ import OHIF from '@ohif/core';
import { connect } from 'react-redux';
import throttle from 'lodash.throttle';
import { setEnabledElement } from './state';
import initSRTools from './tools/initSRTools';
const { setViewportActive, setViewportSpecificData } = OHIF.redux.actions;
const {
@@ -53,7 +54,11 @@ const mapStateToProps = (state, ownProps) => {
// Currently justing using escape hatch + commands
// activeTool: activeButton && activeButton.command,
...dataFromStore,
isStackPrefetchEnabled: isActive,
isStackPrefetchEnabled: ownProps.hasOwnProperty('isStackPrefetchEnabled')
? ownProps.isStackPrefetchEnabled
: ownProps.stackPrefetch
? ownProps.stackPrefetch.enabled
: isActive,
isPlaying,
frameRate,
//stack: viewportSpecificData.stack,
@@ -88,6 +93,7 @@ const mapDispatchToProps = (dispatch, ownProps) => {
plugin: 'cornerstone',
})
);
initSRTools(enabledElement);
},
onMeasurementsChanged: (event, action) => {
@@ -1,9 +1,11 @@
import React, { Component } from 'react';
import OHIFCornerstoneViewportOverlay from './components/OHIFCornerstoneViewportOverlay';
import ConnectedCornerstoneViewport from './ConnectedCornerstoneViewport';
import OHIF from '@ohif/core';
import PropTypes from 'prop-types';
import cornerstone from 'cornerstone-core';
import checkForSRAnnotations from './tools/checkForSRAnnotations';
const { StackManager } = OHIF.utils;
@@ -14,6 +16,7 @@ class OHIFCornerstoneViewport extends Component {
static defaultProps = {
customProps: {},
isStackPrefetchEnabled: true,
};
static propTypes = {
@@ -22,6 +25,8 @@ class OHIFCornerstoneViewport extends Component {
viewportIndex: PropTypes.number,
children: PropTypes.node,
customProps: PropTypes.object,
stackPrefetch: PropTypes.object,
isStackPrefetchEnabled: PropTypes.bool,
};
static id = 'OHIFCornerstoneViewport';
@@ -179,10 +184,12 @@ class OHIFCornerstoneViewport extends Component {
if (
displaySet.displaySetInstanceUID !==
prevDisplaySet.displaySetInstanceUID ||
prevDisplaySet.displaySetInstanceUID ||
displaySet.SOPInstanceUID !== prevDisplaySet.SOPInstanceUID ||
displaySet.frameIndex !== prevDisplaySet.frameIndex
) {
const { viewportIndex } = this.props;
checkForSRAnnotations({ displaySet, viewportIndex });
this.setStateFromProps();
}
}
@@ -194,6 +201,7 @@ class OHIFCornerstoneViewport extends Component {
return null;
}
const { viewportIndex } = this.props;
const { inconsistencyWarnings } = this.props.viewportData.displaySet;
const {
imageIds,
currentImageIdIndex,
@@ -219,7 +227,7 @@ class OHIFCornerstoneViewport extends Component {
const { displaySet } = this.props.viewportData;
const { StudyInstanceUID } = displaySet;
if (currentImageIdIndex > 0) {
if (currentImageIdIndex >= 0) {
this.props.onNewImage({
StudyInstanceUID,
SOPInstanceUID: sopInstanceUid,
@@ -229,18 +237,39 @@ class OHIFCornerstoneViewport extends Component {
}
};
const overlay = props => {
const displaySet = this.props.viewportData.displaySet;
let filteredSRLabels;
if (displaySet.SRLabels && displaySet.SRLabels.length !== 0) {
filteredSRLabels = displaySet.SRLabels.filter(
SRLabel =>
SRLabel.ReferencedSOPInstanceUID === displaySet.SOPInstanceUID
);
}
return (
<OHIFCornerstoneViewportOverlay
{...props}
inconsistencyWarnings={inconsistencyWarnings}
SRLabels={filteredSRLabels}
/>
);
};
return (
<>
<ConnectedCornerstoneViewport
viewportIndex={viewportIndex}
imageIds={imageIds}
imageIdIndex={currentImageIdIndex}
onNewImage={newImageHandler}
onNewImageDebounceTime={700}
onNewImageDebounced={newImageHandler}
onNewImageDebounceTime={300}
viewportOverlayComponent={overlay}
stackPrefetch={this.props.stackPrefetch}
isStackPrefetchEnabled={this.props.isStackPrefetchEnabled}
// ~~ Connected (From REDUX)
// frameRate={frameRate}
// isPlaying={false}
// isStackPrefetchEnabled={true}
// onElementEnabled={() => {}}
// setViewportActive{() => {}}
{...this.props.customProps}
+8 -1
View File
@@ -268,6 +268,7 @@ const commandsModule = ({ servicesManager }) => {
SOPInstanceUID,
frameIndex,
activeViewportIndex,
refreshViewports = true,
}) => {
const study = studyMetadataManager.get(StudyInstanceUID);
@@ -278,6 +279,10 @@ const commandsModule = ({ servicesManager }) => {
);
});
if (!displaySet) {
return;
}
displaySet.SOPInstanceUID = SOPInstanceUID;
displaySet.frameIndex = frameIndex;
@@ -285,7 +290,9 @@ const commandsModule = ({ servicesManager }) => {
setViewportSpecificData(activeViewportIndex, displaySet)
);
refreshCornerstoneViewports();
if (refreshViewports) {
refreshCornerstoneViewports();
}
},
};
@@ -0,0 +1,73 @@
.imageViewerViewport.empty ~ .OHIFCornerstoneViewportOverlay {
display: none;
}
.OHIFCornerstoneViewportOverlay {
color: #9ccef9;
}
.OHIFCornerstoneViewportOverlay .overlay-element {
position: absolute;
font-weight: 400;
text-shadow: 1px 1px #000;
pointer-events: none;
}
.OHIFCornerstoneViewportOverlay .top-left {
top: 20px;
left: 20px;
}
.OHIFCornerstoneViewportOverlay .top-center {
top: 20px;
padding-top: 20px;
width: 100%;
text-align: center;
}
.OHIFCornerstoneViewportOverlay .top-right {
top: 20px;
right: 20px;
text-align: right;
}
.OHIFCornerstoneViewportOverlay .bottom-left {
bottom: 20px;
left: 20px;
}
.OHIFCornerstoneViewportOverlay .bottom-left2 {
bottom: 140px;
left: 20px;
}
.OHIFCornerstoneViewportOverlay .bottom-left3 {
bottom: 110px;
left: -20px;
}
.OHIFCornerstoneViewportOverlay .bottom-right {
bottom: 20px;
right: 20px;
text-align: right;
}
.OHIFCornerstoneViewportOverlay.controlsVisible .topright,
.OHIFCornerstoneViewportOverlay.controlsVisible .bottomright {
right: calc(20px + 19px);
}
.OHIFCornerstoneViewportOverlay .warning {
position: absolute;
font-weight: 400;
text-shadow: 1px 1px #000;
pointer-events: inherit;
}
.OHIFCornerstoneViewportOverlay .warning svg {
opacity: 1;
color: #e29e4a;
fill: #e29e4a;
stroke: #e29e4a;
width: 32px;
height: 28px;
}
.OHIFCornerstoneViewportOverlay svg {
color: #9ccef9;
fill: #9ccef9;
stroke: #9ccef9;
background-color: transparent;
margin: 2px;
width: 18px;
height: 18px;
}
@@ -0,0 +1,267 @@
import { PureComponent } from 'react';
import React from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import cornerstone from 'cornerstone-core';
import './OHIFCornerstoneViewportOverlay.css';
import {
isValidNumber,
formatNumberPrecision,
formatDICOMDate,
formatDICOMTime,
formatPN,
getCompression,
} from '../utils/formatStudy';
import classNames from 'classnames';
import { Icon } from '@ohif/ui/src/elements/Icon';
import { Tooltip } from '@ohif/ui/src/components/tooltip';
import { OverlayTrigger } from '@ohif/ui/src/components/overlayTrigger';
const Button = styled.button`
color: white;
padding: 2px 7px;
border-radius: 10px;
outline: 0;
text-transform: none;
margin: 2px 2px;
cursor: pointer;
&:disabled {
cursor: default;
opacity: 0.9;
}
`;
class OHIFCornerstoneViewportOverlay extends PureComponent {
static propTypes = {
scale: PropTypes.number.isRequired,
windowWidth: PropTypes.oneOfType([
PropTypes.number.isRequired,
PropTypes.string.isRequired,
]),
windowCenter: PropTypes.oneOfType([
PropTypes.number.isRequired,
PropTypes.string.isRequired,
]),
imageId: PropTypes.string.isRequired,
imageIndex: PropTypes.number.isRequired,
stackSize: PropTypes.number.isRequired,
inconsistencyWarnings: PropTypes.array,
SRLabels: PropTypes.array,
};
render() {
const {
imageId,
scale,
windowWidth,
windowCenter,
inconsistencyWarnings,
SRLabels,
} = this.props;
if (!imageId) {
return null;
}
const zoomPercentage = formatNumberPrecision(scale * 100, 0);
const seriesMetadata =
cornerstone.metaData.get('generalSeriesModule', imageId) || {};
const imagePlaneModule =
cornerstone.metaData.get('imagePlaneModule', imageId) || {};
const { rows, columns, sliceThickness, sliceLocation } = imagePlaneModule;
const { seriesNumber, seriesDescription } = seriesMetadata;
const generalStudyModule =
cornerstone.metaData.get('generalStudyModule', imageId) || {};
const { studyDate, studyTime, studyDescription } = generalStudyModule;
const patientModule =
cornerstone.metaData.get('patientModule', imageId) || {};
const { patientId, patientName } = patientModule;
const generalImageModule =
cornerstone.metaData.get('generalImageModule', imageId) || {};
const { instanceNumber } = generalImageModule;
const cineModule = cornerstone.metaData.get('cineModule', imageId) || {};
const { frameTime } = cineModule;
const frameRate = formatNumberPrecision(1000 / frameTime, 1);
const compression = getCompression(imageId);
const wwwc = `W: ${
windowWidth.toFixed ? windowWidth.toFixed(0) : windowWidth
} L: ${windowWidth.toFixed ? windowCenter.toFixed(0) : windowCenter}`;
const imageDimensions = `${columns} x ${rows}`;
const { imageIndex, stackSize } = this.props;
const inconsistencyWarningsOn =
inconsistencyWarnings && inconsistencyWarnings.length !== 0
? true
: false;
const getWarningContent = warningList => {
if (Array.isArray(warningList)) {
const listedWarnings = warningList.map((warn, index) => {
return <li key={index}>{warn}</li>;
});
return <ol>{listedWarnings}</ol>;
} else {
return <React.Fragment>{warningList}</React.Fragment>;
}
};
const getWarningInfo = (seriesNumber, inconsistencyWarnings) => {
return (
<React.Fragment>
{inconsistencyWarnings.length != 0 ? (
<OverlayTrigger
key={seriesNumber}
placement="left"
overlay={
<Tooltip
placement="left"
className="in tooltip-warning"
id="tooltip-left"
>
<div className="warningTitle">Series Inconsistencies</div>
<div className="warningContent">
{getWarningContent(inconsistencyWarnings)}
</div>
</Tooltip>
}
>
<div className={classNames('warning')}>
<span className="warning-icon">
<Icon name="exclamation-triangle" />
</span>
</div>
</OverlayTrigger>
) : (
<React.Fragment></React.Fragment>
)}
</React.Fragment>
);
};
const SRLabelsOn = SRLabels && SRLabels.length !== 0 ? true : false;
/**/
const getSRLabelsContent = SRLabels => {
if (Array.isArray(SRLabels)) {
const listedSRLabels = SRLabels.map((SRLabel, index) => {
const color = SRLabel.labels.color;
return (
SRLabel.labels.visible && (
<OverlayTrigger
key={index}
placement="top"
overlay={
<Tooltip
placement="top"
className="in tooltip-warning"
id="tooltip-top"
>
<div className="warningTitle">
{' '}
Coding scheme designators{' '}
</div>
<div className="warningContent">
{SRLabel.labels.labelCodingSchemeDesignator +
' : ' +
SRLabel.labels.valueCodingSchemeDesignator}
</div>
</Tooltip>
}
>
<div style={{ display: 'inline-block' }}>
<Button
style={{
backgroundColor: color,
}}
disabled={true}
key={index}
>
{SRLabel.labels.label + ' : ' + SRLabel.labels.value}
</Button>
</div>
</OverlayTrigger>
)
);
});
return <ol>{listedSRLabels}</ol>;
} else {
return <React.Fragment></React.Fragment>;
}
};
const getSRLabelsInfo = SRLabels => {
return (
<React.Fragment>
{SRLabels.length != 0 ? (
getSRLabelsContent(SRLabels)
) : (
<React.Fragment></React.Fragment>
)}
</React.Fragment>
);
};
const normal = (
<React.Fragment>
<div className="top-left overlay-element">
<div>{formatPN(patientName)}</div>
<div>{patientId}</div>
</div>
<div className="top-right overlay-element">
<div>{studyDescription}</div>
<div>
{formatDICOMDate(studyDate)} {formatDICOMTime(studyTime)}
</div>
</div>
<div className="bottom-right overlay-element">
<div>Zoom: {zoomPercentage}%</div>
<div>{wwwc}</div>
<div className="compressionIndicator">{compression}</div>
</div>
<div className="bottom-left2 warning">
<div>
{inconsistencyWarningsOn
? getWarningInfo(seriesNumber, inconsistencyWarnings)
: ''}
</div>
</div>
<div className="bottom-left3 warning">
<div>{SRLabelsOn ? getSRLabelsInfo(SRLabels) : ''}</div>
</div>
<div className="bottom-left overlay-element">
<div>{seriesNumber >= 0 ? `Ser: ${seriesNumber}` : ''}</div>
<div>
{stackSize > 1
? `Img: ${instanceNumber} ${imageIndex}/${stackSize}`
: ''}
</div>
<div>
{frameRate >= 0 ? `${formatNumberPrecision(frameRate, 2)} FPS` : ''}
<div>{imageDimensions}</div>
<div>
{isValidNumber(sliceLocation)
? `Loc: ${formatNumberPrecision(sliceLocation, 2)} mm `
: ''}
{sliceThickness
? `Thick: ${formatNumberPrecision(sliceThickness, 2)} mm`
: ''}
</div>
<div>{seriesDescription}</div>
</div>
</div>
</React.Fragment>
);
return <div className="OHIFCornerstoneViewportOverlay">{normal}</div>;
}
}
export default OHIFCornerstoneViewportOverlay;
+18 -2
View File
@@ -36,13 +36,29 @@ export default {
preRegistration({ servicesManager, configuration = {} }) {
init({ servicesManager, configuration });
},
getViewportModule({ commandsManager }) {
getViewportModule({ commandsManager, appConfig }) {
const ExtendedOHIFCornerstoneViewport = props => {
/**
* TODO: This appears to be used to set the redux parameters for
* the viewport when new images are loaded. It's very ugly
* and we should remove it.
*/
const onNewImageHandler = jumpData => {
/** Do not trigger all viewports to render unnecessarily */
jumpData.refreshViewports = false;
commandsManager.runCommand('jumpToImage', jumpData);
};
const { studyPrefetcher } = appConfig;
const isStackPrefetchEnabled =
studyPrefetcher && !studyPrefetcher.enabled;
return (
<OHIFCornerstoneViewport {...props} onNewImage={onNewImageHandler} />
<OHIFCornerstoneViewport
{...props}
onNewImage={onNewImageHandler}
isStackPrefetchEnabled={isStackPrefetchEnabled}
/>
);
};
+13 -2
View File
@@ -5,6 +5,8 @@ import csTools from 'cornerstone-tools';
import merge from 'lodash.merge';
import initCornerstoneTools from './initCornerstoneTools.js';
import measurementServiceMappingsFactory from './utils/measurementServiceMappings/measurementServiceMappingsFactory';
import dicomSRModule from './tools/modules/dicomSRModule';
import srModuleId from './tools/id';
/**
*
@@ -15,6 +17,8 @@ import measurementServiceMappingsFactory from './utils/measurementServiceMapping
export default function init({ servicesManager, configuration }) {
const { UIDialogService, MeasurementService } = servicesManager.services;
csTools.register('module', srModuleId, dicomSRModule);
const callInputDialog = (data, event, callback) => {
if (UIDialogService) {
let dialogId = UIDialogService.create({
@@ -37,7 +41,14 @@ export default function init({ servicesManager, configuration }) {
}
};
const { csToolsConfig } = configuration;
const {
csToolsConfig,
stackPrefetch = {
maxImagesToPrefetch: Infinity,
preserveExistingPool: false,
maxSimultaneousRequests: 20,
},
} = configuration;
const metadataProvider = OHIF.cornerstone.metadataProvider;
cornerstone.metaData.addProvider(
@@ -52,7 +63,7 @@ export default function init({ servicesManager, configuration }) {
autoResizeViewports: false,
};
initCornerstoneTools(defaultCsToolsConfig);
initCornerstoneTools({ ...defaultCsToolsConfig, ...stackPrefetch });
const toolsGroupedByType = {
touch: [csTools.PanMultiTouchTool, csTools.ZoomTouchPinchTool],
@@ -37,8 +37,8 @@ export default function(configuration = {}) {
// Configure stack prefetch
cornerstoneTools.stackPrefetch.setConfiguration({
maxImagesToPrefetch: Infinity,
preserveExistingPool: false,
maxSimultaneousRequests: 20,
maxImagesToPrefetch: configuration.maxImagesToPrefetch,
preserveExistingPool: configuration.preserveExistingPool,
maxSimultaneousRequests: configuration.maxSimultaneousRequests,
});
}
@@ -0,0 +1,419 @@
import csTools, {
importInternal,
getToolState,
toolColors,
} from 'cornerstone-tools';
import cornerstone from 'cornerstone-core';
/** Internal imports */
import TOOL_NAMES from './constants/toolNames';
import SCOORD_TYPES from './constants/scoordTypes';
import id from './id';
/** Cornerstone 3rd party dev kit imports */
const draw = importInternal('drawing/draw');
const drawJoinedLines = importInternal('drawing/drawJoinedLines');
const drawCircle = importInternal('drawing/drawCircle');
const drawEllipse = importInternal('drawing/drawEllipse');
const drawHandles = importInternal('drawing/drawHandles');
const drawArrow = importInternal('drawing/drawArrow');
const getNewContext = importInternal('drawing/getNewContext');
const BaseTool = importInternal('base/BaseTool');
const drawLinkedTextBox = importInternal('drawing/drawLinkedTextBox');
/**
* @class DICOMSRDisplayTool - Renders DICOMSR data in a read only manner (i.e. as an overlay).
*
* This is a generic render tool.
*
* A single tool that, given some schema, can render
* POINT, MULTIPOINT, POLYLINE, CIRCLE, and ELLIPSE
* value types for a given imageId.
*
*
* @extends cornerstoneTools.BaseTool
*/
export default class DICOMSRDisplayTool extends BaseTool {
constructor(props = {}) {
const defaultProps = {
mixins: ['enabledOrDisabledBinaryTool'],
name: TOOL_NAMES.DICOM_SR_DISPLAY_TOOL,
};
const initialProps = Object.assign(defaultProps, props);
super(initialProps);
this._module = csTools.getModule(id);
}
renderToolData(evt) {
const eventData = evt.detail;
const { element } = eventData;
const module = this._module;
const toolState = getToolState(element, this.name);
if (!toolState) {
return;
}
const trackingUniqueIdentifiersForElement = module.getters.trackingUniqueIdentifiersForElement(
element
);
const {
activeIndex,
trackingUniqueIdentifiers,
} = trackingUniqueIdentifiersForElement;
const activeTrackingUniqueIdentifier =
trackingUniqueIdentifiers[activeIndex];
// Filter toolData to only render the data for the active SR.
const filteredToolData = toolState.data.filter(td =>
trackingUniqueIdentifiers.includes(td.TrackingUniqueIdentifier)
);
let shouldRepositionTextBoxes = false;
for (let i = 0; i < filteredToolData.length; i++) {
const data = filteredToolData[i];
const { renderableData, labels } = data;
const color =
data.TrackingUniqueIdentifier === activeTrackingUniqueIdentifier
? toolColors.getActiveColor()
: toolColors.getToolColor();
const lineWidth = 2;
const options = {
color,
lineWidth,
handleRadius: 6,
};
Object.keys(renderableData).forEach(GraphicType => {
const renderableDataForGraphicType = renderableData[GraphicType];
switch (GraphicType) {
case SCOORD_TYPES.TEXT:
break;
case SCOORD_TYPES.POINT:
this.renderPoint(renderableDataForGraphicType, eventData, options);
break;
case SCOORD_TYPES.MULTIPOINT:
this.renderMultipoint(
renderableDataForGraphicType,
eventData,
options
);
break;
case SCOORD_TYPES.POLYGON:
case SCOORD_TYPES.POLYLINE:
this.renderPolyLine(
renderableDataForGraphicType,
eventData,
options
);
break;
case SCOORD_TYPES.CIRCLE:
this.renderCircle(renderableDataForGraphicType, eventData, options);
break;
case SCOORD_TYPES.ELLIPSE:
this.renderEllipse(
renderableDataForGraphicType,
eventData,
options
);
break;
}
});
const { element } = eventData;
const context = getNewContext(eventData.canvasContext.canvas);
if (!data.handles || !data.handles.textBox) {
const textBox = {
active: false,
hasMoved: true,
movesIndependently: false,
drawnIndependently: true,
allowedOutsideImage: true,
hasBoundingBox: true,
};
const anchorPoints = _getTextBoxAnchorPointsForRenderableData(
renderableData,
eventData
);
textBox.anchorPoints = anchorPoints;
const bottomRight = {
x: Math.max(...anchorPoints.map(point => point.x)),
y: Math.max(...anchorPoints.map(point => point.y)),
};
textBox.x = bottomRight.x;
textBox.y = bottomRight.y;
data.handles = {};
data.handles.textBox = textBox;
shouldRepositionTextBoxes = true;
}
const text = _getTextBoxLinesFromLabels(labels);
function textBoxAnchorPoints() {
return data.handles.textBox.anchorPoints;
}
if (data.handles.textBox.anchorPoints.length !== 0) {
draw(context, context => {
drawLinkedTextBox(
context,
element,
data.handles.textBox,
text,
data.handles,
textBoxAnchorPoints,
color,
lineWidth,
0,
true
);
});
}
}
// TOOD -> text boxes may overlap with other annotations at the moment.
// To be fixed after we get requirements.
// if (shouldRepositionTextBoxes) {
// this.repositionTextBox(filteredToolData, eventData);
// }
}
// repositionTextBox(toolData, eventData) {
// const toolBoundingBoxes = [];
// for (let i = 0; i < toolData.length; i++) {
// const toolDataI = toolData[i];
// const { textBox } = toolDataI.handles;
// const { anchorPoints } = textBox;
// const boundingBox = _getBoundingBoxFromAnchorPoints(anchorPoints);
// // Get the textbox bounding locations.
// // Get the tool extents.
// }
// }
renderPolyLine(renderableData, eventData, options) {
const { element } = eventData;
const context = getNewContext(eventData.canvasContext.canvas);
renderableData.forEach(points => {
draw(context, context => {
drawJoinedLines(context, element, points[0], points, options);
});
});
}
renderMultipoint(renderableData, eventData, options) {
const context = getNewContext(eventData.canvasContext.canvas);
renderableData.forEach(points => {
draw(context, context => {
drawHandles(context, eventData, points, options);
});
});
}
renderPoint(renderableData, eventData, options) {
// Render single point as an arrow.
const { element, image } = eventData;
const { rows, columns } = image;
const context = getNewContext(eventData.canvasContext.canvas);
const { color, lineWidth } = options;
// Find a suitable length for the image size.
const xOffset = columns / 10;
const yOffset = rows / 10;
renderableData.forEach(points => {
const point = points[0]; // The SCOORD type is POINT so the array length is 1.
draw(context, context => {
// Draw the arrow
const handleStartCanvas = cornerstone.pixelToCanvas(element, point);
const handleEndCanvas = cornerstone.pixelToCanvas(element, {
x: point.x + xOffset,
y: point.y + yOffset,
});
drawArrow(
context,
handleEndCanvas,
handleStartCanvas,
color,
lineWidth,
false
);
});
});
}
renderCircle(renderableData, eventData, options) {
const { element } = eventData;
const context = getNewContext(eventData.canvasContext.canvas);
renderableData.forEach(circle => {
const { center, radius } = circle;
drawCircle(context, element, center, radius, options);
});
}
renderEllipse(renderableData, eventData, options) {
const { element } = eventData;
const context = getNewContext(eventData.canvasContext.canvas);
renderableData.forEach(ellipse => {
const { corner1, corner2 } = ellipse;
drawEllipse(
context,
element,
corner1,
corner2,
options,
'pixel',
0 // TODO -> Work our the initial rotation and add it here so we render appropriately rotated ellipses.
);
});
}
}
function _getTextBoxLinesFromLabels(labels) {
// TODO -> max 3 for now (label + shortAxis + longAxis), need a generic solution for this!
const labelLength = Math.min(labels.length, 3);
const lines = [];
for (let i = 0; i < labelLength; i++) {
const labelEntry = labels[i];
lines.push(`${_labelToShorthand(labelEntry.label)}${labelEntry.value}`);
}
return lines;
}
const SHORT_HAND_MAP = {
'Short Axis': 'W ',
'Long Axis': 'L ',
AREA: 'Area ',
Length: '',
CORNERSTONEFREETEXT: '',
};
function _labelToShorthand(label) {
const shortHand = SHORT_HAND_MAP[label];
if (shortHand !== undefined) {
return shortHand;
}
return label;
}
function _getTextBoxAnchorPointsForRenderableData(renderableData, eventData) {
let anchorPoints = [];
Object.keys(renderableData).forEach(GraphicType => {
const renderableDataForGraphicType = renderableData[GraphicType];
switch (GraphicType) {
case SCOORD_TYPES.TEXT:
break;
case SCOORD_TYPES.POINT:
renderableDataForGraphicType.forEach(points => {
anchorPoints = [...anchorPoints, ...points];
// Add other arrow point based on image size.
const { image } = eventData;
const { rows, columns } = image;
const xOffset = columns / 10;
const yOffset = rows / 10;
const point = points[0];
anchorPoints.push({ x: point.x + xOffset, y: point.y + yOffset });
});
break;
case SCOORD_TYPES.MULTIPOINT:
case SCOORD_TYPES.POLYLINE:
case SCOORD_TYPES.POLYGON:
renderableDataForGraphicType.forEach(points => {
anchorPoints = [...anchorPoints, ...points];
});
break;
case SCOORD_TYPES.CIRCLE:
renderableDataForGraphicType.forEach(circle => {
const { center, radius } = circle;
anchorPoints.push({ x: center.x + radius, y: center.y });
anchorPoints.push({ x: center.x - radius, y: center.y });
anchorPoints.push({ x: center.x, y: center.y + radius });
anchorPoints.push({ x: center.x, y: center.y - radius });
});
break;
case SCOORD_TYPES.ELLIPSE:
renderableDataForGraphicType.forEach(ellipse => {
const { corner1, corner2 } = ellipse;
const halfWidth = Math.abs(corner1.x - corner2.x) / 2;
const halfHeight = Math.abs(corner1.y - corner2.y) / 2;
const center = {
x: (corner1.x + corner2.x) / 2,
y: (corner1.y + corner2.y) / 2,
};
anchorPoints.push({ x: center.x + halfWidth, y: center.y });
anchorPoints.push({ x: center.x - halfWidth, y: center.y });
anchorPoints.push({ x: center.x, y: center.y + halfHeight });
anchorPoints.push({ x: center.x, y: center.y - halfHeight });
});
break;
}
});
return anchorPoints;
}
function _getBoundingBoxFromAnchorPoints(anchorPoints) {
let minX = Infinity;
let maxX = -Infinity;
let minY = Infinity;
let maxY = -Infinity;
anchorPoints.forEach(point => {
const { x, y } = point;
if (x > maxX) {
maxX = x;
} else if (x < minX) {
minX = x;
}
if (y > maxY) {
maxY = y;
} else if (y < minY) {
minY = y;
}
});
}
@@ -0,0 +1,57 @@
import csTools from 'cornerstone-tools';
import cs from 'cornerstone-core';
import OHIF from '@ohif/core';
import { getEnabledElement } from '../state';
import id from './id';
const { studyMetadataManager } = OHIF.utils;
const checkForSRAnnotations = ({ viewportIndex, displaySet }) => {
const srModule = csTools.getModule(id);
const element = getEnabledElement(viewportIndex);
if (!element) {
return;
}
const { StudyInstanceUID } = displaySet;
const studyMetadata = studyMetadataManager.get(StudyInstanceUID);
if (!studyMetadata) {
return;
}
const srDisplaySets = studyMetadata
.getDisplaySets()
.filter(ds => ds.Modality === 'SR');
if (srDisplaySets.length === 0) {
return;
}
const { measurements: _measurements } = srDisplaySets[0];
if (!_measurements || _measurements.length < 1) {
return;
}
const measurements = _measurements.filter(m => m.loaded === true);
const measurement = measurements[0];
if (!measurement) {
return;
}
srModule.setters.trackingUniqueIdentifiersForElement(
element,
measurements.map(measurement => measurement.TrackingUniqueIdentifier),
measurement
);
const { TrackingUniqueIdentifier } = measurement;
srModule.setters.activeTrackingUniqueIdentifierForElement(
element,
TrackingUniqueIdentifier
);
cs.updateImage(element);
};
export default checkForSRAnnotations;
@@ -0,0 +1,9 @@
export default {
TEXT: 'TEXT',
POINT: 'POINT',
MULTIPOINT: 'MULTIPOINT',
POLYLINE: 'POLYLINE',
CIRCLE: 'CIRCLE',
ELLIPSE: 'ELLIPSE',
POLYGON: 'POLYGON',
};
@@ -0,0 +1,5 @@
const TOOL_NAMES = {
DICOM_SR_DISPLAY_TOOL: 'DICOMSRDisplayTool',
};
export default TOOL_NAMES;
+7
View File
@@ -0,0 +1,7 @@
const id = 'org.ohif.dicom-sr';
export default id;
const SOPClassHandlerName = 'dicom-sr';
const SOPClassHandlerId = `${id}.sopClassHandlerModule.${SOPClassHandlerName}`;
export { SOPClassHandlerName, SOPClassHandlerId };
@@ -0,0 +1,108 @@
import cornerstoneTools from 'cornerstone-tools';
import DICOMSRDisplayTool from './DICOMSRDisplayTool';
import TOOL_NAMES from './constants/toolNames';
import getToolAlias from './utils/getToolAlias';
/**
* Initialize SR cornerstone tools.
*
* @param {*} targetElement
*/
const initSRTools = targetElement => {
const primaryToolId = 'Wwwc';
const toolAlias = getToolAlias(primaryToolId); // These are 1:1 for built-in only
// ~~ MAGIC
cornerstoneTools.addToolForElement(targetElement, DICOMSRDisplayTool);
cornerstoneTools.setToolEnabledForElement(
targetElement,
TOOL_NAMES.DICOM_SR_DISPLAY_TOOL
);
// ~~ Variants
cornerstoneTools.addToolForElement(
targetElement,
cornerstoneTools.LengthTool,
{
name: 'SRLength',
configuration: {
renderDashed: true,
},
}
);
cornerstoneTools.addToolForElement(
targetElement,
cornerstoneTools.ArrowAnnotateTool,
{
name: 'SRArrowAnnotate',
configuration: {
renderDashed: true,
},
}
);
cornerstoneTools.addToolForElement(
targetElement,
cornerstoneTools.BidirectionalTool,
{
name: 'SRBidirectional',
configuration: {
renderDashed: true,
},
}
);
cornerstoneTools.addToolForElement(
targetElement,
cornerstoneTools.EllipticalRoiTool,
{
name: 'SREllipticalRoi',
configuration: {
renderDashed: true,
},
}
);
cornerstoneTools.addToolForElement(
targetElement,
cornerstoneTools.RectangleRoiTool,
{
name: 'SRRectangleRoi',
configuration: {
renderDashed: true,
},
}
);
cornerstoneTools.addToolForElement(
targetElement,
cornerstoneTools.FreehandRoiTool,
{
name: 'SRFreehandRoi',
configuration: {
renderDashed: true,
},
}
);
// ~~ Business as usual
cornerstoneTools.setToolActiveForElement(targetElement, 'PanMultiTouch', {
pointers: 2,
});
cornerstoneTools.setToolActiveForElement(targetElement, 'ZoomTouchPinch', {});
// TODO: Add always dashed tool alternative aliases
// TODO: or same name... alternative config?
cornerstoneTools.setToolActiveForElement(targetElement, toolAlias, {
mouseButtonMask: 1,
});
cornerstoneTools.setToolActiveForElement(targetElement, 'Pan', {
mouseButtonMask: 4,
});
cornerstoneTools.setToolActiveForElement(targetElement, 'Zoom', {
mouseButtonMask: 2,
});
cornerstoneTools.setToolActiveForElement(
targetElement,
'StackScrollMouseWheel',
{}
);
};
export default initSRTools;
@@ -0,0 +1,61 @@
import cornerstone from 'cornerstone-core';
const state = {
TrackingUniqueIdentifier: null,
trackingIdentifiersByEnabledElementUUID: {},
};
function setTrackingUniqueIdentifiersForElement(
element,
trackingUniqueIdentifiers,
activeIndex = 0
) {
const enabledElement = cornerstone.getEnabledElement(element);
const { uuid } = enabledElement;
state.trackingIdentifiersByEnabledElementUUID[uuid] = {
trackingUniqueIdentifiers,
activeIndex,
};
}
function setActiveTrackingUniqueIdentifierForElement(
element,
TrackingUniqueIdentifier
) {
const enabledElement = cornerstone.getEnabledElement(element);
const { uuid } = enabledElement;
const trackingIdentifiersForElement =
state.trackingIdentifiersByEnabledElementUUID[uuid];
if (trackingIdentifiersForElement) {
const activeIndex = trackingIdentifiersForElement.trackingUniqueIdentifiers.findIndex(
tuid => tuid === TrackingUniqueIdentifier
);
trackingIdentifiersForElement.activeIndex = activeIndex;
}
}
function getTrackingUniqueIdentifiersForElement(element) {
const enabledElement = cornerstone.getEnabledElement(element);
const { uuid } = enabledElement;
if (state.trackingIdentifiersByEnabledElementUUID[uuid]) {
return state.trackingIdentifiersByEnabledElementUUID[uuid];
}
return { trackingUniqueIdentifiers: [] };
}
export default {
state,
getters: {
trackingUniqueIdentifiersForElement: getTrackingUniqueIdentifiersForElement,
},
setters: {
trackingUniqueIdentifiersForElement: setTrackingUniqueIdentifiersForElement,
activeTrackingUniqueIdentifierForElement: setActiveTrackingUniqueIdentifierForElement,
},
};
@@ -0,0 +1,32 @@
/**
* Get cornerstone tool alias.
*
* @param {string} toolName
* @returns tool alias
*/
export default function getToolAlias(toolName) {
let toolAlias = toolName;
switch (toolName) {
case 'Length':
toolAlias = 'SRLength';
break;
case 'Bidirectional':
toolAlias = 'SRBidirectional';
break;
case 'ArrowAnnotate':
toolAlias = 'SRArrowAnnotate';
break;
case 'EllipticalRoi':
toolAlias = 'SREllipticalRoi';
break;
case 'FreehandRoi':
toolAlias = 'SRFreehandRoi';
break;
case 'RectangleRoi':
toolAlias = 'SRRectangleRoi';
break;
}
return toolAlias;
}
@@ -0,0 +1,109 @@
import moment from 'moment';
/**
* Checks if value is valid.
*
* @param {number} value
* @returns {boolean} is valid.
*/
function isValidNumber(value) {
return typeof value === 'number' && !isNaN(value);
}
/**
* Formats number precision.
*
* @param {number} number
* @param {number} precision
* @returns {number} formatted number.
*/
function formatNumberPrecision(number, precision) {
if (number !== null) {
return parseFloat(number).toFixed(precision);
}
}
/**
* Formats DICOM date.
*
* @param {string} date
* @param {string} strFormat
* @returns {string} formatted date.
*/
function formatDICOMDate(date, strFormat = 'MMM D, YYYY') {
return moment(date, 'YYYYMMDD').format(strFormat);
}
/**
* DICOM Time is stored as HHmmss.SSS, where:
* HH 24 hour time:
* m mm 0..59 Minutes
* s ss 0..59 Seconds
* S SS SSS 0..999 Fractional seconds
*
* Goal: '24:12:12'
*
* @param {*} time
* @param {string} strFormat
* @returns {string} formatted name.
*/
function formatDICOMTime(time, strFormat = 'HH:mm:ss') {
return moment(time, 'HH:mm:ss').format(strFormat);
}
/**
* Formats a patient name for display purposes
*
* @param {string} name
* @returns {string} formatted name.
*/
function formatPN(name) {
if (!name) {
return;
}
// Convert the first ^ to a ', '. String.replace() only affects
// the first appearance of the character.
const commaBetweenFirstAndLast = name.replace('^', ', ');
// Replace any remaining '^' characters with spaces
const cleaned = commaBetweenFirstAndLast.replace(/\^/g, ' ');
// Trim any extraneous whitespace
return cleaned.trim();
}
/**
* Gets compression type
*
* @param {number} imageId
* @returns {string} comrpession type.
*/
function getCompression(imageId) {
const generalImageModule =
cornerstone.metaData.get('generalImageModule', imageId) || {};
const {
lossyImageCompression,
lossyImageCompressionRatio,
lossyImageCompressionMethod,
} = generalImageModule;
if (lossyImageCompression === '01' && lossyImageCompressionRatio !== '') {
const compressionMethod = lossyImageCompressionMethod || 'Lossy: ';
const compressionRatio = formatNumberPrecision(
lossyImageCompressionRatio,
2
);
return compressionMethod + compressionRatio + ' : 1';
}
return 'Lossless / Uncompressed';
}
export { isValidNumber,
formatNumberPrecision,
formatDICOMDate,
formatDICOMTime,
formatPN,
getCompression
};
+86
View File
@@ -3,6 +3,92 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.3.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.3.2...@ohif/extension-debugging@0.3.3) (2022-06-30)
**Note:** Version bump only for package @ohif/extension-debugging
## [0.3.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.3.1...@ohif/extension-debugging@0.3.2) (2022-03-10)
**Note:** Version bump only for package @ohif/extension-debugging
## [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)
### Features
* Update to WADO Image Loader 4.0.3 to add dynamically imported WebAssembly codec support 🚀 ([#2537](https://github.com/OHIF/Viewers/issues/2537)) ([489d4b0](https://github.com/OHIF/Viewers/commit/489d4b0584f4657ceda1c5b9b68d5e9733827e47))
## [0.2.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.2.1...@ohif/extension-debugging@0.2.2) (2021-06-03)
**Note:** Version bump only for package @ohif/extension-debugging
## [0.2.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.2.0...@ohif/extension-debugging@0.2.1) (2021-03-19)
**Note:** Version bump only for package @ohif/extension-debugging
# [0.2.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.1.6...@ohif/extension-debugging@0.2.0) (2021-03-04)
### Features
* **log:** add new log service ([14d6454](https://github.com/OHIF/Viewers/commit/14d6454eafaa2ccb50e133c2945c9558052ea27e))
## [0.1.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.1.5...@ohif/extension-debugging@0.1.6) (2020-10-06)
**Note:** Version bump only for package @ohif/extension-debugging
## [0.1.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.1.4...@ohif/extension-debugging@0.1.5) (2020-09-17)
**Note:** Version bump only for package @ohif/extension-debugging
## [0.1.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.1.3...@ohif/extension-debugging@0.1.4) (2020-09-10)
**Note:** Version bump only for package @ohif/extension-debugging
## 0.1.3 (2020-09-03)
**Note:** Version bump only for package @ohif/extension-debugging
+3 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-debugging",
"version": "0.1.3",
"version": "0.3.3",
"description": "OHIF extension for debugging.",
"author": "OHIF",
"license": "MIT",
@@ -28,13 +28,12 @@
},
"peerDependencies": {
"@ohif/core": "^2.6.0",
"dicom-parser": "^1.8.3",
"dicomweb-client": "^0.5.2"
"dicom-parser": "^1.8.11"
},
"dependencies": {
"@babel/runtime": "^7.5.5",
"detect-browser": "5.1.1",
"dicomweb-client": "^0.6.0",
"dicomweb-client": "^0.8.3",
"file-saver": "^2.0.2",
"jszip": "^3.2.2"
}
@@ -2,3 +2,43 @@
padding: 10px 0 10px;
color: var(--active-color);
}
.debug-report-modal-container {
display: flex;
flex-direction: column;
}
.debug-report-modal-buttons-container {
display: flex;
flex-direction: row;
}
.debug-report-modal-container .errors {
margin-top: 10px;
}
.debug-report-modal-container .errors-container {
border: 1px solid var(--active-color);
border-radius: 5px;
padding: 10px;
overflow: scroll;
max-height: 300px;
}
.debug-overflowText {
margin: 0 auto;
max-width: 300px;
overflow-wrap: break-word;
word-wrap: break-word;
hyphens: auto;
}
.debug-overflowText-border {
margin: 0 auto;
max-width: 300px;
border: solid 2px #ccc;
padding: 12px;
overflow-wrap: break-word;
word-wrap: break-word;
hyphens: auto;
}
+290 -12
View File
@@ -1,22 +1,203 @@
import React from 'react';
import { detect } from 'detect-browser';
import './DebugReportModal.css';
import { ToolbarButton } from '@ohif/ui';
import { utils } from '@ohif/core';
const { studyMetadataManager } = utils;
const DubugReportModal = ({
viewports,
studies,
servers,
extensionManager,
mailTo,
debugModalMessage,
errors = [],
}) => {
const copyDebugDataToClipboard = () => {
const body = getEmailBody();
const textArea = document.createElement('textarea');
textArea.value = body;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
};
const getEmailBody = () => {
let body = `Enter the description of your problem here: \n\n\n`;
body += `============= SESSION INFO =============\n\n`;
// App version
body += '== App ==\n';
body += `version\t${window.version}\n\n`;
// Extensions Versions
body += '== Extensions Versions ==\n';
const { registeredExtensionVesions } = extensionManager;
Object.keys(registeredExtensionVesions).forEach(extensionId => {
const version = registeredExtensionVesions[extensionId];
body += `${extensionId}\t${version}\n`;
});
body += '\n';
// Browser Info
const browser = detect();
const { name, os, type, version } = browser;
body += '== Browser Info ==\n';
body += `name\t ${name}\n`;
body += `os\t ${os}\n`;
body += `type\t ${type}\n`;
body += `version\t ${version}\n\n`;
// Study URL
body += '== URL ==\n';
body += `URL\t ${window.location.href}\n\n`;
// Layout
const { numRows, numColumns, viewportSpecificData } = viewports;
body += '== Viewport Layout ==\n';
body += `Rows\t${numRows}\n`;
body += `Columns\t${numColumns}\n\n`;
body += '== SeriesInstanceUIDs ==\n';
Object.keys(viewportSpecificData).forEach(viewportIndex => {
const vsd = viewportSpecificData[viewportIndex];
const [row, column] = _viewportIndexToViewportPosition(
viewportIndex,
numColumns
);
body += `[${row},${column}]\t${vsd.SeriesInstanceUID}\n`;
});
body += '== ReferencedSEGSeriesInstanceUIDs ==\n';
Object.keys(viewportSpecificData).forEach(viewportIndex => {
const displaySet = viewportSpecificData[viewportIndex];
const [referencedDisplaySetsRef] = _getReferencedSeriesInstanceUIDsString(
displaySet,
'SEG'
);
const [row, column] = _viewportIndexToViewportPosition(
viewportIndex,
numColumns
);
body += `[${row},${column}]\t${referencedDisplaySetsRef}\n`;
});
body += '== ReferencedRTSTRUCTSeriesInstanceUIDs ==\n';
Object.keys(viewportSpecificData).forEach(viewportIndex => {
const displaySet = viewportSpecificData[viewportIndex];
const [referencedDisplaySetsRef] = _getReferencedSeriesInstanceUIDsString(
displaySet,
'RTSTRUCT'
);
const [row, column] = _viewportIndexToViewportPosition(
viewportIndex,
numColumns
);
body += `[${row},${column}]\t${referencedDisplaySetsRef}\n`;
});
body += '== ReferencedSRSeriesInstanceUIDs ==\n';
Object.keys(viewportSpecificData).forEach(viewportIndex => {
const displaySet = viewportSpecificData[viewportIndex];
const [referencedDisplaySetsRef] = _getReferencedSeriesInstanceUIDsString(
displaySet,
'SR'
);
const [row, column] = _viewportIndexToViewportPosition(
viewportIndex,
numColumns
);
body += `[${row},${column}]\t${referencedDisplaySetsRef}\n`;
});
return body;
};
const mailToFunction = () => {
const StudyInstanceUID = Object.keys(studies.studyData)[0];
const subject = encodeURI(`Issue with Study: ${StudyInstanceUID}`);
let body = getEmailBody();
// TODO Text dump of rest of stuff.
body = encodeURI(body);
window.location.href = `mailto:${mailTo}?subject=${subject}&body=${body}`;
};
return (
<div>
<table>
{getAppVersion()}
{getExtensionVersions(extensionManager)}
{getBrowserInfo()}
{getCurrentStudyUrl()}
{getLayout(viewports)}
</table>
<div className="debug-report-modal-container">
{debugModalMessage ? <p>{debugModalMessage}</p> : null}
<div className="debug-report-modal-buttons-container">
{mailTo ? (
<div>
<ToolbarButton
label={'Send Bug Report'}
onClick={mailToFunction}
icon={'envelope-square'}
isActive={false}
/>
</div>
) : null}
<div>
<ToolbarButton
label={'Copy To Clipboard'}
onClick={copyDebugDataToClipboard}
icon={'clipboard'}
isActive={false}
/>
</div>
</div>
<div>
<table>
{getAppVersion()}
{getExtensionVersions(extensionManager)}
{getBrowserInfo()}
{getCurrentStudyUrl()}
{getLayout(viewports)}
</table>
</div>
<div className="errors">
<h3>Errors ({errors.length})</h3>
<div className="errors-container">
{errors.map(error => {
return (
<div>
<pre>Message: {error.message}</pre>
{error.error && <pre>Stack: {error.error.stack}</pre>}
</div>
);
})}
</div>
</div>
</div>
);
};
@@ -39,11 +220,11 @@ const getCurrentStudyUrl = () => {
return (
<React.Fragment>
<tr>
<th className="debugReportModalHeader">App</th>
<th className="debugReportModalHeader">URL</th>
</tr>
<tr>
<td>URL</td>
<td>{window.location.href}</td>
<td className="debug-overflowText">{window.location.href}</td>
</tr>
</React.Fragment>
);
@@ -94,6 +275,18 @@ const getLayout = viewports => {
<th>SeriesInstanceUIDs</th>
</tr>
{getSeriesInstanceUIDsPerRow(viewports)}
<tr>
<th>ReferencedSEGSeriesInstanceUIDs</th>
</tr>
{getReferencedSeriesInstanceUIDsPerRow(viewports, 'SEG')}
<tr>
<th>ReferencedRTSTRUCTSeriesInstanceUIDs</th>
</tr>
{getReferencedSeriesInstanceUIDsPerRow(viewports, 'RTSTRUCT')}
<tr>
<th>ReferencedSRSeriesInstanceUIDs</th>
</tr>
{getReferencedSeriesInstanceUIDsPerRow(viewports, 'SR')}
</React.Fragment>
);
};
@@ -128,10 +321,95 @@ const getBrowserInfo = () => {
);
};
const getSeriesInstanceUIDsPerRow = viewports => {
/**
* Returns DisplaySets that reference the target series, sorted by dateTime
*
* @param {string} StudyInstanceUID
* @param {string} SeriesInstanceUID
* @returns Array
*/
const _getReferencedDisplaysets = (
StudyInstanceUID,
SeriesInstanceUID,
Modality
) => {
/* Referenced DisplaySets */
const studyMetadata = studyMetadataManager.get(StudyInstanceUID);
const referencedDisplaysets = studyMetadata.getDerivedDatasets({
referencedSeriesInstanceUID: SeriesInstanceUID,
Modality,
});
/* Sort */
referencedDisplaysets.sort((a, b) => {
const aNumber = Number(`${a.SeriesDate}${a.SeriesTime}`);
const bNumber = Number(`${b.SeriesDate}${b.SeriesTime}`);
return bNumber - aNumber;
});
return referencedDisplaysets;
};
const _getReferencedSeriesInstanceUIDsString = (displaySet, Modality) => {
const referencedDisplaySets = _getReferencedDisplaysets(
displaySet.StudyInstanceUID,
displaySet.SeriesInstanceUID,
Modality
);
let referencedDisplaySetsRef = 'None';
const referencedDisplaySetsCount = referencedDisplaySets.length;
if (referencedDisplaySetsCount !== 0) {
referencedDisplaySetsRef = '';
for (let i = 0; i < referencedDisplaySetsCount - 1; i++) {
referencedDisplaySetsRef +=
referencedDisplaySets[i].SeriesInstanceUID + ', ';
}
referencedDisplaySetsRef +=
referencedDisplaySets[referencedDisplaySetsCount - 1].SeriesInstanceUID;
}
return [referencedDisplaySetsRef, referencedDisplaySetsCount];
};
const getReferencedSeriesInstanceUIDsPerRow = (viewports, Modality) => {
const { viewportSpecificData, numColumns } = viewports;
debugger;
// NOTE viewportSpecificData is actually an object with numerical keys.
return Object.keys(viewportSpecificData).map(viewportIndex => {
const displaySet = viewportSpecificData[viewportIndex];
const [
referencedDisplaySetsRef,
referencedDisplaySetsCount,
] = _getReferencedSeriesInstanceUIDsString(displaySet, Modality);
const [row, column] = _viewportIndexToViewportPosition(
viewportIndex,
numColumns
);
if (referencedDisplaySetsCount > 1) {
return (
<tr>
<td>{`[${row},${column}]`}</td>
<td className="debug-overflowText-border">
{referencedDisplaySetsRef}
</td>
</tr>
);
} else {
return (
<tr>
<td>{`[${row},${column}]`}</td>
<td className="debug-overflowText">{referencedDisplaySetsRef}</td>
</tr>
);
}
});
};
const getSeriesInstanceUIDsPerRow = viewports => {
const { viewportSpecificData, numColumns } = viewports;
// NOTE viewportSpecificData is actually an object with numerical keys.
return Object.keys(viewportSpecificData).map(viewportIndex => {
@@ -1,4 +1,6 @@
import OHIF from '@ohif/core';
import { useLogger } from '@ohif/ui';
import {
save,
upload,
@@ -11,6 +13,8 @@ import _downloadAndZip, { downloadInstances } from './downloadAndZip';
import DebugReportModal from './DebugReportModal';
import React from 'react';
import state from './state';
const {
utils: { Queue },
} = OHIF;
@@ -93,12 +97,16 @@ export function getCommands(context, servicesManager, extensionManager) {
const { UIModalService } = servicesManager.services;
const WrappedDebugReportModal = function() {
const { state: loggerState } = useLogger();
return (
<DebugReportModal
viewports={viewports}
studies={studies}
servers={servers}
extensionManager={extensionManager}
mailTo={state.mailTo}
debugModalMessage={state.debugModalMessage}
errors={loggerState.errors}
/>
);
};
+12 -1
View File
@@ -2,6 +2,7 @@ import { getDicomWebClientFromConfig } from './utils';
import { getCommands } from './commandsModule';
import { version } from '../package.json';
import toolbarModule from './toolbarModule';
import state from './state';
/**
* Constants
@@ -29,11 +30,21 @@ export default {
* LIFECYCLE HOOKS
*/
preRegistration({ appConfig }) {
preRegistration({ appConfig, configuration }) {
const dicomWebClient = getDicomWebClientFromConfig(appConfig);
if (dicomWebClient) {
sharedContext.dicomWebClient = dicomWebClient;
}
if (configuration) {
if (configuration.mailTo) {
state.mailTo = configuration.mailTo;
}
if (configuration.debugModalMessage) {
state.debugModalMessage = configuration.debugModalMessage;
}
}
},
/**
+3
View File
@@ -0,0 +1,3 @@
const state = { mailTo: undefined, debugModalMessage: undefined };
export default state;
+214
View File
@@ -3,6 +3,220 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.23](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.22...@ohif/extension-dicom-html@1.3.23) (2022-09-01)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.22](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.21...@ohif/extension-dicom-html@1.3.22) (2022-06-30)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.21](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.20...@ohif/extension-dicom-html@1.3.21) (2022-04-05)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.20](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.19...@ohif/extension-dicom-html@1.3.20) (2022-03-25)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.19](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.18...@ohif/extension-dicom-html@1.3.19) (2022-03-14)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.18](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.17...@ohif/extension-dicom-html@1.3.18) (2022-02-03)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.17](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.16...@ohif/extension-dicom-html@1.3.17) (2022-02-03)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.16](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.15...@ohif/extension-dicom-html@1.3.16) (2022-02-02)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [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)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.10](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.9...@ohif/extension-dicom-html@1.3.10) (2021-06-02)
### Bug Fixes
* **dicom-html:** Add parsed dicom meta info section ([#2419](https://github.com/OHIF/Viewers/issues/2419)) ([403688b](https://github.com/OHIF/Viewers/commit/403688b18c52468fc1101166ec0c1734fb710039))
## [1.3.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.8...@ohif/extension-dicom-html@1.3.9) (2021-04-22)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.7...@ohif/extension-dicom-html@1.3.8) (2021-04-22)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.6...@ohif/extension-dicom-html@1.3.7) (2021-04-21)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.5...@ohif/extension-dicom-html@1.3.6) (2021-04-21)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.4...@ohif/extension-dicom-html@1.3.5) (2021-04-15)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.3...@ohif/extension-dicom-html@1.3.4) (2021-03-09)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.2...@ohif/extension-dicom-html@1.3.3) (2021-03-03)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.1...@ohif/extension-dicom-html@1.3.2) (2021-02-25)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.3.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.0...@ohif/extension-dicom-html@1.3.1) (2021-02-05)
**Note:** Version bump only for package @ohif/extension-dicom-html
# [1.3.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.2.9...@ohif/extension-dicom-html@1.3.0) (2020-12-10)
### Features
* visualize overlapping segments in cornerstone ([#2185](https://github.com/OHIF/Viewers/issues/2185)) ([29fceac](https://github.com/OHIF/Viewers/commit/29fceacee97d51f1952a0f6b574c66596d32c201))
## [1.2.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.2.8...@ohif/extension-dicom-html@1.2.9) (2020-10-07)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.2.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.2.7...@ohif/extension-dicom-html@1.2.8) (2020-09-10)
**Note:** Version bump only for package @ohif/extension-dicom-html
## [1.2.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.2.6...@ohif/extension-dicom-html@1.2.7) (2020-09-03)
**Note:** Version bump only for package @ohif/extension-dicom-html
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-dicom-html",
"version": "1.2.7",
"version": "1.3.23",
"description": "OHIF extension for rendering structured reports to HTML",
"author": "OHIF",
"license": "MIT",
@@ -29,7 +29,7 @@
},
"peerDependencies": {
"@ohif/core": "^0.50.0",
"dcmjs": "0.16.3",
"dcmjs": "0.24.10",
"prop-types": "^15.6.2",
"react": "^16.8.6",
"react-dom": "^16.8.6"
+13 -2
View File
@@ -160,7 +160,7 @@ const getContentSequence = (data, level = 1) => {
const root = [];
if (header) {
const HeaderDynamicLevel = `h${level}`;
const HeaderDynamicLevel = `h${Math.min(level, 6)}`;
root.push(<HeaderDynamicLevel key={header}>{header}</HeaderDynamicLevel>);
}
@@ -168,6 +168,16 @@ const getContentSequence = (data, level = 1) => {
Object.keys(data).forEach(key => {
const value = data[key];
if (key === '_meta') {
const HeaderDynamicLevel = `h3`;
root.push(<hr key={root.length} />);
root.push(
<HeaderDynamicLevel key="Metadata">
DICOM File Meta Information
</HeaderDynamicLevel>
);
}
let content;
if (value instanceof Object) {
content = getContentSequence(value, level + 1);
@@ -207,7 +217,7 @@ class DicomHtmlViewport extends Component {
};
componentDidMount() {
const dataSet = this.setContentFromByteArray(this.props.byteArray);
this.setContentFromByteArray(this.props.byteArray);
}
setContentFromByteArray(byteArray) {
@@ -215,6 +225,7 @@ class DicomHtmlViewport extends Component {
const dicomData = DicomMessage.readFile(arrayBuffer);
const dataset = DicomMetaDictionary.naturalizeDataset(dicomData.dict);
dataset._meta = DicomMetaDictionary.namifyDataset(dicomData.meta);
dataset._meta = DicomMetaDictionary.naturalizeDataset(dataset._meta);
const mainData = getMainData(dataset);
const contentSequence = getContentSequence(dataset);
@@ -1,14 +1,16 @@
import { MODULE_TYPES, utils } from '@ohif/core';
import { MODULE_TYPES, utils, metadata } from '@ohif/core';
// TODO: Should probably use dcmjs for this
const SOP_CLASS_UIDS = {
BASIC_TEXT_SR: '1.2.840.10008.5.1.4.1.1.88.11',
ENHANCED_SR: '1.2.840.10008.5.1.4.1.1.88.22',
COMPREHENSIVE_SR: '1.2.840.10008.5.1.4.1.1.88.33',
COMPREHENSIVE_3D_SR: '1.2.840.10008.5.1.4.1.1.88.34',
PROCEDURE_LOG_STORAGE: '1.2.840.10008.5.1.4.1.1.88.40',
MAMMOGRAPHY_CAD_SR: '1.2.840.10008.5.1.4.1.1.88.50',
CHEST_CAD_SR: '1.2.840.10008.5.1.4.1.1.88.65',
X_RAY_RADIATION_DOSE_SR: '1.2.840.10008.5.1.4.1.1.88.67',
ACQUISITION_CONTEXT_SR_STORAGE: '1.2.840.10008.5.1.4.1.1.88.71',
};
const sopClassUIDs = Object.values(SOP_CLASS_UIDS);
@@ -22,13 +24,15 @@ const OHIFDicomHtmlSopClassHandler = {
getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {
const instance = series.getFirstInstance();
const metadata = instance.getData().metadata;
const {
SeriesDescription,
SeriesNumber,
SeriesDate,
SeriesTime,
SeriesNumber,
} = instance._instance.metadata;
} = metadata;
return {
const srDisplaySet = {
plugin: 'html',
Modality: 'SR',
displaySetInstanceUID: utils.guid(),
@@ -37,11 +41,23 @@ const OHIFDicomHtmlSopClassHandler = {
SOPInstanceUID: instance.getSOPInstanceUID(),
SeriesInstanceUID: series.getSeriesInstanceUID(),
StudyInstanceUID: study.getStudyInstanceUID(),
SeriesDescription,
metadata,
SeriesDate,
SeriesTime,
SeriesNumber,
authorizationHeaders,
sopClassUids: sopClassUIDs,
images: series._instances,
isDerived: true,
referencedDisplaySets: [],
};
srDisplaySet.getSourceDisplaySet = function() {
return srDisplaySet.referencedDisplaySets;
};
return srDisplaySet;
},
};
+27
View File
@@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [0.52.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-microscopy@0.51.4...@ohif/extension-dicom-microscopy@0.52.0) (2021-03-04)
### Features
* **log:** add new log service ([14d6454](https://github.com/OHIF/Viewers/commit/14d6454eafaa2ccb50e133c2945c9558052ea27e))
## [0.51.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-microscopy@0.51.3...@ohif/extension-dicom-microscopy@0.51.4) (2021-01-21)
**Note:** Version bump only for package @ohif/extension-dicom-microscopy
## [0.51.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-microscopy@0.51.2...@ohif/extension-dicom-microscopy@0.51.3) (2020-09-10)
**Note:** Version bump only for package @ohif/extension-dicom-microscopy
## [0.51.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-microscopy@0.51.1...@ohif/extension-dicom-microscopy@0.51.2) (2020-09-03)
**Note:** Version bump only for package @ohif/extension-dicom-microscopy
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-dicom-microscopy",
"version": "0.51.2",
"version": "0.52.0",
"description": "OHIF extension for Dicom Microscopy",
"author": "OHIF",
"license": "MIT",
@@ -12,11 +12,13 @@ const DicomMicroscopySopClassHandler = {
getDisplaySetFromSeries(series, study, dicomWebClient) {
const instance = series.getFirstInstance();
const metadata = instance.getData().metadata;
const {
SeriesDescription,
SeriesNumber,
ContentDate,
ContentTime,
SeriesNumber,
} = instance._instance.metadata;
} = metadata;
// Note: We are passing the dicomweb client into each viewport!
@@ -28,9 +30,11 @@ const DicomMicroscopySopClassHandler = {
SOPInstanceUID: instance.getSOPInstanceUID(),
SeriesInstanceUID: series.getSeriesInstanceUID(),
StudyInstanceUID: study.getStudyInstanceUID(),
SeriesDescription,
SeriesDate: ContentDate, // Map ContentDate/Time to SeriesTime for series list sorting.
SeriesTime: ContentTime,
SeriesNumber,
metadata,
};
},
};
@@ -62,11 +62,30 @@ class DicomMicroscopyViewport extends Component {
);
const microscopyViewer = api.VLWholeSlideMicroscopyImageViewer;
this.viewer = new microscopyViewer({
client: dicomWebClient,
metadata,
retrieveRendered: false,
});
try {
this.viewer = new microscopyViewer({
client: dicomWebClient,
metadata,
retrieveRendered: false,
});
} catch (error) {
console.error('[Microscopy Viewer] Failed to load:', error);
const {
UINotificationService,
LoggerService,
} = this.props.servicesManager.services;
if (UINotificationService) {
const message =
'Failed to load viewport. Please check that you have hardware acceleration enabled.';
LoggerService.error({ error, message });
UINotificationService.show({
autoClose: false,
title: 'Microscopy Viewport',
message,
type: 'error',
});
}
}
this.viewer.render({ container });
});
@@ -92,8 +111,8 @@ class DicomMicroscopyViewport extends Component {
{this.state.error ? (
<h2>{JSON.stringify(this.state.error)}</h2>
) : (
<div style={style} ref={this.container} />
)}
<div style={style} ref={this.container} />
)}
</div>
);
}
+8 -10
View File
@@ -6,14 +6,6 @@ const Component = React.lazy(() => {
return import('./DicomMicroscopyViewport');
});
const DicomMicroscopyViewport = props => {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<Component {...props} />
</React.Suspense>
);
};
export default {
/**
* Only required property. Should be a unique value across all extensions.
@@ -21,8 +13,14 @@ export default {
id: 'microscopy',
version,
getViewportModule() {
return DicomMicroscopyViewport;
getViewportModule({ servicesManager }) {
return props => {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<Component {...props} servicesManager={servicesManager} />
</React.Suspense>
);
};
},
getSopClassHandlerModule() {
return DicomMicroscopySopClassHandler;
+35
View File
@@ -3,6 +3,41 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-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)
### Features
* Update to WADO Image Loader 4.0.3 to add dynamically imported WebAssembly codec support 🚀 ([#2537](https://github.com/OHIF/Viewers/issues/2537)) ([489d4b0](https://github.com/OHIF/Viewers/commit/489d4b0584f4657ceda1c5b9b68d5e9733827e47))
## [1.0.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-pdf@1.0.5...@ohif/extension-dicom-pdf@1.0.6) (2020-09-10)
**Note:** Version bump only for package @ohif/extension-dicom-pdf
## [1.0.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-pdf@1.0.4...@ohif/extension-dicom-pdf@1.0.5) (2020-09-03)
**Note:** Version bump only for package @ohif/extension-dicom-pdf
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-dicom-pdf",
"version": "1.0.5",
"version": "1.1.2",
"description": "OHIF extension for Dicom PDF",
"author": "OHIF",
"license": "MIT",
@@ -29,7 +29,7 @@
},
"peerDependencies": {
"@ohif/core": "^0.50.0",
"dicom-parser": "^1.8.3",
"dicom-parser": "^1.8.11",
"prop-types": "^15.6.2",
"react": "^16.8.6",
"react-dom": "^16.8.6"
+3 -1
View File
@@ -33,6 +33,7 @@ class DicomPDFViewport extends Component {
static propTypes = {
byteArray: TypedArrayProp.uint8,
rawPdf: PropTypes.bool,
useNative: PropTypes.bool,
viewportData: PropTypes.object,
activeViewportIndex: PropTypes.number,
@@ -45,7 +46,8 @@ class DicomPDFViewport extends Component {
};
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);
this.setState(state => ({ ...state, fileURL }));
@@ -12,11 +12,13 @@ const OHIFDicomPDFSopClassHandler = {
getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {
const instance = series.getFirstInstance();
const metadata = instance.getData().metadata;
const {
ContentDate,
ContentTime,
SeriesDescription,
SeriesNumber,
} = instance._instance.metadata;
} = metadata;
return {
plugin: 'pdf',
@@ -27,9 +29,11 @@ const OHIFDicomPDFSopClassHandler = {
SOPInstanceUID: instance.getSOPInstanceUID(),
SeriesInstanceUID: series.getSeriesInstanceUID(),
StudyInstanceUID: study.getStudyInstanceUID(),
SeriesDescription,
SeriesDate: ContentDate, // Map ContentDate/Time to SeriesTime for series list sorting.
SeriesTime: ContentTime,
SeriesNumber,
metadata,
authorizationHeaders: authorizationHeaders,
};
},
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import OHIF from '@ohif/core';
import OHIFComponentPlugin from './OHIFComponentPlugin.js';
import DicomPDFViewport from './DicomPDFViewport';
import { str2ab } from '@ohif/core';
const { DicomLoaderService } = OHIF.utils;
@@ -18,6 +19,7 @@ class OHIFDicomPDFViewport extends Component {
state = {
byteArray: null,
rawPdf: false,
error: null,
};
@@ -34,6 +36,15 @@ class OHIFDicomPDFViewport extends Component {
componentDidMount() {
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(
data => this.setState({ byteArray: new Uint8Array(data) }),
error => {
@@ -49,15 +60,16 @@ class OHIFDicomPDFViewport extends Component {
viewportIndex,
activeViewportIndex,
} = this.props;
const { byteArray, error } = this.state;
const { byteArray, error, rawPdf } = this.state;
const { id, init, destroy } = OHIFDicomPDFViewport;
const pluginProps = { id, init, destroy };
return (
<OHIFComponentPlugin {...pluginProps}>
{byteArray && (
{(byteArray) && (
<DicomPDFViewport
byteArray={byteArray}
rawPdf={rawPdf}
setViewportActive={setViewportActive}
viewportIndex={viewportIndex}
activeViewportIndex={activeViewportIndex}
+303
View File
@@ -3,6 +3,309 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.7.13](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.12...@ohif/extension-dicom-rt@0.7.13) (2022-09-01)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.7.12](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.11...@ohif/extension-dicom-rt@0.7.12) (2022-08-31)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.7.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.10...@ohif/extension-dicom-rt@0.7.11) (2022-04-05)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.7.10](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.9...@ohif/extension-dicom-rt@0.7.10) (2022-03-25)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.7.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.8...@ohif/extension-dicom-rt@0.7.9) (2022-03-14)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.7.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.7...@ohif/extension-dicom-rt@0.7.8) (2022-02-03)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.7.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.6...@ohif/extension-dicom-rt@0.7.7) (2022-02-02)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [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)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.7.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.0...@ohif/extension-dicom-rt@0.7.1) (2021-09-28)
**Note:** Version bump only for package @ohif/extension-dicom-rt
# [0.7.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.14...@ohif/extension-dicom-rt@0.7.0) (2021-09-23)
### Features
* Update to WADO Image Loader 4.0.3 to add dynamically imported WebAssembly codec support 🚀 ([#2537](https://github.com/OHIF/Viewers/issues/2537)) ([489d4b0](https://github.com/OHIF/Viewers/commit/489d4b0584f4657ceda1c5b9b68d5e9733827e47))
## [0.6.14](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.13...@ohif/extension-dicom-rt@0.6.14) (2021-09-03)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.13](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.12...@ohif/extension-dicom-rt@0.6.13) (2021-06-02)
### Bug Fixes
* **dicom-html:** Add parsed dicom meta info section ([#2419](https://github.com/OHIF/Viewers/issues/2419)) ([403688b](https://github.com/OHIF/Viewers/commit/403688b18c52468fc1101166ec0c1734fb710039))
## [0.6.12](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.11...@ohif/extension-dicom-rt@0.6.12) (2021-05-17)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.10...@ohif/extension-dicom-rt@0.6.11) (2021-04-22)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.10](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.9...@ohif/extension-dicom-rt@0.6.10) (2021-04-22)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.8...@ohif/extension-dicom-rt@0.6.9) (2021-04-21)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.7...@ohif/extension-dicom-rt@0.6.8) (2021-04-15)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.6...@ohif/extension-dicom-rt@0.6.7) (2021-03-09)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.5...@ohif/extension-dicom-rt@0.6.6) (2021-03-03)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.4...@ohif/extension-dicom-rt@0.6.5) (2021-02-25)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.3...@ohif/extension-dicom-rt@0.6.4) (2021-02-05)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.2...@ohif/extension-dicom-rt@0.6.3) (2021-01-21)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.1...@ohif/extension-dicom-rt@0.6.2) (2021-01-21)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.6.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.6.0...@ohif/extension-dicom-rt@0.6.1) (2020-12-10)
### Bug Fixes
* panel issues and mpr button (IDC2122-IDC2117) ([32022f5](https://github.com/OHIF/Viewers/commit/32022f51f2d24f53f4c98188980db038a6dfe76c))
# [0.6.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.5.0...@ohif/extension-dicom-rt@0.6.0) (2020-12-10)
### Features
* visualize overlapping segments in cornerstone ([#2185](https://github.com/OHIF/Viewers/issues/2185)) ([29fceac](https://github.com/OHIF/Viewers/commit/29fceacee97d51f1952a0f6b574c66596d32c201))
# [0.5.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.4.9...@ohif/extension-dicom-rt@0.5.0) (2020-12-03)
### Features
* Update approach to better handle rtdose instead of disabling panel ([f3cecf1](https://github.com/OHIF/Viewers/commit/f3cecf129b16f8d24d239aa44fdff7f46e6ba683))
## [0.4.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.4.8...@ohif/extension-dicom-rt@0.4.9) (2020-10-12)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.4.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.4.7...@ohif/extension-dicom-rt@0.4.8) (2020-10-07)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.4.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.4.6...@ohif/extension-dicom-rt@0.4.7) (2020-10-06)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.4.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.4.5...@ohif/extension-dicom-rt@0.4.6) (2020-09-17)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.4.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.4.4...@ohif/extension-dicom-rt@0.4.5) (2020-09-10)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.4.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.4.3...@ohif/extension-dicom-rt@0.4.4) (2020-09-10)
**Note:** Version bump only for package @ohif/extension-dicom-rt
## [0.4.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.4.2...@ohif/extension-dicom-rt@0.4.3) (2020-09-03)
**Note:** Version bump only for package @ohif/extension-dicom-rt
+7 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-dicom-rt",
"version": "0.4.3",
"version": "0.7.13",
"description": "OHIF extension for rendering DICOM RTSTRUCTs on top of cornerstone images.",
"author": "OHIF",
"license": "MIT",
@@ -29,12 +29,14 @@
},
"peerDependencies": {
"@ohif/core": "^0.50.0",
"cornerstone-core": "^2.2.8",
"cornerstone-tools": "^4.20.1",
"dcmjs": "0.16.3",
"cornerstone-core": "^2.6.1",
"cornerstone-tools": "^6.0.6",
"dcmjs": "0.24.10",
"gl-matrix": "^3.3.0",
"prop-types": "^15.6.2",
"react": "^16.8.6",
"react-dom": "^16.8.6"
"react-dom": "^16.8.6",
"react-tooltip": "4.2.10"
},
"dependencies": {
"@babel/runtime": "^7.5.5",
@@ -15,7 +15,7 @@ const OHIFDicomRTStructSopClassHandler = {
id: 'OHIFDicomRTStructSopClassHandler',
type: MODULE_TYPES.SOP_CLASS_HANDLER,
sopClassUIDs,
getDisplaySetFromSeries: function(
getDisplaySetFromSeries: function (
series,
study,
dicomWebClient,
@@ -56,6 +56,7 @@ const OHIFDicomRTStructSopClassHandler = {
SeriesTime,
SeriesNumber,
SeriesDescription,
metadata,
};
if (!metadata.ReferencedSeriesSequence) {
@@ -70,11 +71,11 @@ const OHIFDicomRTStructSopClassHandler = {
}
}
rtStructDisplaySet.getSourceDisplaySet = function(studies) {
return getSourceDisplaySet(studies, rtStructDisplaySet);
rtStructDisplaySet.getSourceDisplaySet = function (studies, activateLabelMap = true) {
return getSourceDisplaySet(studies, rtStructDisplaySet, activateLabelMap);
};
rtStructDisplaySet.load = function(referencedDisplaySet, studies) {
rtStructDisplaySet.load = function (referencedDisplaySet, studies) {
return loadRTStruct(
rtStructDisplaySet,
referencedDisplaySet,
@@ -39,6 +39,8 @@
border-radius: 5px;
}
.icons .angle-double-down, .icons .angle-double-up {
.icons .angle-double-down,
.icons .angle-double-up {
margin-left: 15px;
margin-right: -5px;
}
@@ -9,16 +9,21 @@
.dcmrt-panel .dcmrt-panel-header {
display: flex;
flex-direction: row;
flex-direction: column;
justify-content: space-between;
color: white;
}
.dcmrt-panel .dcmrt-panel-header h3 {
margin-top: 0;
}
.dcmrt-panel .dcmrt-panel-header .cog-icon {
align-self: flex-end;
color: var(--default-color);
cursor: pointer;
margin-bottom: 20px;
min-height: 23px;
max-height: 23px;
}
.dcmrt-panel .dcmrt-panel-header .cog-icon:hover {
@@ -12,6 +12,9 @@ import StructureSetItem from '../StructureSetItem/StructureSetItem';
import RTPanelSettings from '../RTSettings/RTSettings';
import PanelSection from '../PanelSection/PanelSection';
import LoadingIndicator from '../LoadingIndicator/LoadingIndicator';
import TOOL_NAMES from '../../utils/toolNames';
const { RTSTRUCT_DISPLAY_TOOL } = TOOL_NAMES;
const { studyMetadataManager } = utils;
@@ -28,19 +31,20 @@ const refreshViewport = () => {
*
* @param {Object} props
* @param {Array} props.studies
* @param {Array} props.viewports - viewportSpecificData
* @param {Array} props.getActiveViewport - get active viewport data
* @param {number} props.activeIndex - activeViewportIndex
* @param {number} props.isOpen - isOpen
* @returns component
*/
const RTPanel = ({
studies,
viewports,
activeIndex,
isOpen,
onContourItemClick,
activeContexts = [],
contexts = {},
activeViewport,
getActiveViewport,
}) => {
const isVTK = () => activeContexts.includes(contexts.VTK);
const isCornerstone = () => activeContexts.includes(contexts.CORNERSTONE);
@@ -51,11 +55,11 @@ const RTPanel = ({
referencedDisplaysets: [],
sets: [],
selectedSet: null,
isLocked: false,
};
const [state, setState] = useState(DEFAULT_STATE);
const [showSettings, setShowSettings] = useState(false);
const activeViewport = viewports[activeIndex];
/*
* TODO: Improve the way we notify parts of the app that depends on rts to be loaded.
@@ -75,30 +79,39 @@ const RTPanel = ({
* without subscribing to external events.
*/
useEffect(() => {
document.addEventListener('extensiondicomrtrtloaded', updateStructureSets);
updateStructureSets();
document.addEventListener('rt-panel-tab-updated', updateStructureSets);
return () => {
document.removeEventListener(
'extensiondicomrtrtloaded',
updateStructureSets
);
document.removeEventListener('rt-panel-tab-updated', updateStructureSets);
};
}, []);
useEffect(() => {
const studyMetadata = studyMetadataManager.get(
activeViewport.StudyInstanceUID
);
const referencedDisplaysets = studyMetadata.getDerivedDatasets({
referencedSeriesInstanceUID: activeViewport.SeriesInstanceUID,
Modality: 'RTSTRUCT',
});
setState(state => ({ ...state, isLocked: !referencedDisplaysets.length }));
}, [activeViewport]);
const updateStructureSets = () => {
const viewport = getActiveViewport();
const module = cornerstoneTools.getModule('rtstruct');
const StructureSets = module.state.StructureSets;
if (StructureSets && StructureSets.length) {
const viewportSets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid(
activeViewport.SeriesInstanceUID
viewport.SeriesInstanceUID
);
const studyMetadata = studyMetadataManager.get(
activeViewport.StudyInstanceUID
);
const studyMetadata = studyMetadataManager.get(viewport.StudyInstanceUID);
const referencedDisplaysets = studyMetadata.getDerivedDatasets({
referencedSeriesInstanceUID: activeViewport.SeriesInstanceUID,
referencedSeriesInstanceUID: viewport.SeriesInstanceUID,
Modality: 'RTSTRUCT',
});
@@ -115,10 +128,6 @@ const RTPanel = ({
}
};
useEffect(() => {
updateStructureSets();
}, [studies, viewports, activeIndex]);
useEffect(() => {
setShowSettings(showSettings && !isOpen);
}, [isOpen]);
@@ -144,13 +153,16 @@ const RTPanel = ({
if (isCornerstone()) {
const enabledElements = cornerstone.getEnabledElements();
const element = enabledElements[activeIndex].element;
const toolState = cornerstoneTools.getToolState(element, 'stack');
const stackToolState = cornerstoneTools.getToolState(
element,
'stack'
);
if (!toolState) {
if (!stackToolState) {
return;
}
const imageIds = toolState.data[0].imageIds;
const imageIds = stackToolState.data[0].imageIds;
const module = cornerstoneTools.getModule('rtstruct');
const imageId = module.getters.imageIdOfCenterFrameOfROIContour(
@@ -159,6 +171,18 @@ const RTPanel = ({
imageIds
);
const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.saveToolState();
const imageIdSpecificToolState = toolState[imageId];
const rtstructData =
imageIdSpecificToolState[RTSTRUCT_DISPLAY_TOOL];
const specificData = rtstructData.data.find(
rtData => rtData.ROINumber === ROINumber
);
specificData.highlight = true;
const frameIndex = imageIds.indexOf(imageId);
const SOPInstanceUID = cornerstone.metaData.get(
'SOPInstanceUID',
@@ -213,16 +237,19 @@ const RTPanel = ({
return (
<div className="dcmrt-panel">
<div className="dcmrt-panel-header">
{' '}
{!state.isLocked && (
<Icon
className="cog-icon"
name="cog"
width="25px"
height="25px"
onClick={() => setShowSettings(true)}
/>
)}
<h3>RT Structure Sets</h3>
<Icon
className="cog-icon"
name="cog"
width="25px"
height="25px"
onClick={() => setShowSettings(true)}
/>
</div>
{!state.referencedDisplaysets.length && (
{!state.isLocked && !state.referencedDisplaysets.length && (
<LoadingIndicator expand height="70px" width="70px" />
)}
{state.sets &&
@@ -231,12 +258,15 @@ const RTPanel = ({
const module = cornerstoneTools.getModule('rtstruct');
const sets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid(
viewports[activeIndex].SeriesInstanceUID
activeViewport.SeriesInstanceUID
);
const loadedSet = sets.find(
set => set.SeriesInstanceUID === SeriesInstanceUID
);
if (!loadedSet) return null;
return (
<PanelSection
key={SeriesInstanceUID}
@@ -258,17 +288,17 @@ const RTPanel = ({
module.setters.hideStructureSet(loadedSet.SeriesInstanceUID);
}
const sets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid(
viewports[activeIndex].SeriesInstanceUID
activeViewport.SeriesInstanceUID
);
setState(state => ({ ...state, sets }));
refreshViewport();
}}
onExpandChange={async () => {
if (!isLoaded) {
await displaySet.load(viewports[activeIndex], studies);
await displaySet.load(activeViewport, studies);
const module = cornerstoneTools.getModule('rtstruct');
const sets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid(
viewports[activeIndex].SeriesInstanceUID
activeViewport.SeriesInstanceUID
);
const selectedSet = sets.find(
set => set.SeriesInstanceUID === SeriesInstanceUID
@@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { TableListItem, Icon, Tooltip, OverlayTrigger } from '@ohif/ui';
import ReactTooltip from 'react-tooltip';
import './StructureSetItem.css';
@@ -68,7 +69,18 @@ const StructureSetItem = ({
>
<div>
<div className="item-label" style={{ marginBottom: 4 }}>
<span>{label}</span>
<a data-tip data-for={`StructureHover${index}`}>
<span>{label}</span>
</a>
<ReactTooltip
id={`StructureHover${index}`}
delayShow={250}
place="right"
border={true}
type="light"
>
<span>{label}</span>
</ReactTooltip>
{!isDisabled && (
<Icon
className={`eye-icon ${isVisible && '--visible'}`}
+7 -31
View File
@@ -1,38 +1,14 @@
export default function getSourceDisplaySet(studies, rtStructDisplaySet) {
const referencedDisplaySet = _getReferencedDisplaySet(
import { metadata } from '@ohif/core';
export default function getSourceDisplaySet(studies, rtStructDisplaySet, activateLabelMap = true) {
const referencedDisplaySet = metadata.StudyMetadata.getReferencedDisplaySet(
rtStructDisplaySet,
studies
);
rtStructDisplaySet.load(referencedDisplaySet, studies);
if (activateLabelMap) {
rtStructDisplaySet.load(referencedDisplaySet, studies);
}
return referencedDisplaySet;
}
const _getReferencedDisplaySet = (rtStructDisplaySet, studies) => {
let allDisplaySets = [];
studies.forEach(study => {
allDisplaySets = allDisplaySets.concat(study.displaySets);
});
const otherDisplaySets = allDisplaySets.filter(
ds => ds.displaySetInstanceUID !== rtStructDisplaySet.displaySetInstanceUID
);
const ReferencedSeriesSequence = Array.isArray(
rtStructDisplaySet.metadata.ReferencedSeriesSequence
)
? rtStructDisplaySet.metadata.ReferencedSeriesSequence
: [rtStructDisplaySet.metadata.ReferencedSeriesSequence];
const referencedSeriesInstanceUIDs = ReferencedSeriesSequence.map(
ReferencedSeries => ReferencedSeries.SeriesInstanceUID
);
const referencedDisplaySet = otherDisplaySets.find(ds =>
referencedSeriesInstanceUIDs.includes(ds.SeriesInstanceUID)
);
return referencedDisplaySet;
};
+63 -14
View File
@@ -1,10 +1,14 @@
import React from 'react';
import { utils } from '@ohif/core';
import init from './init.js';
import sopClassHandlerModule from './OHIFDicomRTStructSopClassHandler';
import id from './id.js';
import RTPanel from './components/RTPanel/RTPanel';
import { version } from '../package.json';
const { studyMetadataManager } = utils;
export default {
/**
* Only required property. Should be a unique value across all extensions.
@@ -39,30 +43,75 @@ export default {
);
};
const RTPanelTabChangedEvent = 'rt-panel-tab-updated';
/**
* Trigger's an event to update the state of the panel's RoundedButtonGroup.
*
* This is required to avoid extension state
* coupling with the viewer's ToolbarRow component.
*
* @param {object} data
*/
const triggerRTPanelUpdatedEvent = data => {
const event = new CustomEvent(RTPanelTabChangedEvent, {
detail: data,
});
document.dispatchEvent(event);
};
const onRTStructsLoaded = ({ detail }) => {
const { rtStructDisplaySet, referencedDisplaySet } = detail;
const studyMetadata = studyMetadataManager.get(
rtStructDisplaySet.StudyInstanceUID
);
const referencedDisplaysets = studyMetadata.getDerivedDatasets({
referencedSeriesInstanceUID: referencedDisplaySet.SeriesInstanceUID,
Modality: 'RTSTRUCT',
});
triggerRTPanelUpdatedEvent({
badgeNumber: referencedDisplaysets.length,
target: 'rt-panel',
});
};
document.addEventListener('extensiondicomrtrtloaded', onRTStructsLoaded);
return {
menuOptions: [
{
icon: 'list',
label: 'RTSTRUCT',
target: 'rt-panel',
isDisabled: studies => {
stateEvent: RTPanelTabChangedEvent,
isDisabled: (studies, activeViewport) => {
if (!studies) {
return true;
}
for (let i = 0; i < studies.length; i++) {
const study = studies[i];
if (study && study.series) {
for (let j = 0; j < study.series.length; j++) {
const series = study.series[j];
if (
/* Could be expanded to contain RTPLAN and RTDOSE information in the future */
['RTSTRUCT'].includes(series.Modality)
) {
return false;
}
}
if (activeViewport) {
const studyMetadata = studyMetadataManager.get(
activeViewport.StudyInstanceUID
);
if (!studyMetadata) {
return;
}
const referencedDisplaySets = studyMetadata.getDerivedDatasets({
referencedSeriesInstanceUID: activeViewport.SeriesInstanceUID,
Modality: 'RTSTRUCT',
});
if (
referencedDisplaySets &&
referencedDisplaySets.some(ds =>
['RTSTRUCT'].includes(ds.Modality)
)
) {
triggerRTPanelUpdatedEvent({
badgeNumber: referencedDisplaySets.length,
target: 'rt-panel',
});
return false;
}
}
+99 -3
View File
@@ -4,6 +4,7 @@ import cornerstone from 'cornerstone-core';
import cornerstoneTools from 'cornerstone-tools';
import transformPointsToImagePlane from './utils/transformPointsToImagePlane';
import TOOL_NAMES from './utils/toolNames';
import { vec3 } from 'gl-matrix';
const dicomlab2RGB = dcmjs.data.Colors.dicomlab2RGB;
const globalImageIdSpecificToolStateManager =
@@ -86,8 +87,20 @@ export default async function loadRTStruct(
ContourGeometricType,
} = ContourSequenceArray[c];
const sopInstanceUID = ContourImageSequence.ReferencedSOPInstanceUID;
const sopInstanceUID = ContourImageSequence
? ContourImageSequence.ReferencedSOPInstanceUID
: _getClosestSOPInstanceUID(
ContourData,
ContourGeometricType,
NumberOfContourPoints,
imageIdSopInstanceUidPairs
);
const imageId = _getImageId(imageIdSopInstanceUidPairs, sopInstanceUID);
if (!imageId) {
continue;
}
const imageIdSpecificToolData = _getOrCreateImageIdSpecificToolData(
toolState,
imageId,
@@ -158,7 +171,13 @@ export default async function loadRTStruct(
* allows us to easily watch the module or the rtstruct loading process in any other component
* without subscribing to external events.
*/
const event = new CustomEvent('extensiondicomrtrtloaded');
const event = new CustomEvent('extensiondicomrtrtloaded', {
detail: {
rtStructDisplaySet,
referencedDisplaySet,
studies,
},
});
document.dispatchEvent(event);
}
@@ -286,7 +305,9 @@ const _getImageId = (imageIdSopInstanceUidPairs, sopInstanceUID) => {
imageIdSopInstanceUidPairsEntry.sopInstanceUID === sopInstanceUID
);
return imageIdSopInstanceUidPairsEntry.imageId;
return imageIdSopInstanceUidPairsEntry
? imageIdSopInstanceUidPairsEntry.imageId
: null;
};
function _getImageIdSopInstanceUidPairsForDisplaySet(
@@ -324,3 +345,78 @@ function _getImageIdSopInstanceUidPairsForDisplaySet(
function _toArray(objOrArray) {
return Array.isArray(objOrArray) ? objOrArray : [objOrArray];
}
function _getClosestSOPInstanceUID(
ContourData,
ContourGeometricType,
NumberOfContourPoints,
imageIdSopInstanceUidPairs
) {
const closest = {
distance: Infinity,
sopInstanceUID: null,
};
let point;
switch (ContourGeometricType) {
case 'POINT':
point = ContourData;
break;
case 'CLOSED_PLANAR':
case 'OPEN_PLANAR':
// These are defined as planar, so get the of the region to get the
// Best mapping to a plane even if its potentially off center.
point = [0, 0, 0];
for (let p = 0; p < NumberOfContourPoints * 3; p += 3) {
point[0] += ContourData[p];
point[1] += ContourData[p + 1];
point[2] += ContourData[p + 2];
}
point[0] /= NumberOfContourPoints;
point[1] /= NumberOfContourPoints;
point[2] /= NumberOfContourPoints;
}
imageIdSopInstanceUidPairs.forEach(pair => {
const { imageId } = pair;
const imagePlaneModule = cornerstone.metaData.get(
'imagePlaneModule',
imageId
);
const distance = distanceFromPointToPlane(point, imagePlaneModule);
if (distance < closest.distance) {
closest.distance = distance;
closest.sopInstanceUID = pair.sopInstanceUID;
}
});
return closest.sopInstanceUID;
}
/**
*
* @param {number[3]} P - The point
* @param {object} imagePlaneModule The cornerstone metadata object for the imagePlane
*/
function distanceFromPointToPlane(P, imagePlaneModule) {
const {
rowCosines,
columnCosines,
imagePositionPatient: Q,
} = imagePlaneModule;
let N = [];
vec3.cross(N, rowCosines, columnCosines);
const [A, B, C] = N;
const D = -A * Q[0] - B * Q[1] - C * Q[2];
return Math.abs(A * P[0] + B * P[1] + C * P[2] + D); // Denominator is sqrt(A**2 + B**2 + C**2) which is 1 as its a normal vector
}
@@ -1,6 +1,6 @@
import { importInternal, getToolState, toolColors } from 'cornerstone-tools';
import TOOL_NAMES from '../utils/toolNames';
import drawCanvasCrosshairs from '../utils/drawCanvasCrosshairs';
// Cornerstone 3rd party dev kit imports
const draw = importInternal('drawing/draw');
@@ -37,11 +37,17 @@ export default class RTStructDisplayTool extends BaseTool {
return;
}
const { lineWidth, opacity } = rtstructModule.configuration;
const {
lineWidth,
opacity,
highlightOpacity,
} = rtstructModule.configuration;
// We have tool data for this element - iterate over each one and draw it
const context = getNewContext(eventData.canvasContext.canvas);
let crossHairCenter;
for (let i = 0; i < toolState.data.length; i++) {
const data = toolState.data[i];
@@ -75,27 +81,51 @@ export default class RTStructDisplayTool extends BaseTool {
colorArray[2]
},${opacity})`;
let highlight = data.highlight;
const options = { color, lineWidth };
if (highlight) {
crossHairCenter = { x: 0, y: 0 };
points.forEach(point => {
crossHairCenter.x += point.x;
crossHairCenter.y += point.y;
});
crossHairCenter.x /= points.length;
crossHairCenter.y /= points.length;
// TODO: Disabling hightlight for now, it'd be good to bring it back
// when we have a good way of doing this for SEG.
// options.fillStyle = color = `rgba(${colorArray[0]},${colorArray[1]},${
// colorArray[2]
// },${highlightOpacity})`;
// Draw highlight lines.
delete data.highlight; // Don't highlight on next render.
}
switch (data.type) {
case 'CLOSED_PLANAR':
this._renderClosedPlanar(context, eventData.element, points, {
color,
lineWidth,
});
this._renderClosedPlanar(context, eventData.element, points, options);
break;
case 'POINT':
this._renderPoint(context, eventData.element, points, {
color,
lineWidth,
});
this._renderPoint(context, eventData.element, points, options);
break;
case 'OPEN_PLANAR':
this._renderOpenPlanar(context, eventData.element, points, {
color,
lineWidth,
});
this._renderOpenPlanar(context, eventData.element, points, options);
break;
}
}
if (crossHairCenter) {
drawCanvasCrosshairs(eventData, crossHairCenter, {
color: toolColors.getActiveColor(),
lineWidth: 1,
});
}
}
_renderClosedPlanar(context, element, points, options) {
@@ -13,7 +13,8 @@ function refreshViewport() {
const configuration = {
lineWidth: 3,
opacity: 1.0,
opacity: 0.75,
highlightOpacity: 0.5,
};
const state = {
@@ -0,0 +1,56 @@
import cornerstone from 'cornerstone-core';
import cornerstoneTools from 'cornerstone-tools';
const { importInternal } = cornerstoneTools;
const draw = importInternal('drawing/draw');
const drawLine = importInternal('drawing/drawLine');
const getNewContext = importInternal('drawing/getNewContext');
export default function _drawCanvasCrosshairs(eventData, center, options) {
const context = getNewContext(eventData.canvasContext.canvas);
const { element } = eventData;
const centerCanvas = cornerstone.pixelToCanvas(element, center);
const { clientWidth: width, clientHeight: height } = element;
const offset = 10;
draw(context, context => {
drawLine(
context,
element,
{ x: centerCanvas.x + offset, y: centerCanvas.y },
{ x: width, y: centerCanvas.y },
options,
'canvas'
);
drawLine(
context,
element,
{ x: centerCanvas.x - offset, y: centerCanvas.y },
{ x: 0, y: centerCanvas.y },
options,
'canvas'
);
drawLine(
context,
element,
{ x: centerCanvas.x, y: centerCanvas.y + offset },
{ x: centerCanvas.x, y: height },
options,
'canvas'
);
drawLine(
context,
element,
{ x: centerCanvas.x, y: centerCanvas.y - offset },
{ x: centerCanvas.x, y: 0 },
options,
'canvas'
);
});
}
+308
View File
@@ -3,6 +3,314 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.7.15](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.14...@ohif/extension-dicom-segmentation@0.7.15) (2022-09-19)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.7.14](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.13...@ohif/extension-dicom-segmentation@0.7.14) (2022-09-12)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.7.13](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.12...@ohif/extension-dicom-segmentation@0.7.13) (2022-09-01)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.7.12](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.11...@ohif/extension-dicom-segmentation@0.7.12) (2022-08-31)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.7.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.10...@ohif/extension-dicom-segmentation@0.7.11) (2022-04-05)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.7.10](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.9...@ohif/extension-dicom-segmentation@0.7.10) (2022-03-25)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.7.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.8...@ohif/extension-dicom-segmentation@0.7.9) (2022-03-14)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.7.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.7...@ohif/extension-dicom-segmentation@0.7.8) (2022-02-03)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.7.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.6...@ohif/extension-dicom-segmentation@0.7.7) (2022-02-02)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [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)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.7.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.0...@ohif/extension-dicom-segmentation@0.7.1) (2021-09-28)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
# [0.7.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.11...@ohif/extension-dicom-segmentation@0.7.0) (2021-09-23)
### Features
* Update to WADO Image Loader 4.0.3 to add dynamically imported WebAssembly codec support 🚀 ([#2537](https://github.com/OHIF/Viewers/issues/2537)) ([489d4b0](https://github.com/OHIF/Viewers/commit/489d4b0584f4657ceda1c5b9b68d5e9733827e47))
## [0.6.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.10...@ohif/extension-dicom-segmentation@0.6.11) (2021-09-03)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.6.10](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.9...@ohif/extension-dicom-segmentation@0.6.10) (2021-06-02)
### Bug Fixes
* **dicom-html:** Add parsed dicom meta info section ([#2419](https://github.com/OHIF/Viewers/issues/2419)) ([403688b](https://github.com/OHIF/Viewers/commit/403688b18c52468fc1101166ec0c1734fb710039))
## [0.6.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.8...@ohif/extension-dicom-segmentation@0.6.9) (2021-05-17)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.6.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.7...@ohif/extension-dicom-segmentation@0.6.8) (2021-04-22)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.6.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.6...@ohif/extension-dicom-segmentation@0.6.7) (2021-04-22)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.6.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.5...@ohif/extension-dicom-segmentation@0.6.6) (2021-04-21)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.6.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.4...@ohif/extension-dicom-segmentation@0.6.5) (2021-04-21)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.6.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.3...@ohif/extension-dicom-segmentation@0.6.4) (2021-04-16)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.6.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.2...@ohif/extension-dicom-segmentation@0.6.3) (2021-04-15)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.6.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.1...@ohif/extension-dicom-segmentation@0.6.2) (2021-03-31)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.6.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.6.0...@ohif/extension-dicom-segmentation@0.6.1) (2021-03-09)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
# [0.6.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.5.4...@ohif/extension-dicom-segmentation@0.6.0) (2021-03-04)
### Features
* **log:** add new log service ([14d6454](https://github.com/OHIF/Viewers/commit/14d6454eafaa2ccb50e133c2945c9558052ea27e))
## [0.5.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.5.3...@ohif/extension-dicom-segmentation@0.5.4) (2021-03-03)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.5.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.5.2...@ohif/extension-dicom-segmentation@0.5.3) (2021-02-25)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.5.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.5.1...@ohif/extension-dicom-segmentation@0.5.2) (2021-02-05)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.5.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.5.0...@ohif/extension-dicom-segmentation@0.5.1) (2021-01-21)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
# [0.5.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.4.7...@ohif/extension-dicom-segmentation@0.5.0) (2020-12-10)
### Features
* visualize overlapping segments in cornerstone ([#2185](https://github.com/OHIF/Viewers/issues/2185)) ([29fceac](https://github.com/OHIF/Viewers/commit/29fceacee97d51f1952a0f6b574c66596d32c201))
## [0.4.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.4.6...@ohif/extension-dicom-segmentation@0.4.7) (2020-10-07)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.4.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.4.5...@ohif/extension-dicom-segmentation@0.4.6) (2020-09-17)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.4.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.4.4...@ohif/extension-dicom-segmentation@0.4.5) (2020-09-10)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.4.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.4.3...@ohif/extension-dicom-segmentation@0.4.4) (2020-09-10)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
## [0.4.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.4.2...@ohif/extension-dicom-segmentation@0.4.3) (2020-09-03)
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
+6 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-dicom-segmentation",
"version": "0.4.3",
"version": "0.7.15",
"description": "OHIF extension for viewing segmentations in the 2D MPR view",
"author": "OHIF",
"license": "MIT",
@@ -29,9 +29,9 @@
},
"peerDependencies": {
"@ohif/core": "^0.50.0",
"cornerstone-core": "^2.2.8",
"cornerstone-tools": "^4.20.1",
"dcmjs": "0.16.3",
"cornerstone-core": "^2.6.1",
"cornerstone-tools": "^6.0.6",
"dcmjs": "0.24.10",
"prop-types": "^15.6.2",
"react": "^16.8.6",
"react-dom": "^16.8.6"
@@ -39,6 +39,7 @@
"dependencies": {
"@babel/runtime": "^7.5.5",
"gl-matrix": "^3.3.0",
"react-select": "^3.0.8"
"react-select": "^3.0.8",
"react-tooltip": "4.2.10"
}
}
@@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { TableListItem, Icon } from '@ohif/ui';
import ReactTooltip from 'react-tooltip';
import './SegmentItem.css';
@@ -17,13 +18,31 @@ ColoredCircle.propTypes = {
color: PropTypes.array.isRequired,
};
const SegmentItem = ({ index, label, onClick, itemClass, color, visible = true, onVisibilityChange }) => {
const SegmentItem = ({
index,
label,
onClick,
itemClass,
color,
labelmap3D,
visible,
onVisibilityChange,
}) => {
const [isVisible, setIsVisible] = useState(visible);
useEffect(() => {
setIsVisible(visible);
}, [visible]);
const onClickHandler = () => onClick(index);
const onVisibilityChangeHandler = event => {
event.stopPropagation();
const newVisibility = !isVisible;
setIsVisible(newVisibility);
onVisibilityChange(newVisibility, index, labelmap3D);
};
return (
<div className="dcmseg-segment-item">
<TableListItem
@@ -33,22 +52,28 @@ const SegmentItem = ({ index, label, onClick, itemClass, color, visible = true,
itemClass={itemClass}
itemMeta={<ColoredCircle color={color} />}
itemMetaClass="segment-color-section"
onItemClick={onClick}
onItemClick={onClickHandler}
>
<div>
<div className="segment-label" style={{ marginBottom: 4 }}>
<span>{label}</span>
<a data-tip data-for={`SegmentHover${index}`}>
<span>{label}</span>
</a>
<ReactTooltip
id={`SegmentHover${index}`}
delayShow={250}
place="right"
border={true}
type="light"
>
<span>{label}</span>
</ReactTooltip>
<Icon
className={`eye-icon ${isVisible && '--visible'}`}
name={isVisible ? 'eye' : 'eye-closed'}
width="20px"
height="20px"
onClick={event => {
event.stopPropagation();
const newVisibility = !isVisible;
setIsVisible(newVisibility);
onVisibilityChange(newVisibility);
}}
onClick={onVisibilityChangeHandler}
/>
</div>
{false && <div className="segment-info">{'...'}</div>}
@@ -61,7 +86,7 @@ const SegmentItem = ({ index, label, onClick, itemClass, color, visible = true,
<span style={{ marginRight: '4px' }}>
<Icon name="edit" width="14px" height="14px" />
</span>
Relabel
Relabel
</button>
<button
className="btnAction"
@@ -70,7 +95,7 @@ const SegmentItem = ({ index, label, onClick, itemClass, color, visible = true,
<span style={{ marginRight: '4px' }}>
<Icon name="edit" width="14px" height="14px" />
</span>
Description
Description
</button>
</div>
)}
@@ -90,7 +115,7 @@ SegmentItem.propTypes = {
SegmentItem.defaultProps = {
itemClass: '',
onClick: () => { }
onClick: () => {},
};
export default SegmentItem;
@@ -6,6 +6,7 @@
width: 100%;
display: flex;
flex-direction: column;
padding: 20px;
}
.dcmseg-segmentation-panel.disabled {
@@ -14,19 +15,19 @@
}
.dcmseg-segmentation-panel h3 {
padding-left: 20px;
margin-top: 0;
}
.dcmseg-segmentation-panel .segmentations {
padding: 0 20px 20px 20px;
padding-bottom: 10px;
}
.dcmseg-segmentation-panel .cog-icon {
margin: 20px 20px 0 0;
align-self: flex-end;
color: var(--default-color);
cursor: pointer;
min-height: 23px;
max-height: 23px;
}
.dcmseg-segmentation-panel .cog-icon:hover {
@@ -48,11 +49,11 @@
height: 150px;
}
.dcmseg-segmentation-panel .selector-form>div {
.dcmseg-segmentation-panel .selector-form > div {
width: 100%;
}
.dcmseg-segmentation-panel .selector-form>div:first-of-type {
.dcmseg-segmentation-panel .selector-form > div:first-of-type {
display: flex;
flex-direction: row;
justify-content: center;
@@ -64,3 +65,61 @@
flex: unset;
margin-right: 16px;
}
.SegmentsSection {
display: flex;
flex-direction: column;
color: var(--text-primary-color);
font-size: 12px;
margin-bottom: 0px;
height: 100%;
}
.SegmentsSection .header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
background-color: var(--ui-gray-dark);
border-radius: 5px;
font-weight: bold;
padding: 10px 15px;
}
.SegmentsSection .count {
font-size: 15px;
color: var(--active-color);
margin-left: 15px;
border-radius: 5px;
background-color: var(--ui-gray-darker);
text-align: center;
min-width: 25px;
}
.SegmentsSection .header .eye-icon,
.SegmentsSection .header .angle-double-down,
.SegmentsSection .header .angle-double-up {
cursor: pointer;
color: var(--active-color);
}
.SegmentsSection .header .eye-icon:hover,
.SegmentsSection .header .angle-double-down:hover,
.SegmentsSection .header .angle-double-up:hover {
color: var(--hover-color);
}
.SegmentsSection .header .eye-icon.expanded {
color: var(--default-color);
}
.SegmentsSection .header .icons {
display: flex;
align-items: center;
border-radius: 5px;
}
.SegmentsSection .header .icons .angle-double-down,
.SegmentsSection .header .icons .angle-double-up {
margin-left: 15px;
}
File diff suppressed because it is too large. Load diff
@@ -3,7 +3,7 @@ import Select from 'react-select';
const SegmentationSelect = ({ value, formatOptionLabel, options }) => (
<Select
value={value}
value={value === undefined ? null : value}
formatOptionLabel={formatOptionLabel}
styles={segmentationSelectStyles}
options={options}
@@ -4,7 +4,7 @@ import { Range } from '@ohif/ui';
import './SegmentationSettings.css';
const SegmentationSettings = ({ configuration, onBack, onChange, disabledFields = [] }) => {
const SegmentationSettings = ({ configuration, onBack, onChange, servicesManager, disabledFields = [] }) => {
const [state, setState] = useState({
renderFill: configuration.renderFill,
renderOutline: configuration.renderOutline,
@@ -13,7 +13,8 @@ const SegmentationSettings = ({ configuration, onBack, onChange, disabledFields
outlineAlpha: configuration.outlineAlpha,
outlineWidth: configuration.outlineWidth,
fillAlphaInactive: configuration.fillAlphaInactive,
outlineAlphaInactive: configuration.outlineAlphaInactive
outlineAlphaInactive: configuration.outlineAlphaInactive,
segsTolerance: configuration.segsTolerance,
});
useEffect(() => {
@@ -133,6 +134,40 @@ const SegmentationSettings = ({ configuration, onBack, onChange, disabledFields
)}
</div>
)}
<div className="settings-group" style={{ marginBottom: 15 }}>
<label style={{ margin: '0 15px' }}>
Tolerance:
<input
style={{ margin: '0 15px' }}
label="Tolerance"
onKeyPress={event => {
const validate = string => {
let rgx = /[^-.e0-9]+/g;
return string.match(rgx);
};
if (validate(event.key)) {
event.preventDefault();
}
}}
onChange={event => {
save('segsTolerance', event.target.value);
const { UINotificationService, LoggerService } = servicesManager.services;
const error = new Error('Segmentation loader tolerance changed. This operation can potentially generate errors in the Segmentation parsing.');
LoggerService.error({ error, message: error.message });
UINotificationService.show({
title: 'Segmentation panel',
message: error.message,
type: 'warning',
autoClose: true,
});
}
}
value={state.segsTolerance}
/>
</label>
</div>
</div>
);
};
@@ -169,11 +204,12 @@ SegmentationSettings.propTypes = {
renderFill: PropTypes.bool.isRequired,
renderOutline: PropTypes.bool.isRequired,
shouldRenderInactiveLabelmaps: PropTypes.bool.isRequired,
fillAlpha: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, /* TODO: why fillAlpha is string? */
outlineAlpha: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, /* TODO: why fillAlpha is string? */
fillAlpha: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
outlineAlpha: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
outlineWidth: PropTypes.number.isRequired,
fillAlphaInactive: PropTypes.number.isRequired,
outlineAlphaInactive: PropTypes.number.isRequired,
fillAlphaInactive: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
outlineAlphaInactive: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
segsTolerance: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
}).isRequired,
onBack: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
@@ -1,6 +1,11 @@
import { MODULE_TYPES, utils } from '@ohif/core';
import loadSegmentation from './loadSegmentation';
import getSourceDisplaySet from './getSourceDisplaySet';
import OHIF from '@ohif/core';
import dcmjs from 'dcmjs';
const { DicomLoaderService } = OHIF.utils;
const { DicomMessage, DicomMetaDictionary } = dcmjs.data;
// TODO: Should probably use dcmjs for this
const SOP_CLASS_UIDS = {
@@ -28,12 +33,12 @@ export default function getSopClassHandlerModule({ servicesManager }) {
const {
SeriesDate,
SeriesTime,
SeriesNumber,
SeriesDescription,
FrameOfReferenceUID,
SOPInstanceUID,
SeriesInstanceUID,
StudyInstanceUID,
SeriesNumber,
} = metadata;
const segDisplaySet = {
@@ -46,26 +51,145 @@ export default function getSopClassHandlerModule({ servicesManager }) {
StudyInstanceUID,
FrameOfReferenceUID,
authorizationHeaders,
metadata,
isDerived: true,
referencedDisplaySetUID: null, // Assigned when loaded.
labelmapIndex: null, // Assigned when loaded.
isLoaded: false,
loadError: false,
hasOverlapping: false,
SeriesDate,
SeriesTime,
SeriesNumber,
SeriesDescription,
metadata,
tolerance: 1e-2,
};
segDisplaySet.getSourceDisplaySet = function(studies) {
return getSourceDisplaySet(studies, segDisplaySet);
segDisplaySet.getSourceDisplaySet = function(
studies,
activateLabelMap = true,
onDisplaySetLoadFailureHandler
) {
return getSourceDisplaySet(
studies,
segDisplaySet,
activateLabelMap,
onDisplaySetLoadFailureHandler
);
};
segDisplaySet.load = function(referencedDisplaySet, studies) {
return loadSegmentation(segDisplaySet, referencedDisplaySet, studies);
segDisplaySet.load = async function(referencedDisplaySet, studies) {
segDisplaySet.isLoaded = true;
const { StudyInstanceUID } = referencedDisplaySet;
const segArrayBuffer = await DicomLoaderService.findDicomDataPromise(
segDisplaySet,
studies
);
const dicomData = DicomMessage.readFile(segArrayBuffer);
const dataset = DicomMetaDictionary.naturalizeDataset(dicomData.dict);
dataset._meta = DicomMetaDictionary.namifyDataset(dicomData.meta);
const imageIds = _getImageIdsForDisplaySet(
studies,
StudyInstanceUID,
referencedDisplaySet.SeriesInstanceUID
);
const results = await _parseSeg(segArrayBuffer, imageIds, segDisplaySet.tolerance);
if (results === undefined) {
return;
}
const {
labelmapBufferArray,
segMetadata,
segmentsOnFrame,
segmentsOnFrameArray,
} = results;
let labelmapIndex;
if (labelmapBufferArray.length > 1) {
let labelmapIndexes = [];
for (let i = 0; i < labelmapBufferArray.length; ++i) {
segMetadata.segmentationSeriesInstanceUID =
segDisplaySet.SeriesInstanceUID;
segMetadata.hasOverlapping = true;
labelmapIndexes.push(
await loadSegmentation(
imageIds,
segDisplaySet,
labelmapBufferArray[i],
segMetadata,
segmentsOnFrame,
segmentsOnFrameArray[i]
)
);
}
/**
* Since overlapping segments have virtual labelmaps,
* originLabelMapIndex is used in the panel to select the correct dropdown value.
*/
segDisplaySet.hasOverlapping = true;
segDisplaySet.originLabelMapIndex = labelmapIndexes[0];
labelmapIndex = labelmapIndexes[0];
console.warn('Overlapping segments!');
} else {
segMetadata.segmentationSeriesInstanceUID =
segDisplaySet.SeriesInstanceUID;
segMetadata.hasOverlapping = false;
labelmapIndex = await loadSegmentation(
imageIds,
segDisplaySet,
labelmapBufferArray[0],
segMetadata,
segmentsOnFrame,
[]
);
}
};
return segDisplaySet;
},
};
}
function _parseSeg(
arrayBuffer,
imageIds,
tolerance = 1e-2,
skipOverlapping = false,
cornerstoneToolsVersion = 4
) {
return dcmjs.adapters.Cornerstone.Segmentation.generateToolState(
imageIds,
arrayBuffer,
cornerstone.metaData,
skipOverlapping,
tolerance,
cornerstoneToolsVersion
);
}
function _getImageIdsForDisplaySet(
studies,
StudyInstanceUID,
SeriesInstanceUID
) {
const study = studies.find(
study => study.StudyInstanceUID === StudyInstanceUID
);
const displaySets = study.displaySets.filter(displaySet => {
return displaySet.SeriesInstanceUID === SeriesInstanceUID;
});
if (displaySets.length > 1) {
console.warn(
'More than one display set with the same SeriesInstanceUID. This is not supported yet...'
);
// TODO -> We could make check the instance list and see if any match?
// Do we split the segmentation into two cornerstoneTools segmentations if there are images in both series?
// ^ Will that even happen?
}
const referencedDisplaySet = displaySets[0];
return referencedDisplaySet.images.map(image => image.getImageId());
}
@@ -1,88 +1,16 @@
import setActiveLabelmap from './utils/setActiveLabelMap';
import { classes } from '@ohif/core';
import { metadata } from '@ohif/core';
const { ImageSet } = classes;
export default function getSourceDisplaySet(studies, segDisplaySet, activateLabelMap = true, onDisplaySetLoadFailureHandler) {
const referencedDisplaySet = metadata.StudyMetadata.getReferencedDisplaySet(segDisplaySet, studies);
export default function getSourceDisplaySet(studies, segDisplaySet) {
const referencedDisplaySet = _getReferencedDisplaySet(segDisplaySet, studies);
setActiveLabelmap(referencedDisplaySet, studies, segDisplaySet);
return referencedDisplaySet;
}
const _getReferencedDisplaySet = (segDisplaySet, studies) => {
let allDisplaySets = [];
studies.forEach(study => {
allDisplaySets = allDisplaySets.concat(study.displaySets);
});
const otherDisplaySets = allDisplaySets.filter(
ds => ds.displaySetInstanceUID !== segDisplaySet.displaySetInstanceUID
);
const { metadata } = segDisplaySet;
let referencedSeriesInstanceUIDs;
if (metadata.ReferencedSeriesSequence) {
const ReferencedSeriesSequence = _toArray(
metadata.ReferencedSeriesSequence
);
referencedSeriesInstanceUIDs = ReferencedSeriesSequence.map(
ReferencedSeries => ReferencedSeries.SeriesInstanceUID
);
} else {
const { PerFrameFunctionalGroupsSequence } = metadata;
let SourceImageSequence;
if (metadata.SourceImageSequence) {
SourceImageSequence = metadata.SourceImageSequence;
} else {
const firstFunctionalGroups = _toArray(
PerFrameFunctionalGroupsSequence
)[0];
const { DerivationImageSequence } = firstFunctionalGroups;
SourceImageSequence = DerivationImageSequence;
}
const firstSourceImage = _toArray(SourceImageSequence)[0];
const { ReferencedSOPInstanceUID } = firstSourceImage;
referencedSeriesInstanceUIDs = _findReferencedSeriesInstanceUIDsFromSOPInstanceUID(
otherDisplaySets,
ReferencedSOPInstanceUID
);
let activatedLabelmapPromise;
if (activateLabelMap) {
activatedLabelmapPromise = setActiveLabelmap(referencedDisplaySet, studies, segDisplaySet, undefined, onDisplaySetLoadFailureHandler);
}
const referencedDisplaySet = otherDisplaySets.find(ds =>
referencedSeriesInstanceUIDs.includes(ds.SeriesInstanceUID)
);
return referencedDisplaySet;
};
const _findReferencedSeriesInstanceUIDsFromSOPInstanceUID = (
displaySets,
SOPInstanceUID
) => {
const imageSets = displaySets.filter(ds => ds instanceof ImageSet);
for (let i = 0; i < imageSets.length; i++) {
const { images } = imageSets[i];
for (let j = 0; j < images.length; j++) {
if (images[j].SOPInstanceUID === SOPInstanceUID) {
return [images[j].getData().metadata.SeriesInstanceUID];
}
}
return {
referencedDisplaySet : referencedDisplaySet,
activatedLabelmapPromise : activatedLabelmapPromise
}
};
function _toArray(arrayOrObject) {
return Array.isArray(arrayOrObject) ? arrayOrObject : [arrayOrObject];
}
+62 -3
View File
@@ -1,9 +1,12 @@
import React from 'react';
import OHIF from '@ohif/core';
import init from './init.js';
import toolbarModule from './toolbarModule.js';
import getSopClassHandlerModule from './getOHIFDicomSegSopClassHandler.js';
import SegmentationPanel from './components/SegmentationPanel/SegmentationPanel.js';
import { version } from '../package.json';
const { studyMetadataManager } = OHIF.utils;
export default {
/**
@@ -25,12 +28,12 @@ export default {
return toolbarModule;
},
getPanelModule({ commandsManager, api, servicesManager }) {
const { UINotificationService } = servicesManager.services;
const { UINotificationService, LoggerService } = servicesManager.services;
const ExtendedSegmentationPanel = props => {
const { activeContexts } = api.hooks.useAppContext();
const onDisplaySetLoadFailureHandler = error => {
LoggerService.error({ error, message: error.message });
UINotificationService.show({
title: 'DICOM Segmentation Loader',
message: error.message,
@@ -74,17 +77,56 @@ export default {
onConfigurationChange={onConfigurationChangeHandler}
onSelectedSegmentationChange={onSelectedSegmentationChangeHandler}
onDisplaySetLoadFailure={onDisplaySetLoadFailureHandler}
servicesManager={servicesManager}
/>
);
};
const SegmentationPanelTabUpdatedEvent = 'segmentation-panel-tab-updated';
/**
* Trigger's an event to update the state of the panel's RoundedButtonGroup.
*
* This is required to avoid extension state
* coupling with the viewer's ToolbarRow component.
*
* @param {object} data
*/
const triggerSegmentationPanelTabUpdatedEvent = data => {
const event = new CustomEvent(SegmentationPanelTabUpdatedEvent, {
detail: data,
});
document.dispatchEvent(event);
};
const onSegmentationsLoaded = ({ detail }) => {
const { segDisplaySet, segMetadata } = detail;
const studyMetadata = studyMetadataManager.get(
segDisplaySet.StudyInstanceUID
);
const referencedDisplaysets = studyMetadata.getDerivedDatasets({
referencedSeriesInstanceUID: segMetadata.seriesInstanceUid,
Modality: 'SEG',
});
triggerSegmentationPanelTabUpdatedEvent({
badgeNumber: referencedDisplaysets.length,
target: 'segmentation-panel',
});
};
document.addEventListener(
'extensiondicomsegmentationsegloaded',
onSegmentationsLoaded
);
return {
menuOptions: [
{
icon: 'list',
label: 'Segmentations',
target: 'segmentation-panel',
isDisabled: studies => {
stateEvent: SegmentationPanelTabUpdatedEvent,
isDisabled: (studies, activeViewport) => {
if (!studies) {
return true;
}
@@ -97,6 +139,23 @@ export default {
const series = study.series[j];
if (series.Modality === 'SEG') {
if (activeViewport) {
const studyMetadata = studyMetadataManager.get(
activeViewport.StudyInstanceUID
);
if (!studyMetadata) {
return;
}
const referencedDS = studyMetadata.getDerivedDatasets({
referencedSeriesInstanceUID:
activeViewport.SeriesInstanceUID,
Modality: 'SEG',
});
triggerSegmentationPanelTabUpdatedEvent({
badgeNumber: referencedDS.length,
target: 'segmentation-panel',
});
}
return false;
}
}
@@ -1,4 +1,5 @@
import csTools from 'cornerstone-tools';
import DICOMSegTempCrosshairsTool from './tools/DICOMSegTempCrosshairsTool';
/**
*
@@ -17,4 +18,6 @@ export default function init({ servicesManager, configuration = {} }) {
alwaysEraseOnClick: true,
},
});
csTools.addTool(DICOMSegTempCrosshairsTool);
}
@@ -1,92 +1,77 @@
import OHIF from '@ohif/core';
import dcmjs from 'dcmjs';
import cornerstone from 'cornerstone-core';
import cornerstoneTools from 'cornerstone-tools';
const { DicomLoaderService } = OHIF.utils;
export default async function loadSegmentation(
imageIds,
segDisplaySet,
referencedDisplaySet,
studies
labelmapBuffer,
segMetadata,
segmentsOnFrame,
labelmapSegments
) {
const { StudyInstanceUID } = referencedDisplaySet;
const { setters } = cornerstoneTools.getModule('segmentation');
// Set here is loading is asynchronous.
// If this function throws its set back to false.
segDisplaySet.isLoaded = true;
// TODO: Could define a color LUT based on colors in the SEG.
const labelmapIndex = _getNextLabelmapIndex(imageIds[0]);
const colorLUTIndex = _makeColorLUTAndGetIndex(segMetadata);
const segArrayBuffer = await DicomLoaderService.findDicomDataPromise(
segDisplaySet,
studies
setters.labelmap3DByFirstImageId(
imageIds[0],
labelmapBuffer,
labelmapIndex,
segMetadata,
imageIds.length,
segmentsOnFrame,
colorLUTIndex
);
const dicomData = dcmjs.data.DicomMessage.readFile(segArrayBuffer);
const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(
dicomData.dict
);
if (!segDisplaySet.labelmapSegments) {
segDisplaySet.labelmapSegments = {};
}
dataset._meta = dcmjs.data.DicomMetaDictionary.namifyDataset(dicomData.meta);
/**
* Cache each labelmap segments.
* This data is used to determine the active label map when a given segment is activated/clicked.
*/
segDisplaySet.labelmapSegments[labelmapIndex] = labelmapSegments.length
? Array.from(
new Set(labelmapSegments.filter(a => !!a).reduce((a, b) => a.concat(b)))
)
: [];
segDisplaySet.labelmapIndex = labelmapIndex;
const imageIds = _getImageIdsForDisplaySet(
studies,
StudyInstanceUID,
referencedDisplaySet.SeriesInstanceUID
);
return new Promise((resolve, reject) => {
let results;
try {
results = _parseSeg(segArrayBuffer, imageIds);
} catch (error) {
segDisplaySet.isLoaded = false;
segDisplaySet.loadError = true;
reject(error);
}
const { labelmapBuffer, segMetadata, segmentsOnFrame } = results;
const { setters } = cornerstoneTools.getModule('segmentation');
// TODO: Could define a color LUT based on colors in the SEG.
const labelmapIndex = _getNextLabelmapIndex(imageIds[0]);
const colorLUTIndex = _makeColorLUTAndGetIndex(segMetadata);
setters.labelmap3DByFirstImageId(
imageIds[0],
/*
* TODO: Improve the way we notify parts of the app that depends on segs to be loaded.
*
* Currently we are using a non-ideal implementation through a custom event to notify the segmentation panel
* or other components that could rely on loaded segmentations that
* the segments were loaded so that e.g. when the user opens the panel
* before the segments are fully loaded, the panel can subscribe to this custom event
* and update itself with the new segments.
*
* This limitation is due to the fact that the cs segmentation module is an object (which will be
* updated after the segments are loaded) that React its not aware of its changes
* because the module object its not passed in to the panel component as prop but accessed externally.
*
* Improving this event approach to something reactive that can be tracked inside the react lifecycle,
* allows us to easily watch the module or the segmentations loading process in any other component
* without subscribing to external events.
*/
console.log('Segmentation loaded.');
const event = new CustomEvent('extensiondicomsegmentationsegloaded', {
detail: {
imageIds,
segDisplaySet,
labelmapBuffer,
labelmapIndex,
segMetadata,
imageIds.length,
segmentsOnFrame,
colorLUTIndex
);
segDisplaySet.labelmapIndex = labelmapIndex;
/*
* TODO: Improve the way we notify parts of the app that depends on segs to be loaded.
*
* Currently we are using a non-ideal implementation through a custom event to notify the segmentation panel
* or other components that could rely on loaded segmentations that
* the segments were loaded so that e.g. when the user opens the panel
* before the segments are fully loaded, the panel can subscribe to this custom event
* and update itself with the new segments.
*
* This limitation is due to the fact that the cs segmentation module is an object (which will be
* updated after the segments are loaded) that React its not aware of its changes
* because the module object its not passed in to the panel component as prop but accessed externally.
*
* Improving this event approach to something reactive that can be tracked inside the react lifecycle,
* allows us to easily watch the module or the segmentations loading process in any other component
* without subscribing to external events.
*/
console.log('Segmentation loaded.');
const event = new CustomEvent('extensiondicomsegmentationsegloaded');
document.dispatchEvent(event);
resolve(labelmapIndex);
labelmapSegments,
},
});
document.dispatchEvent(event);
return labelmapIndex;
}
function _getNextLabelmapIndex(firstImageId) {
@@ -172,38 +157,3 @@ function _getNextColorLUTIndex() {
return colorLUTIndex;
}
function _parseSeg(arrayBuffer, imageIds) {
return dcmjs.adapters.Cornerstone.Segmentation.generateToolState(
imageIds,
arrayBuffer,
cornerstone.metaData
);
}
function _getImageIdsForDisplaySet(
studies,
StudyInstanceUID,
SeriesInstanceUID
) {
const study = studies.find(
study => study.StudyInstanceUID === StudyInstanceUID
);
const displaySets = study.displaySets.filter(displaySet => {
return displaySet.SeriesInstanceUID === SeriesInstanceUID;
});
if (displaySets.length > 1) {
console.warn(
'More than one display set with the same SeriesInstanceUID. This is not supported yet...'
);
// TODO -> We could make check the instance list and see if any match?
// Do we split the segmentation into two cornerstoneTools segmentations if there are images in both series?
// ^ Will that even happen?
}
const referencedDisplaySet = displaySets[0];
return referencedDisplaySet.images.map(image => image.getImageId());
}
@@ -0,0 +1,127 @@
import cornerstoneTools, {
importInternal,
getToolState,
toolColors,
getModule,
globalImageIdSpecificToolStateManager,
} from 'cornerstone-tools';
import cornerstone from 'cornerstone-core';
import drawCanvasCrosshairs from '../utils/drawCanvasCrosshairs';
import TOOL_NAMES from './TOOL_NAMES';
const { DICOM_SEG_TEMP_CROSSHAIRS_TOOL } = TOOL_NAMES;
const { getters } = getModule('segmentation');
// Cornerstone 3rd party dev kit imports
const BaseTool = importInternal('base/BaseTool');
/**
* @class RTStructDisplayTool - Renders RTSTRUCT data in a read only manner (i.e. as an overlay).
* @extends cornerstoneTools.BaseTool
*/
export default class DICOMSegTempCrosshairsTool extends BaseTool {
constructor(props = {}) {
const defaultProps = {
mixins: ['enabledOrDisabledBinaryTool'],
name: DICOM_SEG_TEMP_CROSSHAIRS_TOOL,
};
const initialProps = Object.assign(defaultProps, props);
super(initialProps);
this._rtStructModule = cornerstoneTools.getModule('rtstruct');
}
renderToolData(evt) {
const eventData = evt.detail;
const { element } = eventData;
const toolState = getToolState(evt.currentTarget, this.name);
if (!toolState) {
return;
}
// We have tool data for this element - iterate over each one and draw it
for (let i = 0; i < toolState.data.length; i++) {
const data = toolState.data[i];
const crossHairCenter = data.center;
drawCanvasCrosshairs(eventData, crossHairCenter, {
color: toolColors.getActiveColor(),
lineWidth: 1,
});
// Remove the crosshairs, we only render them for one redraw.
toolState.data.pop();
}
}
}
DICOMSegTempCrosshairsTool.addCrosshair = (element, imageId, segmentNumber) => {
const labelmap3D = getters.labelmap3D(element);
const stackToolState = cornerstoneTools.getToolState(element, 'stack');
const enabledElement = cornerstone.getEnabledElement(element);
const { rows, columns } = enabledElement.image;
if (!stackToolState) {
return;
}
const imageIds = stackToolState.data[0].imageIds;
const imageIdIndex = imageIds.findIndex(imgId => imgId === imageId);
const labelmap2D = labelmap3D.labelmaps2D[imageIdIndex];
const { pixelData } = labelmap2D;
let xCenter = 0;
let yCenter = 0;
let count = 0;
for (let y = 0; y < rows; y++) {
for (let x = 0; x < columns; x++) {
if (pixelData[y * columns + x] === segmentNumber) {
count++;
xCenter += x + 0.5;
yCenter += y + 0.5;
}
}
}
xCenter /= count;
yCenter /= count;
const globalToolState = globalImageIdSpecificToolStateManager.saveToolState();
if (!globalToolState[imageId]) {
globalToolState[imageId] = {};
}
const imageIdSpecificToolState = globalToolState[imageId];
if (!imageIdSpecificToolState[DICOM_SEG_TEMP_CROSSHAIRS_TOOL]) {
imageIdSpecificToolState[DICOM_SEG_TEMP_CROSSHAIRS_TOOL] = { data: [] };
} else if (!imageIdSpecificToolState[DICOM_SEG_TEMP_CROSSHAIRS_TOOL].data) {
imageIdSpecificToolState[DICOM_SEG_TEMP_CROSSHAIRS_TOOL].data = [];
}
const toolSpecificData =
imageIdSpecificToolState[DICOM_SEG_TEMP_CROSSHAIRS_TOOL].data;
toolSpecificData.push({ center: { x: xCenter, y: yCenter }, segmentNumber });
// Enable the tool if not enabled for the element.
const tool = cornerstoneTools.getToolForElement(
element,
DICOM_SEG_TEMP_CROSSHAIRS_TOOL
);
if (tool.mode !== 'enabled') {
// If not already active or passive, set passive so contours render.
cornerstoneTools.setToolEnabled(DICOM_SEG_TEMP_CROSSHAIRS_TOOL);
}
};
@@ -0,0 +1,5 @@
const TOOL_NAMES = {
DICOM_SEG_TEMP_CROSSHAIRS_TOOL: 'DICOMSegTempCrosshairsTool',
};
export default TOOL_NAMES;
@@ -0,0 +1,56 @@
import cornerstone from 'cornerstone-core';
import cornerstoneTools from 'cornerstone-tools';
const { importInternal } = cornerstoneTools;
const draw = importInternal('drawing/draw');
const drawLine = importInternal('drawing/drawLine');
const getNewContext = importInternal('drawing/getNewContext');
export default function _drawCanvasCrosshairs(eventData, center, options) {
const context = getNewContext(eventData.canvasContext.canvas);
const { element } = eventData;
const centerCanvas = cornerstone.pixelToCanvas(element, center);
const { clientWidth: width, clientHeight: height } = element;
const offset = 10;
draw(context, context => {
drawLine(
context,
element,
{ x: centerCanvas.x + offset, y: centerCanvas.y },
{ x: width, y: centerCanvas.y },
options,
'canvas'
);
drawLine(
context,
element,
{ x: centerCanvas.x - offset, y: centerCanvas.y },
{ x: 0, y: centerCanvas.y },
options,
'canvas'
);
drawLine(
context,
element,
{ x: centerCanvas.x, y: centerCanvas.y + offset },
{ x: centerCanvas.x, y: height },
options,
'canvas'
);
drawLine(
context,
element,
{ x: centerCanvas.x, y: centerCanvas.y - offset },
{ x: centerCanvas.x, y: 0 },
options,
'canvas'
);
});
}
@@ -20,7 +20,7 @@ export default async function setActiveLabelmap(
displaySet,
callback = () => {},
onDisplaySetLoadFailure = err => {
throw new Error(err.message);
console.error(err.message);
}
) {
const studyMetadata = studyMetadataManager.get(
@@ -37,31 +37,52 @@ export default async function setActiveLabelmap(
? brushStackState.activeLabelmapIndex
: undefined;
if (displaySet.labelmapIndex === activeLabelmapIndex) {
let labelmapIndex =
displaySet.hasOverlapping === true
? displaySet.originLabelMapIndex
: displaySet.labelmapIndex;
if (labelmapIndex === activeLabelmapIndex) {
log.warn(`${activeLabelmapIndex} is already the active labelmap`);
return displaySet.labelmapIndex;
return labelmapIndex;
}
if (!displaySet.isLoaded) {
const loadPromise = displaySet.load(referencedDisplaySet, studies);
loadPromise.catch(error => {
if (!displaySet.isLoaded && !displaySet.loadError) {
try {
await displaySet.load(referencedDisplaySet, studies);
} catch (error) {
displaySet.isLoaded = false;
displaySet.loadError = true;
displaySet.segLoadErrorMessagge = error.message;
onDisplaySetLoadFailure(error);
// Return old index.
return activeLabelmapIndex;
});
/*
* TODO: Improve the way we notify parts of the app
* that depends on derived display sets to be loaded.
* (Implement pubsub for better tracking of derived display sets)
*/
const event = new CustomEvent('segmentationLoadingError');
document.dispatchEvent(event);
await loadPromise;
return -1;
}
}
labelmapIndex =
displaySet.hasOverlapping === true
? displaySet.originLabelMapIndex
: displaySet.labelmapIndex;
// This might have just been created, so need to use the non-cached value.
state = cornerstoneTools.getModule('segmentation').state;
brushStackState = state.series[firstImageId];
brushStackState.activeLabelmapIndex = displaySet.labelmapIndex;
if (brushStackState) {
brushStackState.activeLabelmapIndex = labelmapIndex;
}
refreshViewports();
callback();
return displaySet.labelmapIndex;
return labelmapIndex;
}
@@ -0,0 +1,8 @@
const path = require('path');
const webpackCommon = require('./../../../.webpack/webpack.commonjs.js');
const SRC_DIR = path.join(__dirname, '../src');
const DIST_DIR = path.join(__dirname, '../dist');
module.exports = (env, argv) => {
return webpackCommon(env, argv, { SRC_DIR, DIST_DIR });
};
@@ -0,0 +1,38 @@
const merge = require('webpack-merge');
const path = require('path');
const webpackCommon = require('./../../../.webpack/webpack.commonjs.js');
const pkg = require('./../package.json');
const ROOT_DIR = path.join(__dirname, './..');
const SRC_DIR = path.join(__dirname, '../src');
const DIST_DIR = path.join(__dirname, '../dist');
module.exports = (env, argv) => {
const commonConfig = webpackCommon(env, argv, { SRC_DIR, DIST_DIR });
return merge(commonConfig, {
devtool: 'source-map',
stats: {
colors: true,
hash: true,
timings: true,
assets: true,
chunks: false,
chunkModules: false,
modules: false,
children: false,
warnings: true,
},
optimization: {
minimize: true,
sideEffects: true,
},
output: {
path: ROOT_DIR,
library: 'OHIFExtDicomP10Downloader',
libraryTarget: 'umd',
libraryExport: 'default',
filename: pkg.main,
},
});
};
+260
View File
@@ -0,0 +1,260 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.2.24](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.23...@ohif/extension-dicom-tag-browser@0.2.24) (2022-09-01)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.23](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.22...@ohif/extension-dicom-tag-browser@0.2.23) (2022-04-06)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.22](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.21...@ohif/extension-dicom-tag-browser@0.2.22) (2022-04-05)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.21](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.20...@ohif/extension-dicom-tag-browser@0.2.21) (2022-03-25)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.20](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.19...@ohif/extension-dicom-tag-browser@0.2.20) (2022-03-14)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.19](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.18...@ohif/extension-dicom-tag-browser@0.2.19) (2022-02-03)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.18](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.17...@ohif/extension-dicom-tag-browser@0.2.18) (2022-02-02)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [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)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.10...@ohif/extension-dicom-tag-browser@0.2.11) (2021-06-03)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.10](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.9...@ohif/extension-dicom-tag-browser@0.2.10) (2021-06-02)
### Bug Fixes
* **dicom-html:** Add parsed dicom meta info section ([#2419](https://github.com/OHIF/Viewers/issues/2419)) ([403688b](https://github.com/OHIF/Viewers/commit/403688b18c52468fc1101166ec0c1734fb710039))
## [0.2.9](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.8...@ohif/extension-dicom-tag-browser@0.2.9) (2021-04-22)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.8](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.7...@ohif/extension-dicom-tag-browser@0.2.8) (2021-04-22)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.7](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.6...@ohif/extension-dicom-tag-browser@0.2.7) (2021-04-21)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.6](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.5...@ohif/extension-dicom-tag-browser@0.2.6) (2021-04-15)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.4...@ohif/extension-dicom-tag-browser@0.2.5) (2021-03-09)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.3...@ohif/extension-dicom-tag-browser@0.2.4) (2021-03-03)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.2...@ohif/extension-dicom-tag-browser@0.2.3) (2021-02-25)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.1...@ohif/extension-dicom-tag-browser@0.2.2) (2021-02-05)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.2.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.0...@ohif/extension-dicom-tag-browser@0.2.1) (2021-02-05)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
# [0.2.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.1.1...@ohif/extension-dicom-tag-browser@0.2.0) (2020-12-10)
### Features
* visualize overlapping segments in cornerstone ([#2185](https://github.com/OHIF/Viewers/issues/2185)) ([29fceac](https://github.com/OHIF/Viewers/commit/29fceacee97d51f1952a0f6b574c66596d32c201))
## [0.1.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.1.0...@ohif/extension-dicom-tag-browser@0.1.1) (2020-12-03)
### Bug Fixes
* fallback to original dataset VR for XS ([f57725a](https://github.com/OHIF/Viewers/commit/f57725ac8bfd59ea46ab334a1823882afadefba1))
# [0.1.0](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.0.5...@ohif/extension-dicom-tag-browser@0.1.0) (2020-12-03)
### Features
* add show scroll option to modal ([be494a7](https://github.com/OHIF/Viewers/commit/be494a7376d15777dbe598289c4ecdb9f48a6a48))
## [0.0.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.0.4...@ohif/extension-dicom-tag-browser@0.0.5) (2020-12-03)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.0.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.0.3...@ohif/extension-dicom-tag-browser@0.0.4) (2020-10-07)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## [0.0.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.0.2...@ohif/extension-dicom-tag-browser@0.0.3) (2020-09-24)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
## 0.0.2 (2020-09-10)
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Open Health Imaging Foundation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+1
View File
@@ -0,0 +1 @@
# @ohif/extension-dicom-tag-browser
+40
View File
@@ -0,0 +1,40 @@
{
"name": "@ohif/extension-dicom-tag-browser",
"version": "0.2.24",
"description": "OHIF extension for checking DICOM headers.",
"author": "OHIF",
"license": "MIT",
"repository": "OHIF/Viewers",
"main": "dist/index.umd.js",
"module": "src/index.js",
"publishConfig": {
"access": "public"
},
"engines": {
"node": ">=10",
"npm": ">=6",
"yarn": ">=1.16.0"
},
"files": [
"dist",
"README.md"
],
"scripts": {
"dev": "cross-env NODE_ENV=development webpack --config .webpack/webpack.dev.js --watch --debug --output-pathinfo",
"build": "cross-env NODE_ENV=production webpack --config .webpack/webpack.prod.js",
"build:package": "yarn run build",
"prepublishOnly": "yarn run build",
"start": "yarn run dev"
},
"peerDependencies": {
"@ohif/core": "^2.6.0",
"dcmjs": "0.24.10",
"react": "^16.8.6"
},
"dependencies": {
"@babel/runtime": "^7.5.5",
"dicomweb-client": "^0.8.3",
"moment": "2.24.0",
"react-select": "^3.0.8"
}
}
@@ -0,0 +1,59 @@
import React from 'react';
import Select from 'react-select';
const DicomBrowserSelect = ({ value, formatOptionLabel, options }) => (
<Select
value={value}
formatOptionLabel={formatOptionLabel}
styles={dicomBrowserSelectStyles}
options={options}
/>
);
const computedstyle = getComputedStyle(document.body);
const uiGrayDarker = computedstyle.getPropertyValue('--ui-gray-darker');
const activeColor = computedstyle.getPropertyValue('--active-color');
const defaultColor = computedstyle.getPropertyValue('--default-color');
const uiGrayDark = computedstyle.getPropertyValue('--ui-gray-dark');
const dicomBrowserSelectStyles = {
singleValue: (base, state) => ({
...base,
width: '100%',
}),
control: (base, state) => ({
...base,
cursor: 'pointer',
background: uiGrayDarker,
borderRadius: state.isFocused ? '5px 5px 5px 5px' : 5,
borderColor: state.isFocused ? activeColor : defaultColor,
minHeight: '50px',
'&:hover': {
borderColor: activeColor,
},
}),
menu: base => ({
...base,
borderRadius: 5,
background: uiGrayDarker,
}),
option: (base, state) => ({
...base,
width: '100%',
cursor: 'pointer',
'&:first-of-type': {
borderTopLeftRadius: 5,
borderTopRightRadius: 5,
},
'&:last-of-type': {
borderBottomLeftRadius: 5,
borderBottomRightRadius: 5,
},
background: state.isSelected ? uiGrayDark : uiGrayDarker,
'&:hover': {
background: uiGrayDark,
},
}),
};
export default DicomBrowserSelect;
@@ -0,0 +1,26 @@
.dcmseg-segmentation-item {
display: flex;
justify-content: start;
margin: 0;
width: 100%;
}
.dcmseg-segmentation-item .segmentation-meta {
display: flex;
flex-direction: column;
flex-grow: 1;
overflow: hidden;
}
.dcmseg-segmentation-item .segmentation-meta-title {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
color: white;
max-width: calc(100% - 30px);
}
.dcmseg-segmentation-item .segmentation-meta-description {
font-size: 12px;
color: var(--text-secondary-color);
}
@@ -0,0 +1,27 @@
import React from 'react';
import PropTypes from 'prop-types';
import './DicomBrowserSelectItem.css';
const DicomBrowserSelectItem = ({ onClick, title, description }) => {
return (
<li className="dcmseg-segmentation-item" onClick={onClick}>
<div className="segmentation-meta">
<div className="segmentation-meta-title">{title}</div>
<div className="segmentation-meta-description">{description}</div>
</div>
</li>
);
};
DicomBrowserSelectItem.propTypes = {
onClick: PropTypes.func.isRequired,
title: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
};
DicomBrowserSelectItem.defaultProps = {
description: '',
};
export default DicomBrowserSelectItem;
@@ -0,0 +1,46 @@
.dicom-tag-browser-table {
margin-right: auto;
margin-left: auto;
}
.dicom-tag-browser-table-wrapper {
height: 500px;
overflow-y: scroll;
}
.dicom-tag-browser-table tr {
padding-left: 10px;
padding-right: 10px;
color: var(--table-text-primary-color);
border-top: 1px solid #ddd;
white-space: nowrap;
}
.dicom-tag-browser-content {
overflow: hidden;
width: 100%;
padding-bottom: 50px;
}
.dicom-tag-browser-instance-range .range {
height: 20px;
}
.dicom-tag-browser-instance-range {
padding: 20px 0 20px 0;
}
.dicom-tag-browser-table td.dicom-tag-browser-table-center {
text-align: center;
}
.dicom-tag-browser-table th {
padding-left: 10px;
padding-right: 10px;
text-align: center;
color: var(--active-color);
}
.dicom-tag-browser-table th.dicom-tag-browser-table-left {
text-align: left;
}
Loaded 100 of 477 files, more files were not shown because too many files have changed in this diff. Show more