feat(data overlay): add foreground background control plus orientation change in the UI and add RTDOSE support (#5007)

This commit is contained in:
Alireza authored and GitHub committed 2025-05-05 16:35:05 -04:00
1 parent c1fced0573
commit cd4e6408bc
105 files changed
+3117 -788

No files matched your search

+178
View File
@@ -0,0 +1,178 @@
---
id: add-viewport-icon
title: How to add a custom icon to the viewport corners
summary: Learn how to add a custom icon or dropdown to one of the viewport corners in OHIF.
---
# How to add a custom icon to the viewport corners
## Question
How can I add a custom icon or dropdown to one of the viewport corners in OHIF?
## Answer
OHIF provides a customizable viewport action menu system that allows you to add icons, buttons, or dropdowns to any of the four corners of a viewport (topLeft, topRight, bottomLeft, bottomRight). This is done through the `customizationService` and the viewport action corners API.
Here's a complete example that shows how to add a mode switch dropdown to the top-left corner of the viewport:
```tsx
import React from 'react';
import { Icons } from '@ohif/ui-next';
import { useSystem } from '@ohif/core';
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
Button,
} from '@ohif/ui-next';
// This is a complete, self-contained component that shows a dropdown menu
// for switching modes when clicked
function getModeSwitchMenu({ viewportId, element, location }) {
const ModeSwitchMenu = () => {
const { servicesManager } = useSystem();
const { router } = servicesManager.services;
const { viewportActionCornersService } = servicesManager.services;
const handleModeSwitch = (mode) => {
const currentStudyInstanceUID = router.query.StudyInstanceUIDs;
// Navigate to the selected mode with the current study
router.navigate(`/${mode}?StudyInstanceUIDs=${currentStudyInstanceUID}`);
};
// Get proper alignment based on the location
let align = 'center';
let side = 'bottom';
if (location !== undefined) {
const positioning = viewportActionCornersService.getAlignAndSide(location);
align = positioning.align;
side = positioning.side;
}
return (
<div className="flex justify-end">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
size="icon"
className="text-highlight"
>
<Icons.Tool />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent
className="min-w-[160px]"
align={align}
side={side}
sideOffset={5}
>
<DropdownMenuLabel className="-ml-1">Mode</DropdownMenuLabel>
<DropdownMenuItem onClick={() => handleModeSwitch('longitudinal')}>
Longitudinal
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleModeSwitch('segmentation')}>
Segmentation
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleModeSwitch('tmtv')}>
TMTV
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleModeSwitch('microscopy')}>
Microscopy
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
);
};
return <ModeSwitchMenu />;
}
// In your mode or extension, add this to the customizations
// This example shows how to add it in the onModeEnter lifecycle hook
function onModeEnter({ servicesManager }) {
const { customizationService } = servicesManager.services;
// Add the mode switch icon to the top-left corner of the viewport
customizationService.setCustomizations({
'viewportActionMenu.topLeft': {
// Use $push to add to existing items or $set to replace all items
$push: [
{
id: 'modeSwitch',
enabled: true,
component: getModeSwitchMenu,
},
],
},
});
}
```
## Key Concepts
1. **Location-based customization**: The viewport is divided into four corners identified by:
- `viewportActionMenu.topLeft`
- `viewportActionMenu.topRight`
- `viewportActionMenu.bottomLeft`
- `viewportActionMenu.bottomRight`
2. **Component structure**:
- `id` - A unique identifier for your component
- `enabled` - Boolean to control if the component should be displayed
- `component` - A function that returns a React component to render
3. **Component positioning**: The component's position within a corner is determined by its order in the array. Components are rendered in the order they appear.
4. **Dropdown positioning**: Use the `viewportActionCornersService.getAlignAndSide()` method to get the correct alignment for your dropdown menu based on its location.
## Adding Multiple Components
If you want to add multiple components to the same corner or different corners, you can do it in a single customization:
```js
customizationService.setCustomizations({
'viewportActionMenu.topLeft': {
$push: [
{
id: 'modeSwitch',
enabled: true,
component: getModeSwitchMenu,
},
],
},
'viewportActionMenu.topRight': {
$push: [
{
id: 'anotherComponent',
enabled: true,
component: getAnotherComponent,
},
],
},
});
```
## Replacing Existing Components
If you want to replace all components in a corner instead of adding to them, use `$set` instead of `$push`:
```js
customizationService.setCustomizations({
'viewportActionMenu.topLeft': {
$set: [
{
id: 'modeSwitch',
enabled: true,
component: getModeSwitchMenu,
},
// This will be the only components in the top-left corner
],
},
});
```
Remember that this customization will affect all viewports in the active mode. If you need different behavior for different viewports, you should check the `viewportId` parameter in your component's logic.
+1
View File
@@ -6,6 +6,7 @@ summary: Technical explanations and solutions for OHIF Viewer implementation cha
# Technical FAQ
* [How to add a custom icon to the viewport corners](./add-viewport-icon.md)
## Viewer opens but does not show any thumbnails
@@ -0,0 +1,22 @@
---
sidebar_position: 1
sidebar_label: 3.10 -> 3.11 beta
---
# Migration Guide
This guide provides information about migrating from OHIF version 3.10 to version 3.11.
## General
`viewportActionMenu.segmentationOverlay` is renamed to `viewportActionMenu.dataOverlay`
as it handles now both segmentation and data overlay.
## Viewport Action Menu Customization
The structure for defining viewport action menu customizations has changed. See the [Viewport Action Menu](./viewport-action-menu.md) migration guide for details.
## updateStoredPositionPresentation
now uses displaySetInstanceUIDs instead of displaySetInstanceUID.
@@ -0,0 +1,102 @@
---
sidebar_position: 2
sidebar_label: Viewport Action Menu
summary: Migration guide for OHIF 3.11's viewport action menu customization changes, including the transition from individual item configurations to location-based arrays and the removal of index priorities.
---
# Viewport Action Menu Customization
In OHIF 3.11, we've redesigned how viewport action menu customizations are defined to make them more intuitive and organized by location.
## Changes
Previously, viewport action menu customizations were defined with individual item configurations that specified location and priority:
```ts
export default {
'viewportActionMenu.orientationMenu': {
enabled: true,
location: viewportActionCornersService.LOCATIONS.topLeft,
indexPriority: 1,
},
'viewportActionMenu.dataOverlay': {
enabled: true,
location: viewportActionCornersService.LOCATIONS.topLeft,
indexPriority: 2,
},
// ...
};
```
Now, viewport action menu customizations are organized by location, with each location having its own customization ID:
```ts
export default {
'viewportActionMenu.topLeft': [
{
id: 'orientationMenu',
enabled: true,
},
{
id: 'dataOverlay',
enabled: true,
},
{
id: 'windowLevelActionMenu',
enabled: true,
},
],
'viewportActionMenu.topRight': [],
'viewportActionMenu.bottomLeft': [],
'viewportActionMenu.bottomRight': [],
};
```
## Migration Steps
1. Reorganize your viewport action menu customizations by using location-based customization IDs (`viewportActionMenu.topLeft`, `viewportActionMenu.topRight`, etc.).
2. For each component, move it into the appropriate location array.
3. Replace the component key with an `id` property that doesn't include the prefix (just use `orientationMenu` instead of `viewportActionMenu.orientationMenu`).
4. Remove the `location` property (since it's now implied by the customization ID).
5. Remove the `indexPriority` property (order in the array now determines display order).
6. For each component, provide a `component` function that returns the component instance.
## Component Rendering
Component rendering logic is now included directly in the item configuration via a `component` function:
```ts
const createOrientationMenu = ({ viewportId, element, location }) => {
return getViewportOrientationMenu({
viewportId,
element,
location,
});
};
const createDataOverlay = ({ viewportId, element, displaySets, location }) => {
return getViewportDataOverlaySettingsMenu({
viewportId,
element,
displaySets,
location,
});
};
export default {
'viewportActionMenu.topLeft': [
{
id: 'orientationMenu',
enabled: true,
component: createOrientationMenu,
},
{
id: 'dataOverlay',
enabled: true,
component: createDataOverlay,
},
// other components...
],
// other locations...
};
```
@@ -1,6 +1,6 @@
---
sidebar_position: 1
sidebar_label: 3.9 -> 3.10 beta
sidebar_label: 3.9 -> 3.10
title: Migration Guide from 3.9 to 3.10 beta
summary: Migration guide for upgrading from OHIF 3.9 to 3.10 beta, covering general changes, customization service improvements, UI component upgrades, command handling, hotkey updates, routing changes, and testing strategies.
---
@@ -937,8 +937,8 @@ window.config = {
`,
},
{
id: 'viewportActionMenu.segmentationOverlay',
description: 'Configures the display and location of the segmentation overlay in the viewport.',
id: 'viewportActionMenu.dataOverlay',
description: 'Configures the display and location of the data overlay in the viewport.',
image: segmentationOverlay,
default: null,
configuration: `
@@ -946,7 +946,7 @@ window.config = {
// rest of window config
customizationService: [
{
'viewportActionMenu.segmentationOverlay': {
'viewportActionMenu.dataOverlay': {
$merge: {
enabled: true,
location: 1, // Set the location of the overlay in the viewport.