Compare commits

..
Author SHA1 Message Date
ohif-bot 71c16615d1 chore(version): Update package versions [skip ci] 2025-10-03 16:32:53 +00:00
ohif-bot b1fc82315c chore(version): version.json [skip ci] 2025-10-03 16:32:46 +00:00
AlirezaandCursor Agent 6a1df9de4a fix: study browser mode for multiple studies (#5457)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2025-10-03 12:28:05 -04:00
ohif-bot 06445dcaa2 chore(version): Update package versions [skip ci] 2025-10-02 21:10:24 +00:00
ohif-bot a344183355 chore(version): version.json [skip ci] 2025-10-02 21:10:17 +00:00
ZZzzaaKK 2f28a0deab fix(studyBrowserCustomization): fix thumbnail menu item actions in study browser (#5283) 2025-10-02 17:05:45 -04:00
ohif-bot e04310a02d chore(version): Update package versions [skip ci] 2025-10-01 18:37:20 +00:00
ohif-bot 4efb7efd0e chore(version): version.json [skip ci] 2025-10-01 18:37:11 +00:00
Bill WallaceandIbrahim 9ad0d7fc8c feat: Add inherit from basic/longitudinal modes (#5435)
Co-authored-by: Ibrahim <ibrahim.mdev@gmail.com>
2025-10-01 14:31:26 -04:00
ohif-bot 71d21ee184 chore(version): Update package versions [skip ci] 2025-09-30 22:34:04 +00:00
ohif-bot 9677dfdb90 chore(version): version.json [skip ci] 2025-09-30 22:33:57 +00:00
Smoothengineer 5b361fb289 docs: grammar: change "it's" to "its" (#5451) 2025-09-30 18:29:00 -04:00
ohif-bot d9c5b840a5 chore(version): Update package versions [skip ci] 2025-09-30 19:12:30 +00:00
ohif-bot ec3a70b5a7 chore(version): version.json [skip ci] 2025-09-30 19:12:18 +00:00
Joe Boccanfuso a46b00f76b chore(deps): Update cornerstone3D to 4.3.14. (#5450) 2025-09-30 15:07:13 -04:00
ohif-bot f0e9865ca1 chore(version): Update package versions [skip ci] 2025-09-30 17:55:16 +00:00
ohif-bot 0d37705435 chore(version): version.json [skip ci] 2025-09-30 17:55:07 +00:00
Vinícius Alves de Faria Resende 12ac509c40 test(SegmentationService): Adding 98.63% of test line coverage to Segmentation Service through unit tests (#5421) 2025-09-30 13:49:13 -04:00
ohif-bot 9353a840ee chore(version): Update package versions [skip ci] 2025-09-29 20:01:26 +00:00
ohif-bot 8030577fb2 chore(version): version.json [skip ci] 2025-09-29 20:01:18 +00:00
Joe Boccanfuso dd86a8eabd fix(segmentation): Restored segment label tool in longitudinal mode. (#5443) 2025-09-29 15:56:11 -04:00
ohif-bot 47164463cc chore(version): Update package versions [skip ci] 2025-09-29 16:53:02 +00:00
ohif-bot 00b74664f9 chore(version): version.json [skip ci] 2025-09-29 16:52:54 +00:00
Dan RukasandJoe Boccanfuso c91752d575 ui(settings): Moved Segment Label Display from tools to settings panel (#5422)
Co-authored-by: Joe Boccanfuso <joe.boccanfuso@radicalimaging.com>
2025-09-29 12:47:45 -04:00
ohif-bot 41d4398342 chore(version): Update package versions [skip ci] 2025-09-29 02:32:36 +00:00
ohif-bot f0a5795b68 chore(version): version.json [skip ci] 2025-09-29 02:32:30 +00:00
Joe Boccanfuso 80f314a422 fix(security): Removed dependency on tar-fs by removing dependencies on storybook and sharp. (#5438) 2025-09-28 22:28:06 -04:00
ohif-bot a6408d6033 chore(version): Update package versions [skip ci] 2025-09-26 14:10:20 +00:00
ohif-bot 5332d3e5f5 chore(version): version.json [skip ci] 2025-09-26 14:10:12 +00:00
Joe Boccanfuso d41eca4ed5 chore(deps): update cornerstone to 4.3.10 (#5436) 2025-09-26 10:04:30 -04:00
ohif-bot a5ddcf43de chore(version): Update package versions [skip ci] 2025-09-25 18:12:56 +00:00
ohif-bot bd19ab983d chore(version): version.json [skip ci] 2025-09-25 18:12:49 +00:00
Igor Octaviano d88a341884 fix: Improve rt handling for bulkdata (#5415) 2025-09-25 14:07:35 -04:00
ohif-bot 6db50d26b2 chore(version): Update package versions [skip ci] 2025-09-25 14:26:37 +00:00
ohif-bot 3906c754f1 chore(version): version.json [skip ci] 2025-09-25 14:26:30 +00:00
毛知劲 | LIS/PACS/RIS 产品负责人 7783d0f558 fix(i18n): Add and update i18n Translation for Toolbar Tool Names (#5392) 2025-09-25 10:22:02 -04:00
ohif-bot add69e5e4f chore(version): Update package versions [skip ci] 2025-09-22 02:53:26 +00:00
ohif-bot d32edcca45 chore(version): version.json [skip ci] 2025-09-22 02:53:19 +00:00
Vinícius Alves de Faria Resende 69dbe27784 feat(Segmentation): Segmentation highlight animation function selection (#5401) 2025-09-21 22:48:35 -04:00
ohif-bot de201d567f chore(version): Update package versions [skip ci] 2025-09-19 13:30:27 +00:00
ohif-bot 26a042d8b9 chore(version): version.json [skip ci] 2025-09-19 13:30:20 +00:00
Vinícius Alves de Faria Resende 74b82bd934 fix(SegmentationService): _getSegmentCenter wrongly handling seg center availability (#5396) 2025-09-19 09:25:32 -04:00
ohif-bot a7576e07a7 chore(version): Update package versions [skip ci] 2025-09-17 19:40:05 +00:00
ohif-bot 66b2f16c9e chore(version): version.json [skip ci] 2025-09-17 19:39:58 +00:00
Joe Boccanfuso cf10e3cf67 chore(tests): update screenshots (#5413) 2025-09-17 15:35:13 -04:00
ohif-bot 3ea981b40c chore(version): Update package versions [skip ci] 2025-09-17 16:07:53 +00:00
ohif-bot e1ce9c63ee chore(version): version.json [skip ci] 2025-09-17 16:07:46 +00:00
dependabot[bot]andJoe Boccanfuso 06073af035 chore(deps): bump axios from 1.11.0 to 1.12.0 (#5412)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Joe Boccanfuso <joe.boccanfuso@radicalimaging.com>
2025-09-17 12:02:33 -04:00
ohif-bot 19f7bba5d8 chore(version): Update package versions [skip ci] 2025-09-16 19:56:57 +00:00
ohif-bot 5f7045eb09 chore(version): version.json [skip ci] 2025-09-16 19:56:51 +00:00
dependabot[bot]andJoe Boccanfuso 8610c862a9 chore(deps): bump axios from 1.11.0 to 1.12.0 (#5402)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Joe Boccanfuso <joe.boccanfuso@radicalimaging.com>
2025-09-16 15:52:13 -04:00
ohif-bot 8c8a4c2222 chore(version): Update package versions [skip ci] 2025-09-10 16:44:52 +00:00
ohif-bot 57cc0b0ae3 chore(version): version.json [skip ci] 2025-09-10 16:44:45 +00:00
Vinícius Alves de Faria Resende 56c5828b02 fix(ErrorBoundary): Fixing console errors and Improving error logging for better developer experience (#5378) 2025-09-10 12:40:09 -04:00
ohif-bot f6d05bc21c chore(version): Update package versions [skip ci] 2025-09-05 12:39:54 +00:00
ohif-bot a5d72a130a chore(version): version.json [skip ci] 2025-09-05 12:39:47 +00:00
Vinícius Alves de Faria Resende d6ea179ac4 fix(cornerstone-dicom-rt): adding caching usage to cornerstone-dicom-rt SOP Class Handler (#5387) 2025-09-05 08:35:16 -04:00
ohif-bot 7de1c78fc4 chore(version): Update package versions [skip ci] 2025-08-29 13:16:02 +00:00
ohif-bot 5f8f559426 chore(version): version.json [skip ci] 2025-08-29 13:15:55 +00:00
Omar Hamad 79473c2ea4 fix(oidc): resolve navigation throttling and blank screen during sign-in/sign-out with Keycloak + dcm4chee + Traefik (#5373) 2025-08-29 09:11:09 -04:00
ohif-bot ecf91bdcd4 chore(version): Update package versions [skip ci] 2025-08-29 12:22:34 +00:00
ohif-bot 2df818c8cd chore(version): version.json [skip ci] 2025-08-29 12:22:27 +00:00
이양구andBill Wallace 0f6f2bb432 fix: routerBasename declaration location (#5347)
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
2025-08-29 08:17:38 -04:00
ohif-bot 9f2835be2d chore(version): Update package versions [skip ci] 2025-08-28 19:12:46 +00:00
ohif-bot 01a1265291 chore(version): version.json [skip ci] 2025-08-28 19:12:40 +00:00
Copilotandsedghi 83ee20d249 Replace individual system info fields with envinfo command in bug report template (#5368)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sedghi <7490180+sedghi@users.noreply.github.com>
2025-08-28 15:08:02 -04:00
ohif-bot a0a571cb4b chore(version): Update package versions [skip ci] 2025-08-28 18:04:29 +00:00
ohif-bot d45fd931b3 chore(version): version.json [skip ci] 2025-08-28 18:04:23 +00:00
Alireza fc0e7f8572 upgrade cs3d to 4.0 (#5371) 2025-08-28 13:59:26 -04:00
ohif-bot cb9c099f36 chore(version): Update package versions [skip ci] 2025-08-28 17:02:31 +00:00
ohif-bot ccb8a0dcc3 chore(version): version.json [skip ci] 2025-08-28 17:02:24 +00:00
Alireza 6a1838bf0d fix/migration 3p11 (#5370) 2025-08-28 12:57:45 -04:00
ohif-bot df0593aac9 chore(version): Update package versions [skip ci] 2025-08-28 16:15:59 +00:00
ohif-bot aa9b881c54 chore(version): version.json [skip ci] 2025-08-28 16:15:51 +00:00
Pedro Köhler d91cc230e5 fix: seg preview (#5338) 2025-08-28 12:11:03 -04:00
ohif-bot e0f7b5b5db chore(version): Update package versions [skip ci] 2025-08-25 16:13:39 +00:00
ohif-bot ada7fb45e1 chore(version): version.json [skip ci] 2025-08-25 16:13:32 +00:00
Alireza 368a176c09 fix: docker deploy (#5359) 2025-08-25 12:08:07 -04:00
ohif-bot 25d411ecf9 chore(version): Update package versions [skip ci] 2025-08-25 15:19:11 +00:00
ohif-bot 6f839142de chore(version): version.json [skip ci] 2025-08-25 15:19:04 +00:00
Copilotandsedghi bedb1854f9 fix: Docker build failure due to missing lerna command (#5357)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sedghi <7490180+sedghi@users.noreply.github.com>
2025-08-25 11:14:30 -04:00
ohif-bot 7f8cc666a5 chore(version): Update package versions [skip ci] 2025-08-25 14:27:59 +00:00
ohif-bot 132db911c6 chore(version): version.json [skip ci] 2025-08-25 14:27:52 +00:00
d2694048a4 fix: local ModalitiesInStudy check (#5285)
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
Co-authored-by: Alireza <ar.sedghi@gmail.com>
2025-08-25 10:22:40 -04:00
ohif-bot 722efe9587 chore(version): Update package versions [skip ci] 2025-08-25 14:17:15 +00:00
ohif-bot 7e8f702eb3 chore(version): version.json [skip ci] 2025-08-25 14:17:08 +00:00
Pedro Köhler 21d6ba2bb3 fix: add back clear segmentation representations (#5336) 2025-08-25 10:12:33 -04:00
ohif-bot 9b39719149 chore(version): Update package versions [skip ci] 2025-08-25 14:01:15 +00:00
ohif-bot 2f66c7746c chore(version): version.json [skip ci] 2025-08-25 14:01:09 +00:00
Salim Kanoun b9d6f558cb fix: Segmentation stats customization module (#5324) 2025-08-25 09:56:36 -04:00
ohif-bot e071ed740f chore(version): Update package versions [skip ci] 2025-08-25 13:11:45 +00:00
ohif-bot 0b4020a7e0 chore(version): version.json [skip ci] 2025-08-25 13:11:38 +00:00
Igor Octaviano 840b5d37d1 fix: Add seriesInstanceUID fallback for callByRetrieveAETitle (#5332) 2025-08-25 09:06:52 -04:00
ohif-bot 49dddc50d3 chore(version): Update package versions [skip ci] 2025-08-22 14:35:20 +00:00
ohif-bot 396f75b906 chore(version): version.json [skip ci] 2025-08-22 14:35:13 +00:00
6fe9df6ec9 feat: Jump to measurement moves the camera if it is not in the viewport (#5023)
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
Co-authored-by: Igor Octaviano <igoroctaviano@gmail.com>
2025-08-22 10:30:18 -04:00
ohif-bot 16759506e5 chore(version): Update package versions [skip ci] 2025-08-22 13:41:26 +00:00
ohif-bot 0688fac419 chore(version): version.json [skip ci] 2025-08-22 13:41:19 +00:00
dependabot[bot] e1112b7abe chore(deps): bump sha.js from 2.4.11 to 2.4.12 (#5350)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-22 09:36:19 -04:00
Pedro Köhler a2133ef6cb fix: header icon logic (#5339) 2025-08-22 09:34:41 -04:00
ohif-bot 824816154b chore(version): Update package versions [skip ci] 2025-08-20 12:18:35 +00:00
ohif-bot 2fe9866b28 chore(version): version.json [skip ci] 2025-08-20 12:18:28 +00:00
Igor OctavianoandBill Wallace 2ed6818171 feat: Add WSI bulk data annotations support (ANN) (#4972)
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
2025-08-20 08:13:30 -04:00
ohif-bot 0164ad5519 chore(version): Update package versions [skip ci] 2025-08-15 18:17:11 +00:00
ohif-bot 244a91fda5 chore(version): version.json [skip ci] 2025-08-15 18:17:04 +00:00
Bill Wallace becba7861f fix: load 3dsr (#5335) 2025-08-15 14:12:34 -04:00
ohif-bot 730de56a5f chore(version): Update package versions [skip ci] 2025-08-13 20:09:38 +00:00
ohif-bot 72372c022f chore(version): version.json [skip ci] 2025-08-13 20:09:30 +00:00
Leonardo Campos 266b1f58f0 feat(orientationMarkers): improved the orientation markers with a simplified version (#5328) 2025-08-13 16:04:50 -04:00
ohif-bot ede7c4e3ee chore(version): Update package versions [skip ci] 2025-08-11 18:10:59 +00:00
ohif-bot a055cfe924 chore(version): version.json [skip ci] 2025-08-11 18:10:51 +00:00
Ujjwal Kumar Baranwal 0e83f4515c fix: Update Dockerfile (#5319) 2025-08-11 14:06:07 -04:00
ohif-bot 51b2303b0a chore(version): Update package versions [skip ci] 2025-08-11 14:41:28 +00:00
ohif-bot 078cac76bf chore(version): version.json [skip ci] 2025-08-11 14:41:21 +00:00
Alireza 07b310d6e6 docs: fix nav bar (#5322) 2025-08-11 10:36:28 -04:00
ohif-bot f36eeb182c chore(version): Update package versions [skip ci] 2025-08-11 13:53:50 +00:00
ohif-bot 6242f28bc5 chore(version): version.json [skip ci] 2025-08-11 13:53:43 +00:00
Alireza 2553b54432 docs: update release banner (#5321) 2025-08-11 09:48:32 -04:00
ohif-bot 6a54eee330 chore(version): Update package versions [skip ci] 2025-08-08 14:33:24 +00:00
ohif-bot 6b676750c0 chore(version): version.json [skip ci] 2025-08-08 14:33:18 +00:00
devin-ai-integration[bot]andAlireza f1d158bbe8 fix: Guard series.instances in DicomJSONDataSource to prevent TypeError (OHI-2114) (#5312)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Alireza <ar.sedghi@gmail.com>
2025-08-08 10:28:42 -04:00
ohif-bot 96862d64fc chore(version): Update package versions [skip ci] 2025-08-05 14:22:01 +00:00
ohif-bot 0f201ecf16 chore(version): version.json [skip ci] 2025-08-05 14:21:53 +00:00
Alireza 479d26f7c7 chore: remove manual approve (#5299) 2025-08-05 10:17:00 -04:00
ohif-bot 481c2ff781 chore(version): Update package versions [skip ci] 2025-08-05 14:11:38 +00:00
ohif-bot 0687120542 chore(version): version.json [skip ci] 2025-08-05 14:11:31 +00:00
Alireza 1bfb680b6b chore(ci): move to next version [BUMP BETA] (#5298) 2025-08-05 10:06:19 -04:00
ohif-bot 974ef29aa1 chore(version): Update package versions [skip ci] 2025-08-05 13:31:53 +00:00
ohif-bot a4d1f56c01 chore(version): version.json [skip ci] 2025-08-05 13:31:46 +00:00
Alireza 35bc074a53 fix(annotation): Add command to show pleura percentage in USAnnotationPanel and update condition for BLinePleuraPercentage (#5297) 2025-08-05 09:26:52 -04:00
ohif-bot 4d74611eb1 chore(version): Update package versions [skip ci] 2025-07-31 04:25:53 +00:00
ohif-bot 79cfc58533 chore(version): version.json [skip ci] 2025-07-31 04:25:47 +00:00
Pedro KöhlerandBill Wallace 735405a855 feat: add support to scoord3d (#5016)
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
2025-07-31 00:21:26 -04:00
ohif-bot af40f06524 chore(version): Update package versions [skip ci] 2025-07-30 14:12:33 +00:00
ohif-bot 568cd0b39d chore(version): version.json [skip ci] 2025-07-30 14:12:26 +00:00
rodrigobasilio2022 8643c868fd Adds containsAll validator (#5279) 2025-07-30 10:07:12 -04:00
ohif-bot eede2945ae chore(version): Update package versions [skip ci] 2025-07-30 02:35:07 +00:00
ohif-bot 1fc38c7379 chore(version): version.json [skip ci] 2025-07-30 02:35:00 +00:00
Pedro KöhlerandJoe Boccanfuso 271b84f78f feat: improve segment label (#5217)
Co-authored-by: Joe Boccanfuso <joe.boccanfuso@radicalimaging.com>
2025-07-29 22:30:18 -04:00
ohif-bot dd896fea25 chore(version): Update package versions [skip ci] 2025-07-28 19:30:15 +00:00
ohif-bot 1e3f69d977 chore(version): version.json [skip ci] 2025-07-28 19:30:08 +00:00
Joe Boccanfuso 341f1c4ce7 fix(colorbar): Allow for AdvancedRenderingControls to be placed at the left or right of the viewport. (#5273) 2025-07-28 15:25:36 -04:00
ohif-bot b8ff0a80f0 chore(version): Update package versions [skip ci] 2025-07-28 16:25:07 +00:00
ohif-bot 760194ac80 chore(version): version.json [skip ci] 2025-07-28 16:24:59 +00:00
Joe Boccanfuso d24fe54d2b fix(colorbar): Allow for AdvancedRenderingControls to be placed at the top or bottom of the viewport. (#5270) 2025-07-28 12:19:58 -04:00
ohif-bot 1cc78112e5 chore(version): Update package versions [skip ci] 2025-07-28 13:42:43 +00:00
ohif-bot 0f816e4733 chore(version): version.json [skip ci] 2025-07-28 13:42:35 +00:00
Salim Kanoun 04dcacd3a5 fix: null save voi range properties (#5268) 2025-07-28 09:37:24 -04:00
Joe Boccanfuso 47e231f061 fix(multiframes): Corrected combining frame instances for multiframes. (#5264) 2025-07-28 09:35:29 -04:00
ohif-bot 4b7c26e273 chore(version): Update package versions [skip ci] 2025-07-28 05:41:04 +00:00
ohif-bot d45dc473ad chore(version): version.json [skip ci] 2025-07-28 05:40:57 +00:00
dxlin c766f3c054 test(SegmentationPanel): add test for jump to center of segments from PACS and basic add, rename, delete from panel (#5262) 2025-07-28 01:35:50 -04:00
ohif-bot 03941dca8e chore(version): Update package versions [skip ci] 2025-07-25 17:36:46 +00:00
ohif-bot be6e228c36 chore(version): version.json [skip ci] 2025-07-25 17:36:39 +00:00
Ibrahim 570e087007 fix(tooltips): tool tips should be portals (#5265) 2025-07-25 13:30:43 -04:00
ohif-bot afac23a79a chore(version): Update package versions [skip ci] 2025-07-25 13:47:18 +00:00
ohif-bot 3322f652fe chore(version): version.json [skip ci] 2025-07-25 13:47:10 +00:00
Emmanuel Ferdman d0cf9e02f4 fix: prevent failure in DICOM loader for wadouri type (#5260)
Signed-off-by: Emmanuel Ferdman <emmanuelferdman@gmail.com>
2025-07-25 09:41:53 -04:00
ohif-bot 84e3e43ae3 chore(version): Update package versions [skip ci] 2025-07-24 17:03:31 +00:00
ohif-bot 71b685364f chore(version): version.json [skip ci] 2025-07-24 17:03:24 +00:00
Joe Boccanfuso 3c8446a5e5 fix(ArrowAnnotate): Allow free-form text for arrow annotations (#5259) 2025-07-24 12:58:45 -04:00
ohif-bot 4e6530d1d8 chore(version): Update package versions [skip ci] 2025-07-23 22:13:34 +00:00
ohif-bot 0b87691d50 chore(version): version.json [skip ci] 2025-07-23 22:13:27 +00:00
Joe Boccanfuso 730046f83c Fix flaky SEGDataOverlayForUnreferencedDisplaySetNoHydration test. (#5254) 2025-07-23 18:08:42 -04:00
ohif-bot 763002f2fe chore(version): Update package versions [skip ci] 2025-07-23 19:10:24 +00:00
ohif-bot 76e630cf61 chore(version): version.json [skip ci] 2025-07-23 19:10:18 +00:00
arul-trenserandBill Wallace 428b6ffbe7 fix: issue introduced from PR 5022 (#5223)
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
2025-07-23 15:05:42 -04:00
ohif-bot 78597aacac chore(version): Update package versions [skip ci] 2025-07-23 18:20:06 +00:00
ohif-bot eacebad315 chore(version): version.json [skip ci] 2025-07-23 18:19:59 +00:00
MatheusRdkandCopilot c8261d9883 Handle 200 status response and add default error handling (#5227)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-23 14:14:08 -04:00
ohif-bot eedaa9a2e2 chore(version): Update package versions [skip ci] 2025-07-23 17:58:03 +00:00
ohif-bot fa37acc2fb chore(version): version.json [skip ci] 2025-07-23 17:57:56 +00:00
dependabot[bot]andJoe Boccanfuso 05526e5cdc chore(deps): bump axios from 1.10.0 to 1.11.0 (#5252)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Joe Boccanfuso <joe.boccanfuso@radicalimaging.com>
2025-07-23 13:53:02 -04:00
ohif-bot cf2e58bdb9 chore(version): Update package versions [skip ci] 2025-07-23 16:53:09 +00:00
ohif-bot 9b953f0942 chore(version): version.json [skip ci] 2025-07-23 16:53:02 +00:00
IbrahimandBill Wallace 75cc6eff32 fix(calibration): do not override user set calibration (#5231)
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
2025-07-23 12:48:29 -04:00
ohif-bot c271e869c2 chore(version): Update package versions [skip ci] 2025-07-23 16:27:02 +00:00
ohif-bot b71b14efdd chore(version): version.json [skip ci] 2025-07-23 16:26:55 +00:00
Teo Udovčić 7ffe17deea fix: disable seg download/export buttons until a user has drawn something (#4953) 2025-07-23 12:21:31 -04:00
ohif-bot dd2e89bfdb chore(version): Update package versions [skip ci] 2025-07-23 16:15:47 +00:00
ohif-bot 18f8c88a89 chore(version): version.json [skip ci] 2025-07-23 16:15:40 +00:00
Patrick WespiandJoe Boccanfuso bd3ff5f57c fix(ViewportOrientationMarkers): round rotation to fix floating point issue (#5135)
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2025-07-23 12:10:49 -04:00
ohif-bot 04a599962d chore(version): Update package versions [skip ci] 2025-07-23 14:55:46 +00:00
ohif-bot 3be5d84fc4 chore(version): version.json [skip ci] 2025-07-23 14:55:40 +00:00
Joe Boccanfuso 83d4bc4a5a fix(security): Removed stylus package due to potential security vulnerability and we don't use it. (#5250) 2025-07-23 10:50:53 -04:00
Joe Boccanfuso 83ea0ad93e fix(docs): Added docs for multimonitor and local linking (#5247) 2025-07-23 10:14:01 -04:00
ohif-bot b77b2f3fa0 chore(version): Update package versions [skip ci] 2025-07-22 17:35:21 +00:00
ohif-bot 111c3b3d0d chore(version): version.json [skip ci] 2025-07-22 17:35:15 +00:00
76a2b90c17 chore(deps): bump form-data from 4.0.3 to 4.0.4 (#5244)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Joe Boccanfuso <joe.boccanfuso@radicalimaging.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2025-07-22 13:30:29 -04:00
ohif-bot aa83cda49c chore(version): Update package versions [skip ci] 2025-07-22 12:36:09 +00:00
ohif-bot 1ae4967fe5 chore(version): version.json [skip ci] 2025-07-22 12:36:02 +00:00
arul-trenser 12de7a85c9 feat(segmentation): Add customization for handling missing referencedDisplaySetInstanceUID for the SEG/RTSTRUCT. (#4983) 2025-07-22 08:30:54 -04:00
ohif-bot 91d0ae7da6 chore(version): Update package versions [skip ci] 2025-07-21 14:49:45 +00:00
ohif-bot f7fab0c461 chore(version): version.json [skip ci] 2025-07-21 14:49:38 +00:00
Joe Boccanfuso bde0eb1f07 fix(docs): Added entry for the showStudyList configuration setting. (#5235) 2025-07-21 10:44:28 -04:00
ohif-bot 73ee3140ea chore(version): Update package versions [skip ci] 2025-07-21 14:20:21 +00:00
ohif-bot 2a738dec09 chore(version): version.json [skip ci] 2025-07-21 14:20:15 +00:00
Joe Boccanfuso 3d5ee687cb fix(security): Pin eslint-config-prettier and eslint-plugin-prettier versions. (#5234) 2025-07-21 10:15:28 -04:00
ohif-bot 7060aeca4b chore(version): Update package versions [skip ci] 2025-07-21 13:11:39 +00:00
ohif-bot 5ecb8e9821 chore(version): version.json [skip ci] 2025-07-21 13:11:32 +00:00
Salim Kanoun ed3de96e4c fix: labelmap init (#5228) 2025-07-21 09:06:34 -04:00
ohif-bot db8a54d965 chore(version): Update package versions [skip ci] 2025-07-18 16:13:18 +00:00
ohif-bot 3980150aef chore(version): version.json [skip ci] 2025-07-18 16:13:10 +00:00
Joe Boccanfuso 3d4ec3181d fix(multimonitor): Study browser more menu fixes (#5208) 2025-07-18 12:08:18 -04:00
ohif-bot 779907e526 chore(version): Update package versions [skip ci] 2025-07-17 12:16:46 +00:00
ohif-bot 1841d6202f chore(version): version.json [skip ci] 2025-07-17 12:16:38 +00:00
arul-trenser 6a4ca70836 fix: image slices are displayed in reverse order, if we switch from common layout to 2D MPR (#5022) 2025-07-17 08:11:26 -04:00
794 changed files with 29618 additions and 8649 deletions

No files matched your search

+5
View File
@@ -455,8 +455,13 @@ workflows:
filters:
branches:
only: master
# - HOLD_FOR_APPROVAL:
# type: approval
# requires:
# - BUILD
- NPM_PUBLISH:
requires:
# - HOLD_FOR_APPROVAL
- BUILD
- DOCKER_BETA_PUBLISH:
requires:
+22 -21
View File
@@ -51,28 +51,29 @@ body:
validations:
required: true
- type: input
id: os
- type: textarea
id: system_info
attributes:
label: 'OS'
description: 'Your operating system.'
placeholder: 'e.g., Windows 10, macOS 10.15.4'
validations:
required: true
- type: input
id: node-version
attributes:
label: 'Node version'
description: 'Your Node.js version.'
placeholder: 'e.g., 20.18.1'
validations:
required: true
- type: input
id: browser
attributes:
label: 'Browser'
description: 'Your browser.'
placeholder: 'e.g., Chrome 83.0.4103.116, Firefox 77.0.1, Safari 13.1.1'
label: 'System Information'
description: 'Please run the following command in your terminal and paste the output:'
placeholder: |
Run: npx envinfo --system --binaries --browsers
Then paste the output here. It should look something like:
System:
OS: Windows 10 10.0.19042
CPU: (8) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 15.89 GB / 31.74 GB
Shell: 1.0.0 - C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe
Binaries:
Node: 20.18.1 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.22 - C:\Users\user\AppData\Roaming\npm\yarn.CMD
npm: 10.8.2 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: 83.0.4103.116
Edge: Spartan (44.19041.1266.0), Chromium (83.0.478.58)
Firefox: 77.0.1
validations:
required: true
+3
View File
@@ -60,3 +60,6 @@ tests/playwright-report/
/playwright/.cache/
**/.claude/settings.local.json
# Backup files
*~
-2
View File
@@ -201,8 +201,6 @@ module.exports = (env, argv, { SRC_DIR, ENTRY }) => {
'@hooks': path.resolve(__dirname, '../platform/app/src/hooks'),
'@routes': path.resolve(__dirname, '../platform/app/src/routes'),
'@state': path.resolve(__dirname, '../platform/app/src/state'),
'dicom-microscopy-viewer':
'dicom-microscopy-viewer/dist/dynamic-import/dicomMicroscopyViewer.min.js',
},
// Which directories to search when resolving modules
modules: [
+687
View File
@@ -3,6 +3,693 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
### Bug Fixes
* study browser mode for multiple studies ([#5457](https://github.com/OHIF/Viewers/issues/5457)) ([6a1df9d](https://github.com/OHIF/Viewers/commit/6a1df9de4ad3c10a4653f18e03aff6bda4962fd1))
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
### Bug Fixes
* **studyBrowserCustomization:** fix thumbnail menu item actions in study browser ([#5283](https://github.com/OHIF/Viewers/issues/5283)) ([2f28a0d](https://github.com/OHIF/Viewers/commit/2f28a0deab5e43f432bbd9b5989928c9b0450278))
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
### Features
* Add inherit from basic/longitudinal modes ([#5435](https://github.com/OHIF/Viewers/issues/5435)) ([9ad0d7f](https://github.com/OHIF/Viewers/commit/9ad0d7fc8cf34867fa2cfc2bf2b2f63451ec03e5))
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
### Bug Fixes
* **segmentation:** Restored segment label tool in longitudinal mode. ([#5443](https://github.com/OHIF/Viewers/issues/5443)) ([dd86a8e](https://github.com/OHIF/Viewers/commit/dd86a8eabd0712d25e7652a242377fe09597e8d5))
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
### Bug Fixes
* **security:** Removed dependency on tar-fs by removing dependencies on storybook and sharp. ([#5438](https://github.com/OHIF/Viewers/issues/5438)) ([80f314a](https://github.com/OHIF/Viewers/commit/80f314a422ec45fff6cdd5869f4293a110d00125))
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
### Bug Fixes
* Improve rt handling for bulkdata ([#5415](https://github.com/OHIF/Viewers/issues/5415)) ([d88a341](https://github.com/OHIF/Viewers/commit/d88a341884f7361865bc10159c1a82633667ab5b))
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
### Bug Fixes
* **i18n:** Add and update i18n Translation for Toolbar Tool Names ([#5392](https://github.com/OHIF/Viewers/issues/5392)) ([7783d0f](https://github.com/OHIF/Viewers/commit/7783d0f558bbb7016c29513b6fe76ed069dbd75c))
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
### Features
* **Segmentation:** Segmentation highlight animation function selection ([#5401](https://github.com/OHIF/Viewers/issues/5401)) ([69dbe27](https://github.com/OHIF/Viewers/commit/69dbe2778493cdfc7a8da5e757c95217bb31edc2))
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
### Bug Fixes
* **SegmentationService:** _getSegmentCenter wrongly handling seg center availability ([#5396](https://github.com/OHIF/Viewers/issues/5396)) ([74b82bd](https://github.com/OHIF/Viewers/commit/74b82bd93442411ad68f4872992126c40321eb9e))
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
### Bug Fixes
* **ErrorBoundary:** Fixing console errors and Improving error logging for better developer experience ([#5378](https://github.com/OHIF/Viewers/issues/5378)) ([56c5828](https://github.com/OHIF/Viewers/commit/56c5828b02d53bfd17182bb8d0c126b7cd4f400e))
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
### Bug Fixes
* **cornerstone-dicom-rt:** adding caching usage to cornerstone-dicom-rt SOP Class Handler ([#5387](https://github.com/OHIF/Viewers/issues/5387)) ([d6ea179](https://github.com/OHIF/Viewers/commit/d6ea179ac43a47d4011b8dcaf59d79d99382d6c8))
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
### Bug Fixes
* **oidc:** resolve navigation throttling and blank screen during sign-in/sign-out with Keycloak + dcm4chee + Traefik ([#5373](https://github.com/OHIF/Viewers/issues/5373)) ([79473c2](https://github.com/OHIF/Viewers/commit/79473c2ea4196b758614480860a8c596730b4147))
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
### Bug Fixes
* routerBasename declaration location ([#5347](https://github.com/OHIF/Viewers/issues/5347)) ([0f6f2bb](https://github.com/OHIF/Viewers/commit/0f6f2bb432d7021d3a92b38b58de51a380d9b0c9))
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
### Bug Fixes
* seg preview ([#5338](https://github.com/OHIF/Viewers/issues/5338)) ([d91cc23](https://github.com/OHIF/Viewers/commit/d91cc230e5231ca32ee28736f661a1497f7834c5))
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
### Bug Fixes
* docker deploy ([#5359](https://github.com/OHIF/Viewers/issues/5359)) ([368a176](https://github.com/OHIF/Viewers/commit/368a176c093aa2ccf4197c46543209d5ff69939a))
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
### Bug Fixes
* Docker build failure due to missing lerna command ([#5357](https://github.com/OHIF/Viewers/issues/5357)) ([bedb185](https://github.com/OHIF/Viewers/commit/bedb1854f96928f6db5707dce74ea75b1445e9bd))
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
### Bug Fixes
* local ModalitiesInStudy check ([#5285](https://github.com/OHIF/Viewers/issues/5285)) ([d269404](https://github.com/OHIF/Viewers/commit/d2694048a47faf9028184d0272df12e2602ae674))
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
### Bug Fixes
* add back clear segmentation representations ([#5336](https://github.com/OHIF/Viewers/issues/5336)) ([21d6ba2](https://github.com/OHIF/Viewers/commit/21d6ba2bb30df5b99bf5728163caff514aaa5dcd))
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
### Bug Fixes
* Segmentation stats customization module ([#5324](https://github.com/OHIF/Viewers/issues/5324)) ([b9d6f55](https://github.com/OHIF/Viewers/commit/b9d6f558cbe5957f83e6d92305a78662a0b186ed))
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
### Bug Fixes
* Add seriesInstanceUID fallback for callByRetrieveAETitle ([#5332](https://github.com/OHIF/Viewers/issues/5332)) ([840b5d3](https://github.com/OHIF/Viewers/commit/840b5d37d15537abc38316d636da7c144e6d9223))
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
### Features
* Jump to measurement moves the camera if it is not in the viewport ([#5023](https://github.com/OHIF/Viewers/issues/5023)) ([6fe9df6](https://github.com/OHIF/Viewers/commit/6fe9df6ec93c0f37e3bb9f8bf6425bae025e75c8))
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
### Bug Fixes
* header icon logic ([#5339](https://github.com/OHIF/Viewers/issues/5339)) ([a2133ef](https://github.com/OHIF/Viewers/commit/a2133ef6cb6e47fad22908fb1338ee57c67eb8f8))
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
### Bug Fixes
* load 3dsr ([#5335](https://github.com/OHIF/Viewers/issues/5335)) ([becba78](https://github.com/OHIF/Viewers/commit/becba7861f99ae4e190caddea8b663e60a9883f5))
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
### Features
* **orientationMarkers:** improved the orientation markers with a simplified version ([#5328](https://github.com/OHIF/Viewers/issues/5328)) ([266b1f5](https://github.com/OHIF/Viewers/commit/266b1f58f01ac6742a9bb40dda28459e7cddc683))
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
### Bug Fixes
* Update Dockerfile ([#5319](https://github.com/OHIF/Viewers/issues/5319)) ([0e83f45](https://github.com/OHIF/Viewers/commit/0e83f4515c902ffa3dbab2d68ec81b93881e1768))
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
### Bug Fixes
* Guard series.instances in DicomJSONDataSource to prevent TypeError (OHI-2114) ([#5312](https://github.com/OHIF/Viewers/issues/5312)) ([f1d158b](https://github.com/OHIF/Viewers/commit/f1d158bbe81fd9f6052ce23c8588c9c93d76360c))
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
**Note:** Version bump only for package ohif-monorepo-root
# [3.11.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.115...v3.11.0-beta.116) (2025-08-05)
### Bug Fixes
* **annotation:** Add command to show pleura percentage in USAnnotationPanel and update condition for BLinePleuraPercentage ([#5297](https://github.com/OHIF/Viewers/issues/5297)) ([35bc074](https://github.com/OHIF/Viewers/commit/35bc074a53bd8c804dba44830145a6633302f11d))
# [3.11.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.114...v3.11.0-beta.115) (2025-07-31)
### Features
* add support to scoord3d ([#5016](https://github.com/OHIF/Viewers/issues/5016)) ([735405a](https://github.com/OHIF/Viewers/commit/735405a8554c7ee6283faa83fc42ff8bb9ac34ff))
# [3.11.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.113...v3.11.0-beta.114) (2025-07-30)
**Note:** Version bump only for package ohif-monorepo-root
# [3.11.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.112...v3.11.0-beta.113) (2025-07-30)
### Features
* improve segment label ([#5217](https://github.com/OHIF/Viewers/issues/5217)) ([271b84f](https://github.com/OHIF/Viewers/commit/271b84f78fcc3974006c7e1a4dbb2ef322fdb9ec))
# [3.11.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.111...v3.11.0-beta.112) (2025-07-28)
### Bug Fixes
* **colorbar:** Allow for AdvancedRenderingControls to be placed at the left or right of the viewport. ([#5273](https://github.com/OHIF/Viewers/issues/5273)) ([341f1c4](https://github.com/OHIF/Viewers/commit/341f1c4ce799d1bcef3632e0d135be0cfcb333a9))
# [3.11.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.110...v3.11.0-beta.111) (2025-07-28)
### Bug Fixes
* **colorbar:** Allow for `AdvancedRenderingControls` to be placed at the top or bottom of the viewport. ([#5270](https://github.com/OHIF/Viewers/issues/5270)) ([d24fe54](https://github.com/OHIF/Viewers/commit/d24fe54d2b5598c8356afa9ce91939018940ee19))
# [3.11.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.109...v3.11.0-beta.110) (2025-07-28)
### Bug Fixes
* **multiframes:** Corrected combining frame instances for multiframes. ([#5264](https://github.com/OHIF/Viewers/issues/5264)) ([47e231f](https://github.com/OHIF/Viewers/commit/47e231f0618443e70c1daae718e7dd0908954b52))
* null save voi range properties ([#5268](https://github.com/OHIF/Viewers/issues/5268)) ([04dcacd](https://github.com/OHIF/Viewers/commit/04dcacd3a5d0d565b163c96222c8c7f948a05abd))
# [3.11.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.108...v3.11.0-beta.109) (2025-07-28)
**Note:** Version bump only for package ohif-monorepo-root
# [3.11.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.107...v3.11.0-beta.108) (2025-07-25)
### Bug Fixes
* **tooltips:** tool tips should be portals ([#5265](https://github.com/OHIF/Viewers/issues/5265)) ([570e087](https://github.com/OHIF/Viewers/commit/570e08700720d561c3d1201e03142634fccf5939))
# [3.11.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.106...v3.11.0-beta.107) (2025-07-25)
### Bug Fixes
* prevent failure in DICOM loader for wadouri type ([#5260](https://github.com/OHIF/Viewers/issues/5260)) ([d0cf9e0](https://github.com/OHIF/Viewers/commit/d0cf9e02f438cd8d26ed5bca5fb528549f4c8b98))
# [3.11.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.105...v3.11.0-beta.106) (2025-07-24)
### Bug Fixes
* **ArrowAnnotate:** Allow free-form text for arrow annotations ([#5259](https://github.com/OHIF/Viewers/issues/5259)) ([3c8446a](https://github.com/OHIF/Viewers/commit/3c8446a5e5caf8c050275bd4c193defa9e370b32))
# [3.11.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.104...v3.11.0-beta.105) (2025-07-23)
**Note:** Version bump only for package ohif-monorepo-root
# [3.11.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.103...v3.11.0-beta.104) (2025-07-23)
### Bug Fixes
* issue introduced from PR 5022 ([#5223](https://github.com/OHIF/Viewers/issues/5223)) ([428b6ff](https://github.com/OHIF/Viewers/commit/428b6ffbe75d606a72548555ac0e365299b0de4f))
# [3.11.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.102...v3.11.0-beta.103) (2025-07-23)
**Note:** Version bump only for package ohif-monorepo-root
# [3.11.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.101...v3.11.0-beta.102) (2025-07-23)
**Note:** Version bump only for package ohif-monorepo-root
# [3.11.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.100...v3.11.0-beta.101) (2025-07-23)
### Bug Fixes
* **calibration:** do not override user set calibration ([#5231](https://github.com/OHIF/Viewers/issues/5231)) ([75cc6ef](https://github.com/OHIF/Viewers/commit/75cc6eff32bc890c240c7b6830b7ef729b6df379))
# [3.11.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.99...v3.11.0-beta.100) (2025-07-23)
### Bug Fixes
* disable seg download/export buttons until a user has drawn something ([#4953](https://github.com/OHIF/Viewers/issues/4953)) ([7ffe17d](https://github.com/OHIF/Viewers/commit/7ffe17deea8d5642ad69d11943cff3298c227be2))
# [3.11.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.98...v3.11.0-beta.99) (2025-07-23)
### Bug Fixes
* **ViewportOrientationMarkers:** round rotation to fix floating point issue ([#5135](https://github.com/OHIF/Viewers/issues/5135)) ([bd3ff5f](https://github.com/OHIF/Viewers/commit/bd3ff5f57c2fee35e92be4571048cc057eeaf29d))
# [3.11.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.97...v3.11.0-beta.98) (2025-07-23)
### Bug Fixes
* **docs:** Added docs for multimonitor and local linking ([#5247](https://github.com/OHIF/Viewers/issues/5247)) ([83ea0ad](https://github.com/OHIF/Viewers/commit/83ea0ad93e6cd278e9a585c1bd1c27fccd426d5a))
* **security:** Removed stylus package due to potential security vulnerability and we don't use it. ([#5250](https://github.com/OHIF/Viewers/issues/5250)) ([83d4bc4](https://github.com/OHIF/Viewers/commit/83d4bc4a5a470bc09ede78c92ef89611dbce1d00))
# [3.11.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.96...v3.11.0-beta.97) (2025-07-22)
**Note:** Version bump only for package ohif-monorepo-root
# [3.11.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.95...v3.11.0-beta.96) (2025-07-22)
### Features
* **segmentation:** Add customization for handling missing referencedDisplaySetInstanceUID for the SEG/RTSTRUCT. ([#4983](https://github.com/OHIF/Viewers/issues/4983)) ([12de7a8](https://github.com/OHIF/Viewers/commit/12de7a85c9330471d81f481de7bc65e60c1c4ab3))
# [3.11.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.94...v3.11.0-beta.95) (2025-07-21)
### Bug Fixes
* **docs:** Added entry for the showStudyList configuration setting. ([#5235](https://github.com/OHIF/Viewers/issues/5235)) ([bde0eb1](https://github.com/OHIF/Viewers/commit/bde0eb1f07698b7375f7c4a58753d0368703e5bf))
# [3.11.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.93...v3.11.0-beta.94) (2025-07-21)
### Bug Fixes
* **security:** Pin eslint-config-prettier and eslint-plugin-prettier versions. ([#5234](https://github.com/OHIF/Viewers/issues/5234)) ([3d5ee68](https://github.com/OHIF/Viewers/commit/3d5ee687cb105acfbcfb045a95ca32047e8dd78a))
# [3.11.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.92...v3.11.0-beta.93) (2025-07-21)
### Bug Fixes
* labelmap init ([#5228](https://github.com/OHIF/Viewers/issues/5228)) ([ed3de96](https://github.com/OHIF/Viewers/commit/ed3de96e4c2d44d6df366043bdb4b09769902eff))
# [3.11.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.91...v3.11.0-beta.92) (2025-07-18)
### Bug Fixes
* **multimonitor:** Study browser more menu fixes ([#5208](https://github.com/OHIF/Viewers/issues/5208)) ([3d4ec31](https://github.com/OHIF/Viewers/commit/3d4ec3181d1c031600a1f76eb57a062f15de0ab9))
# [3.11.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.90...v3.11.0-beta.91) (2025-07-17)
### Bug Fixes
* image slices are displayed in reverse order, if we switch from common layout to 2D MPR ([#5022](https://github.com/OHIF/Viewers/issues/5022)) ([6a4ca70](https://github.com/OHIF/Viewers/commit/6a4ca7083623f21ae4c810507da0c4634bc10de9))
# [3.11.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.89...v3.11.0-beta.90) (2025-07-16)
+2 -2
View File
@@ -50,7 +50,7 @@ RUN apt-get update && apt-get install -y build-essential python3
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
RUN npm install -g bun
# RUN npm install -g lerna@7.4.2
RUN npm install -g lerna@7.4.2
ENV PATH=/usr/src/app/node_modules/.bin:$PATH
# Do an initial install and then a final install
@@ -98,7 +98,7 @@ COPY --from=builder /usr/src/app/platform/app/dist/dicom-microscopy-viewer /usr/
# In entrypoint.sh, app-config.js might be overwritten, so chmod it to be writeable.
# The nginx user cannot chmod it, so change to root.
USER root
RUN chown -R nginx:nginx /usr/share/nginx/html
RUN chown -R nginx:nginx /usr/share/nginx/html && chmod -R 666 /usr/share/nginx/html
USER nginx
ENTRYPOINT ["/usr/src/entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
+1 -1
View File
@@ -76,7 +76,7 @@ contributions of individuals, research groups, and commercial organizations.
After more than 8-years of integrating with many companies and organizations,
The OHIF Viewer has been rebuilt from the ground up to better address the
varying workflow and configuration needs of its many users. All of the Viewer's
core features are built using it's own extension system. The same extensibility
core features are built using its own extension system. The same extensibility
that allows us to offer:
- 2D and 3D medical image viewing
+553
View File
@@ -3,6 +3,559 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
### Bug Fixes
* **security:** Removed dependency on tar-fs by removing dependencies on storybook and sharp. ([#5438](https://github.com/OHIF/Viewers/issues/5438)) ([80f314a](https://github.com/OHIF/Viewers/commit/80f314a422ec45fff6cdd5869f4293a110d00125))
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.115...v3.11.0-beta.116) (2025-08-05)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.114...v3.11.0-beta.115) (2025-07-31)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.113...v3.11.0-beta.114) (2025-07-30)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.112...v3.11.0-beta.113) (2025-07-30)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.111...v3.11.0-beta.112) (2025-07-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.110...v3.11.0-beta.111) (2025-07-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.109...v3.11.0-beta.110) (2025-07-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.108...v3.11.0-beta.109) (2025-07-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.107...v3.11.0-beta.108) (2025-07-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.106...v3.11.0-beta.107) (2025-07-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.105...v3.11.0-beta.106) (2025-07-24)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.104...v3.11.0-beta.105) (2025-07-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.103...v3.11.0-beta.104) (2025-07-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.102...v3.11.0-beta.103) (2025-07-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.101...v3.11.0-beta.102) (2025-07-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.100...v3.11.0-beta.101) (2025-07-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.99...v3.11.0-beta.100) (2025-07-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.98...v3.11.0-beta.99) (2025-07-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.97...v3.11.0-beta.98) (2025-07-23)
### Bug Fixes
* **security:** Removed stylus package due to potential security vulnerability and we don't use it. ([#5250](https://github.com/OHIF/Viewers/issues/5250)) ([83d4bc4](https://github.com/OHIF/Viewers/commit/83d4bc4a5a470bc09ede78c92ef89611dbce1d00))
# [3.11.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.96...v3.11.0-beta.97) (2025-07-22)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.95...v3.11.0-beta.96) (2025-07-22)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.94...v3.11.0-beta.95) (2025-07-21)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.93...v3.11.0-beta.94) (2025-07-21)
### Bug Fixes
* **security:** Pin eslint-config-prettier and eslint-plugin-prettier versions. ([#5234](https://github.com/OHIF/Viewers/issues/5234)) ([3d5ee68](https://github.com/OHIF/Viewers/commit/3d5ee687cb105acfbcfb045a95ca32047e8dd78a))
# [3.11.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.92...v3.11.0-beta.93) (2025-07-21)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.91...v3.11.0-beta.92) (2025-07-18)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.90...v3.11.0-beta.91) (2025-07-17)
**Note:** Version bump only for package @externals/devDependencies
# [3.11.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.89...v3.11.0-beta.90) (2025-07-16)
**Note:** Version bump only for package @externals/devDependencies
+11 -13
View File
@@ -1,7 +1,7 @@
{
"name": "@externals/devDependencies",
"description": "External dev dependencies - put dev build dependencies here",
"version": "3.11.0-beta.90",
"version": "3.12.0-beta.41",
"license": "MIT",
"private": true,
"engines": {
@@ -12,7 +12,7 @@
"@babel/runtime": "^7.20.13",
"@kitware/vtk.js": "32.12.0",
"clsx": "^2.1.1",
"core-js": "^3.2.1",
"core-js": "3.45.1",
"moment": "^2.30.1"
},
"peerDependencies": {
@@ -22,9 +22,9 @@
"devDependencies": {
"@babel/eslint-parser": "7.28.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
"@rsbuild/core": "^1.3.16",
"@rsbuild/plugin-node-polyfill": "^1.3.0",
"@rsbuild/plugin-react": "^1.3.1",
"@rsbuild/core": "^1.5.1",
"@rsbuild/plugin-node-polyfill": "^1.4.2",
"@rsbuild/plugin-react": "^1.4.0",
"@svgr/webpack": "^8.1.0",
"@swc/helpers": "^0.5.15",
"@types/jest": "^27.5.0",
@@ -39,14 +39,14 @@
"css-loader": "^6.8.1",
"dotenv": "^8.1.0",
"eslint": "^8.39.0",
"eslint-config-prettier": "^7.2.0",
"eslint-config-prettier": "7.2.0",
"eslint-config-react-app": "^6.0.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-flowtype": "^7.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-prettier": "5.5.1",
"eslint-plugin-promise": "^5.2.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.4.0",
@@ -62,14 +62,14 @@
"jest-junit": "^6.4.0",
"lerna": "^7.2.0",
"lint-staged": "^9.0.2",
"mini-css-extract-plugin": "^2.1.0",
"mini-css-extract-plugin": "2.9.2",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"postcss": "^8.3.5",
"postcss-import": "^14.0.2",
"postcss-loader": "^6.1.1",
"postcss-preset-env": "^7.4.3",
"prettier": "^3.0.3",
"prettier-plugin-tailwindcss": "^0.5.4",
"prettier": "3.6.2",
"prettier-plugin-tailwindcss": "0.6.9",
"react-refresh": "^0.14.2",
"semver": "^7.5.1",
"serve": "^14.2.4",
@@ -77,12 +77,10 @@
"shx": "^0.3.3",
"source-map-loader": "^4.0.1",
"style-loader": "^1.0.0",
"stylus": "^0.59.0",
"stylus-loader": "^7.1.3",
"terser-webpack-plugin": "^5.1.4",
"typescript": "5.5.4",
"unused-webpack-plugin": "2.4.0",
"webpack": "^5.94.0",
"webpack": "5.95.0",
"webpack-bundle-analyzer": "^4.8.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "5.2.2",
+547
View File
@@ -3,6 +3,553 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.115...v3.11.0-beta.116) (2025-08-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.114...v3.11.0-beta.115) (2025-07-31)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.113...v3.11.0-beta.114) (2025-07-30)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.112...v3.11.0-beta.113) (2025-07-30)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.111...v3.11.0-beta.112) (2025-07-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.110...v3.11.0-beta.111) (2025-07-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.109...v3.11.0-beta.110) (2025-07-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.108...v3.11.0-beta.109) (2025-07-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.107...v3.11.0-beta.108) (2025-07-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.106...v3.11.0-beta.107) (2025-07-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.105...v3.11.0-beta.106) (2025-07-24)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.104...v3.11.0-beta.105) (2025-07-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.103...v3.11.0-beta.104) (2025-07-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.102...v3.11.0-beta.103) (2025-07-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.101...v3.11.0-beta.102) (2025-07-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.100...v3.11.0-beta.101) (2025-07-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.99...v3.11.0-beta.100) (2025-07-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.98...v3.11.0-beta.99) (2025-07-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.97...v3.11.0-beta.98) (2025-07-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.96...v3.11.0-beta.97) (2025-07-22)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.95...v3.11.0-beta.96) (2025-07-22)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.94...v3.11.0-beta.95) (2025-07-21)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.93...v3.11.0-beta.94) (2025-07-21)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.92...v3.11.0-beta.93) (2025-07-21)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.91...v3.11.0-beta.92) (2025-07-18)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.90...v3.11.0-beta.91) (2025-07-17)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.11.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.89...v3.11.0-beta.90) (2025-07-16)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
+2 -2
View File
@@ -1,9 +1,9 @@
{
"name": "@externals/dicom-microscopy-viewer",
"description": "External reference to dicom-microscopy-viewer",
"version": "3.11.0-beta.90",
"version": "3.12.0-beta.41",
"license": "MIT",
"dependencies": {
"dicom-microscopy-viewer": "^0.46.1"
"dicom-microscopy-viewer": "^0.48.6"
}
}
+2 -3
View File
@@ -38,14 +38,13 @@
"resolutions": {
"**/@babel/runtime": "^7.20.13",
"commander": "8.3.0",
"dcmjs": "^0.42.0",
"dcmjs": "0.43.1",
"dicomweb-client": ">=0.10.4",
"nth-check": "^2.1.1",
"trim-newlines": "^5.0.0",
"glob-parent": "^6.0.2",
"trim": "^1.0.0",
"package-json": "^8.1.0",
"typescript": "5.5.4",
"sharp": "^0.32.6"
"typescript": "5.5.4"
}
}
+1
View File
@@ -35,6 +35,7 @@ module.exports = {
'@babel/plugin-transform-typescript',
'@babel/plugin-transform-class-static-block',
'@babel/plugin-transform-for-of',
['babel-plugin-transform-import-meta', { module: 'ES6' }],
],
},
production: {
+480 -1354
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1 +1 @@
faef74ab21801841ad6b6a2104bc88a52c5c0b9e
6a1df9de4ad3c10a4653f18e03aff6bda4962fd1
@@ -3,6 +3,556 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.115...v3.11.0-beta.116) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.114...v3.11.0-beta.115) (2025-07-31)
### Features
* add support to scoord3d ([#5016](https://github.com/OHIF/Viewers/issues/5016)) ([735405a](https://github.com/OHIF/Viewers/commit/735405a8554c7ee6283faa83fc42ff8bb9ac34ff))
# [3.11.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.113...v3.11.0-beta.114) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.112...v3.11.0-beta.113) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.111...v3.11.0-beta.112) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.110...v3.11.0-beta.111) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.109...v3.11.0-beta.110) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.108...v3.11.0-beta.109) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.107...v3.11.0-beta.108) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.106...v3.11.0-beta.107) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.105...v3.11.0-beta.106) (2025-07-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.104...v3.11.0-beta.105) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.103...v3.11.0-beta.104) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.102...v3.11.0-beta.103) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.101...v3.11.0-beta.102) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.100...v3.11.0-beta.101) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.99...v3.11.0-beta.100) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.98...v3.11.0-beta.99) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.97...v3.11.0-beta.98) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.96...v3.11.0-beta.97) (2025-07-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.95...v3.11.0-beta.96) (2025-07-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.94...v3.11.0-beta.95) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.93...v3.11.0-beta.94) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.92...v3.11.0-beta.93) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.91...v3.11.0-beta.92) (2025-07-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.90...v3.11.0-beta.91) (2025-07-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.11.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.89...v3.11.0-beta.90) (2025-07-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-pmap",
"version": "3.11.0-beta.90",
"version": "3.12.0-beta.41",
"description": "DICOM Parametric Map read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,10 +33,10 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@ohif/core": "3.11.0-beta.90",
"@ohif/extension-cornerstone": "3.11.0-beta.90",
"@ohif/extension-default": "3.11.0-beta.90",
"@ohif/i18n": "3.11.0-beta.90",
"@ohif/core": "3.12.0-beta.41",
"@ohif/extension-cornerstone": "3.12.0-beta.41",
"@ohif/extension-default": "3.12.0-beta.41",
"@ohif/i18n": "3.12.0-beta.41",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.30.3",
"@cornerstonejs/core": "^3.30.3",
"@cornerstonejs/adapters": "4.3.14",
"@cornerstonejs/core": "4.3.14",
"@kitware/vtk.js": "32.12.0",
"react-color": "^2.19.3"
}
@@ -3,6 +3,559 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
### Bug Fixes
* Improve rt handling for bulkdata ([#5415](https://github.com/OHIF/Viewers/issues/5415)) ([d88a341](https://github.com/OHIF/Viewers/commit/d88a341884f7361865bc10159c1a82633667ab5b))
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
### Bug Fixes
* **cornerstone-dicom-rt:** adding caching usage to cornerstone-dicom-rt SOP Class Handler ([#5387](https://github.com/OHIF/Viewers/issues/5387)) ([d6ea179](https://github.com/OHIF/Viewers/commit/d6ea179ac43a47d4011b8dcaf59d79d99382d6c8))
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.115...v3.11.0-beta.116) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.114...v3.11.0-beta.115) (2025-07-31)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.113...v3.11.0-beta.114) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.112...v3.11.0-beta.113) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.111...v3.11.0-beta.112) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.110...v3.11.0-beta.111) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.109...v3.11.0-beta.110) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.108...v3.11.0-beta.109) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.107...v3.11.0-beta.108) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.106...v3.11.0-beta.107) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.105...v3.11.0-beta.106) (2025-07-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.104...v3.11.0-beta.105) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.103...v3.11.0-beta.104) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.102...v3.11.0-beta.103) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.101...v3.11.0-beta.102) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.100...v3.11.0-beta.101) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.99...v3.11.0-beta.100) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.98...v3.11.0-beta.99) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.97...v3.11.0-beta.98) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.96...v3.11.0-beta.97) (2025-07-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.95...v3.11.0-beta.96) (2025-07-22)
### Features
* **segmentation:** Add customization for handling missing referencedDisplaySetInstanceUID for the SEG/RTSTRUCT. ([#4983](https://github.com/OHIF/Viewers/issues/4983)) ([12de7a8](https://github.com/OHIF/Viewers/commit/12de7a85c9330471d81f481de7bc65e60c1c4ab3))
# [3.11.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.94...v3.11.0-beta.95) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.93...v3.11.0-beta.94) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.92...v3.11.0-beta.93) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.91...v3.11.0-beta.92) (2025-07-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.90...v3.11.0-beta.91) (2025-07-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.11.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.89...v3.11.0-beta.90) (2025-07-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-rt",
"version": "3.11.0-beta.90",
"version": "3.12.0-beta.41",
"description": "DICOM RT read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,10 +33,10 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@ohif/core": "3.11.0-beta.90",
"@ohif/extension-cornerstone": "3.11.0-beta.90",
"@ohif/extension-default": "3.11.0-beta.90",
"@ohif/i18n": "3.11.0-beta.90",
"@ohif/core": "3.12.0-beta.41",
"@ohif/extension-cornerstone": "3.12.0-beta.41",
"@ohif/extension-default": "3.12.0-beta.41",
"@ohif/i18n": "3.12.0-beta.41",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@@ -4,7 +4,11 @@ import i18n from '@ohif/i18n';
import { SOPClassHandlerId } from './id';
import loadRTStruct from './loadRTStruct';
const sopClassUids = ['1.2.840.10008.5.1.4.1.1.481.3'];
const { sopClassDictionary } = utils;
const sopClassUids = [sopClassDictionary.RTStructureSetStorage];
const cachedRTStructsSEG = new Set<string>();
const loadPromises = {};
@@ -113,39 +117,45 @@ function _load(
) {
const { SOPInstanceUID } = rtDisplaySet;
const { segmentationService } = servicesManager.services;
if (
(rtDisplaySet.loading || rtDisplaySet.isLoaded) &&
loadPromises[SOPInstanceUID] &&
_segmentationExistsInCache(rtDisplaySet, segmentationService)
cachedRTStructsSEG.has(rtDisplaySet.displaySetInstanceUID)
) {
return loadPromises[SOPInstanceUID];
}
rtDisplaySet.loading = true;
const { unsubscribe } = segmentationService.subscribe(
segmentationService.EVENTS.SEGMENTATION_LOADING_COMPLETE,
(evt: { rtDisplaySet: { displaySetInstanceUID: string } }) => {
if (evt.rtDisplaySet?.displaySetInstanceUID === rtDisplaySet.displaySetInstanceUID) {
cachedRTStructsSEG.add(rtDisplaySet.displaySetInstanceUID);
unsubscribe();
}
}
);
// We don't want to fire multiple loads, so we'll wait for the first to finish
// and also return the same promise to any other callers.
loadPromises[SOPInstanceUID] = new Promise(async (resolve, reject) => {
if (!rtDisplaySet.structureSet) {
const structureSet = await loadRTStruct(extensionManager, rtDisplaySet, headers);
loadPromises[SOPInstanceUID] = new Promise<void>(async (resolve, reject) => {
try {
if (!rtDisplaySet.structureSet) {
const structureSet = await loadRTStruct(extensionManager, rtDisplaySet, headers);
rtDisplaySet.structureSet = structureSet;
}
rtDisplaySet.structureSet = structureSet;
}
if (createSegmentation) {
await segmentationService.createSegmentationForRTDisplaySet(rtDisplaySet);
}
if (createSegmentation) {
segmentationService
.createSegmentationForRTDisplaySet(rtDisplaySet)
.then(() => {
rtDisplaySet.loading = false;
resolve();
})
.catch(error => {
rtDisplaySet.loading = false;
reject(error);
});
} else {
rtDisplaySet.loading = false;
resolve();
} catch (error) {
reject(error);
} finally {
rtDisplaySet.loading = false;
}
});
@@ -187,11 +197,6 @@ function _deriveReferencedSeriesSequenceFromFrameOfReferenceSequence(
return ReferencedSeriesSequence;
}
function _segmentationExistsInCache() {
// Todo: fix this
return false;
}
function getSopClassHandlerModule(params: OhifTypes.Extensions.ExtensionParams) {
const { servicesManager, extensionManager } = params;
@@ -2,9 +2,34 @@ import dcmjs from 'dcmjs';
const { DicomMessage, DicomMetaDictionary } = dcmjs.data;
const dicomlab2RGB = dcmjs.data.Colors.dicomlab2RGB;
async function checkAndLoadContourData(instance, datasource) {
/**
* Checks and loads contour data for RT Structure Set, handling both inline and bulk data URIs.
* Processes ROIContourSequence to extract contour data and resolve any bulk data references.
*
* @async
* @function checkAndLoadContourData
* @param {Object} params - Parameters object
* @param {Object} params.instance - Initial RT Structure instance
* @param {Object} params.dataSource - Data source for retrieving bulk data
* @param {Object} params.extensionManager - OHIF extension manager
* @param {Object} params.rtStructDisplaySet - RT Structure display set
* @param {Object} params.headers - HTTP headers for requests
* @returns {Promise<Object>} Promise that resolves to the processed RT Structure instance with loaded contour data
* @throws {Promise<string>} Rejects with error message if instance is invalid or data retrieval fails
*/
async function checkAndLoadContourData({
instance: initialInstance,
dataSource,
extensionManager,
rtStructDisplaySet,
headers,
}) {
let instance = initialInstance;
if (!instance || !instance.ROIContourSequence) {
return Promise.reject('Invalid instance object or ROIContourSequence');
instance = await getRTStructInstance({ extensionManager, rtStructDisplaySet, headers });
if (!instance || !instance.ROIContourSequence) {
return Promise.reject('Invalid instance object or ROIContourSequence');
}
}
const promisesMap = new Map();
@@ -30,11 +55,11 @@ async function checkAndLoadContourData(instance, datasource) {
} else if (contourData && contourData.BulkDataURI) {
const bulkDataURI = contourData.BulkDataURI;
if (!datasource || !datasource.retrieve || !datasource.retrieve.bulkDataURI) {
return Promise.reject('Invalid datasource object or retrieve function');
if (!dataSource || !dataSource.retrieve || !dataSource.retrieve.bulkDataURI) {
return Promise.reject('Invalid dataSource object or retrieve function');
}
const bulkDataPromise = datasource.retrieve.bulkDataURI({
const bulkDataPromise = dataSource.retrieve.bulkDataURI({
BulkDataURI: bulkDataURI,
StudyInstanceUID: instance.StudyInstanceUID,
SeriesInstanceUID: instance.SeriesInstanceUID,
@@ -87,35 +112,74 @@ async function checkAndLoadContourData(instance, datasource) {
console.error(error);
}
});
return instance;
}
export default async function loadRTStruct(extensionManager, rtStructDisplaySet, headers) {
/**
* Retrieves and parses RT Structure Set instance from DICOM data.
* Uses the cornerstone utility module to load DICOM data and converts it to a naturalized dataset.
*
* @async
* @function getRTStructInstance
* @param {Object} params - Parameters object
* @param {Object} params.extensionManager - OHIF extension manager
* @param {Object} params.rtStructDisplaySet - RT Structure display set
* @param {Object} params.headers - HTTP headers for requests
* @returns {Promise<Object>} Promise that resolves to the parsed RT Structure dataset
*/
const getRTStructInstance = async ({ extensionManager, rtStructDisplaySet, headers }) => {
const utilityModule = extensionManager.getModuleEntry(
'@ohif/extension-cornerstone.utilityModule.common'
);
const { dicomLoaderService } = utilityModule.exports;
const segArrayBuffer = await dicomLoaderService.findDicomDataPromise(
rtStructDisplaySet,
null,
headers
);
const dicomData = DicomMessage.readFile(segArrayBuffer);
const rtStructDataset = DicomMetaDictionary.naturalizeDataset(dicomData.dict);
rtStructDataset._meta = DicomMetaDictionary.namifyDataset(dicomData.meta);
return rtStructDataset;
};
/**
* Main function to load and process RT Structure Set data.
* Creates a structure set object with ROI contours, metadata, and visualization properties.
* Handles both bulk data URI and inline contour data scenarios.
*
* @async
* @function loadRTStruct
* @param {Object} extensionManager - OHIF extension manager
* @param {Object} rtStructDisplaySet - RT Structure display set to process
* @param {Object} headers - HTTP headers for data requests
* @returns {Promise<Object>} Promise that resolves to a structure set object containing:
* - StructureSetLabel: Label of the structure set
* - SeriesInstanceUID: Series instance UID
* - ROIContours: Array of ROI contour data with points and metadata
* - visible: Visibility state
* - ReferencedSOPInstanceUIDsSet: Set of referenced SOP instance UIDs
*/
export default async function loadRTStruct(extensionManager, rtStructDisplaySet, headers) {
const dataSource = extensionManager.getActiveDataSource()[0];
const { bulkDataURI } = dataSource.getConfig?.() || {};
const { dicomLoaderService } = utilityModule.exports;
// Set here is loading is asynchronous.
// If this function throws its set back to false.
rtStructDisplaySet.isLoaded = true;
let instance = rtStructDisplaySet.instance;
if (!bulkDataURI || !bulkDataURI.enabled) {
const segArrayBuffer = await dicomLoaderService.findDicomDataPromise(
rtStructDisplaySet,
null,
headers
);
const dicomData = DicomMessage.readFile(segArrayBuffer);
const rtStructDataset = DicomMetaDictionary.naturalizeDataset(dicomData.dict);
rtStructDataset._meta = DicomMetaDictionary.namifyDataset(dicomData.meta);
instance = rtStructDataset;
instance = await getRTStructInstance({ extensionManager, rtStructDisplaySet, headers });
} else {
await checkAndLoadContourData(instance, dataSource);
instance = await checkAndLoadContourData({
instance,
dataSource,
extensionManager,
rtStructDisplaySet,
headers,
});
}
const { StructureSetROISequence, ROIContourSequence, RTROIObservationsSequence } = instance;
@@ -132,21 +196,16 @@ export default async function loadRTStruct(extensionManager, rtStructDisplaySet,
for (let i = 0; i < ROIContourSequence.length; i++) {
const ROIContour = ROIContourSequence[i];
const { ContourSequence } = ROIContour;
if (!ContourSequence) {
continue;
}
const isSupported = false;
const ContourSequenceArray = _toArray(ContourSequence);
const contourPoints = [];
for (let c = 0; c < ContourSequenceArray.length; c++) {
for (const ContourSequenceItem of ContourSequenceArray) {
const { ContourData, NumberOfContourPoints, ContourGeometricType, ContourImageSequence } =
ContourSequenceArray[c];
let isSupported = false;
ContourSequenceItem;
const points = [];
for (let p = 0; p < NumberOfContourPoints * 3; p += 3) {
@@ -157,22 +216,18 @@ export default async function loadRTStruct(extensionManager, rtStructDisplaySet,
});
}
switch (ContourGeometricType) {
case 'CLOSED_PLANAR':
case 'OPEN_PLANAR':
case 'POINT':
isSupported = true;
break;
default:
continue;
}
const supportedContourTypesMap = new Map([
['CLOSED_PLANAR', false],
['OPEN_NONPLANAR', false],
['OPEN_PLANAR', false],
['POINT', true],
]);
contourPoints.push({
numberOfPoints: NumberOfContourPoints,
points,
type: ContourGeometricType,
isSupported,
isSupported: supportedContourTypesMap.get(ContourGeometricType) ?? false,
});
if (ContourImageSequence?.ReferencedSOPInstanceUID) {
@@ -187,20 +242,30 @@ export default async function loadRTStruct(extensionManager, rtStructDisplaySet,
StructureSetROISequence,
RTROIObservationsSequence,
ROIContour,
contourPoints,
isSupported
contourPoints
);
}
return structureSet;
}
/**
* Sets metadata for ROI contour data and adds it to the structure set.
* Extracts ROI information from StructureSetROISequence and RTROIObservationsSequence,
* then creates a complete ROI contour data object with visualization properties.
*
* @function _setROIContourMetadata
* @param {Object} structureSet - The structure set object to add ROI contour to
* @param {Array} StructureSetROISequence - Array of structure set ROI definitions
* @param {Array} RTROIObservationsSequence - Array of RT ROI observations
* @param {Object} ROIContour - ROI contour object containing contour data
* @param {Array} contourPoints - Array of processed contour points
*/
function _setROIContourMetadata(
structureSet,
StructureSetROISequence,
RTROIObservationsSequence,
ROIContour,
contourPoints,
isSupported
contourPoints
) {
const StructureSetROI = StructureSetROISequence.find(
structureSetROI => structureSetROI.ROINumber === ROIContour.ReferencedROINumber
@@ -211,9 +276,9 @@ function _setROIContourMetadata(
ROIName: StructureSetROI.ROIName,
ROIGenerationAlgorithm: StructureSetROI.ROIGenerationAlgorithm,
ROIDescription: StructureSetROI.ROIDescription,
isSupported,
contourPoints,
visible: true,
colorArray: [],
};
_setROIContourDataColor(ROIContour, ROIContourData);
@@ -230,6 +295,14 @@ function _setROIContourMetadata(
structureSet.ROIContours.push(ROIContourData);
}
/**
* Sets the display color for ROI contour data.
* Uses ROIDisplayColor if available, otherwise converts RecommendedDisplayCIELabValue to RGB.
*
* @function _setROIContourDataColor
* @param {Object} ROIContour - ROI contour object containing color information
* @param {Object} ROIContourData - ROI contour data object to set color on
*/
function _setROIContourDataColor(ROIContour, ROIContourData) {
let { ROIDisplayColor, RecommendedDisplayCIELabValue } = ROIContour;
@@ -243,6 +316,15 @@ function _setROIContourDataColor(ROIContour, ROIContourData) {
}
}
/**
* Sets RT ROI observations metadata for ROI contour data.
* Finds matching RTROIObservations by ROINumber and adds observation details to contour data.
*
* @function _setROIContourRTROIObservations
* @param {Object} ROIContourData - ROI contour data object to add observations to
* @param {Array} RTROIObservationsSequence - Array of RT ROI observations
* @param {number} ROINumber - ROI number to match observations
*/
function _setROIContourRTROIObservations(ROIContourData, RTROIObservationsSequence, ROINumber) {
const RTROIObservations = RTROIObservationsSequence.find(
RTROIObservations => RTROIObservations.ReferencedROINumber === ROINumber
@@ -262,6 +344,14 @@ function _setROIContourRTROIObservations(ROIContourData, RTROIObservationsSequen
}
}
/**
* Converts a single object or array to an array.
* Utility function to ensure consistent array handling for DICOM sequences.
*
* @function _toArray
* @param {*} objOrArray - Object or array to convert
* @returns {Array} Array containing the input (if already array) or wrapped in array
*/
function _toArray(objOrArray) {
return Array.isArray(objOrArray) ? objOrArray : [objOrArray];
}
@@ -51,6 +51,21 @@ function OHIFCornerstoneRTViewport(props: withAppTypes) {
const referencedDisplaySetRef = useRef(null);
const referencedDisplaySetInstanceUID = rtDisplaySet.referencedDisplaySetInstanceUID;
// If the referencedDisplaySetInstanceUID is not found, it means the RTStruct series is being
// launched without its corresponding referenced display set (e.g., the RTStruct series is launched using
// series launch /mode?StudyInstanceUIDs=&SeriesInstanceUID).
// In such cases, we attempt to handle this scenario gracefully by
// invoking a custom handler. Ideally, if a user tries to launch a series that isn't viewable,
// (eg.: we can prompt them with an explanation and provide a link to the full study).
if (!referencedDisplaySetInstanceUID) {
const missingReferenceDisplaySetHandler = customizationService.getCustomization(
'missingReferenceDisplaySetHandler'
);
const { handled } = missingReferenceDisplaySetHandler();
if (handled) {
return;
}
}
const referencedDisplaySet = displaySetService.getDisplaySetByUID(
referencedDisplaySetInstanceUID
);
@@ -3,6 +3,562 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.115...v3.11.0-beta.116) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.114...v3.11.0-beta.115) (2025-07-31)
### Features
* add support to scoord3d ([#5016](https://github.com/OHIF/Viewers/issues/5016)) ([735405a](https://github.com/OHIF/Viewers/commit/735405a8554c7ee6283faa83fc42ff8bb9ac34ff))
# [3.11.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.113...v3.11.0-beta.114) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.112...v3.11.0-beta.113) (2025-07-30)
### Features
* improve segment label ([#5217](https://github.com/OHIF/Viewers/issues/5217)) ([271b84f](https://github.com/OHIF/Viewers/commit/271b84f78fcc3974006c7e1a4dbb2ef322fdb9ec))
# [3.11.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.111...v3.11.0-beta.112) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.110...v3.11.0-beta.111) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.109...v3.11.0-beta.110) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.108...v3.11.0-beta.109) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.107...v3.11.0-beta.108) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.106...v3.11.0-beta.107) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.105...v3.11.0-beta.106) (2025-07-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.104...v3.11.0-beta.105) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.103...v3.11.0-beta.104) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.102...v3.11.0-beta.103) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.101...v3.11.0-beta.102) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.100...v3.11.0-beta.101) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.99...v3.11.0-beta.100) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.98...v3.11.0-beta.99) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.97...v3.11.0-beta.98) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.96...v3.11.0-beta.97) (2025-07-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.95...v3.11.0-beta.96) (2025-07-22)
### Features
* **segmentation:** Add customization for handling missing referencedDisplaySetInstanceUID for the SEG/RTSTRUCT. ([#4983](https://github.com/OHIF/Viewers/issues/4983)) ([12de7a8](https://github.com/OHIF/Viewers/commit/12de7a85c9330471d81f481de7bc65e60c1c4ab3))
# [3.11.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.94...v3.11.0-beta.95) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.93...v3.11.0-beta.94) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.92...v3.11.0-beta.93) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.91...v3.11.0-beta.92) (2025-07-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.90...v3.11.0-beta.91) (2025-07-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.11.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.89...v3.11.0-beta.90) (2025-07-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-seg",
"version": "3.11.0-beta.90",
"version": "3.12.0-beta.41",
"description": "DICOM SEG read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,10 +33,10 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@ohif/core": "3.11.0-beta.90",
"@ohif/extension-cornerstone": "3.11.0-beta.90",
"@ohif/extension-default": "3.11.0-beta.90",
"@ohif/i18n": "3.11.0-beta.90",
"@ohif/core": "3.12.0-beta.41",
"@ohif/extension-cornerstone": "3.12.0-beta.41",
"@ohif/extension-default": "3.12.0-beta.41",
"@ohif/i18n": "3.12.0-beta.41",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
@@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.30.3",
"@cornerstonejs/core": "^3.30.3",
"@cornerstonejs/adapters": "4.3.14",
"@cornerstonejs/core": "4.3.14",
"@kitware/vtk.js": "32.12.0",
"react-color": "^2.19.3"
}
@@ -1,7 +1,14 @@
function createSEGToolGroupAndAddTools(ToolGroupService, customizationService, toolGroupId) {
function createSEGToolGroupAndAddTools({
commandsManager,
toolGroupService,
customizationService,
toolGroupId,
}) {
const tools = customizationService.getCustomization('cornerstone.overlayViewportTools');
return ToolGroupService.createToolGroupAndAddTools(toolGroupId, tools);
const updatedTools = commandsManager.run('initializeSegmentLabelTool', { tools });
return toolGroupService.createToolGroupAndAddTools(toolGroupId, updatedTools);
}
export default createSEGToolGroupAndAddTools;
@@ -54,6 +54,21 @@ function OHIFCornerstoneSEGViewport(props: withAppTypes) {
const { viewports, activeViewportId } = viewportGrid;
const referencedDisplaySetInstanceUID = segDisplaySet.referencedDisplaySetInstanceUID;
// If the referencedDisplaySetInstanceUID is not found, it means the SEG series is being
// launched without its corresponding referenced display set (e.g., the SEG series is launched using
// series launch /mode?StudyInstanceUIDs=&SeriesInstanceUID).
// In such cases, we attempt to handle this scenario gracefully by
// invoking a custom handler. Ideally, if a user tries to launch a series that isn't viewable,
// (eg.: we can prompt them with an explanation and provide a link to the full study).
if (!referencedDisplaySetInstanceUID) {
const missingReferenceDisplaySetHandler = customizationService.getCustomization(
'missingReferenceDisplaySetHandler'
);
const { handled } = missingReferenceDisplaySetHandler();
if (handled) {
return;
}
}
const referencedDisplaySet = displaySetService.getDisplaySetByUID(
referencedDisplaySetInstanceUID
);
@@ -199,7 +214,12 @@ function OHIFCornerstoneSEGViewport(props: withAppTypes) {
// This creates a custom tool group which has the lifetime of this view
// only, and does NOT interfere with currently displayed segmentations.
toolGroup = createSEGToolGroupAndAddTools(toolGroupService, customizationService, toolGroupId);
toolGroup = createSEGToolGroupAndAddTools({
commandsManager,
toolGroupService,
customizationService,
toolGroupId,
});
return () => {
// remove the segmentation representations if seg displayset changed
@@ -3,6 +3,559 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
### Bug Fixes
* load 3dsr ([#5335](https://github.com/OHIF/Viewers/issues/5335)) ([becba78](https://github.com/OHIF/Viewers/commit/becba7861f99ae4e190caddea8b663e60a9883f5))
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.115...v3.11.0-beta.116) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.114...v3.11.0-beta.115) (2025-07-31)
### Features
* add support to scoord3d ([#5016](https://github.com/OHIF/Viewers/issues/5016)) ([735405a](https://github.com/OHIF/Viewers/commit/735405a8554c7ee6283faa83fc42ff8bb9ac34ff))
# [3.11.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.113...v3.11.0-beta.114) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.112...v3.11.0-beta.113) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.111...v3.11.0-beta.112) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.110...v3.11.0-beta.111) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.109...v3.11.0-beta.110) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.108...v3.11.0-beta.109) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.107...v3.11.0-beta.108) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.106...v3.11.0-beta.107) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.105...v3.11.0-beta.106) (2025-07-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.104...v3.11.0-beta.105) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.103...v3.11.0-beta.104) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.102...v3.11.0-beta.103) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.101...v3.11.0-beta.102) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.100...v3.11.0-beta.101) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.99...v3.11.0-beta.100) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.98...v3.11.0-beta.99) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.97...v3.11.0-beta.98) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.96...v3.11.0-beta.97) (2025-07-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.95...v3.11.0-beta.96) (2025-07-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.94...v3.11.0-beta.95) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.93...v3.11.0-beta.94) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.92...v3.11.0-beta.93) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.91...v3.11.0-beta.92) (2025-07-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.90...v3.11.0-beta.91) (2025-07-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.11.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.89...v3.11.0-beta.90) (2025-07-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
+9 -9
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-sr",
"version": "3.11.0-beta.90",
"version": "3.12.0-beta.41",
"description": "OHIF extension for an SR Cornerstone Viewport",
"author": "OHIF",
"license": "MIT",
@@ -34,11 +34,11 @@
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"peerDependencies": {
"@ohif/core": "3.11.0-beta.90",
"@ohif/extension-cornerstone": "3.11.0-beta.90",
"@ohif/extension-measurement-tracking": "3.11.0-beta.90",
"@ohif/ui": "3.11.0-beta.90",
"dcmjs": "^0.42.0",
"@ohif/core": "3.12.0-beta.41",
"@ohif/extension-cornerstone": "3.12.0-beta.41",
"@ohif/extension-measurement-tracking": "3.12.0-beta.41",
"@ohif/ui": "3.12.0-beta.41",
"dcmjs": "0.43.1",
"dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8",
"prop-types": "^15.6.2",
@@ -46,9 +46,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.30.3",
"@cornerstonejs/core": "^3.30.3",
"@cornerstonejs/tools": "^3.30.3",
"@cornerstonejs/adapters": "4.3.14",
"@cornerstonejs/core": "4.3.14",
"@cornerstonejs/tools": "4.3.14",
"classnames": "^2.3.2"
}
}
@@ -32,12 +32,7 @@ const _generateReport = (measurementData, additionalFindingTypes, options: Optio
additionalFindingTypes
);
const report = MeasurementReport.generateReport(
filteredToolState,
metaData,
utilities.worldToImageCoords,
options
);
const report = MeasurementReport.generateReport(filteredToolState, metaData, options);
const { dataset } = report;
@@ -54,7 +49,7 @@ const _generateReport = (measurementData, additionalFindingTypes, options: Optio
const commandsModule = (props: withAppTypes) => {
const { servicesManager, extensionManager, commandsManager } = props;
const { customizationService, viewportGridService, displaySetService } = servicesManager.services;
const { customizationService } = servicesManager.services;
const actions = {
changeColorMeasurement: ({ uid }) => {
@@ -129,6 +124,9 @@ const commandsModule = (props: withAppTypes) => {
console.log('naturalizedReport missing imaging content', naturalizedReport);
throw new Error('Invalid report, no content');
}
if (!naturalizedReport.SOPClassUID) {
throw new Error('No sop class uid');
}
const onBeforeDicomStore = customizationService.getCustomization('onBeforeDicomStore');
@@ -63,18 +63,12 @@ function OHIFCornerstoneSRMeasurementViewport(props) {
const updateViewport = useCallback(
newMeasurementSelected => {
const { StudyInstanceUID, displaySetInstanceUID, sopClassUids } = srDisplaySet;
const { StudyInstanceUID, displaySetInstanceUID } = srDisplaySet;
if (!StudyInstanceUID || !displaySetInstanceUID) {
return;
}
if (sopClassUids && sopClassUids.length > 1) {
// Todo: what happens if there are multiple SOP Classes? Why we are
// not throwing an error?
console.warn('More than one SOPClassUID in the same series is not yet supported.');
}
_getViewportReferencedDisplaySetData(
srDisplaySet,
newMeasurementSelected,
@@ -92,7 +86,7 @@ function OHIFCornerstoneSRMeasurementViewport(props) {
const { presentationIds } = viewportOptions;
const measurement = srDisplaySet.measurements[newMeasurementSelected];
setPositionPresentation(presentationIds.positionPresentationId, {
viewReference: {
viewReference: measurement.viewReference || {
referencedImageId: measurement.imageId,
},
});
@@ -258,6 +252,9 @@ async function _getViewportReferencedDisplaySetData(
}
const referencedDisplaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
if (!referencedDisplaySet?.images) {
return { referencedDisplaySetMetadata: null, referencedDisplaySet: null };
}
const image0 = referencedDisplaySet.images[0];
const referencedDisplaySetMetadata = {
@@ -15,8 +15,12 @@ import { CodeNameCodeSequenceValues, CodingSchemeDesignators } from './enums';
const { sopClassDictionary } = utils;
const { CORNERSTONE_3D_TOOLS_SOURCE_NAME, CORNERSTONE_3D_TOOLS_SOURCE_VERSION } = CSExtensionEnums;
const { ImageSet, MetadataProvider: metadataProvider } = classes;
const { CodeScheme: Cornerstone3DCodeScheme } = adaptersSR.Cornerstone3D;
const { MetadataProvider: metadataProvider } = classes;
const {
TEXT_ANNOTATION_POSITION,
COMMENT_CODE,
CodeScheme: Cornerstone3DCodeScheme,
} = adaptersSR.Cornerstone3D;
type InstanceMetadata = Types.InstanceMetadata;
@@ -31,6 +35,7 @@ const sopClassUids = [
sopClassDictionary.BasicTextSR,
sopClassDictionary.EnhancedSR,
sopClassDictionary.ComprehensiveSR,
sopClassDictionary.Comprehensive3DSR,
];
const validateSameStudyUID = (uid: string, instances): void => {
@@ -49,7 +54,7 @@ const validateSameStudyUID = (uid: string, instances): void => {
* @param instances is a list of instances from THIS series that are not
* in this DICOM SR Display Set already.
*/
function addInstances(instances: InstanceMetadata[], displaySetService: DisplaySetService) {
function addInstances(instances: InstanceMetadata[], _displaySetService: DisplaySetService) {
this.instances.push(...instances);
utils.sortStudyInstances(this.instances);
// The last instance is the newest one, so is the one most interesting.
@@ -216,6 +221,12 @@ async function _load(
});
}
function _measurementBelongsToDisplaySet({ measurement, displaySet }) {
return (
measurement.coords[0].ReferencedFrameOfReferenceSequence === displaySet.FrameOfReferenceUID
);
}
/**
* Checks if measurements can be added to a display set.
*
@@ -236,18 +247,10 @@ function _checkIfCanAddMeasurementsToDisplaySet(
measurement => measurement.loaded === false
);
if (
unloadedMeasurements.length === 0 ||
!(newDisplaySet instanceof ImageSet) ||
newDisplaySet.unsupported
) {
if (!unloadedMeasurements.length || newDisplaySet.unsupported) {
return;
}
// const { sopClassUids } = newDisplaySet;
// Create a Set for faster lookups
// const sopClassUidSet = new Set(sopClassUids);
// Create a Map to efficiently look up ImageIds by SOPInstanceUID and frame number
const imageIdMap = new Map<string, string>();
const imageIds = dataSource.getImageIdsForDisplaySet(newDisplaySet);
@@ -266,6 +269,7 @@ function _checkIfCanAddMeasurementsToDisplaySet(
for (let j = unloadedMeasurements.length - 1; j >= 0; j--) {
let measurement = unloadedMeasurements[j];
const is3DMeasurement = measurement.coords?.[0]?.ValueType === 'SCOORD3D';
const onBeforeSRAddMeasurement = customizationService.getCustomization(
'onBeforeSRAddMeasurement'
@@ -280,9 +284,17 @@ function _checkIfCanAddMeasurementsToDisplaySet(
}
// if it is 3d SR we can just add the SR annotation
if (is3DSR) {
if (
is3DSR &&
is3DMeasurement &&
_measurementBelongsToDisplaySet({ measurement, displaySet: newDisplaySet })
) {
_measurementBelongsToDisplaySet({ measurement, displaySet: newDisplaySet })
addSRAnnotation(measurement, null, null);
measurement.loaded = true;
measurement.displaySetInstanceUID = newDisplaySet.displaySetInstanceUID;
unloadedMeasurements.splice(j, 1);
continue;
}
@@ -469,11 +481,7 @@ function _getMergedContentSequencesByTrackingUniqueIdentifiers(MeasurementGroups
* @returns {any} - The processed measurement result.
*/
function _processMeasurement(mergedContentSequence) {
if (
mergedContentSequence.some(
group => group.ValueType === 'SCOORD' || group.ValueType === 'SCOORD3D'
)
) {
if (mergedContentSequence.some(group => isScoordOr3d(group) && !isTextPosition(group))) {
return _processTID1410Measurement(mergedContentSequence);
}
@@ -511,12 +519,25 @@ function _processTID1410Measurement(mergedContentSequence) {
const NUMContentItems = mergedContentSequence.filter(group => group.ValueType === 'NUM');
const { ConceptNameCodeSequence: conceptNameItem } = graphicItem;
const { CodeValue: graphicValue, CodingSchemeDesignator: graphicDesignator } = conceptNameItem;
const graphicCode = `${graphicDesignator}:${graphicValue}`;
const pointDataItem = _getCoordsFromSCOORDOrSCOORD3D(graphicItem);
const is3DMeasurement = pointDataItem.ValueType === 'SCOORD3D';
const pointLength = is3DMeasurement ? 3 : 2;
const pointsLength = pointDataItem.GraphicData.length / pointLength;
const measurement = {
loaded: false,
labels: [],
coords: [_getCoordsFromSCOORDOrSCOORD3D(graphicItem)],
coords: [pointDataItem],
TrackingUniqueIdentifier: UIDREFContentItem.UID,
TrackingIdentifier: TrackingIdentifierContentItem.TextValue,
graphicCode,
is3DMeasurement,
pointsLength,
graphicType: pointDataItem.GraphicType,
};
NUMContentItems.forEach(item => {
@@ -567,6 +588,12 @@ function _processNonGeometricallyDefinedMeasurement(mergedContentSequence) {
item.ConceptNameCodeSequence.CodeValue === CodeNameCodeSequenceValues.FindingSite
);
const commentSites = mergedContentSequence.filter(
item =>
item.ConceptNameCodeSequence.CodingSchemeDesignator === COMMENT_CODE.schemeDesignator &&
item.ConceptNameCodeSequence.CodeValue === COMMENT_CODE.value
);
const measurement = {
loaded: false,
labels: [],
@@ -575,6 +602,14 @@ function _processNonGeometricallyDefinedMeasurement(mergedContentSequence) {
TrackingIdentifier: TrackingIdentifierContentItem.TextValue,
};
if (commentSites) {
for (const group of commentSites) {
if (group.TextValue) {
measurement.labels.push({ label: group.TextValue, value: '' });
}
}
}
if (
finding &&
CodingSchemeDesignators.CornerstoneCodeSchemes.includes(
@@ -726,4 +761,17 @@ function _getSequenceAsArray(sequence) {
return Array.isArray(sequence) ? sequence : [sequence];
}
function isScoordOr3d(group) {
return group.ValueType === 'SCOORD' || group.ValueType === 'SCOORD3D';
}
function isTextPosition(group) {
const concept = group.ConceptNameCodeSequence[0];
return (
concept &&
concept.CodeValue === TEXT_ANNOTATION_POSITION.value &&
concept.CodingSchemeDesignator === TEXT_ANNOTATION_POSITION.schemeDesignator
);
}
export default getSopClassHandlerModule;
+1 -2
View File
@@ -12,7 +12,6 @@ import {
utilities as csToolsUtils,
} from '@cornerstonejs/tools';
import { Types, MeasurementService } from '@ohif/core';
import { StackViewport, utilities as csUtils } from '@cornerstonejs/core';
import { Enums as CSExtensionEnums } from '@ohif/extension-cornerstone';
import DICOMSRDisplayTool from './tools/DICOMSRDisplayTool';
import SCOORD3DPointTool from './tools/SCOORD3DPointTool';
@@ -57,7 +56,7 @@ export default function init({
'SRSCOORD3DPoint',
POINT,
SRSCOOR3DProbeMapper.toAnnotation,
SRSCOOR3DProbeMapper.toMeasurement
SRSCOOR3DProbeMapper.toMeasurement.bind(null, { servicesManager })
);
// Modify annotation tools to use dashed lines on SR
@@ -1,4 +1,4 @@
import { Types, metaData, utilities as csUtils } from '@cornerstonejs/core';
import { type Types } from '@cornerstonejs/core';
import {
annotation,
drawing,
@@ -7,13 +7,8 @@ const SRSCOOR3DProbe = {
* @param {Object} cornerstone Cornerstone event data
* @return {Measurement} Measurement instance
*/
toMeasurement: (
csToolsEventDetail,
displaySetService,
CornerstoneViewportService,
getValueTypeFromToolType,
customizationService
) => {
toMeasurement: ({ servicesManager, getValueTypeFromToolType }, csToolsEventDetail) => {
const { displaySetService } = servicesManager.services;
const { annotation } = csToolsEventDetail;
const { metadata, data, annotationUID } = annotation;
@@ -22,14 +17,25 @@ const SRSCOOR3DProbe = {
return null;
}
const { toolName } = metadata;
const { toolName, FrameOfReferenceUID } = metadata;
const { points } = data.handles;
const displaySets = displaySetService
.getActiveDisplaySets()
.filter(ds => ds.FrameOfReferenceUID === FrameOfReferenceUID);
const displaySet = displaySets.filter(ds => ds.isReconstructable)[0] || displaySets[0];
const { StudyInstanceUID: referenceStudyUID, SeriesInstanceUID: referenceSeriesUID } =
displaySets[0] || {};
const displayText = getDisplayText(annotation);
return {
uid: annotationUID,
points,
metadata,
referenceStudyUID,
referenceSeriesUID,
displaySetInstanceUID: displaySet?.displaySetInstanceUID,
toolName: metadata.toolName,
label: data.label,
displayText: displayText,
@@ -56,7 +62,10 @@ function getDisplayText(annotation) {
}
}
return displayText;
return {
primary: displayText,
secondary: [],
};
}
export default SRSCOOR3DProbe;
@@ -1,9 +1,12 @@
import { Types, annotation } from '@cornerstonejs/tools';
import { metaData } from '@cornerstonejs/core';
import { adaptersSR } from '@cornerstonejs/adapters';
import getRenderableData from './getRenderableData';
import toolNames from '../tools/toolNames';
const { MeasurementReport } = adaptersSR.Cornerstone3D;
export default function addSRAnnotation(measurement, imageId, frameNumber) {
let toolName = toolNames.DICOMSRDisplay;
const renderableData = measurement.coords.reduce((acc, coordProps) => {
@@ -18,6 +21,7 @@ export default function addSRAnnotation(measurement, imageId, frameNumber) {
/** TODO: Read the tool name from the DICOM SR identification type in the future. */
let frameOfReferenceUID = null;
let planeRestriction = null;
if (imageId) {
const imagePlaneModule = metaData.get('imagePlaneModule', imageId);
@@ -25,12 +29,29 @@ export default function addSRAnnotation(measurement, imageId, frameNumber) {
}
if (valueType === 'SCOORD3D') {
toolName = toolNames.SRSCOORD3DPoint;
const adapter = MeasurementReport.getAdapterForTrackingIdentifier(
measurement.TrackingIdentifier
);
if (!adapter) {
toolName = toolNames.SRSCOORD3DPoint;
}
// get the ReferencedFrameOfReferenceUID from the measurement
frameOfReferenceUID = measurement.coords[0].ReferencedFrameOfReferenceSequence;
planeRestriction = {
FrameOfReferenceUID: frameOfReferenceUID,
point: graphicTypePoints[0][0],
};
}
// Store the view reference for use in initial navigation
measurement.viewReference = {
planeRestriction,
FrameOfReferenceUID: frameOfReferenceUID,
referencedImageId: imageId,
};
const SRAnnotation: Types.Annotation = {
annotationUID: TrackingUniqueIdentifier,
highlighted: false,
@@ -38,6 +59,7 @@ export default function addSRAnnotation(measurement, imageId, frameNumber) {
invalidated: false,
metadata: {
toolName,
planeRestriction,
valueType,
graphicType,
FrameOfReferenceUID: frameOfReferenceUID,
@@ -1,17 +1,11 @@
import OHIF from '@ohif/core';
import { annotation } from '@cornerstonejs/tools';
const { log } = OHIF;
import { NO_IMAGE_ID } from '@cornerstonejs/adapters';
function getFilteredCornerstoneToolState(measurementData, additionalFindingTypes) {
const filteredToolState = {};
function addToFilteredToolState(annotation, toolType) {
if (!annotation.metadata?.referencedImageId) {
log.warn(`[DICOMSR] No referencedImageId found for ${toolType} ${annotation.id}`);
return;
}
const imageId = annotation.metadata.referencedImageId;
const imageId = annotation.metadata?.referencedImageId ?? NO_IMAGE_ID;
if (!filteredToolState[imageId]) {
filteredToolState[imageId] = {};
@@ -11,7 +11,11 @@ const { CodeScheme: Cornerstone3DCodeScheme } = adaptersSR.Cornerstone3D;
* @returns {string} The extracted label.
*/
export default function getLabelFromDCMJSImportedToolData(toolData) {
const { findingSites = [], finding } = toolData;
const { findingSites = [], finding, annotation } = toolData;
if (annotation.data.label) {
return annotation.data.label;
}
let freeTextLabel = findingSites.find(
fs => fs.CodeValue === Cornerstone3DCodeScheme.codeValues.CORNERSTONEFREETEXT
@@ -36,6 +36,14 @@ function getRenderableData({ GraphicType, GraphicData, ValueType, imageId }) {
ValueType,
imageId,
});
if (!imageId) {
// without the image id it's not possible to perform the calculations below
// these calculations also do not seem to be needed, since everything works
// just fine when we skip them. At least for SCOORD3D annotations.
return pointsWorld;
}
// We do not have an explicit draw circle svg helper in Cornerstone3D at
// this time, but we can use the ellipse svg helper to draw a circle, so
// here we reshape the data for that purpose.
@@ -90,6 +98,13 @@ function getRenderableData({ GraphicType, GraphicData, ValueType, imageId }) {
imageId,
});
if (!imageId) {
// without the image id it's not possible to perform the calculations below
// these calculations also do not seem to be needed, since everything works
// just fine when we skip them. At least for SCOORD3D annotations.
return pointsWorld;
}
const majorAxisStart = vec3.fromValues(...pointsWorld[0]);
const majorAxisEnd = vec3.fromValues(...pointsWorld[1]);
const minorAxisStart = vec3.fromValues(...pointsWorld[2]);
@@ -1,15 +1,16 @@
import { utilities, metaData } from '@cornerstonejs/core';
import { utilities, metaData, type Types } from '@cornerstonejs/core';
import OHIF, { DicomMetadataStore } from '@ohif/core';
import { vec3 } from 'gl-matrix';
import getLabelFromDCMJSImportedToolData from './getLabelFromDCMJSImportedToolData';
import { adaptersSR } from '@cornerstonejs/adapters';
import { annotation as CsAnnotation } from '@cornerstonejs/tools';
import { annotation as CsAnnotation, type Types as ToolTypes } from '@cornerstonejs/tools';
import { Enums as CSExtensionEnums } from '@ohif/extension-cornerstone';
const { locking } = CsAnnotation;
const { guid } = OHIF.utils;
const { MeasurementReport, CORNERSTONE_3D_TAG } = adaptersSR.Cornerstone3D;
const { MeasurementReport } = adaptersSR.Cornerstone3D;
const { CORNERSTONE_3D_TOOLS_SOURCE_NAME, CORNERSTONE_3D_TOOLS_SOURCE_VERSION } = CSExtensionEnums;
const supportedLegacyCornerstoneTags = ['cornerstoneTools@^4.0.0'];
const convertCode = (codingValues, code) => {
if (!code || code.CodingSchemeDesignator === 'CORNERSTONEJS') {
@@ -37,8 +38,10 @@ const convertSites = (codingValues, sites) => {
};
/**
* Hydrates a structured report, for default viewports.
*
* Hydrates a structured report
* Handles 2d and 3d hydration from SCOORD and SCOORD3D points
* For 3D hydration, chooses a volume display set to display with
* FOr 2D hydration, chooses the (first) display set containing the referenced image.
*/
export default function hydrateStructuredReport(
{ servicesManager, extensionManager, commandsManager }: withAppTypes,
@@ -88,7 +91,7 @@ export default function hydrateStructuredReport(
// Mapping of legacy datasets is now directly handled by adapters module
const datasetToUse = instance;
// Use dcmjs to generate toolState.
// Use CS3D adapters to generate toolState.
let storedMeasurementByAnnotationType = MeasurementReport.generateToolState(
datasetToUse,
// NOTE: we need to pass in the imageIds to dcmjs since the we use them
@@ -96,7 +99,6 @@ export default function hydrateStructuredReport(
// that measurements were added to the display set are the same order as
// the measurementGroups in the instance.
sopInstanceUIDToImageId,
utilities.imageToWorldCoords,
metaData
);
@@ -147,6 +149,9 @@ export default function hydrateStructuredReport(
for (let i = 0; i < imageIds.length; i++) {
const imageId = imageIds[i];
if (!imageId) {
continue;
}
const { SeriesInstanceUID, StudyInstanceUID } = metaData.get('instance', imageId);
if (!SeriesInstanceUIDs.includes(SeriesInstanceUID)) {
@@ -160,38 +165,55 @@ export default function hydrateStructuredReport(
}
}
/**
* Gets reference data for what frame of reference and the referenced
* image id, or for 3d measurements, the volumeId to apply this annotation to.
*/
function getReferenceData(toolData): ToolTypes.AnnotationMetadata {
// Add the measurement to toolState
// dcmjs and Cornerstone3D has structural defect in supporting multi-frame
// files, and looking up the imageId from sopInstanceUIDToImageId results
// in the wrong value.
const frameNumber = (toolData.annotation.data && toolData.annotation.data.frameNumber) || 1;
const imageId =
imageIdsForToolState[toolData.sopInstanceUid][frameNumber] ||
sopInstanceUIDToImageId[toolData.sopInstanceUid];
if (!imageId) {
return getReferenceData3D(toolData, servicesManager);
}
const instance = metaData.get('instance', imageId);
const {
FrameOfReferenceUID,
// SOPInstanceUID,
// SeriesInstanceUID,
// StudyInstanceUID,
} = instance;
return {
referencedImageId: imageId,
FrameOfReferenceUID,
};
}
Object.keys(hydratableMeasurementsInSR).forEach(annotationType => {
const toolDataForAnnotationType = hydratableMeasurementsInSR[annotationType];
toolDataForAnnotationType.forEach(toolData => {
// Add the measurement to toolState
// dcmjs and Cornerstone3D has structural defect in supporting multi-frame
// files, and looking up the imageId from sopInstanceUIDToImageId results
// in the wrong value.
const frameNumber = (toolData.annotation.data && toolData.annotation.data.frameNumber) || 1;
const imageId =
imageIdsForToolState[toolData.sopInstanceUid][frameNumber] ||
sopInstanceUIDToImageId[toolData.sopInstanceUid];
toolData.uid = guid();
const instance = metaData.get('instance', imageId);
const {
FrameOfReferenceUID,
// SOPInstanceUID,
// SeriesInstanceUID,
// StudyInstanceUID,
} = instance;
const referenceData = getReferenceData(toolData);
const { imageId } = referenceData;
const annotation = {
annotationUID: toolData.annotation.annotationUID,
data: toolData.annotation.data,
metadata: {
...referenceData,
toolName: annotationType,
referencedImageId: imageId,
FrameOfReferenceUID,
},
};
utilities.updatePlaneRestriction(annotation.data.handles.points, annotation.metadata);
const source = measurementService.getSource(
CORNERSTONE_3D_TOOLS_SOURCE_NAME,
@@ -225,7 +247,7 @@ export default function hydrateStructuredReport(
locking.setAnnotationLocked(newAnnotationUID, true);
}
if (!imageIds.includes(imageId)) {
if (imageId && !imageIds.includes(imageId)) {
imageIds.push(imageId);
}
});
@@ -238,3 +260,92 @@ export default function hydrateStructuredReport(
SeriesInstanceUIDs,
};
}
/**
* For 3d annotations, there are often several display sets which could
* be used to display the annotation. Choose the first annotation with the
* same frame of reference that is reconstructable, or the first display set
* otherwise.
*/
function chooseDisplaySet(displaySets, annotation) {
if (!displaySets?.length) {
console.warn('No display set found for', annotation);
return;
}
if (displaySets.length === 1) {
return displaySets[0];
}
const volumeDs = displaySets.find(ds => ds.isReconstructable);
if (volumeDs) {
return volumeDs;
}
return displaySets[0];
}
/**
* Gets the additional reference data appropriate for a 3d reference.
* This will choose a volume id, frame of reference and a plane restriction.
*/
function getReferenceData3D(toolData, servicesManager: Types.ServicesManager) {
const { FrameOfReferenceUID } = toolData.annotation.metadata;
const { points } = toolData.annotation.data.handles;
const { displaySetService } = servicesManager.services;
const displaySetsFOR = displaySetService.getDisplaySetsBy(
ds => ds.FrameOfReferenceUID === FrameOfReferenceUID
);
if (!displaySetsFOR.length || !points?.length) {
return {
FrameOfReferenceUID,
};
}
const ds = chooseDisplaySet(displaySetsFOR, toolData.annotation);
const cameraView = chooseCameraView(ds, points);
const viewReference = {
...cameraView,
volumeId: ds.displaySetInstanceUID,
FrameOfReferenceUID,
};
utilities.updatePlaneRestriction(points, viewReference);
return viewReference;
}
/**
* Chooses a possible camera view - right now this is fairly basic,
* just setting the unknowns to null.
*/
function chooseCameraView(_ds, points) {
const selectedPoints = choosePoints(points);
const cameraFocalPoint = <Point3>centerOf(selectedPoints);
// These are sufficient to be null for now and can be set on first view
let viewPlaneNormal: Types.Point3 = null;
let viewUp: Types.Point3 = null;
return {
cameraFocalPoint,
viewPlaneNormal,
viewUp,
};
}
function centerOf(points) {
const scale = 1 / points.length;
const center = vec3.create();
for (const point of points) {
vec3.scaleAndAdd(center, center, point, scale);
}
return center;
}
function choosePoints(points) {
if (points.length === 1 || points.length === 2) {
return points;
}
const firstIndex = 0;
const secondIndex = Math.ceil(points.length / 4);
const thirdIndex = Math.ceil(points.length / 2);
// TODO - check if colinear, if so try to find another 3 points.
const newPoints = [points[firstIndex], points[secondIndex], points[thirdIndex]];
return newPoints;
}
@@ -22,13 +22,20 @@ export default function isRehydratable(displaySet, mappings) {
const { measurements } = displaySet;
for (let i = 0; i < measurements.length; i++) {
const { TrackingIdentifier } = measurements[i] || {};
if (!TrackingIdentifier) {
console.warn('No tracking identifier for measurement ', measurements[i]);
const measurement = measurements[i];
if (!measurement) {
continue;
}
const { TrackingIdentifier = '', graphicType, graphicCode, pointsLength } = measurement;
if (!TrackingIdentifier && !graphicType) {
console.warn('No tracking identifier or graphicType for measurement ', measurement);
continue;
}
const adapter = MeasurementReport.getAdapterForTrackingIdentifier(TrackingIdentifier);
const hydratable = adapter && mappingDefinitions.has(adapter.toolType);
const adapters = MeasurementReport.getAdaptersForTypes(graphicCode, graphicType, pointsLength);
const hydratable =
(adapter && mappingDefinitions.has(adapter.toolType)) ||
(adapters && adapters.some(adapter => mappingDefinitions.has(adapter.toolType)));
if (hydratable) {
return true;
@@ -3,6 +3,556 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.115...v3.11.0-beta.116) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.114...v3.11.0-beta.115) (2025-07-31)
### Features
* add support to scoord3d ([#5016](https://github.com/OHIF/Viewers/issues/5016)) ([735405a](https://github.com/OHIF/Viewers/commit/735405a8554c7ee6283faa83fc42ff8bb9ac34ff))
# [3.11.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.113...v3.11.0-beta.114) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.112...v3.11.0-beta.113) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.111...v3.11.0-beta.112) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.110...v3.11.0-beta.111) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.109...v3.11.0-beta.110) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.108...v3.11.0-beta.109) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.107...v3.11.0-beta.108) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.106...v3.11.0-beta.107) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.105...v3.11.0-beta.106) (2025-07-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.104...v3.11.0-beta.105) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.103...v3.11.0-beta.104) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.102...v3.11.0-beta.103) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.101...v3.11.0-beta.102) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.100...v3.11.0-beta.101) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.99...v3.11.0-beta.100) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.98...v3.11.0-beta.99) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.97...v3.11.0-beta.98) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.96...v3.11.0-beta.97) (2025-07-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.95...v3.11.0-beta.96) (2025-07-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.94...v3.11.0-beta.95) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.93...v3.11.0-beta.94) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.92...v3.11.0-beta.93) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.91...v3.11.0-beta.92) (2025-07-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.90...v3.11.0-beta.91) (2025-07-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.11.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.89...v3.11.0-beta.90) (2025-07-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dynamic-volume",
"version": "3.11.0-beta.90",
"version": "3.12.0-beta.41",
"description": "OHIF extension for 4D volumes data",
"author": "OHIF",
"license": "MIT",
@@ -29,12 +29,12 @@
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"peerDependencies": {
"@ohif/core": "3.11.0-beta.90",
"@ohif/extension-cornerstone": "3.11.0-beta.90",
"@ohif/extension-default": "3.11.0-beta.90",
"@ohif/i18n": "3.11.0-beta.90",
"@ohif/ui": "3.11.0-beta.90",
"dcmjs": "^0.42.0",
"@ohif/core": "3.12.0-beta.41",
"@ohif/extension-cornerstone": "3.12.0-beta.41",
"@ohif/extension-default": "3.12.0-beta.41",
"@ohif/i18n": "3.12.0-beta.41",
"@ohif/ui": "3.12.0-beta.41",
"dcmjs": "0.43.1",
"dicom-parser": "^1.8.21",
"hammerjs": "^2.0.8",
"prop-types": "^15.6.2",
@@ -42,8 +42,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/core": "^3.30.3",
"@cornerstonejs/tools": "^3.30.3",
"@cornerstonejs/core": "4.3.14",
"@cornerstonejs/tools": "4.3.14",
"classnames": "^2.3.2"
}
}
+604
View File
@@ -3,6 +3,610 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
### Bug Fixes
* **segmentation:** Restored segment label tool in longitudinal mode. ([#5443](https://github.com/OHIF/Viewers/issues/5443)) ([dd86a8e](https://github.com/OHIF/Viewers/commit/dd86a8eabd0712d25e7652a242377fe09597e8d5))
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
### Bug Fixes
* **i18n:** Add and update i18n Translation for Toolbar Tool Names ([#5392](https://github.com/OHIF/Viewers/issues/5392)) ([7783d0f](https://github.com/OHIF/Viewers/commit/7783d0f558bbb7016c29513b6fe76ed069dbd75c))
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
### Features
* **Segmentation:** Segmentation highlight animation function selection ([#5401](https://github.com/OHIF/Viewers/issues/5401)) ([69dbe27](https://github.com/OHIF/Viewers/commit/69dbe2778493cdfc7a8da5e757c95217bb31edc2))
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
### Bug Fixes
* **SegmentationService:** _getSegmentCenter wrongly handling seg center availability ([#5396](https://github.com/OHIF/Viewers/issues/5396)) ([74b82bd](https://github.com/OHIF/Viewers/commit/74b82bd93442411ad68f4872992126c40321eb9e))
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
### Bug Fixes
* **cornerstone-dicom-rt:** adding caching usage to cornerstone-dicom-rt SOP Class Handler ([#5387](https://github.com/OHIF/Viewers/issues/5387)) ([d6ea179](https://github.com/OHIF/Viewers/commit/d6ea179ac43a47d4011b8dcaf59d79d99382d6c8))
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
### Bug Fixes
* seg preview ([#5338](https://github.com/OHIF/Viewers/issues/5338)) ([d91cc23](https://github.com/OHIF/Viewers/commit/d91cc230e5231ca32ee28736f661a1497f7834c5))
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
### Bug Fixes
* add back clear segmentation representations ([#5336](https://github.com/OHIF/Viewers/issues/5336)) ([21d6ba2](https://github.com/OHIF/Viewers/commit/21d6ba2bb30df5b99bf5728163caff514aaa5dcd))
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
### Bug Fixes
* Segmentation stats customization module ([#5324](https://github.com/OHIF/Viewers/issues/5324)) ([b9d6f55](https://github.com/OHIF/Viewers/commit/b9d6f558cbe5957f83e6d92305a78662a0b186ed))
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
### Features
* Jump to measurement moves the camera if it is not in the viewport ([#5023](https://github.com/OHIF/Viewers/issues/5023)) ([6fe9df6](https://github.com/OHIF/Viewers/commit/6fe9df6ec93c0f37e3bb9f8bf6425bae025e75c8))
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
### Features
* **orientationMarkers:** improved the orientation markers with a simplified version ([#5328](https://github.com/OHIF/Viewers/issues/5328)) ([266b1f5](https://github.com/OHIF/Viewers/commit/266b1f58f01ac6742a9bb40dda28459e7cddc683))
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.115...v3.11.0-beta.116) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.114...v3.11.0-beta.115) (2025-07-31)
### Features
* add support to scoord3d ([#5016](https://github.com/OHIF/Viewers/issues/5016)) ([735405a](https://github.com/OHIF/Viewers/commit/735405a8554c7ee6283faa83fc42ff8bb9ac34ff))
# [3.11.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.113...v3.11.0-beta.114) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.112...v3.11.0-beta.113) (2025-07-30)
### Features
* improve segment label ([#5217](https://github.com/OHIF/Viewers/issues/5217)) ([271b84f](https://github.com/OHIF/Viewers/commit/271b84f78fcc3974006c7e1a4dbb2ef322fdb9ec))
# [3.11.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.111...v3.11.0-beta.112) (2025-07-28)
### Bug Fixes
* **colorbar:** Allow for AdvancedRenderingControls to be placed at the left or right of the viewport. ([#5273](https://github.com/OHIF/Viewers/issues/5273)) ([341f1c4](https://github.com/OHIF/Viewers/commit/341f1c4ce799d1bcef3632e0d135be0cfcb333a9))
# [3.11.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.110...v3.11.0-beta.111) (2025-07-28)
### Bug Fixes
* **colorbar:** Allow for `AdvancedRenderingControls` to be placed at the top or bottom of the viewport. ([#5270](https://github.com/OHIF/Viewers/issues/5270)) ([d24fe54](https://github.com/OHIF/Viewers/commit/d24fe54d2b5598c8356afa9ce91939018940ee19))
# [3.11.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.109...v3.11.0-beta.110) (2025-07-28)
### Bug Fixes
* null save voi range properties ([#5268](https://github.com/OHIF/Viewers/issues/5268)) ([04dcacd](https://github.com/OHIF/Viewers/commit/04dcacd3a5d0d565b163c96222c8c7f948a05abd))
# [3.11.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.108...v3.11.0-beta.109) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.107...v3.11.0-beta.108) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.106...v3.11.0-beta.107) (2025-07-25)
### Bug Fixes
* prevent failure in DICOM loader for wadouri type ([#5260](https://github.com/OHIF/Viewers/issues/5260)) ([d0cf9e0](https://github.com/OHIF/Viewers/commit/d0cf9e02f438cd8d26ed5bca5fb528549f4c8b98))
# [3.11.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.105...v3.11.0-beta.106) (2025-07-24)
### Bug Fixes
* **ArrowAnnotate:** Allow free-form text for arrow annotations ([#5259](https://github.com/OHIF/Viewers/issues/5259)) ([3c8446a](https://github.com/OHIF/Viewers/commit/3c8446a5e5caf8c050275bd4c193defa9e370b32))
# [3.11.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.104...v3.11.0-beta.105) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.103...v3.11.0-beta.104) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.102...v3.11.0-beta.103) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.101...v3.11.0-beta.102) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.100...v3.11.0-beta.101) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.99...v3.11.0-beta.100) (2025-07-23)
### Bug Fixes
* disable seg download/export buttons until a user has drawn something ([#4953](https://github.com/OHIF/Viewers/issues/4953)) ([7ffe17d](https://github.com/OHIF/Viewers/commit/7ffe17deea8d5642ad69d11943cff3298c227be2))
# [3.11.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.98...v3.11.0-beta.99) (2025-07-23)
### Bug Fixes
* **ViewportOrientationMarkers:** round rotation to fix floating point issue ([#5135](https://github.com/OHIF/Viewers/issues/5135)) ([bd3ff5f](https://github.com/OHIF/Viewers/commit/bd3ff5f57c2fee35e92be4571048cc057eeaf29d))
# [3.11.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.97...v3.11.0-beta.98) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.96...v3.11.0-beta.97) (2025-07-22)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.95...v3.11.0-beta.96) (2025-07-22)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.94...v3.11.0-beta.95) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.93...v3.11.0-beta.94) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.92...v3.11.0-beta.93) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.91...v3.11.0-beta.92) (2025-07-18)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.90...v3.11.0-beta.91) (2025-07-17)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.11.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.89...v3.11.0-beta.90) (2025-07-16)
+6 -2
View File
@@ -1,9 +1,13 @@
const base = require('../../jest.config.base.js');
const pkg = require('./package');
module.exports = {
...base,
displayName: pkg.name,
moduleNameMapper: {
...base.moduleNameMapper,
'@ohif/(.*)': '<rootDir>/../../platform/$1/src',
'^@cornerstonejs/([^/]+)/(.*)$': '<rootDir>/../../node_modules/@cornerstonejs/$1/dist/esm/$2',
'^@cornerstonejs/([^/]+)$': '<rootDir>/../../node_modules/@cornerstonejs/$1/dist/esm',
},
// rootDir: "../.."
// testMatch: [
// //`<rootDir>/platform/${pack.name}/**/*.spec.js`
+14 -12
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone",
"version": "3.11.0-beta.90",
"version": "3.12.0-beta.41",
"description": "OHIF extension for Cornerstone",
"author": "OHIF",
"license": "MIT",
@@ -31,17 +31,19 @@
"dev:cornerstone": "yarn run dev",
"build": "cross-env NODE_ENV=production webpack --progress --config .webpack/webpack.prod.js",
"build:package-1": "yarn run build",
"start": "yarn run dev"
"start": "yarn run dev",
"test:unit": "jest --watchAll",
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"peerDependencies": {
"@cornerstonejs/codec-charls": "^1.2.3",
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^3.30.3",
"@ohif/core": "3.11.0-beta.90",
"@ohif/ui": "3.11.0-beta.90",
"dcmjs": "^0.42.0",
"@cornerstonejs/dicom-image-loader": "4.3.14",
"@ohif/core": "3.12.0-beta.41",
"@ohif/ui": "3.12.0-beta.41",
"dcmjs": "0.43.1",
"dicom-parser": "^1.8.21",
"hammerjs": "^2.0.8",
"prop-types": "^15.6.2",
@@ -51,12 +53,12 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.30.3",
"@cornerstonejs/ai": "^3.30.3",
"@cornerstonejs/core": "^3.30.3",
"@cornerstonejs/labelmap-interpolation": "^3.30.3",
"@cornerstonejs/polymorphic-segmentation": "^3.30.3",
"@cornerstonejs/tools": "^3.30.3",
"@cornerstonejs/adapters": "4.3.14",
"@cornerstonejs/ai": "4.3.14",
"@cornerstonejs/core": "4.3.14",
"@cornerstonejs/labelmap-interpolation": "4.3.14",
"@cornerstonejs/polymorphic-segmentation": "4.3.14",
"@cornerstonejs/tools": "4.3.14",
"@itk-wasm/morphological-contour-interpolation": "1.1.0",
"@kitware/vtk.js": "32.12.0",
"html2canvas": "^1.4.1",
@@ -13,7 +13,6 @@ import CinePlayer from '../components/CinePlayer';
import type { Types } from '@ohif/core';
import OHIFViewportActionCorners from '../components/OHIFViewportActionCorners';
import ViewportColorbarsContainer from '../components/ViewportColorbar';
import { getViewportPresentations } from '../utils/presentations/getViewportPresentations';
import { useSynchronizersStore } from '../stores/useSynchronizersStore';
import ActiveViewportBehavior from '../utils/ActiveViewportBehavior';
@@ -305,31 +304,6 @@ const OHIFCornerstoneViewport = React.memo(
loadViewportData();
}, [viewportOptions, displaySets, dataSource]);
/**
* There are two scenarios for jump to click
* 1. Current viewports contain the displaySet that the annotation was drawn on
* 2. Current viewports don't contain the displaySet that the annotation was drawn on
* and we need to change the viewports displaySet for jumping.
* Since measurement_jump happens via events and listeners, the former case is handled
* by the measurement_jump direct callback, but the latter case is handled first by
* the viewportGrid to set the correct displaySet on the viewport, AND THEN we check
* the cache for jumping to see if there is any jump queued, then we jump to the correct slice.
*/
useEffect(() => {
if (isJumpToMeasurementDisabled) {
return;
}
const { unsubscribe } = measurementService.subscribe(
MeasurementService.EVENTS.JUMP_TO_MEASUREMENT_VIEWPORT,
event => handleJumpToMeasurement(event, elementRef, viewportId, cornerstoneViewportService)
);
return () => {
unsubscribe();
};
}, [displaySets, elementRef, viewportId, isJumpToMeasurementDisabled, servicesManager]);
const Notification = customizationService.getCustomization('ui.notificationComponent');
return (
@@ -387,54 +361,6 @@ const OHIFCornerstoneViewport = React.memo(
areEqual
);
// Helper function to handle jumping to measurements
function handleJumpToMeasurement(event, elementRef, viewportId, cornerstoneViewportService) {
const { measurement, isConsumed } = event;
if (!measurement || isConsumed) {
return;
}
const enabledElement = getEnabledElement(elementRef.current);
if (!enabledElement) {
return;
}
const viewport = enabledElement.viewport as csTypes.IStackViewport | csTypes.IVolumeViewport;
const { metadata, displaySetInstanceUID } = measurement;
const viewportDisplaySets = cornerstoneViewportService.getViewportDisplaySets(viewportId);
const showingDisplaySet = viewportDisplaySets.find(
ds => ds.displaySetInstanceUID === displaySetInstanceUID
);
let metadataToUse = metadata;
// if it is not showing the displaySet we need to remove the FOR from the metadata
if (!showingDisplaySet) {
metadataToUse = {
...metadata,
FrameOfReferenceUID: undefined,
};
}
// Todo: make it work with cases where we want to define FOR based measurements too
if (!viewport.isReferenceViewable(metadataToUse, WITH_NAVIGATION)) {
return;
}
try {
viewport.setViewReference(metadata);
viewport.render();
} catch (e) {
console.warn('Unable to apply', metadata, e);
}
cs3DTools.annotation.selection.setAnnotationSelected(measurement.uid);
event?.consume?.();
}
function _rehydrateSynchronizers(viewportId: string, syncGroupService: any) {
const { synchronizersStore } = useSynchronizersStore.getState();
const synchronizers = synchronizersStore[viewportId];
@@ -558,16 +484,4 @@ function areEqual(prevProps, nextProps) {
return true;
}
// Helper function to check if display sets have changed
function haveDisplaySetsChanged(prevDisplaySets, currentDisplaySets) {
if (prevDisplaySets.length !== currentDisplaySets.length) {
return true;
}
return currentDisplaySets.some((currentDS, index) => {
const prevDS = prevDisplaySets[index];
return currentDS.displaySetInstanceUID !== prevDS.displaySetInstanceUID;
});
}
export default OHIFCornerstoneViewport;
@@ -1,12 +1,6 @@
import React, { useEffect, useState, useMemo, useRef } from 'react';
import React, { useEffect, useState, useMemo } from 'react';
import classNames from 'classnames';
import {
metaData,
Enums,
Types,
getEnabledElement,
utilities as coreUtilities,
} from '@cornerstonejs/core';
import { metaData, Enums, getEnabledElement } from '@cornerstonejs/core';
import { utilities } from '@cornerstonejs/tools';
import { vec3 } from 'gl-matrix';
@@ -22,75 +16,36 @@ function ViewportOrientationMarkers({
servicesManager,
orientationMarkers = ['top', 'left'],
}: withAppTypes) {
// Rotation is in degrees
const [rotation, setRotation] = useState(0);
const [flipHorizontal, setFlipHorizontal] = useState(false);
const [flipVertical, setFlipVertical] = useState(false);
const [cameraModifiedTime, setCameraModifiedTime] = useState(0);
const { isViewportBackgroundLight: isLight } = useViewportRendering(viewportId);
const { cornerstoneViewportService } = servicesManager.services;
// Store initial viewUp and viewRight for volume viewports
const initialVolumeOrientationRef = useRef<{
initialViewUp: number[] | null;
initialViewRight: number[] | null;
}>({
initialViewUp: null,
initialViewRight: null,
});
useEffect(() => {
initialVolumeOrientationRef.current.initialViewUp = null;
initialVolumeOrientationRef.current.initialViewRight = null;
if (viewportData?.viewportType !== 'stack' && element && getEnabledElement(element)) {
const { viewport } = getEnabledElement(element);
const { viewUp, viewPlaneNormal } = viewport.getCamera();
const viewRight = vec3.create();
vec3.cross(viewRight, viewUp, viewPlaneNormal);
initialVolumeOrientationRef.current.initialViewUp = [...viewUp];
initialVolumeOrientationRef.current.initialViewRight = [...viewRight];
}
}, [element, viewportData]);
useEffect(() => {
const cameraModifiedListener = (evt: Types.EventTypes.CameraModifiedEvent) => {
const { previousCamera, camera } = evt.detail;
const { rotation } = camera;
if (rotation !== undefined) {
setRotation(rotation);
}
if (
camera.flipHorizontal !== undefined &&
previousCamera.flipHorizontal !== camera.flipHorizontal
) {
setFlipHorizontal(camera.flipHorizontal);
}
if (
camera.flipVertical !== undefined &&
previousCamera.flipVertical !== camera.flipVertical
) {
setFlipVertical(camera.flipVertical);
}
};
const cameraModifiedListener = () => setCameraModifiedTime(Date.now());
element.addEventListener(Enums.Events.CAMERA_MODIFIED, cameraModifiedListener);
return () => {
element.removeEventListener(Enums.Events.CAMERA_MODIFIED, cameraModifiedListener);
};
}, []);
}, [element]);
const markers = useMemo(() => {
if (!viewportData) {
if (!viewportData || cameraModifiedTime === 0) {
return '';
}
if (!element || !getEnabledElement(element)) {
console.log(`ViewportOrientationMarkers :: Viewport element not enabled (${viewportId})`);
return '';
}
const ohifViewport = cornerstoneViewportService.getViewportInfo(viewportId);
if (!ohifViewport) {
console.log(`ViewportOrientationMarkers :: No viewport (${viewportId})`);
return '';
}
let rowCosines, columnCosines, isDefaultValueSetForRowCosine, isDefaultValueSetForColumnCosine;
if (viewportData.viewportType === 'stack') {
const imageIndex = imageSliceData.imageIndex;
const imageId = viewportData.data[0].imageIds?.[imageIndex];
@@ -100,58 +55,25 @@ function ViewportOrientationMarkers({
return false;
}
({
rowCosines,
columnCosines,
isDefaultValueSetForColumnCosine,
isDefaultValueSetForColumnCosine,
} = metaData.get('imagePlaneModule', imageId) || {});
} else {
if (!element || !getEnabledElement(element)) {
return '';
}
const { isDefaultValueSetForRowCosine, isDefaultValueSetForColumnCosine } =
metaData.get('imagePlaneModule', imageId) || {};
if (
initialVolumeOrientationRef.current.initialViewUp &&
initialVolumeOrientationRef.current.initialViewRight
) {
// Use initial orientation values for consistency, even as the camera changes
columnCosines = [
-initialVolumeOrientationRef.current.initialViewUp[0],
-initialVolumeOrientationRef.current.initialViewUp[1],
-initialVolumeOrientationRef.current.initialViewUp[2],
];
rowCosines = initialVolumeOrientationRef.current.initialViewRight;
} else {
console.warn('ViewportOrientationMarkers::No initial orientation values');
if (isDefaultValueSetForColumnCosine || isDefaultValueSetForRowCosine) {
return '';
}
}
if (
!rowCosines ||
!columnCosines ||
rotation === undefined ||
isDefaultValueSetForRowCosine ||
isDefaultValueSetForColumnCosine
) {
return '';
}
const { viewport } = getEnabledElement(element);
const p00 = viewport.canvasToWorld([0, 0]);
const p10 = viewport.canvasToWorld([1, 0]);
const p01 = viewport.canvasToWorld([0, 1]);
const rowCosines = vec3.sub(vec3.create(), p10, p00);
const columnCosines = vec3.sub(vec3.create(), p01, p00);
const markers = _getOrientationMarkers(
rowCosines,
columnCosines,
rotation,
flipVertical,
flipHorizontal
);
vec3.normalize(rowCosines, rowCosines);
vec3.normalize(columnCosines, columnCosines);
const ohifViewport = cornerstoneViewportService.getViewportInfo(viewportId);
if (!ohifViewport) {
console.log('ViewportOrientationMarkers::No viewport');
return null;
}
const markers = _getOrientationMarkers(rowCosines, columnCosines);
return orientationMarkers.map((m, index) => (
<div
@@ -168,16 +90,7 @@ function ViewportOrientationMarkers({
<div className="orientation-marker-value">{markers[m]}</div>
</div>
));
}, [
viewportData,
imageSliceData,
rotation,
flipVertical,
flipHorizontal,
orientationMarkers,
element,
isLight,
]);
}, [viewportData, imageSliceData, cameraModifiedTime, orientationMarkers, element, isLight]);
return <div className="ViewportOrientationMarkers select-none">{markers}</div>;
}
@@ -189,10 +102,8 @@ function ViewportOrientationMarkers({
*
* @param {*} rowCosines
* @param {*} columnCosines
* @param {*} rotation in degrees
* @returns
*/
function _getOrientationMarkers(rowCosines, columnCosines, rotation, flipVertical, flipHorizontal) {
function _getOrientationMarkers(rowCosines, columnCosines) {
const rowString = getOrientationStringLPS(rowCosines);
const columnString = getOrientationStringLPS(columnCosines);
const oppositeRowString = invertOrientationStringLPS(rowString);
@@ -205,43 +116,6 @@ function _getOrientationMarkers(rowCosines, columnCosines, rotation, flipVertica
bottom: columnString,
};
// If any vertical or horizontal flips are applied, change the orientation strings ahead of
// the rotation applications
if (flipVertical) {
markers.top = invertOrientationStringLPS(markers.top);
markers.bottom = invertOrientationStringLPS(markers.bottom);
}
if (flipHorizontal) {
markers.left = invertOrientationStringLPS(markers.left);
markers.right = invertOrientationStringLPS(markers.right);
}
// Swap the labels accordingly if the viewport has been rotated
// This could be done in a more complex way for intermediate rotation values (e.g. 45 degrees)
if (rotation === 90 || rotation === -270) {
return {
top: markers.left,
left: invertOrientationStringLPS(markers.top),
right: invertOrientationStringLPS(markers.bottom),
bottom: markers.right, // left
};
} else if (rotation === -90 || rotation === 270) {
return {
top: invertOrientationStringLPS(markers.left),
left: markers.top,
bottom: markers.left,
right: markers.bottom,
};
} else if (rotation === 180 || rotation === -180) {
return {
top: invertOrientationStringLPS(markers.top),
left: invertOrientationStringLPS(markers.left),
bottom: invertOrientationStringLPS(markers.bottom),
right: invertOrientationStringLPS(markers.right),
};
}
return markers;
}
+209 -35
View File
@@ -40,6 +40,9 @@ import { updateSegmentBidirectionalStats } from './utils/updateSegmentationStats
import { generateSegmentationCSVReport } from './utils/generateSegmentationCSVReport';
import { getUpdatedViewportsForSegmentation } from './utils/hydrationUtils';
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
import { isMeasurementWithinViewport } from './utils/isMeasurementWithinViewport';
import { getCenterExtent } from './utils/getCenterExtent';
import { EasingFunctionEnum } from './utils/transitions';
const { DefaultHistoryMemo } = csUtils.HistoryMemo;
const toggleSyncFunctions = {
@@ -58,10 +61,7 @@ const getLabelmapTools = ({ toolGroupService }) => {
// tools is an object with toolName as the key and tool as the value
Object.keys(tools).forEach(toolName => {
const tool = tools[toolName];
if (
tool instanceof cornerstoneTools.LabelmapBaseTool &&
tool.shouldResolvePreviewRequests()
) {
if (tool instanceof cornerstoneTools.LabelmapBaseTool) {
labelmapTools.push(tool);
}
});
@@ -102,6 +102,7 @@ let segmentAIEnabled = false;
function commandsModule({
servicesManager,
commandsManager,
extensionManager,
}: OhifTypes.Extensions.ExtensionParams): OhifTypes.Extensions.CommandsModule {
const {
viewportGridService,
@@ -145,6 +146,91 @@ function commandsModule({
}
const actions = {
jumpToMeasurementViewport: ({ annotationUID, measurement }) => {
cornerstoneTools.annotation.selection.setAnnotationSelected(annotationUID, true);
const { metadata } = measurement;
const activeViewportId = viewportGridService.getActiveViewportId();
// Finds the best viewport to jump to for showing the annotation view reference
// This may be different from active if there is a viewport already showing the display set.
const viewportId = cornerstoneViewportService.findNavigationCompatibleViewportId(
activeViewportId,
metadata
);
if (viewportId) {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
viewport.setViewReference(metadata);
viewport.render();
/**
* If the measurement is not visible inside the current viewport,
* we need to move the camera to the measurement.
*/
if (!isMeasurementWithinViewport(viewport, measurement)) {
const camera = viewport.getCamera();
const { focalPoint: cameraFocalPoint, position: cameraPosition } = camera;
const { center, extent } = getCenterExtent(measurement);
const position = vec3.sub(vec3.create(), cameraPosition, cameraFocalPoint);
vec3.add(position, position, center);
viewport.setCamera({ focalPoint: center, position: position as any });
/** Zoom out if the measurement is too large */
const measurementSize = vec3.dist(extent.min, extent.max);
if (measurementSize > camera.parallelScale) {
const scaleFactor = measurementSize / camera.parallelScale;
viewport.setZoom(viewport.getZoom() / scaleFactor);
}
viewport.render();
}
return;
}
const { displaySetInstanceUID: referencedDisplaySetInstanceUID } = measurement;
if (!referencedDisplaySetInstanceUID) {
console.warn('ViewportGrid::No display set found in', measurement);
return;
}
// Finds the viewport to update to show the given displayset/orientation.
// This will choose a view already containing the measurement display set
// if possible, otherwise will fallback to the active.
const viewportToUpdate = cornerstoneViewportService.findUpdateableViewportConfiguration(
activeViewportId,
measurement
);
if (!viewportToUpdate) {
console.warn('Unable to find a viewport to show this in');
return;
}
const updatedViewports = hangingProtocolService.getViewportsRequireUpdate(
viewportToUpdate.viewportId,
referencedDisplaySetInstanceUID
);
if (!updatedViewports?.[0]) {
console.warn(
'ViewportGrid::Unable to navigate to viewport containing',
referencedDisplaySetInstanceUID
);
return;
}
updatedViewports[0].viewportOptions = viewportToUpdate.viewportOptions;
// Update stored position presentation
commandsManager.run('updateStoredPositionPresentation', {
viewportId: viewportToUpdate.viewportId,
displaySetInstanceUIDs: [referencedDisplaySetInstanceUID],
referencedImageId: measurement.referencedImageId,
options: {
...measurement.metadata,
},
});
commandsManager.run('setDisplaySetsForViewports', { viewportsToUpdate: updatedViewports });
},
hydrateSecondaryDisplaySet: async ({ displaySet, viewportId }) => {
if (!displaySet) {
return;
@@ -327,6 +413,8 @@ function commandsModule({
type,
});
},
/** Stores the changed position presentation */
updateStoredPositionPresentation: ({
viewportId,
displaySetInstanceUIDs,
@@ -350,22 +438,23 @@ function commandsModule({
([key, value]) => {
return (
displaySetInstanceUIDs.every(uid => key.includes(uid)) &&
value.viewportId === viewportId
value?.viewportId === viewportId
);
}
)?.[0];
}
// Create presentation data with referencedImageId and options if provided
const presentationData = referencedImageId
? {
...presentations.positionPresentation,
viewReference: {
referencedImageId,
...options,
},
}
: presentations.positionPresentation;
const presentationData =
referencedImageId || options?.FrameOfReferenceUID
? {
...presentations.positionPresentation,
viewReference: {
referencedImageId,
...options,
},
}
: presentations.positionPresentation;
if (previousReferencedDisplaySetStoreKey) {
setPositionPresentation(previousReferencedDisplaySetStoreKey, presentationData);
@@ -429,8 +518,8 @@ function commandsModule({
if (!labelConfig) {
const label = await callInputDialog({
uiDialogService,
title: 'Edit Measurement Label',
placeholder: measurement.label || 'Enter new label',
title: i18n.t('Tools:Edit Measurement Label'),
placeholder: measurement.label || i18n.t('Tools:Enter new label'),
defaultValue: measurement.label,
});
@@ -637,10 +726,22 @@ function commandsModule({
viewportGridService.setActiveViewportId(viewportId);
},
arrowTextCallback: async ({ callback }) => {
arrowTextCallback: async ({ callback, data }) => {
const labelConfig = customizationService.getCustomization('measurementLabels');
const renderContent = customizationService.getCustomization('ui.labellingComponent');
if (!labelConfig) {
const label = await callInputDialog({
uiDialogService,
title: i18n.t('Tools:Edit Arrow Text'),
placeholder: data?.data?.label || i18n.t('Tools:Enter new text'),
defaultValue: data?.data?.label || '',
});
callback?.(label);
return;
}
const value = await callInputDialogAutoComplete({
uiDialogService,
labelConfig,
@@ -877,8 +978,8 @@ function commandsModule({
if (!cornerstoneViewportService.getCornerstoneViewport(activeViewportId)) {
// Cannot download a non-cornerstone viewport (image).
uiNotificationService.show({
title: 'Download Image',
message: 'Image cannot be downloaded',
title: i18n.t('Tools:Download Image'),
message: i18n.t('Tools:Image cannot be downloaded'),
type: 'error',
});
return;
@@ -889,7 +990,7 @@ function commandsModule({
if (uiModalService) {
uiModalService.show({
content: CornerstoneViewportDownloadForm,
title: 'Download High Quality Image',
title: i18n.t('Tools:Download High Quality Image'),
contentProps: {
activeViewportId,
cornerstoneViewportService,
@@ -1353,7 +1454,7 @@ function commandsModule({
const segs = segmentationService.getSegmentations();
const label = options.label || `Segmentation ${segs.length + 1}`;
const label = options.label || `${i18n.t('Tools:Segmentation')} ${segs.length + 1}`;
const segmentationId = options.segmentationId || `${csUtils.uuidv4()}`;
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
@@ -1367,7 +1468,7 @@ function commandsModule({
segments: options.createInitialSegment
? {
1: {
label: `${i18n.t('Segment')} 1`,
label: `${i18n.t('Tools:Segment')} 1`,
active: true,
},
}
@@ -1418,7 +1519,33 @@ function commandsModule({
segmentationId
);
segmentationService.setActiveSegment(segmentationId, segmentIndex);
segmentationService.jumpToSegmentCenter(segmentationId, segmentIndex);
const { highlightAlpha, highlightSegment, animationLength, animationFunctionType } =
(customizationService.getCustomization(
'panelSegmentation.jumpToSegmentHighlightAnimationConfig'
) as Object as {
highlightAlpha?: number;
highlightSegment?: boolean;
animationLength?: number;
animationFunctionType?: EasingFunctionEnum;
}) ?? {};
const validAnimationFunctionType = Object.values(EasingFunctionEnum).includes(
animationFunctionType
)
? animationFunctionType
: undefined;
segmentationService.jumpToSegmentCenter(
segmentationId,
segmentIndex,
undefined,
highlightAlpha,
highlightSegment,
animationLength,
undefined,
validAnimationFunctionType
);
},
/**
@@ -1618,8 +1745,8 @@ function commandsModule({
callInputDialog({
uiDialogService,
title: 'Edit Segment Label',
placeholder: 'Enter new label',
title: i18n.t('Tools:Edit Segment Label'),
placeholder: i18n.t('Tools:Enter new label'),
defaultValue: segment.label,
}).then(label => {
segmentationService.setSegmentLabel(segmentationId, segmentIndex, label);
@@ -1638,8 +1765,8 @@ function commandsModule({
callInputDialog({
uiDialogService,
title: 'Edit Segmentation Label',
placeholder: 'Enter new label',
title: i18n.t('Tools:Edit Segmentation Label'),
placeholder: i18n.t('Tools:Enter new label'),
defaultValue: label,
}).then(label => {
segmentationService.addOrUpdateSegmentation({ segmentationId, label });
@@ -1661,7 +1788,7 @@ function commandsModule({
uiDialogService.show({
content: colorPickerDialog,
title: 'Segment Color',
title: i18n.t('Tools:Segment Color'),
contentProps: {
value: rgbaColor,
onSave: newRgbaColor => {
@@ -1731,17 +1858,64 @@ function commandsModule({
}
});
},
toggleSegmentLabel: ({ toggle }) => {
toggleSegmentLabel: ({ enabled }: { enabled?: boolean }) => {
const toolName = cornerstoneTools.SegmentLabelTool.toolName;
const toolGroupIds = toolGroupService.getToolGroupIds();
const isToolOn = toolGroupIds.some(toolGroupId => {
const toolGroup = cornerstoneTools.ToolGroupManager.getToolGroup(toolGroupId);
const mode = toolGroup.getToolInstance(toolName)?.mode;
return mode === 'Active';
});
const enableTool = enabled !== undefined ? enabled : !isToolOn;
toolGroupIds.forEach(toolGroupId => {
const toolGroup = cornerstoneTools.ToolGroupManager.getToolGroup(toolGroupId);
if (toggle) {
toolGroup.setToolActive(cornerstoneTools.SegmentLabelTool.toolName);
if (enableTool) {
toolGroup.setToolActive(toolName);
} else {
toolGroup.setToolDisabled(cornerstoneTools.SegmentLabelTool.toolName);
toolGroup.setToolDisabled(toolName);
}
});
},
/**
* Used to sync the apps initial state with the config file settings.
*
* Will mutate the tools object of the given tool group and add the segmentLabelTool to the proper place.
*
* Use it before initializing the toolGroup with the tools.
*/
initializeSegmentLabelTool: ({ tools }) => {
const appConfig = extensionManager.appConfig;
const segmentLabelConfig = appConfig.segmentation?.segmentLabel;
if (segmentLabelConfig?.enabledByDefault) {
const activeTools = tools?.active ?? [];
activeTools.push({
toolName: toolNames.SegmentLabel,
configuration: {
hoverTimeout: segmentLabelConfig?.hoverTimeout ?? 1,
color: segmentLabelConfig?.labelColor,
background: segmentLabelConfig?.background,
},
});
tools.active = activeTools;
return tools;
}
const disabledTools = tools?.disabled ?? [];
disabledTools.push({
toolName: toolNames.SegmentLabel,
configuration: {
hoverTimeout: segmentLabelConfig?.hoverTimeout ?? 1,
color: segmentLabelConfig?.labelColor,
},
});
tools.disabled = disabledTools;
return tools;
},
toggleUseCenterSegmentIndex: ({ toggle }) => {
let labelmapTools = getLabelmapTools({ toolGroupService });
labelmapTools = labelmapTools.filter(tool => !tool.toolName.includes('Eraser'));
@@ -2095,9 +2269,7 @@ function commandsModule({
updateMeasurement: {
commandFn: actions.updateMeasurement,
},
jumpToMeasurement: {
commandFn: actions.jumpToMeasurement,
},
jumpToMeasurement: actions.jumpToMeasurement,
removeMeasurement: {
commandFn: actions.removeMeasurement,
},
@@ -2357,6 +2529,8 @@ function commandsModule({
startRecordingForAnnotationGroup: actions.startRecordingForAnnotationGroup,
endRecordingForAnnotationGroup: actions.endRecordingForAnnotationGroup,
toggleSegmentLabel: actions.toggleSegmentLabel,
jumpToMeasurementViewport: actions.jumpToMeasurementViewport,
initializeSegmentLabelTool: actions.initializeSegmentLabelTool,
};
return {
@@ -1,6 +1,20 @@
import { useToolbar, useViewportMousePosition } from '@ohif/core/src/hooks';
import React, { useState, useEffect, useRef } from 'react';
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { useViewportRendering } from '../../hooks';
import { ButtonLocation } from '@ohif/core/src/services/ToolBarService/ToolbarService';
import classNames from 'classnames';
const mouseNearControlsRanges = {
[ButtonLocation.TopMiddle]: { minX: 0, minY: 0, maxX: 1, maxY: 0.1 },
[ButtonLocation.BottomMiddle]: { minX: 0, minY: 0.9, maxX: 1, maxY: 1 },
[ButtonLocation.LeftMiddle]: { minX: 0, minY: 0, maxX: 0.1, maxY: 1 },
[ButtonLocation.RightMiddle]: { minX: 0.9, minY: 0, maxX: 1, maxY: 1 },
};
const getFlexDirectionClassName = (location: ButtonLocation) =>
location === ButtonLocation.LeftMiddle || location === ButtonLocation.RightMiddle
? 'flex-col'
: 'flex-row';
function AdvancedRenderingControls({
viewportId,
@@ -24,10 +38,11 @@ function AdvancedRenderingControls({
});
const mousePosition = useViewportMousePosition(viewportId);
const [isAtBottom, setIsAtBottom] = useState(false);
const [isMouseNearControls, setIsMouseNearControls] = useState(false);
const [showAllIcons, setShowAllIcons] = useState(true);
const firstMountRef = useRef(true);
const { hasColorbar } = useViewportRendering(viewportId);
const [isAnItemOpen, setIsAnItemOpen] = useState(false);
useEffect(() => {
if (firstMountRef.current) {
@@ -43,13 +58,30 @@ function AdvancedRenderingControls({
useEffect(() => {
if (!showAllIcons && mousePosition.isInViewport) {
if (mousePosition.isInBottomPercentage(10)) {
setIsAtBottom(true);
const mouseHoverLocation = mouseNearControlsRanges[location];
if (mousePosition.isWithinNormalizedBox(mouseHoverLocation)) {
setIsMouseNearControls(true);
} else {
setIsAtBottom(false);
setIsMouseNearControls(false);
}
}
}, [mousePosition, showAllIcons]);
}, [location, mousePosition, showAllIcons]);
const handleOnItemOpen = useCallback(
(id, viewportId) => {
openItem(id, viewportId);
setIsAnItemOpen(true);
},
[openItem, setIsAnItemOpen]
);
const handleOnItemClose = useCallback(
(id, viewportId) => {
closeItem(id, viewportId);
setIsAnItemOpen(false);
},
[closeItem, setIsAnItemOpen]
);
if (!toolbarButtons?.length) {
return null;
@@ -60,7 +92,7 @@ function AdvancedRenderingControls({
}
return (
<div className="flex flex-row gap-2">
<div className={classNames('flex gap-2', getFlexDirectionClassName(location))}>
{toolbarButtons.map(toolDef => {
if (!toolDef) {
return null;
@@ -73,8 +105,8 @@ function AdvancedRenderingControls({
...componentProps,
isOpen: isItemOpen(id, viewportId),
isLocked: isItemLocked(id, viewportId),
onOpen: () => openItem(id, viewportId),
onClose: () => closeItem(id, viewportId),
onOpen: () => handleOnItemOpen(id, viewportId),
onClose: () => handleOnItemClose(id, viewportId),
onToggleLock: () => toggleLock(id, viewportId),
viewportId,
};
@@ -97,7 +129,8 @@ function AdvancedRenderingControls({
// Always show all icons on first mount for 3 seconds
// After that, always show Colorbar, show others only when mouse is at bottom
const shouldBeVisible = showAllIcons || id === 'Colorbar' || isAtBottom;
const shouldBeVisible =
isAnItemOpen || showAllIcons || id === 'Colorbar' || isMouseNearControls;
return (
<div
@@ -24,36 +24,38 @@ export const groupByStudy = (items, grouping, childProps) => {
let firstSelected, firstGroup;
items.forEach(item => {
const studyUID = getItemStudyInstanceUID(item);
if (!groups.has(studyUID)) {
const items = [];
const filter = MeasurementFilters.filterAnd(
MeasurementFilters.filterMeasurementsByStudyUID(studyUID),
grouping.filter
);
const group = {
...grouping,
items,
displayMeasurements: items,
key: studyUID,
isSelected: studyUID === activeStudyUID,
StudyInstanceUID: studyUID,
filter,
measurementFilter: filter,
};
if (group.isSelected && !firstSelected) {
firstSelected = group;
items
.filter(item => item.displaySetInstanceUID)
.forEach(item => {
const studyUID = getItemStudyInstanceUID(item);
if (!groups.has(studyUID)) {
const items = [];
const filter = MeasurementFilters.filterAnd(
MeasurementFilters.filterMeasurementsByStudyUID(studyUID),
grouping.filter
);
const group = {
...grouping,
items,
displayMeasurements: items,
key: studyUID,
isSelected: studyUID === activeStudyUID,
StudyInstanceUID: studyUID,
filter,
measurementFilter: filter,
};
if (group.isSelected && !firstSelected) {
firstSelected = group;
}
firstGroup ||= group;
groups.set(studyUID, group);
}
firstGroup ||= group;
groups.set(studyUID, group);
}
if (!firstSelected && firstGroup) {
firstGroup.isSelected = true;
}
const group = groups.get(studyUID);
group.items.push(item);
});
if (!firstSelected && firstGroup) {
firstGroup.isSelected = true;
}
const group = groups.get(studyUID);
group.items.push(item);
});
return groups;
};
@@ -27,6 +27,9 @@ type ColorbarProps = {
numColorbars: number;
};
export const isHorizontal = (position: ColorbarPositionType): boolean =>
position === 'top' || position === 'bottom';
/**
* ViewportColorbar Component
* A React wrapper for the cornerstone ViewportColorbar that adds a close button
@@ -143,8 +146,9 @@ const ViewportColorbar = memo(function ViewportColorbar({
display: 'flex',
alignItems: 'center',
pointerEvents: 'auto',
minWidth: position === 'bottom' ? width / 2.5 : '17px',
minHeight: position === 'bottom' ? '20px' : numColorbars === 1 ? height / 3 : height / 4,
minWidth: isHorizontal(position) ? width / 2.5 : '17px',
minHeight: isHorizontal(position) ? '20px' : numColorbars === 1 ? height / 3 : height / 4,
height: '1px', // sometimes flex items with min-height need a starting point for its height calculation
...positionStylesFromConfig,
}}
></div>
@@ -2,7 +2,7 @@ import React, { useEffect, useState, useMemo, memo, useCallback } from 'react';
import { useSystem } from '@ohif/core';
import { ColorbarCustomization } from '../../types/Colorbar';
import type { ColorMapPreset } from '../../types/Colormap';
import ViewportColorbar from './ViewportColorbar';
import ViewportColorbar, { isHorizontal } from './ViewportColorbar';
import useViewportRendering from '../../hooks/useViewportRendering';
import { useViewportDisplaySets } from '../../hooks/useViewportDisplaySets';
type ViewportColorbarsContainerProps = {
@@ -74,10 +74,8 @@ const ViewportColorbarsContainer = memo(function ViewportColorbarsContainer({
return null;
}
const isBottom = position === 'bottom';
const isSingleViewport = viewportDisplaySets.length === 1;
const showFullList = isSingleViewport || !isBottom;
const showFullList = isSingleViewport || !isHorizontal(position);
const colorbarsToUse = showFullList
? colorbars
@@ -1,9 +1,11 @@
import React, { ReactElement, useCallback } from 'react';
import { Switch } from '@ohif/ui-next';
import { useViewportRendering } from '../../hooks/useViewportRendering';
import { useTranslation } from 'react-i18next';
export function Colorbar({ viewportId }: { viewportId?: string } = {}): ReactElement {
const { hasColorbar, toggleColorbar } = useViewportRendering(viewportId);
const { t } = useTranslation('WindowLevelActionMenu');
const handleToggle = useCallback(() => {
toggleColorbar();
@@ -16,7 +18,7 @@ export function Colorbar({ viewportId }: { viewportId?: string } = {}): ReactEle
className="flex-grow"
onClick={handleToggle}
>
Display Color bar
{t('Display Color bar')}
</span>
<Switch
className="ml-2 flex-shrink-0"
@@ -1,9 +1,11 @@
import React, { ReactElement, useEffect, useRef, useState } from 'react';
import { AllInOneMenu, ScrollArea, Switch, Tabs, TabsList, TabsTrigger } from '@ohif/ui-next';
import { useViewportRendering } from '../../hooks/useViewportRendering';
import { useTranslation } from 'react-i18next';
export function Colormap({ viewportId }: { viewportId?: string } = {}): ReactElement {
const { viewportDisplaySets } = useViewportRendering(viewportId);
const { t } = useTranslation('WindowLevelActionMenu');
const [activeDisplaySetUID, setActiveDisplaySetUID] = useState<string | undefined>(
viewportDisplaySets?.[0]?.displaySetInstanceUID
@@ -74,7 +76,7 @@ export function Colormap({ viewportId }: { viewportId?: string } = {}): ReactEle
className="hover:bg-accent flex h-8 w-full flex-shrink-0 cursor-pointer items-center px-2 text-base hover:rounded"
onClick={() => setShowPreview(!showPreview)}
>
<span className="flex-shrink-0">Preview in viewport</span>
<span className="flex-shrink-0">{t('Preview in viewport')}</span>
<Switch
className="ml-auto flex-shrink-0"
checked={showPreview}
@@ -7,6 +7,7 @@ import { WindowLevel } from './WindowLevel';
import { VolumeRenderingPresets } from './VolumeRenderingPresets';
import { VolumeRenderingOptions } from './VolumeRenderingOptions';
import { useViewportRendering } from '../../hooks/useViewportRendering';
import i18n from 'i18next';
export type WindowLevelActionMenuProps = {
viewportId: string;
@@ -58,6 +59,7 @@ export function WindowLevelActionMenuContent({
isVisible={true}
align={align}
side={side}
backLabel={i18n.t('WindowLevelActionMenu:Back to Display Options')}
>
<AllInOneMenu.ItemPanel>
{!is3DVolume && <Colorbar viewportId={viewportId} />}
@@ -65,7 +67,7 @@ export function WindowLevelActionMenuContent({
{colorbarProperties?.colormaps && !is3DVolume && (
<AllInOneMenu.SubMenu
key="colorLUTPresets"
itemLabel="Color LUT"
itemLabel={t('Color LUT')}
itemIcon="icon-color-lut"
className="flex h-[calc(100%-32px)] flex-col"
>
@@ -86,7 +88,7 @@ export function WindowLevelActionMenuContent({
{volumeRenderingPresets && is3DVolume && <VolumeRenderingPresets viewportId={viewportId} />}
{volumeRenderingQualityRange && is3DVolume && (
<AllInOneMenu.SubMenu itemLabel="Rendering Options">
<AllInOneMenu.SubMenu itemLabel={t('Rendering Options')}>
<VolumeRenderingOptions viewportId={viewportId} />
</AllInOneMenu.SubMenu>
)}
@@ -108,6 +108,7 @@ export const CustomDropdownMenuContent = () => {
e.preventDefault();
actions.downloadCSVSegmentationReport(segmentationId);
}}
disabled={!allowExport}
>
{t('CSV Report')}
</DropdownMenuItem>
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
import { ImageModal, FooterAction } from '@ohif/ui-next';
import { useTranslation } from 'react-i18next';
const MAX_TEXTURE_SIZE = 10000;
const DEFAULT_FILENAME = 'image';
@@ -37,6 +37,7 @@ function ViewportDownloadFormNew({
const [showWarningMessage, setShowWarningMessage] = useState(true);
const [filename, setFilename] = useState(DEFAULT_FILENAME);
const [fileType, setFileType] = useState('jpg');
const { t } = useTranslation('CaptureViewportModal');
useEffect(() => {
if (!viewportElement) {
@@ -82,7 +83,7 @@ function ViewportDownloadFormNew({
value={filename}
onChange={e => setFilename(e.target.value)}
>
File name
{t('File name')}
</ImageModal.Filename>
<ImageModal.Filetype
selected={fileType}
@@ -109,7 +110,7 @@ function ViewportDownloadFormNew({
maxWidth={MAX_TEXTURE_SIZE.toString()}
maxHeight={MAX_TEXTURE_SIZE.toString()}
>
Image size <span className="text-muted-foreground">px</span>
{t('Image size')} <span className="text-muted-foreground">px</span>
</ImageModal.ImageSize>
<ImageModal.SwitchOption
@@ -117,7 +118,7 @@ function ViewportDownloadFormNew({
checked={showAnnotations}
onCheckedChange={onAnnotationsChange}
>
Include annotations
{t('Include annotations')}
</ImageModal.SwitchOption>
{warningState.enabled && (
<ImageModal.SwitchOption
@@ -125,19 +126,21 @@ function ViewportDownloadFormNew({
checked={showWarningMessage}
onCheckedChange={setShowWarningMessage}
>
Include warning message
{t('Include warning message')}
</ImageModal.SwitchOption>
)}
<FooterAction className="mt-2">
<FooterAction.Right>
<FooterAction.Secondary onClick={onClose}>Cancel</FooterAction.Secondary>
<FooterAction.Secondary onClick={onClose}>
{t('Common:Cancel')}
</FooterAction.Secondary>
<FooterAction.Primary
onClick={() => {
onDownload(filename || DEFAULT_FILENAME, fileType);
onClose();
}}
>
Save
{t('Common:Save')}
</FooterAction.Primary>
</FooterAction.Right>
</FooterAction>
@@ -34,15 +34,20 @@ export default {
if (!viewportId) {
return [];
}
const displaySetInsaneUIDs = viewportGridService.getDisplaySetsUIDsForViewport(viewportId);
const displaySetInstanceUIDs = viewportGridService.getDisplaySetsUIDsForViewport(viewportId);
if (!displaySetInsaneUIDs) {
if (!displaySetInstanceUIDs) {
return [];
}
const displaySets = displaySetInsaneUIDs.map(uid =>
displaySetService.getDisplaySetByUID(uid)
);
const displaySets = displaySetInstanceUIDs.map(uid => {
const displaySet = displaySetService.getDisplaySetByUID(uid);
const referencedDisplaySetUID = displaySet?.measurements?.[0]?.displaySetInstanceUID;
if (displaySet.Modality === 'SR' && referencedDisplaySetUID) {
return displaySetService.getDisplaySetByUID(referencedDisplaySetUID);
}
return displaySet;
});
return hangingProtocols
.map(hp => {
@@ -36,9 +36,9 @@ export default function getSegmentationPanelCustomization({ commandsManager, ser
'segmentationToolbox.config': () => {
// Get initial states based on current configuration
const [previewEdits, setPreviewEdits] = useState(false);
const [segmentLabelEnabled, setSegmentLabelEnabled] = useState(false);
const [toggleSegmentEnabled, setToggleSegmentEnabled] = useState(false);
const [useCenterAsSegmentIndex, setUseCenterAsSegmentIndex] = useState(false);
const [shouldShowLabelOnHover, setShouldShowLabelOnHover] = useState(false);
const handlePreviewEditsChange = checked => {
setPreviewEdits(checked);
commandsManager.run('toggleSegmentPreviewEdit', { toggle: checked });
@@ -54,19 +54,19 @@ export default function getSegmentationPanelCustomization({ commandsManager, ser
commandsManager.run('toggleUseCenterSegmentIndex', { toggle: checked });
};
const handleToggleShowLabelOnHover = checked => {
setShouldShowLabelOnHover(checked);
commandsManager.run('toggleSegmentLabel', { toggle: checked });
const handleSegmentLabelEnabledChange = checked => {
setSegmentLabelEnabled(checked);
commandsManager.run('toggleSegmentLabel', { enabled: checked });
};
return (
<div className="bg-muted flex flex-col gap-4 border-b border-b-[2px] border-black px-2 py-3">
<div className="bg-muted flex flex-col gap-2 border-b border-b-[2px] border-black px-2 py-3">
<div className="flex items-center gap-2">
<Switch
checked={previewEdits}
onCheckedChange={handlePreviewEditsChange}
/>
<span className="text-base text-white">Preview edits before creating</span>
<span className="text-foreground text-base">Preview edits before creating</span>
</div>
<div className="flex items-center gap-2">
@@ -74,7 +74,7 @@ export default function getSegmentationPanelCustomization({ commandsManager, ser
checked={useCenterAsSegmentIndex}
onCheckedChange={handleUseCenterAsSegmentIndexChange}
/>
<span className="text-base text-white">Use center as segment index</span>
<span className="text-foreground text-base">Use center as segment index</span>
</div>
<div className="flex items-center gap-2">
@@ -82,15 +82,15 @@ export default function getSegmentationPanelCustomization({ commandsManager, ser
checked={toggleSegmentEnabled}
onCheckedChange={handleToggleSegmentEnabledChange}
/>
<span className="text-base text-white">Hover on segment border to activate</span>
<span className="text-foreground text-base">Hover on segment border to activate</span>
</div>
<div className="flex items-center gap-2">
<Switch
checked={shouldShowLabelOnHover}
onCheckedChange={handleToggleShowLabelOnHover}
checked={segmentLabelEnabled}
onCheckedChange={handleSegmentLabelEnabledChange}
/>
<span className="text-base text-white">Show segment label on mouse hover</span>
<span className="text-foreground text-base">Show segment name on hover</span>
</div>
</div>
);
@@ -12,13 +12,17 @@ import miscCustomization from './customizations/miscCustomization';
import captureViewportModalCustomization from './customizations/captureViewportModalCustomization';
import viewportDownloadWarningCustomization from './customizations/viewportDownloadWarningCustomization';
function getCustomizationModule({ commandsManager, servicesManager }) {
function getCustomizationModule({ commandsManager, servicesManager, extensionManager }) {
return [
{
name: 'default',
value: {
...viewportOverlayCustomization,
...getSegmentationPanelCustomization({ commandsManager, servicesManager }),
...getSegmentationPanelCustomization({
commandsManager,
servicesManager,
extensionManager,
}),
...layoutSelectorCustomization,
...viewportToolsCustomization,
...viewportClickCommandsCustomization,
@@ -262,13 +262,13 @@ export function useViewportRendering(
if (volumeId) {
properties = viewport.getProperties(volumeId);
if (properties.voiRange) {
if (properties?.voiRange) {
setVoiRange(properties.voiRange);
voiRangeRef.current = properties.voiRange;
}
// Get opacity from colormap if available
if (properties.colormap && properties.colormap.opacity !== undefined) {
if (properties?.colormap?.opacity !== undefined) {
const isArray = Array.isArray(properties.colormap.opacity);
const opacity = isArray
? properties.colormap.opacity.reduce((max, current) => Math.max(max, current), 0)
@@ -279,7 +279,7 @@ export function useViewportRendering(
}
// Get threshold from colormap if available
if (properties.colormap && properties.colormap.threshold !== undefined) {
if (properties?.colormap && properties.colormap.threshold !== undefined) {
setThresholdState(properties.colormap.threshold);
}
}
+2 -2
View File
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const fourUp = {
id: 'fourUp',
locked: true,
name: '3D four up',
name: i18n.t('Hps:3D four up'),
icon: 'layout-advanced-3d-four-up',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
+3 -3
View File
@@ -1,9 +1,9 @@
import { Types } from '@ohif/core';
import i18n from 'i18next';
const frameView: Types.HangingProtocol.Protocol = {
id: '@ohif/frameView',
description: 'Frame view for the active series',
name: 'Frame View',
description: i18n.t('Hps:Frame view for the active series'),
name: i18n.t('Hps:Frame View'),
icon: 'tool-stack-scroll',
isPreset: true,
toolGroupIds: ['default'],
+2 -2
View File
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const main3D = {
id: 'main3D',
locked: true,
name: '3D main',
name: i18n.t('Hps:3D main'),
icon: 'layout-advanced-3d-main',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
+2 -2
View File
@@ -1,5 +1,5 @@
import { Types } from '@ohif/core';
import i18n from 'i18next';
export const VOI_SYNC_GROUP = {
type: 'voi',
id: 'mpr',
@@ -22,7 +22,7 @@ export const HYDRATE_SEG_SYNC_GROUP = {
export const mpr: Types.HangingProtocol.Protocol = {
id: 'mpr',
name: 'MPR',
name: i18n.t('Hps:MPR'),
locked: true,
icon: 'layout-advanced-mpr',
isPreset: true,
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const mprAnd3DVolumeViewport = {
id: 'mprAnd3DVolumeViewport',
locked: true,
name: 'mpr',
name: i18n.t('Hps:mpr'),
createdDate: '2023-03-15T10:29:44.894Z',
modifiedDate: '2023-03-15T10:29:44.894Z',
availableTo: {},
+2 -1
View File
@@ -1,9 +1,10 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const only3D = {
id: 'only3D',
locked: true,
name: '3D only',
name: i18n.t('Hps:3D only'),
icon: 'layout-advanced-3d-only',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
+2 -2
View File
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const primary3D = {
id: 'primary3D',
locked: true,
name: '3D primary',
name: i18n.t('Hps:3D primary'),
icon: 'layout-advanced-3d-primary',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const primaryAxial = {
id: 'primaryAxial',
locked: true,
name: 'Axial Primary',
name: i18n.t('Hps:Axial Primary'),
icon: 'layout-advanced-axial-primary',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
+1 -1
View File
@@ -195,7 +195,7 @@ const cornerstoneExtension: Types.Extensions.Extension = {
{
name: 'cornerstone',
component: ExtendedOHIFCornerstoneViewport,
isReferenceViewable: props => utils.isReferenceViewable({ ...props, servicesManager }),
isReferenceViewable: utils.isReferenceViewable.bind(null, servicesManager),
},
];
},
+8 -9
View File
@@ -55,6 +55,10 @@ export default async function init({
extensionManager,
appConfig,
}: withAppTypes): Promise<void> {
// Use a public library path of PUBLIC_URL plus the component name
// This safely separates components that are loaded as-is.
window.PUBLIC_LIB_URL ||= './${component}/';
// Note: this should run first before initializing the cornerstone
// DO NOT CHANGE THE ORDER
@@ -189,15 +193,10 @@ export default async function init({
initCineService(servicesManager);
initStudyPrefetcherService(servicesManager);
[
measurementService.EVENTS.JUMP_TO_MEASUREMENT_LAYOUT,
measurementService.EVENTS.JUMP_TO_MEASUREMENT_VIEWPORT,
].forEach(event => {
measurementService.subscribe(event, evt => {
const { measurement } = evt;
const { uid: annotationUID } = measurement;
cornerstoneTools.annotation.selection.setAnnotationSelected(annotationUID, true);
});
measurementService.subscribe(measurementService.EVENTS.JUMP_TO_MEASUREMENT, evt => {
const { measurement } = evt;
const { uid: annotationUID } = measurement;
commandsManager.runCommand('jumpToMeasurementViewport', { measurement, annotationUID, evt });
});
// When a custom image load is performed, update the relevant viewports
@@ -409,10 +409,6 @@ const connectMeasurementServiceToTools = ({
setAnnotationLabel(sourceAnnotation, element, label);
}
if (metadata.toolName === 'ArrowAnnotate') {
data.text = label;
}
// update the isLocked state
annotation.locking.setAnnotationLocked(uid, isLocked);
@@ -440,7 +436,7 @@ const connectMeasurementServiceToTools = ({
return;
}
const { referenceSeriesUID, referenceStudyUID, SOPInstanceUID } = measurement;
const { referenceSeriesUID, referenceStudyUID, SOPInstanceUID, metadata } = measurement;
const instance = DicomMetadataStore.getInstance(
referenceStudyUID,
@@ -467,8 +463,12 @@ const connectMeasurementServiceToTools = ({
annotationUID: measurement.uid,
highlighted: false,
isLocked: false,
invalidated: false,
// This is used to force a re-render of the annotation to
// re-calculate cached stats since sometimes in SR we
// get empty cached stats
invalidated: true,
metadata: {
...metadata,
toolName: measurement.toolName,
FrameOfReferenceUID: measurement.FrameOfReferenceUID,
referencedImageId: imageId,
@@ -1,7 +1,7 @@
import React from 'react';
import { SegmentationTable } from '@ohif/ui-next';
import { useActiveViewportSegmentationRepresentations } from '../hooks/useActiveViewportSegmentationRepresentations';
import { metaData } from '@cornerstonejs/core';
import { metaData, cache } from '@cornerstonejs/core';
import { useSystem } from '@ohif/core/src';
export default function PanelSegmentation({ children }: withAppTypes) {
@@ -104,6 +104,26 @@ export default function PanelSegmentation({ children }: withAppTypes) {
return { segmentationId, isExportable: true };
}
// Check if any segments have anything drawn in any of the viewports
const hasAnySegmentData = (() => {
const imageIds = Labelmap.imageIds;
if (!imageIds?.length) return false;
for (const imageId of imageIds) {
const pixelData = cache.getImage(imageId)?.getPixelData();
if (!pixelData) continue;
for (let i = 0; i < pixelData.length; i++) {
if (pixelData[i] !== 0) return true;
}
}
return false;
})();
if (!hasAnySegmentData) {
return { segmentationId, isExportable: false };
}
const referencedImageIds = Labelmap.referencedImageIds;
const firstImageId = referencedImageIds[0];
const instance = metaData.get('instance', firstImageId);
@@ -9,30 +9,34 @@ import {
utilities as csUtils,
metaData,
} from '@cornerstonejs/core';
import { ViewportType } from '@cornerstonejs/core/enums';
import {
Enums as csToolsEnums,
segmentation as cstSegmentation,
Types as cstTypes,
} from '@cornerstonejs/tools';
import { PubSubService, Types as OHIFTypes } from '@ohif/core';
import i18n from '@ohif/i18n';
import { easeInOutBell, easeInOutBellRelative } from '../../utils/transitions';
import { mapROIContoursToRTStructData } from './RTSTRUCT/mapROIContoursToRTStructData';
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
import { addColorLUT } from '@cornerstonejs/tools/segmentation/addColorLUT';
import { getNextColorLUTIndex } from '@cornerstonejs/tools/segmentation/getNextColorLUTIndex';
import { Segment } from '@cornerstonejs/tools/types/SegmentationStateTypes';
import { ContourStyle, LabelmapStyle, SurfaceStyle } from '@cornerstonejs/tools/types';
import { ViewportType } from '@cornerstonejs/core/enums';
import { SegmentationPresentation, SegmentationPresentationItem } from '../../types/Presentation';
import { updateLabelmapSegmentationImageReferences } from '@cornerstonejs/tools/segmentation/updateLabelmapSegmentationImageReferences';
import { triggerSegmentationRepresentationModified } from '@cornerstonejs/tools/segmentation/triggerSegmentationEvents';
import { convertStackToVolumeLabelmap } from '@cornerstonejs/tools/segmentation/helpers/convertStackToVolumeLabelmap';
import { getLabelmapImageIds } from '@cornerstonejs/tools/segmentation';
import { VOLUME_LOADER_SCHEME } from '../../constants';
const LABELMAP = csToolsEnums.SegmentationRepresentations.Labelmap;
const CONTOUR = csToolsEnums.SegmentationRepresentations.Contour;
import { VOLUME_LOADER_SCHEME } from '../../constants';
import { mapROIContoursToRTStructData } from './RTSTRUCT/mapROIContoursToRTStructData';
import { SegmentationPresentation, SegmentationPresentationItem } from '../../types/Presentation';
import { EasingFunctionEnum, EasingFunctionMap } from '../../utils/transitions';
const {
Labelmap: LABELMAP,
Contour: CONTOUR,
Surface: SURFACE,
} = csToolsEnums.SegmentationRepresentations;
const {
getLabelmapImageIds,
helpers: { convertStackToVolumeLabelmap },
state: { addColorLUT, updateLabelmapSegmentationImageReferences },
triggerSegmentationEvents: { triggerSegmentationRepresentationModified },
} = cstSegmentation;
export type SegmentRepresentation = {
segmentIndex: number;
@@ -149,13 +153,11 @@ class SegmentationService extends PubSubService {
const representations = this.getSegmentationRepresentations(viewportId);
for (const representation of representations) {
const { segmentationId } = representation;
if (!representation) {
continue;
}
const { type } = representation;
const { segmentationId, type } = representation;
segmentationsMap.set(segmentationId, {
segmentationId,
@@ -212,7 +214,7 @@ class SegmentationService extends PubSubService {
viewportId: string,
specifier: {
segmentationId?: string;
type?: SegmentationRepresentations;
type?: csToolsEnums.SegmentationRepresentations;
} = {}
): SegmentationRepresentation[] {
// Get all representations for the viewportId
@@ -245,9 +247,19 @@ class SegmentationService extends PubSubService {
this._onSegmentationDataModifiedFromSource
);
eventTarget.removeEventListener(
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_MODIFIED,
this._onSegmentationRepresentationModifiedFromSource
);
eventTarget.removeEventListener(
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_ADDED,
this._onSegmentationModifiedFromSource
this._onSegmentationRepresentationModifiedFromSource
);
eventTarget.removeEventListener(
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_REMOVED,
this._onSegmentationRepresentationModifiedFromSource
);
eventTarget.removeEventListener(
@@ -283,11 +295,11 @@ class SegmentationService extends PubSubService {
const colorLUTIndex = this._segmentationIdToColorLUTIndexMap.get(segmentationId);
const defaultRepresentationType = csToolsEnums.SegmentationRepresentations.Labelmap;
const defaultRepresentationType = LABELMAP;
let representationTypeToUse = type || defaultRepresentationType;
let isConverted = false;
if (type === csToolsEnums.SegmentationRepresentations.Labelmap) {
if (representationTypeToUse === LABELMAP) {
const { isVolumeViewport, isVolumeSegmentation } = this.determineViewportAndSegmentationType(
csViewport,
segmentation
@@ -354,7 +366,7 @@ class SegmentationService extends PubSubService {
const derivedImages = await imageLoader.createAndCacheDerivedLabelmapImages(referenceImageIds);
const segs = this.getSegmentations();
const label = options.label || `Segmentation ${segs.length + 1}`;
const label = options?.label || `Segmentation ${segs.length + 1}`;
const segImageIds = derivedImages.map(image => image.imageId);
@@ -371,7 +383,7 @@ class SegmentationService extends PubSubService {
config: {
label,
segments:
options.segments && Object.keys(options.segments).length > 0
options?.segments && Object.keys(options.segments).length > 0
? options.segments
: {
1: {
@@ -393,7 +405,7 @@ class SegmentationService extends PubSubService {
segDisplaySet,
options: {
segmentationId?: string;
type: SegmentationRepresentations;
type: csToolsEnums.SegmentationRepresentations;
} = {
type: LABELMAP,
}
@@ -503,9 +515,7 @@ class SegmentationService extends PubSubService {
};
});
// get next color lut index
const colorLUTIndex = getNextColorLUTIndex();
addColorLUT(colorLUT, colorLUTIndex);
const colorLUTIndex = addColorLUT(colorLUT);
this._segmentationIdToColorLUTIndexMap.set(segmentationId, colorLUTIndex);
this._broadcastEvent(EVENTS.SEGMENTATION_LOADING_COMPLETE, {
@@ -540,7 +550,7 @@ class SegmentationService extends PubSubService {
rtDisplaySet,
options: {
segmentationId?: string;
type: SegmentationRepresentations;
type: csToolsEnums.SegmentationRepresentations;
} = {
type: CONTOUR,
}
@@ -574,10 +584,19 @@ class SegmentationService extends PubSubService {
// find the first image id that contains a referenced SOP instance UID
const firstSegmentedSliceImageId =
referencedImageIds?.find(imageId =>
referencedImageIdsWithGeometry.some(referencedId => imageId.includes(referencedId))
referencedImageIdsWithGeometry.some(referencedId =>
imageId.includes(referencedId as string)
)
) || null;
rtDisplaySet.firstSegmentedSliceImageId = firstSegmentedSliceImageId;
if (!structureSet.ROIContours?.length) {
throw new Error(
'The structureSet does not contain any ROIContours. Please ensure the structureSet is loaded first.'
);
}
// Map ROI contours to RT Struct Data
const allRTStructData = mapROIContoursToRTStructData(structureSet, rtDisplaySetUID);
@@ -600,12 +619,6 @@ class SegmentationService extends PubSubService {
},
};
if (!structureSet.ROIContours?.length) {
throw new Error(
'The structureSet does not contain any ROIContours. Please ensure the structureSet is loaded first.'
);
}
const segments: { [segmentIndex: string]: cstTypes.Segment } = {};
let segmentsCachedStats = {};
@@ -613,7 +626,9 @@ class SegmentationService extends PubSubService {
const colorLUT = [[0, 0, 0, 0]]; // First entry is transparent for index 0
// Process each segment similarly to the SEG function
for (const rtStructData of allRTStructData) {
for (let i = 0; i < allRTStructData.length; i++) {
const rtStructData = allRTStructData[i];
const { data, id, color, segmentIndex, geometryId, group } = rtStructData;
// Add the color to the colorLUT array
@@ -662,8 +677,7 @@ class SegmentationService extends PubSubService {
}
// Create and register the colorLUT
const colorLUTIndex = getNextColorLUTIndex();
addColorLUT(colorLUT, colorLUTIndex);
const colorLUTIndex = addColorLUT(colorLUT);
this._segmentationIdToColorLUTIndexMap.set(segmentationId, colorLUTIndex);
// Assign processed segments to segmentation config
@@ -760,7 +774,7 @@ class SegmentationService extends PubSubService {
public hasCustomStyles(specifier: {
viewportId: string;
segmentationId: string;
type: SegmentationRepresentations;
type: csToolsEnums.SegmentationRepresentations;
}): boolean {
return cstSegmentation.config.style.hasCustomStyle(specifier);
}
@@ -768,7 +782,7 @@ class SegmentationService extends PubSubService {
public getStyle = (specifier: {
viewportId: string;
segmentationId: string;
type: SegmentationRepresentations;
type: csToolsEnums.SegmentationRepresentations;
segmentIndex?: number;
}) => {
const style = cstSegmentation.config.style.getStyle(specifier);
@@ -778,12 +792,12 @@ class SegmentationService extends PubSubService {
public setStyle = (
specifier: {
type: SegmentationRepresentations;
type: csToolsEnums.SegmentationRepresentations;
viewportId?: string;
segmentationId?: string;
segmentIndex?: number;
},
style: LabelmapStyle | ContourStyle | SurfaceStyle
style: cstTypes.LabelmapStyle | cstTypes.ContourStyle | cstTypes.SurfaceStyle
) => {
cstSegmentation.config.style.setStyle(specifier, style);
};
@@ -901,7 +915,7 @@ class SegmentationService extends PubSubService {
segmentationId: string,
segmentIndex: number,
isVisible: boolean,
type?: SegmentationRepresentations
type?: csToolsEnums.SegmentationRepresentations
): void {
this._setSegmentVisibility(viewportId, segmentationId, segmentIndex, isVisible, type);
}
@@ -938,7 +952,7 @@ class SegmentationService extends PubSubService {
viewportId: string,
segmentationId: string,
segmentIndex: number,
type: SegmentationRepresentations
type: csToolsEnums.SegmentationRepresentations
): void {
const isVisible = cstSegmentation.config.visibility.getSegmentIndexVisibility(
viewportId,
@@ -1010,7 +1024,7 @@ class SegmentationService extends PubSubService {
public getLabelmapVolume(segmentationId: string) {
const csSegmentation = cstSegmentation.state.getSegmentation(segmentationId);
const labelmapData = csSegmentation.representationData[
SegmentationRepresentations.Labelmap
LABELMAP
] as cstTypes.LabelmapToolOperationDataVolume;
if (!labelmapData || !labelmapData.volumeId) {
@@ -1112,7 +1126,10 @@ class SegmentationService extends PubSubService {
*/
public toggleSegmentationRepresentationVisibility = (
viewportId: string,
{ segmentationId, type }: { segmentationId: string; type: SegmentationRepresentations }
{
segmentationId,
type,
}: { segmentationId: string; type: csToolsEnums.SegmentationRepresentations }
): void => {
this._toggleSegmentationRepresentationVisibility(viewportId, segmentationId, type);
};
@@ -1161,7 +1178,7 @@ class SegmentationService extends PubSubService {
viewportId: string,
specifier: {
segmentationId?: string;
type?: SegmentationRepresentations;
type?: csToolsEnums.SegmentationRepresentations;
} = {}
): void {
cstSegmentation.removeSegmentationRepresentations(viewportId, specifier);
@@ -1175,7 +1192,7 @@ class SegmentationService extends PubSubService {
highlightSegment = true,
animationLength = 750,
highlightHideOthers = false,
highlightFunctionType = 'ease-in-out' // todo: make animation functions configurable from outside
animationFunctionType: EasingFunctionEnum = EasingFunctionEnum.EASE_IN_OUT
): void {
const center = this._getSegmentCenter(segmentationId, segmentIndex);
if (!center) {
@@ -1201,7 +1218,8 @@ class SegmentationService extends PubSubService {
viewportId,
highlightAlpha,
animationLength,
highlightHideOthers
highlightHideOthers,
animationFunctionType
);
});
}
@@ -1213,7 +1231,7 @@ class SegmentationService extends PubSubService {
alpha = 0.9,
animationLength = 750,
hideOthers = true,
highlightFunctionType = 'ease-in-out'
animationFunctionType: EasingFunctionEnum = EasingFunctionEnum.EASE_IN_OUT
): void {
if (this.highlightIntervalId) {
clearInterval(this.highlightIntervalId);
@@ -1246,7 +1264,8 @@ class SegmentationService extends PubSubService {
segments,
viewportId,
animationLength,
representation
representation,
animationFunctionType
);
});
}
@@ -1271,7 +1290,7 @@ class SegmentationService extends PubSubService {
private _setSegmentationRepresentationVisibility(
viewportId: string,
segmentationId: string,
type: SegmentationRepresentations,
type: csToolsEnums.SegmentationRepresentations,
isVisible: boolean
): void {
const representations = this.getSegmentationRepresentations(viewportId, {
@@ -1331,14 +1350,17 @@ class SegmentationService extends PubSubService {
private async handleVolumeViewportCase(csViewport, segmentation, isVolumeSegmentation) {
if (csViewport.type === ViewportType.VOLUME_3D) {
return { representationTypeToUse: SegmentationRepresentations.Surface, isConverted: false };
return {
representationTypeToUse: SURFACE,
isConverted: false,
};
} else {
await this.handleVolumeViewport(
csViewport as csTypes.IVolumeViewport,
segmentation,
isVolumeSegmentation
);
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted: false };
return { representationTypeToUse: LABELMAP, isConverted: false };
}
}
@@ -1348,14 +1370,17 @@ class SegmentationService extends PubSubService {
isVolumeSegmentation: boolean,
viewportId: string,
segmentationId: string
): Promise<{ representationTypeToUse: SegmentationRepresentations; isConverted: boolean }> {
): Promise<{
representationTypeToUse: csToolsEnums.SegmentationRepresentations;
isConverted: boolean;
}> {
if (isVolumeSegmentation) {
const isConverted = await this.convertStackToVolumeViewport(csViewport);
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted };
return { representationTypeToUse: LABELMAP, isConverted };
}
if (updateLabelmapSegmentationImageReferences(viewportId, segmentationId)) {
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted: false };
return { representationTypeToUse: LABELMAP, isConverted: false };
}
const isConverted = await this.attemptStackToVolumeConversion(
@@ -1365,7 +1390,7 @@ class SegmentationService extends PubSubService {
segmentationId
);
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted };
return { representationTypeToUse: LABELMAP, isConverted };
}
private async _addSegmentationRepresentation(
@@ -1476,11 +1501,7 @@ class SegmentationService extends PubSubService {
segImage.FrameOfReferenceUID === frameOfReferenceUID
) {
const isConverted = await this.convertStackToVolumeViewport(viewport);
triggerSegmentationRepresentationModified(
viewportId,
segmentationId,
SegmentationRepresentations.Labelmap
);
triggerSegmentationRepresentationModified(viewportId, segmentationId, LABELMAP);
return isConverted;
}
@@ -1608,10 +1629,11 @@ class SegmentationService extends PubSubService {
segmentIndex: number,
alpha: number,
hideOthers: boolean,
segments: Segment[],
segments: cstTypes.Segment[],
viewportId: string,
animationLength: number,
representation: cstTypes.SegmentationRepresentation
representation: cstTypes.SegmentationRepresentation,
animationFunctionType: EasingFunctionEnum
) {
const { segmentationId } = representation;
const newSegmentSpecificConfig = {
@@ -1645,6 +1667,8 @@ class SegmentationService extends PubSubService {
const elapsed = timestamp - startTime;
const progress = Math.min(elapsed / animationLength, 1);
const easingFunction = EasingFunctionMap.get(animationFunctionType);
cstSegmentation.config.style.setStyle(
{
segmentationId,
@@ -1652,7 +1676,7 @@ class SegmentationService extends PubSubService {
type: LABELMAP,
},
{
fillAlpha: easeInOutBell(progress, fillAlpha),
fillAlpha: easingFunction(progress, fillAlpha),
}
);
@@ -1677,21 +1701,20 @@ class SegmentationService extends PubSubService {
segmentIndex: number,
alpha: number,
hideOthers: boolean,
segments: Segment[],
segments: cstTypes.Segment[],
viewportId: string,
animationLength: number,
representation: cstTypes.SegmentationRepresentation
representation: cstTypes.SegmentationRepresentation,
animationFunctionType: EasingFunctionEnum
) {
const { segmentationId } = representation;
const startTime = performance.now();
const prevStyle = cstSegmentation.config.style.getStyle({
type: CONTOUR,
}) as ContourStyle;
}) as cstTypes.ContourStyle;
const prevOutlineWidth = prevStyle.outlineWidth;
// make this configurable
const baseline = Math.max(prevOutlineWidth * 3.5, 5);
const animate = (currentTime: number) => {
const progress = (currentTime - startTime) / animationLength;
@@ -1700,7 +1723,8 @@ class SegmentationService extends PubSubService {
return;
}
const reversedProgress = easeInOutBellRelative(progress, baseline, prevOutlineWidth);
const OUTLINE_ANIMATION_SCALE_FACTOR = 5;
const easingFunction = EasingFunctionMap.get(animationFunctionType);
cstSegmentation.config.style.setStyle(
{
@@ -1709,7 +1733,7 @@ class SegmentationService extends PubSubService {
type: CONTOUR,
},
{
outlineWidth: reversedProgress,
outlineWidth: easingFunction(progress, prevOutlineWidth, OUTLINE_ANIMATION_SCALE_FACTOR),
}
);
@@ -1722,7 +1746,7 @@ class SegmentationService extends PubSubService {
private _toggleSegmentationRepresentationVisibility = (
viewportId: string,
segmentationId: string,
type: SegmentationRepresentations
type: csToolsEnums.SegmentationRepresentations
): void => {
const representations = this.getSegmentationRepresentations(viewportId, {
segmentationId,
@@ -1754,7 +1778,10 @@ class SegmentationService extends PubSubService {
return `${volumeLoaderSchema}:${displaySet.displaySetInstanceUID}`;
}
private _getSegmentCenter(segmentationId, segmentIndex) {
private _getSegmentCenter(
segmentationId: string,
segmentIndex: number
): { image?: csTypes.Point3; world: csTypes.Point3 } | undefined {
const segmentation = this.getSegmentation(segmentationId);
if (!segmentation) {
@@ -1765,19 +1792,17 @@ class SegmentationService extends PubSubService {
const { cachedStats } = segments[segmentIndex];
if (!cachedStats || !cachedStats?.center || !cachedStats?.namedStats?.center) {
return;
if (cachedStats?.center) {
const { center } = cachedStats;
return center as { image: csTypes.Point3; world: csTypes.Point3 };
}
const { center } = cachedStats;
if (!center) {
if (cachedStats?.namedStats?.center) {
return {
world: cachedStats.namedStats.center.value,
};
}
return center;
}
private _setSegmentLockedStatus(segmentationId: string, segmentIndex: number, isLocked: boolean) {
@@ -1789,7 +1814,7 @@ class SegmentationService extends PubSubService {
segmentationId: string,
segmentIndex: number,
isVisible: boolean,
type?: SegmentationRepresentations
type?: csToolsEnums.SegmentationRepresentations
) {
cstSegmentation.config.visibility.setSegmentIndexVisibility(
viewportId,
@@ -36,7 +36,6 @@ import { useLutPresentationStore } from '../../stores/useLutPresentationStore';
import { usePositionPresentationStore } from '../../stores/usePositionPresentationStore';
import { useSynchronizersStore } from '../../stores/useSynchronizersStore';
import { useSegmentationPresentationStore } from '../../stores/useSegmentationPresentationStore';
import { VOLUME_LOADER_SCHEME } from '../../constants';
const EVENTS = {
VIEWPORT_DATA_CHANGED: 'event::cornerstoneViewportService:viewportDataChanged',
@@ -47,6 +46,7 @@ const MIN_STACK_VIEWPORTS_TO_ENQUEUE_RESIZE = 12;
const MIN_VOLUME_VIEWPORTS_TO_ENQUEUE_RESIZE = 6;
export const WITH_NAVIGATION = { withNavigation: true, withOrientation: false };
export const WITH_ORIENTATION = { withNavigation: true, withOrientation: true };
/**
* Handles cornerstone viewport logic including enabling, disabling, and
@@ -417,6 +417,11 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
// and we would lose the presentation.
this.storePresentation({ viewportId: viewportInfo.getViewportId() });
// Todo: i don't like this here, move it
this.servicesManager.services.segmentationService.clearSegmentationRepresentations(
viewportInfo.getViewportId()
);
if (!viewportInfo) {
throw new Error('element is not enabled for the given viewportId');
}
@@ -551,10 +556,13 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
* was initiated.
* @return the viewportId that the measurement should be displayed in.
*/
public getViewportIdToJump(activeViewportId: string, metadata): string {
public findNavigationCompatibleViewportId(activeViewportId: string, metadata): string {
// First check if the active viewport can just be navigated to show the given item
const activeViewport = this.getCornerstoneViewport(activeViewportId);
if (activeViewport.isReferenceViewable(metadata, { withNavigation: true })) {
if (!activeViewport) {
console.warn('No active viewport found for', activeViewportId);
}
if (activeViewport?.isReferenceViewable(metadata, { withNavigation: true })) {
return activeViewportId;
}
@@ -570,7 +578,7 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
// No viewport is in the right display set/orientation to show this, so see if
// the active viewport could change orientations to show this
if (
activeViewport.isReferenceViewable(metadata, { withNavigation: true, withOrientation: true })
activeViewport?.isReferenceViewable(metadata, { withNavigation: true, withOrientation: true })
) {
return activeViewportId;
}
@@ -589,6 +597,86 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
return null;
}
/**
* Figures out which viewport to update when the viewport type needs to change.
* This may not be the active viewport if there is already a viewport showing
* the display set, but in the wrong orientation.
*
* The viewport will need to update the viewport type and/or display set to
* display the resulting data.
*
* The first choice will be a viewport already showing the correct display set,
* but showing it as a stack.
*
* Second choice is to see if there is a viewport already showing the right
* orientation for the image, but the wrong display set. This fixes the
* case where the user is in MPR and a viewport other than active should be
* the one to change to display the iamge.
*
* Final choice is to use the provide activeViewportId. This will cover
* changes to/from video and wsi viewports and other cases where no
* viewport is really even close to being able to display the measurement.
*/
public findUpdateableViewportConfiguration(activeViewportId: string, measurement) {
const { metadata, displaySetInstanceUID } = measurement;
const { volumeId, referencedImageId } = metadata;
const { displaySetService, viewportGridService } = this.servicesManager.services;
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
let { viewportType } = displaySet;
if (!viewportType) {
if (referencedImageId && !displaySet.isReconstructable) {
viewportType = csEnums.ViewportType.STACK;
} else if (volumeId) {
viewportType = 'volume';
}
}
// Find viewports that could be updated to be volumes to show this view
// That prefers a viewport already showing the right display set.
if (volumeId) {
for (const id of this.viewportsById.keys()) {
const viewport = this.getCornerstoneViewport(id);
if (viewport?.isReferenceViewable(metadata, { asVolume: true, withNavigation: true })) {
return {
viewportId: id,
displaySetInstanceUID,
viewportOptions: { viewportType },
};
}
}
}
// Find a viewport in the correct orientation showing a different display set
// which could be used to display the annotation.
const altMetadata = { ...metadata, volumeId: null, referencedImageId: null };
for (const id of this.viewportsById.keys()) {
const viewport = this.getCornerstoneViewport(id);
const viewportDisplaySetUID = viewportGridService.getDisplaySetsUIDsForViewport(id)?.[0];
if (!viewportDisplaySetUID || !viewport) {
continue;
}
if (volumeId) {
altMetadata.volumeId = viewportDisplaySetUID;
}
altMetadata.FrameOfReferenceUID = this._getFrameOfReferenceUID(viewportDisplaySetUID);
if (viewport.isReferenceViewable(altMetadata, { asVolume: true, withNavigation: true })) {
return {
viewportId: id,
displaySetInstanceUID,
viewportOptions: { viewportType },
};
}
}
// Just display in the active viewport
return {
viewportId: activeViewportId,
displaySetInstanceUID,
viewportOptions: { viewportType },
};
}
/**
* Sets the image data for the given viewport.
*/
@@ -626,7 +714,7 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
// is being used to navigate to the initial view position for measurement
// navigation and other navigation forcing specific views.
let initialImageIndexToUse =
presentations?.positionPresentation?.initialImageIndex ?? initialImageIndex;
presentations?.positionPresentation?.initialImageIndex ?? <number>initialImageIndex;
const { rotation, flipHorizontal, displayArea } = viewportInfo.getViewportOptions();
@@ -662,7 +750,11 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
initialImageIndexToUse = imageIds.indexOf(referencedImageId);
}
if (initialImageIndexToUse === undefined || initialImageIndexToUse === null) {
if (
initialImageIndexToUse === undefined ||
initialImageIndexToUse === null ||
initialImageIndexToUse < 0
) {
initialImageIndexToUse = this._getInitialImageIndexForViewport(viewportInfo, imageIds) || 0;
}
@@ -1085,8 +1177,8 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
const { dimensions, spacing } = imageVolume;
const slabThickness = Math.sqrt(
Math.pow(dimensions[0] * spacing[0], 2) +
Math.pow(dimensions[1] * spacing[1], 2) +
Math.pow(dimensions[2] * spacing[2], 2)
Math.pow(dimensions[1] * spacing[1], 2) +
Math.pow(dimensions[2] * spacing[2], 2)
);
return slabThickness;
@@ -1214,7 +1306,10 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
): void {
const viewRef = positionPresentation?.viewReference;
if (viewRef) {
if (viewport.isReferenceViewable(viewRef, WITH_NAVIGATION)) {
// The orientation can be updated here to navigate to the specified
// measurement or previous item, but this will not switch to volume
// or to stack from the other type
if (viewport.isReferenceViewable(viewRef, WITH_ORIENTATION)) {
viewport.setViewReference(viewRef);
} else {
console.warn('Unable to apply reference viewable', viewRef);
@@ -120,7 +120,7 @@ class DicomLoaderService {
const imageInstance = getImageInstance(dataset);
if (imageInstance) {
const imageId = getImageInstanceId(imageInstance);
let imageId = getImageInstanceId(imageInstance);
let getDicomDataMethod = fetchIt;
const loaderType = getImageLoaderType(imageId);
@@ -0,0 +1,46 @@
/**
* Calculates the center point and bounding box extent of a measurement based on its points.
* @param {Object} measurement - The measurement object containing points
* @param {Array<Array<number>>} measurement.points - Array of 3D points [x, y, z]
* @returns {Object} Object containing center and extent
* @returns {Array<number>} returns.center - The center point [x, y, z]
* @returns {Object} returns.extent - The bounding box extent with min and max points
*/
export const getCenterExtent = (measurement: { points?: number[][] }) => {
const { points } = measurement;
if (!points || !Array.isArray(points) || points.length === 0) {
// Return default values if no points are available
const defaultCenter: [number, number, number] = [0, 0, 0];
const defaultExtent = {
min: [0, 0, 0] as [number, number, number],
max: [0, 0, 0] as [number, number, number],
};
return { center: defaultCenter, extent: defaultExtent };
}
// Initialize min and max with the first point
const min: [number, number, number] = [...points[0]] as [number, number, number];
const max: [number, number, number] = [...points[0]] as [number, number, number];
// Find the bounding box by iterating through all points
for (let i = 1; i < points.length; i++) {
const point = points[i];
for (let j = 0; j < 3; j++) {
min[j] = Math.min(min[j], point[j]);
max[j] = Math.max(max[j], point[j]);
}
}
// Calculate the center point
const center: [number, number, number] = [
(min[0] + max[0]) / 2,
(min[1] + max[1]) / 2,
(min[2] + max[2]) / 2,
];
return {
center,
extent: { min, max },
};
};
@@ -9,6 +9,7 @@ import promptHydrationDialog, {
HydrationCallback,
HydrationSRResult,
} from './promptHydrationDialog';
import { getCenterExtent } from './getCenterExtent';
const utils = {
handleSegmentChange,
@@ -16,6 +17,7 @@ const utils = {
setupSegmentationDataModifiedHandler,
setupSegmentationModifiedHandler,
promptHydrationDialog,
getCenterExtent,
};
export type { HydrationDialogProps, HydrationCallback, HydrationSRResult };
@@ -0,0 +1,33 @@
import { getCenterExtent } from './getCenterExtent';
/**
* Determines if a measurement is within the current viewport extent.
* Uses the measurement's bounding box extent to efficiently check if the entire
* measurement fits within the viewport's visible area.
*
* @param {Object} viewport - The viewport object containing camera information
* @param {Object} measurement - The measurement object containing points to check
* @returns {boolean} True if the measurement extent is within the viewport, false otherwise
*/
export const isMeasurementWithinViewport = (viewport, measurement) => {
const camera = viewport.getCamera();
const { focalPoint, parallelScale } = camera;
// Get the measurement's bounding box extent
const { extent } = getCenterExtent(measurement);
const { min, max } = extent;
// Check if the entire bounding box fits within the viewport extent
// We need to check both the min and max corners of the bounding box
for (let i = 0; i < 3; i++) {
const minDistance = Math.abs(min[i] - focalPoint[i]);
const maxDistance = Math.abs(max[i] - focalPoint[i]);
// If either the min or max point is outside the viewport extent, return false
if (minDistance > parallelScale || maxDistance > parallelScale) {
return false;
}
}
return true; // The entire measurement extent is within the viewport
};
@@ -3,20 +3,17 @@ import { Enums } from '@cornerstonejs/core';
import OrientationAxis = Enums.OrientationAxis;
export const isReferenceViewable = ({
viewportId,
reference,
viewportOptions,
servicesManager,
}) => {
export const isReferenceViewable = (servicesManager, viewportId, reference, viewportOptions?) => {
const { cornerstoneViewportService, displaySetService } = servicesManager.services;
if (!viewportOptions) {
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
// we can make a customization for this to allow
// we can make a customization for this to allow specific settings
// The annotation can be seen either via navigation or by changing to a volume
const isViewable = viewport.isReferenceViewable(reference, {
withNavigation: true,
asVolume: true,
});
return isViewable;
@@ -75,7 +75,7 @@ const ArrowAnnotate = {
frameNumber: mappedAnnotations[0]?.frameNumber || 1,
toolName: metadata.toolName,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
label: data.text,
label: data.label,
displayText: displayText,
data: data.cachedStats,
type: getValueTypeFromToolType(toolName),
@@ -83,7 +83,7 @@ const Bidirectional = {
function getMappedAnnotations(annotation, displaySetService) {
const { metadata, data } = annotation;
const { cachedStats } = data;
const { cachedStats = {} } = data;
const { referencedImageId } = metadata;
const targets = Object.keys(cachedStats);
@@ -84,7 +84,7 @@ const CircleROI = {
function getMappedAnnotations(annotation, displaySetService) {
const { metadata, data } = annotation;
const { cachedStats } = data;
const { cachedStats={} } = data;
const { referencedImageId } = metadata;
const targets = Object.keys(cachedStats);
@@ -92,6 +92,11 @@ function getMappedAnnotations(annotation, displaySetService) {
const { metadata, data } = annotation;
const { cachedStats } = data;
const { referencedImageId } = metadata;
if( !cachedStats ) {
return;
}
const targets = Object.keys(cachedStats);
if (!targets.length) {
@@ -3,7 +3,6 @@ import { getIsLocked } from './utils/getIsLocked';
import { getIsVisible } from './utils/getIsVisible';
import getSOPInstanceAttributes from './utils/getSOPInstanceAttributes';
import { utils } from '@ohif/core';
import { config } from '@cornerstonejs/tools/annotation';
const Length = {
toAnnotation: measurement => {},
@@ -78,7 +77,6 @@ const Length = {
isLocked,
isVisible,
metadata,
// color,
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
referencedImageId,
@@ -95,6 +95,11 @@ function getMappedAnnotations(annotation, displaySetService) {
const { metadata, data } = annotation;
const { cachedStats } = data;
const { referencedImageId } = metadata;
if( !cachedStats ) {
return;
}
const targets = Object.keys(cachedStats);
if (!targets.length) {
@@ -211,9 +211,11 @@ function getDisplayText(mappedAnnotations, displaySet, customizationService) {
mappedAnnotations.forEach(mappedAnnotation => {
const { unit, max, SeriesNumber } = mappedAnnotation;
const maxStr = getStatisticDisplayString(max, unit, 'max');
if (Number.isFinite(max)) {
const maxStr = getStatisticDisplayString(max, unit, 'max');
displayText.primary.push(maxStr);
displayText.primary.push(maxStr);
}
displayText.secondary.push(`S: ${SeriesNumber}${instanceText}${frameText}`);
});
@@ -1,5 +1,36 @@
import * as cornerstone from '@cornerstonejs/core';
function getDisplaySet({ metadata, displaySetService }) {
const { volumeId } = metadata;
if( volumeId ) {
const displaySet = displaySetService.getDisplaySetsBy(displaySet =>
volumeId.includes(displaySet.uid)
)[0];
if( displaySet ) {
return displaySet;
}
console.warn("Unable to find volumeId", volumeId);
metadata.volumeId = null;
}
if (!metadata.FrameOfReferenceUID) {
throw new Error(
'No volumeId and no FrameOfReferenceUID provided. Could not find matching displaySet.'
);
}
const displaySet = Array.from(displaySetService.getDisplaySetCache().values()).find(
ds => ds.instance?.FrameOfReferenceUID === metadata.FrameOfReferenceUID
);
if (!displaySet) {
throw new Error('Could not find matching displaySet for the provided FrameOfReferenceUID.');
}
return displaySet;
}
/**
* It checks if the imageId is provided then it uses it to query
* the metadata and get the SOPInstanceUID, SeriesInstanceUID and StudyInstanceUID.
@@ -13,11 +44,7 @@ export default function getSOPInstanceAttributes(imageId, displaySetService, ann
}
const { metadata } = annotation;
const { volumeId } = metadata;
const displaySet = displaySetService.getDisplaySetsBy(displaySet =>
volumeId.includes(displaySet.uid)
)[0];
const displaySet = getDisplaySet({ metadata, displaySetService });
const { StudyInstanceUID, SeriesInstanceUID } = displaySet;
return {
@@ -16,9 +16,12 @@ export function setupSegmentationDataModifiedHandler({
const { unsubscribe: debouncedUnsubscribe } = segmentationService.subscribeDebounced(
segmentationService.EVENTS.SEGMENTATION_DATA_MODIFIED,
async ({ segmentationId }) => {
const disableUpdateSegmentationStats = customizationService.getCustomization('panelSegmentation.disableUpdateSegmentationStats');
const segmentation = segmentationService.getSegmentation(segmentationId);
if (!segmentation) {
if (!segmentation || disableUpdateSegmentationStats) {
return;
}
@@ -0,0 +1,367 @@
import { linear, ease, easeIn, easeOut, easeInOut, cubicBezier } from './transitions';
describe('Transitions Module', () => {
const EPSILON = 1e-6;
/**
* Helper function to check if two numbers are approximately equal
*/
const approxEqual = (actual: number, expected: number, tolerance = EPSILON): boolean => {
return Math.abs(actual - expected) < tolerance;
};
describe('Standard CSS Easing (Mode 1: no baseline)', () => {
describe('linear', () => {
it('should return 0 at timeProgress=0', () => {
expect(linear(0)).toBe(0);
});
it('should return 1 at timeProgress=1', () => {
expect(linear(1)).toBe(1);
});
it('should return timeProgress for linear progression', () => {
expect(linear(0.25)).toBe(0.25);
expect(linear(0.5)).toBe(0.5);
expect(linear(0.75)).toBe(0.75);
});
});
describe('easeInOut', () => {
it('should return 0 at timeProgress=0', () => {
expect(easeInOut(0)).toBe(0);
});
it('should return 1 at timeProgress=1', () => {
expect(easeInOut(1)).toBe(1);
});
it('should return 0.5 at timeProgress=0.5', () => {
const result = easeInOut(0.5);
expect(approxEqual(result, 0.5)).toBe(true);
});
it('should be slower at start than linear', () => {
const easedValue = easeInOut(0.2);
expect(easedValue).toBeLessThan(0.2);
});
it('should provide smoothing toward the end', () => {
const baseTime = 0.9;
const controlTimeProgressionDifference = 0.2;
const result1 = easeInOut(baseTime);
const result2 = easeInOut(baseTime - controlTimeProgressionDifference);
expect(result1 - result2).toBeLessThan(controlTimeProgressionDifference);
});
});
describe('easeIn', () => {
it('should return 0 at timeProgress=0', () => {
expect(easeIn(0)).toBe(0);
});
it('should return 1 at timeProgress=1', () => {
expect(easeIn(1)).toBe(1);
});
it('should be slower at start', () => {
const easedValue = easeIn(0.4);
expect(easedValue).toBeLessThan(0.4);
});
it('should accelerate toward the end', () => {
const baseTime = 0.9;
const controlTimeProgressionDifference = 0.2;
const result1 = easeIn(baseTime);
const result2 = easeIn(baseTime - controlTimeProgressionDifference);
expect(result1 - result2).toBeGreaterThan(controlTimeProgressionDifference);
});
});
describe('easeOut', () => {
it('should return 0 at timeProgress=0', () => {
expect(easeOut(0)).toBe(0);
});
it('should return 1 at timeProgress=1', () => {
expect(easeOut(1)).toBe(1);
});
it('should be faster at start', () => {
const easedValue = easeOut(0.4);
expect(easedValue).toBeGreaterThan(0.4);
});
it('should provide smoothing toward the end', () => {
const baseTime = 0.9;
const controlTimeProgressionDifference = 0.2;
const result1 = ease(baseTime);
const result2 = ease(baseTime - controlTimeProgressionDifference);
expect(result1 - result2).toBeLessThan(controlTimeProgressionDifference);
});
});
describe('ease', () => {
it('should return 0 at timeProgress=0', () => {
expect(ease(0)).toBe(0);
});
it('should return 1 at timeProgress=1', () => {
expect(ease(1)).toBe(1);
});
it('should provide significant growth at first half', () => {
const result = ease(0.5);
expect(result).toBeGreaterThan(0.75);
});
it('should provide smoothing toward the end', () => {
const baseTime = 0.9;
const controlTimeProgressionDifference = 0.2;
const result1 = ease(baseTime);
const result2 = ease(baseTime - controlTimeProgressionDifference);
expect(result1 - result2).toBeLessThan(controlTimeProgressionDifference);
});
});
});
describe('Baseline Bell-Curve (Mode 2: baseline only)', () => {
const baseline = 0.2;
describe('linear with baseline', () => {
it('should start and end at baseline', () => {
expect(linear(0, baseline)).toBe(baseline);
expect(linear(1, baseline)).toBe(baseline);
});
it('should peak at 1.0 at timeProgress=0.5', () => {
const result = linear(0.5, baseline);
expect(approxEqual(result, 1.0)).toBe(true);
});
it('should create symmetric bell curve', () => {
const quarterValue = linear(0.25, baseline);
const threeQuarterValue = linear(0.75, baseline);
expect(approxEqual(quarterValue, threeQuarterValue)).toBe(true);
});
it('should be between baseline and 1.0', () => {
for (let t = 0; t <= 1; t += 0.1) {
const result = linear(t, baseline);
expect(result).toBeGreaterThanOrEqual(baseline);
expect(result).toBeLessThanOrEqual(1.0);
}
});
});
describe('easeInOut with baseline', () => {
it('should start and end at baseline', () => {
expect(easeInOut(0, baseline)).toBe(baseline);
expect(easeInOut(1, baseline)).toBe(baseline);
});
it('should peak near 1.0 around timeProgress=0.5', () => {
const result = easeInOut(0.5, baseline);
expect(result).toBeGreaterThan(0.8);
expect(result).toBeLessThanOrEqual(1.0);
});
it('should create bell curve with easing', () => {
const quarterValue = easeInOut(0.25, baseline);
const threeQuarterValue = easeInOut(0.75, baseline);
expect(approxEqual(quarterValue, threeQuarterValue, 0.01)).toBe(true);
});
});
describe('all functions with baseline', () => {
const testBaseline = 0.3;
it('should all start and end at baseline', () => {
const functions = [linear, ease, easeIn, easeOut, easeInOut];
functions.forEach(fn => {
expect(fn(0, testBaseline)).toBe(testBaseline);
expect(fn(1, testBaseline)).toBe(testBaseline);
});
});
});
});
describe('Scaled Bell-Curve (Mode 3: baseline + scale)', () => {
const baseline = 2.0;
const scale = 3.0;
const expectedPeak = baseline * scale;
describe('linear with baseline and scale', () => {
it('should start and end at baseline', () => {
expect(linear(0, baseline, scale)).toBe(baseline);
expect(linear(1, baseline, scale)).toBe(baseline);
});
it('should peak at baseline*scale at timeProgress=0.5', () => {
const result = linear(0.5, baseline, scale);
expect(approxEqual(result, expectedPeak)).toBe(true);
});
it('should create symmetric scaled bell curve', () => {
const quarterValue = linear(0.25, baseline, scale);
const threeQuarterValue = linear(0.75, baseline, scale);
expect(approxEqual(quarterValue, threeQuarterValue)).toBe(true);
});
});
describe('easeInOut with baseline and scale', () => {
it('should start and end at baseline', () => {
expect(easeInOut(0, baseline, scale)).toBe(baseline);
expect(easeInOut(1, baseline, scale)).toBe(baseline);
});
it('should peak near baseline*scale around timeProgress=0.5', () => {
const result = easeInOut(0.5, baseline, scale);
expect(result).toBeGreaterThan(baseline + (expectedPeak - baseline) * 0.8);
expect(result).toBeLessThanOrEqual(expectedPeak);
});
});
describe('different scale values', () => {
it('should handle scale < 1 (shrinking)', () => {
const shrinkScale = 0.5;
const result = linear(0.5, 1.0, shrinkScale);
expect(approxEqual(result, 0.5)).toBe(true);
});
it('should handle scale > 1 (growing)', () => {
const growScale = 2.5;
const result = linear(0.5, 1.0, growScale);
expect(approxEqual(result, 2.5)).toBe(true);
});
it('should handle scale = 1 (baseline to baseline)', () => {
const result = linear(0.5, 0.5, 1);
expect(approxEqual(result, 0.5)).toBe(true);
});
});
});
describe('Edge Cases', () => {
describe('baseline = 0 behavior', () => {
it('should behave like standard easing when baseline=0', () => {
expect(linear(0.5, 0)).toBe(linear(0.5));
expect(easeInOut(0.5, 0)).toBe(easeInOut(0.5));
});
});
describe('extreme values', () => {
it('should handle negative baseline', () => {
const result = linear(0.5, -1.0, 2.0);
expect(approxEqual(result, -2.0)).toBe(true);
});
it('should handle large baseline values', () => {
const result = linear(0.5, 100, 1.5);
expect(approxEqual(result, 150)).toBe(true);
});
});
describe('timeProgress edge cases', () => {
it('should handle timeProgress < 0', () => {
expect(linear(-0.1)).toBe(0);
expect(easeInOut(-0.1, 0.2)).toBe(0.2);
});
it('should handle timeProgress > 1', () => {
expect(linear(1.1)).toBe(1);
expect(easeInOut(1.1, 0.2)).toBe(0.2);
});
});
});
describe('Mathematical Properties', () => {
describe('bell curve symmetry for symmetric cubic bezier functions', () => {
it('should be symmetric around timeProgress=0.5', () => {
const baseline = 0.1;
const scale = 2.0;
[linear, easeInOut].forEach(fn => {
for (let offset = 0.1; offset <= 0.4; offset += 0.1) {
const leftValue = fn(0.5 - offset, baseline, scale);
const rightValue = fn(0.5 + offset, baseline, scale);
expect(approxEqual(leftValue, rightValue, 0.01)).toBe(true);
}
});
});
});
describe('monotonicity in first half', () => {
it('should be non-decreasing from 0 to 0.5 for functions that grow under linear in first half', () => {
const baseline = 0.2;
[linear, easeIn, easeInOut].forEach(fn => {
let prevValue = fn(0, baseline);
for (let time = 0.1; time <= 0.5; time += 0.1) {
const currentValue = fn(time, baseline);
expect(currentValue).toBeGreaterThanOrEqual(prevValue - EPSILON);
prevValue = currentValue;
}
});
});
});
});
describe('Utility Functions', () => {
describe('cubicBezier', () => {
it('should create functions that return 0 at t=0 and 1 at t=1', () => {
const customEasing = cubicBezier(0.25, 0.1, 0.75, 0.9);
expect(customEasing(0)).toBe(0);
expect(customEasing(1)).toBe(1);
});
it('should throw error for invalid x values', () => {
expect(() => cubicBezier(-0.1, 0, 1, 1)).toThrow();
expect(() => cubicBezier(0, 0, 1.1, 1)).toThrow();
});
it('should fallback to binary search when Newton-Raphson fails due to small derivative', () => {
/**
* Create a cubic-bezier curve that has a very flat section (small derivative)
* This will cause Newton-Raphson to fail and use binary search fallback
* Using control points that create a nearly horizontal tangent
* Obs: Values obtained by imperative testing
*/
const problematicEasing = cubicBezier(0.98888, 0.00001, 0.00001, 0.98888);
/** Test a value in the problematic region where derivative is very small*/
const result = problematicEasing(0.5);
expect(typeof result).toBe('number');
expect(isNaN(result)).toBe(false);
expect(result).toBeGreaterThanOrEqual(0);
expect(result).toBeLessThanOrEqual(1);
});
});
});
describe('Performance Validation', () => {
it('should handle many rapid calls without issues', () => {
const startTime = performance.now();
for (let i = 0; i < 1000; i++) {
const t = i / 1000;
linear(t);
easeInOut(t, 0.1);
ease(t, 0.2, 1.5);
}
const endTime = performance.now();
expect(endTime - startTime).toBeLessThan(10);
});
});
});
+287 -50
View File
@@ -1,63 +1,300 @@
/**
* It is a bell curved function that uses ease in out quadratic for css
* transition timing function for each side of the curve.
*
* @param {number} x - The current time, in the range [0, 1].
* @param {number} baseline - The baseline value to start from and return to.
* @returns the value of the transition at time x.
*/
export function easeInOutBell(x: number, baseline: number): number {
const alpha = 1 - baseline;
/** Cubic Bezier Implementation */
// prettier-ignore
if (x < 1 / 4) {
return 4 * Math.pow(2 * x, 3) * alpha + baseline;
} else if (x < 1 / 2) {
return (1 - Math.pow(-4 * x + 2, 3) / 2) * alpha + baseline;
} else if (x < 3 / 4) {
return (1 - Math.pow(4 * x - 2, 3) / 2) * alpha + baseline;
} else {
return (- 4 * Math.pow(2 * x - 2, 3)) * alpha + baseline;
/**
* Finds the parameter t for a given x value on a cubic Bézier curve.
* Uses Newton's method first (fast), then falls back to binary search (reliable).
* Based on WebKit/Chromium's UnitBezier implementation.
*
* @param {number} targetX - The x value to find parameter t for
* @param {number} x1 - x-coordinate of first control point
* @param {number} x2 - x-coordinate of second control point
* @returns {number} The parameter t that gives the specified x value
*/
function solveCubicBezierX(targetX: number, x1: number, x2: number): number {
const epsilon = 1e-6;
// Pre-compute polynomial coefficients for performance
const cx = 3.0 * x1;
const bx = 3.0 * (x2 - x1) - cx;
const ax = 1.0 - cx - bx;
function sampleCurveX(t: number): number {
// Evaluate: ax*t³ + bx*t² + cx*t using Horner's rule
return ((ax * t + bx) * t + cx) * t;
}
function sampleCurveDerivativeX(t: number): number {
return (3.0 * ax * t + 2.0 * bx) * t + cx;
}
/**
* Newton's method - fast convergence with good initial guess
* Try this first as it's normally very fast
*/
function newtonRaphsonMethod(targetX: number): number | null {
let t = targetX;
for (let iteration = 0; iteration < 8; iteration++) {
const currentX = sampleCurveX(t);
const error = currentX - targetX;
if (Math.abs(error) < epsilon) {
return t;
}
const derivative = sampleCurveDerivativeX(t);
// Break if derivative is too small (avoid division by zero)
if (Math.abs(derivative) < epsilon) {
break;
}
// Newton-Raphson step: t_new = t_old - f(t_old) / f'(t_old)
t = t - error / derivative;
}
return null;
}
/**
* Binary search fallback - guaranteed to converge
* Use this when Newton's method fails
*/
function binarySearchFallback(targetX: number): number {
let lowerBound = 0.0;
let upperBound = 1.0;
let t = targetX;
while (lowerBound < upperBound) {
const currentX = sampleCurveX(t);
if (Math.abs(currentX - targetX) < epsilon) {
return t;
}
if (targetX > currentX) {
lowerBound = t;
} else {
upperBound = t;
}
t = (upperBound - lowerBound) * 0.5 + lowerBound;
}
return t;
}
const newtonResult = newtonRaphsonMethod(targetX);
if (newtonResult !== null) {
return newtonResult;
}
return binarySearchFallback(targetX);
}
/**
* A reversed bell curved function that starts from 1 and goes to baseline and
* come back to 1 again. It uses ease in out quadratic for css transition
* timing function for each side of the curve.
* Evaluates the Y coordinate of a cubic Bézier curve at parameter t.
* Optimized for CSS timing functions where P0=(0,0) and P3=(1,1).
* Uses pre-computed polynomial coefficients and Horner's rule for performance.
*
* @param {number} x - The current time, in the range [0, 1].
* @param {number} baseline - The baseline value to start from and return to.
* @returns the value of the transition at time x.
* @param {number} t - Parameter value along the curve, typically in [0, 1]
* @param {number} y1 - y-coordinate of first control point
* @param {number} y2 - y-coordinate of second control point
* @returns {number} The Y value of the curve at parameter t
*/
export function reverseEaseInOutBell(x: number, baseline: number): number {
const y = easeInOutBell(x, baseline);
return -y + 1 + baseline;
function sampleCurveY(t: number, y1: number, y2: number): number {
// Pre-compute polynomial coefficients for performance
const cy = 3.0 * y1;
const by = 3.0 * (y2 - y1) - cy;
const ay = 1.0 - cy - by;
// Evaluate: ay*t³ + by*t² + cy*t using Horner's rule
return ((ay * t + by) * t + cy) * t;
}
export function easeInOutBellRelative(
x: number,
baseline: number,
prevOutlineWidth: number
): number {
const range = baseline - prevOutlineWidth;
if (x < 1 / 4) {
return prevOutlineWidth + 4 * Math.pow(2 * x, 3) * range;
} else if (x < 1 / 2) {
return prevOutlineWidth + (1 - Math.pow(-4 * x + 2, 3) / 2) * range;
} else if (x < 3 / 4) {
return prevOutlineWidth + (1 - Math.pow(4 * x - 2, 3) / 2) * range;
} else {
return prevOutlineWidth + -4 * Math.pow(2 * x - 2, 3) * range;
/**
* Cubic Bézier easing function implementation following CSS specifications.
*
* A cubic Bézier curve is defined by four points: P0, P1, P2, and P3.
* In CSS animations, P0 is fixed at (0, 0) and P3 is fixed at (1, 1).
* This function allows you to specify the intermediate control points P1 and P2.
*
* @param {number} x1 - x-coordinate of the first control point P1 (must be in [0, 1])
* @param {number} y1 - y-coordinate of the first control point P1
* @param {number} x2 - x-coordinate of the second control point P2 (must be in [0, 1])
* @param {number} y2 - y-coordinate of the second control point P2
* @returns {function} A function that takes time t ∈ [0, 1] and returns the eased value
*/
export function cubicBezier(x1: number, y1: number, x2: number, y2: number) {
if (x1 < 0 || x1 > 1 || x2 < 0 || x2 > 1) {
throw new Error('x1 and x2 must be in the range [0, 1]');
}
return function (timeProgress: number): number {
if (timeProgress <= 0) return 0;
if (timeProgress >= 1) return 1;
if (x1 === y1 && x2 === y2) {
return timeProgress;
}
const curveParameter = solveCubicBezierX(timeProgress, x1, x2);
return sampleCurveY(curveParameter, y1, y2);
};
}
export function reverseEaseInOutBellRelative(
x: number,
baseline: number,
prevOutlineWidth: number
): number {
const y = easeInOutBellRelative(x, baseline, prevOutlineWidth);
return y;
/** Core Easing Functions */
/**
* Linear easing function - constant speed throughout the animation.
* Equivalent to CSS: cubic-bezier(0.0, 0.0, 1.0, 1.0)
*
* @param {number} timeProgress - The animation progress, in the range [0, 1].
* @returns {number} The linear eased value.
*/
const linearCore = cubicBezier(0.0, 0.0, 1.0, 1.0);
/**
* Ease-in easing function - starts slow and accelerates.
* Equivalent to CSS: cubic-bezier(0.42, 0, 1.0, 1.0)
*
* @param {number} timeProgress - The animation progress, in the range [0, 1].
* @returns {number} The eased value.
*/
const easeInCore = cubicBezier(0.42, 0, 1.0, 1.0);
/**
* Ease-out easing function - starts fast and decelerates.
* Equivalent to CSS: cubic-bezier(0, 0, 0.58, 1.0)
*
* @param {number} timeProgress - The animation progress, in the range [0, 1].
* @returns {number} The eased value.
*/
const easeOutCore = cubicBezier(0, 0, 0.58, 1.0);
/**
* Ease-in-out easing function - starts slow, accelerates, then decelerates.
* Equivalent to CSS: cubic-bezier(0.42, 0, 0.58, 1.0)
*
* @param {number} timeProgress - The animation progress, in the range [0, 1].
* @returns {number} The eased value.
*/
const easeInOutCore = cubicBezier(0.42, 0, 0.58, 1.0);
/**
* Standard ease easing function (CSS default).
* Equivalent to CSS: cubic-bezier(0.25, 0.1, 0.25, 1.0)
*
* @param {number} timeProgress - The animation progress, in the range [0, 1].
* @returns {number} The eased value.
*/
const easeCore = cubicBezier(0.25, 0.1, 0.25, 1.0);
/** Flexible Easing Function Factory */
/**
* Flexible factory function that creates easing functions with optional baseline and scale support.
* Provides bell-curve behavior: baseline → baseline*scale → baseline
*
* @param {Function} coreEasingFn - The core easing function to wrap
* @returns {Function} A function that accepts (timeProgress, baseline?, scale?) and provides flexible behavior
*/
function flexibleEasingFunctionFactory(coreEasingFn: (timeProgress: number) => number) {
return function (timeProgress: number, baseline: number = 0, scale?: number): number {
if (baseline === 0) {
return coreEasingFn(timeProgress);
}
const easedProgress = coreEasingFn(timeProgress);
const targetValue = scale ? baseline * scale : 1;
const range = targetValue - baseline;
// Create bell-curve: baseline → targetValue → baseline
const bellMultiplier = 1 - Math.abs(2 * easedProgress - 1);
return baseline + bellMultiplier * range;
};
}
/**
* Linear easing function with optional baseline and scale support.
* - No params: standard linear progression [0, 1]
* - With baseline only: bell-curve baseline → 1 → baseline
* - With baseline+scale: bell-curve baseline → baseline*scale → baseline
*
* @param {number} timeProgress - The animation progress, in the range [0, 1].
* @param {number} baseline - Optional baseline value (default: 0). Creates bell-curve effect.
* @param {number} scale - Optional scale multiplier (default: 1). Peak value = baseline * scale.
* @returns {number} The linear eased value.
*/
export const linear = flexibleEasingFunctionFactory(linearCore);
/**
* Standard ease easing function with optional baseline and scale support.
* - No params: standard ease progression [0, 1]
* - With baseline only: bell-curve baseline → 1 → baseline
* - With baseline+scale: bell-curve baseline → baseline*scale → baseline
*
* @param {number} timeProgress - The animation progress, in the range [0, 1].
* @param {number} baseline - Optional baseline value (default: 0). Creates bell-curve effect.
* @param {number} scale - Optional scale multiplier (default: 1). Peak value = baseline * scale.
* @returns {number} The eased value.
*/
export const ease = flexibleEasingFunctionFactory(easeCore);
/**
* Ease-in easing function with optional baseline and scale support.
* - No params: standard ease-in progression [0, 1]
* - With baseline only: bell-curve baseline → 1 → baseline
* - With baseline+scale: bell-curve baseline → baseline*scale → baseline
*
* @param {number} timeProgress - The animation progress, in the range [0, 1].
* @param {number} baseline - Optional baseline value (default: 0). Creates bell-curve effect.
* @param {number} scale - Optional scale multiplier (default: 1). Peak value = baseline * scale.
* @returns {number} The eased value.
*/
export const easeIn = flexibleEasingFunctionFactory(easeInCore);
/**
* Ease-out easing function with optional baseline and scale support.
* - No params: standard ease-out progression [0, 1]
* - With baseline only: bell-curve baseline → 1 → baseline
* - With baseline+scale: bell-curve baseline → baseline*scale → baseline
*
* @param {number} timeProgress - The animation progress, in the range [0, 1].
* @param {number} baseline - Optional baseline value (default: 0). Creates bell-curve effect.
* @param {number} scale - Optional scale multiplier (default: 1). Peak value = baseline * scale.
* @returns {number} The eased value.
*/
export const easeOut = flexibleEasingFunctionFactory(easeOutCore);
/**
* Ease-in-out easing function with optional baseline and scale support.
* - No params: standard ease-in-out progression [0, 1]
* - With baseline only: bell-curve baseline → 1 → baseline
* - With baseline+scale: bell-curve baseline → baseline*scale → baseline
*
* @param {number} timeProgress - The animation progress, in the range [0, 1].
* @param {number} baseline - Optional baseline value (default: 0). Creates bell-curve effect.
* @param {number} scale - Optional scale multiplier (default: 1). Peak value = baseline * scale.
* @returns {number} The eased value.
*/
export const easeInOut = flexibleEasingFunctionFactory(easeInOutCore);
/** Export interfaces */
export enum EasingFunctionEnum {
EASE = 'ease',
EASE_IN = 'ease-in',
EASE_OUT = 'ease-out',
EASE_IN_OUT = 'ease-in-out',
LINEAR = 'linear',
}
export const EasingFunctionMap = new Map([
[EasingFunctionEnum.EASE, ease],
[EasingFunctionEnum.EASE_IN, easeIn],
[EasingFunctionEnum.EASE_OUT, easeOut],
[EasingFunctionEnum.EASE_IN_OUT, easeInOut],
[EasingFunctionEnum.LINEAR, linear],
]);
+574
View File
@@ -3,6 +3,580 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
### Bug Fixes
* study browser mode for multiple studies ([#5457](https://github.com/OHIF/Viewers/issues/5457)) ([6a1df9d](https://github.com/OHIF/Viewers/commit/6a1df9de4ad3c10a4653f18e03aff6bda4962fd1))
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
### Bug Fixes
* **studyBrowserCustomization:** fix thumbnail menu item actions in study browser ([#5283](https://github.com/OHIF/Viewers/issues/5283)) ([2f28a0d](https://github.com/OHIF/Viewers/commit/2f28a0deab5e43f432bbd9b5989928c9b0450278))
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
### Bug Fixes
* **i18n:** Add and update i18n Translation for Toolbar Tool Names ([#5392](https://github.com/OHIF/Viewers/issues/5392)) ([7783d0f](https://github.com/OHIF/Viewers/commit/7783d0f558bbb7016c29513b6fe76ed069dbd75c))
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
### Bug Fixes
* Add seriesInstanceUID fallback for callByRetrieveAETitle ([#5332](https://github.com/OHIF/Viewers/issues/5332)) ([840b5d3](https://github.com/OHIF/Viewers/commit/840b5d37d15537abc38316d636da7c144e6d9223))
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
### Bug Fixes
* Guard series.instances in DicomJSONDataSource to prevent TypeError (OHI-2114) ([#5312](https://github.com/OHIF/Viewers/issues/5312)) ([f1d158b](https://github.com/OHIF/Viewers/commit/f1d158bbe81fd9f6052ce23c8588c9c93d76360c))
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-default
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.115...v3.11.0-beta.116) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.114...v3.11.0-beta.115) (2025-07-31)
### Features
* add support to scoord3d ([#5016](https://github.com/OHIF/Viewers/issues/5016)) ([735405a](https://github.com/OHIF/Viewers/commit/735405a8554c7ee6283faa83fc42ff8bb9ac34ff))
# [3.11.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.113...v3.11.0-beta.114) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.112...v3.11.0-beta.113) (2025-07-30)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.111...v3.11.0-beta.112) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.110...v3.11.0-beta.111) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.109...v3.11.0-beta.110) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.108...v3.11.0-beta.109) (2025-07-28)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.107...v3.11.0-beta.108) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.106...v3.11.0-beta.107) (2025-07-25)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.105...v3.11.0-beta.106) (2025-07-24)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.104...v3.11.0-beta.105) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.103...v3.11.0-beta.104) (2025-07-23)
### Bug Fixes
* issue introduced from PR 5022 ([#5223](https://github.com/OHIF/Viewers/issues/5223)) ([428b6ff](https://github.com/OHIF/Viewers/commit/428b6ffbe75d606a72548555ac0e365299b0de4f))
# [3.11.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.102...v3.11.0-beta.103) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.101...v3.11.0-beta.102) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.100...v3.11.0-beta.101) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.99...v3.11.0-beta.100) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.98...v3.11.0-beta.99) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.97...v3.11.0-beta.98) (2025-07-23)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.96...v3.11.0-beta.97) (2025-07-22)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.95...v3.11.0-beta.96) (2025-07-22)
### Features
* **segmentation:** Add customization for handling missing referencedDisplaySetInstanceUID for the SEG/RTSTRUCT. ([#4983](https://github.com/OHIF/Viewers/issues/4983)) ([12de7a8](https://github.com/OHIF/Viewers/commit/12de7a85c9330471d81f481de7bc65e60c1c4ab3))
# [3.11.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.94...v3.11.0-beta.95) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.93...v3.11.0-beta.94) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.92...v3.11.0-beta.93) (2025-07-21)
**Note:** Version bump only for package @ohif/extension-default
# [3.11.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.91...v3.11.0-beta.92) (2025-07-18)
### Bug Fixes
* **multimonitor:** Study browser more menu fixes ([#5208](https://github.com/OHIF/Viewers/issues/5208)) ([3d4ec31](https://github.com/OHIF/Viewers/commit/3d4ec3181d1c031600a1f76eb57a062f15de0ab9))
# [3.11.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.90...v3.11.0-beta.91) (2025-07-17)
### Bug Fixes
* image slices are displayed in reverse order, if we switch from common layout to 2D MPR ([#5022](https://github.com/OHIF/Viewers/issues/5022)) ([6a4ca70](https://github.com/OHIF/Viewers/commit/6a4ca7083623f21ae4c810507da0c4634bc10de9))
# [3.11.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.89...v3.11.0-beta.90) (2025-07-16)
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-default",
"version": "3.11.0-beta.90",
"version": "3.12.0-beta.41",
"description": "Common/default features and functionality for basic image viewing",
"author": "OHIF Core Team",
"license": "MIT",
@@ -34,9 +34,9 @@
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"peerDependencies": {
"@ohif/core": "3.11.0-beta.90",
"@ohif/i18n": "3.11.0-beta.90",
"dcmjs": "^0.42.0",
"@ohif/core": "3.12.0-beta.41",
"@ohif/i18n": "3.12.0-beta.41",
"dcmjs": "0.43.1",
"dicomweb-client": "^0.10.4",
"prop-types": "^15.6.2",
"react": "^18.3.1",
@@ -41,7 +41,7 @@ const getMenuItemsDefault = ({ commandsManager, items, ...props }: withAppTypes)
</DropdownMenuItem>
);
const MenuItemComponent = menuContent?.content || DefaultMenuItem;
const MenuItemComponent = menuContent ?? DefaultMenuItem;
return (
<DropdownMenuContent
@@ -262,17 +262,19 @@ function createDicomJSONApi(dicomJsonConfig) {
const { StudyInstanceUID, SeriesInstanceUID } = displaySet;
const study = findStudies('StudyInstanceUID', StudyInstanceUID)[0];
const series = study.series.find(s => s.SeriesInstanceUID === SeriesInstanceUID) || [];
const series = study.series.find(s => s.SeriesInstanceUID === SeriesInstanceUID) || {};
const instanceMap = new Map();
series.instances.forEach(instance => {
if (instance?.metadata?.SOPInstanceUID) {
const { metadata, url } = instance;
const existingInstances = instanceMap.get(metadata.SOPInstanceUID) || [];
existingInstances.push({ ...metadata, url });
instanceMap.set(metadata.SOPInstanceUID, existingInstances);
}
});
if (series.instances) {
series.instances.forEach(instance => {
if (instance?.metadata?.SOPInstanceUID) {
const { metadata, url } = instance;
const existingInstances = instanceMap.get(metadata.SOPInstanceUID) || [];
existingInstances.push({ ...metadata, url });
instanceMap.set(metadata.SOPInstanceUID, existingInstances);
}
});
}
displaySet.images.forEach(instance => {
const NumberOfFrames = instance.NumberOfFrames || 1;
@@ -25,12 +25,16 @@ export default function (wadoRoot, getAuthrorizationHeader) {
//Call a function when the state changes.
if (xhr.readyState == 4) {
switch (xhr.status) {
case 200:
case 204:
resolve(xhr.responseText);
break;
case 404:
reject('Your dataSource does not support reject functionality');
default:
reject(`Unexpected status code: ${xhr.status}`);
break;
}
}
};
@@ -22,7 +22,7 @@ const { DicomMetaDictionary, DicomDict } = dcmjs.data;
const { naturalizeDataset, denaturalizeDataset } = DicomMetaDictionary;
const ImplementationClassUID = '2.25.270695996825855179949881587723571202391.2.0.0';
const ImplementationVersionName = 'OHIF-VIEWER-2.0.0';
const ImplementationVersionName = 'OHIF-3.11.0';
const EXPLICIT_VR_LITTLE_ENDIAN = '1.2.840.10008.1.2.1';
const metadataProvider = classes.MetadataProvider;
@@ -35,9 +35,11 @@ function PanelStudyBrowser({
const [{ activeViewportId, viewports, isHangingProtocolLayout }] = useViewportGrid();
const [activeTabName, setActiveTabName] = useState(studyMode);
const [expandedStudyInstanceUIDs, setExpandedStudyInstanceUIDs] = useState([
...StudyInstanceUIDs,
]);
const [expandedStudyInstanceUIDs, setExpandedStudyInstanceUIDs] = useState(
studyMode === 'primary' && StudyInstanceUIDs.length > 0
? [StudyInstanceUIDs[0]]
: [...StudyInstanceUIDs]
);
const [hasLoadedViewports, setHasLoadedViewports] = useState(false);
const [studyDisplayList, setStudyDisplayList] = useState([]);
const [displaySets, setDisplaySets] = useState([]);
@@ -383,8 +385,6 @@ function PanelStudyBrowser({
// Set the activeTabName and expand the study
const thumbnailLocation = _findTabAndStudyOfDisplaySet(displaySetInstanceUID, tabs);
if (!thumbnailLocation) {
console.warn('jumpToThumbnail: displaySet thumbnail not found.');
return;
}
const { tabName, StudyInstanceUID } = thumbnailLocation;
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import { CommandsManager } from '@ohif/core';
import { LayoutSelector } from '@ohif/ui-next';
import { useTranslation } from 'react-i18next';
function ToolbarLayoutSelectorWithServices({
commandsManager,
@@ -13,6 +14,7 @@ function ToolbarLayoutSelectorWithServices({
...props
}) {
const { customizationService } = servicesManager.services;
const { t } = useTranslation('ToolbarLayoutSelector');
// Get the presets from the customization service
const commonPresets = customizationService?.getCustomization('layoutSelector.commonPresets') || [
@@ -135,14 +137,14 @@ function ToolbarLayoutSelectorWithServices({
onSelectionChange={handleSelectionChange}
{...props}
>
<LayoutSelector.Trigger tooltip="Change layout" />
<LayoutSelector.Trigger tooltip={t('Change layout')} />
<LayoutSelector.Content>
{/* Left side - Presets */}
{(commonPresets.length > 0 || advancedPresets.length > 0) && (
<div className="bg-popover flex flex-col gap-2.5 rounded-lg p-2">
{commonPresets.length > 0 && (
<>
<LayoutSelector.PresetSection title="Common">
<LayoutSelector.PresetSection title={t('Common')}>
{commonPresets.map((preset, index) => (
<LayoutSelector.Preset
key={`common-preset-${index}`}
@@ -157,7 +159,7 @@ function ToolbarLayoutSelectorWithServices({
)}
{advancedPresets.length > 0 && (
<LayoutSelector.PresetSection title="Advanced">
<LayoutSelector.PresetSection title={t('Advanced')}>
{advancedPresets.map((preset, index) => (
<LayoutSelector.Preset
key={`advanced-preset-${index}`}
@@ -175,14 +177,15 @@ function ToolbarLayoutSelectorWithServices({
{/* Right Side - Grid Layout */}
<div className="bg-muted flex flex-col gap-2.5 border-l-2 border-solid border-black p-2">
<div className="text-muted-foreground text-xs">Custom</div>
<div className="text-muted-foreground text-xs">{t('Custom')}</div>
<LayoutSelector.GridSelector
rows={rows}
columns={columns}
/>
<LayoutSelector.HelpText>
Hover to select <br />
rows and columns <br /> Click to apply
{t('Hover to select')} <br />
{t('rows and columns')} <br />
{t('Click to apply')}
</LayoutSelector.HelpText>
</div>
</LayoutSelector.Content>
Loaded 100 of 794 files, more files were not shown because too many files have changed in this diff. Show more