feat(data overlay): add foreground background control plus orientation change in the UI and add RTDOSE support (#5007)
This commit is contained in:
1 parent
c1fced0573
commit
cd4e6408bc
105 files changed
+3117
-788
No files matched your search
@@ -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.
|
||||
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user