feat(RT): add dicom RT support via volume viewports (#3310)
* feat: initial RT support * make the segmentation service work with representation data * feat: make segmentation service work with representations * fix rtss vis * fix: rt hydration * fix the rendering of rt names * fix imports * refactor: Modify status and click handling for hydration of RTStructures Modify status and click handling for hydration of RTStructures by renaming `onPillClick` to `onStatusClick` in `OHIFCornerstoneRTViewport.tsx` and `_getStatusComponent.tsx` files. Also, update initial segmentation configurations in `PanelSegmentation.tsx` and simplify configuration changes and values for segmentation service in `SegmentationService.ts`. Finally, remove console debug in `CornerstoneViewportService.ts`. * wip for highlighting contours * refactor rt displayset code * review code update * update cornerstone dependencies * refactor: Update license year, version number, and minor code cleanup This commit updates the license year in several files, updates the version number in package.json, and contains minor code cleanup in two files. * add bulkdataURI retrieve for RT * fix package version * apply review comments * apply review comments * apply review comments * feat(panels): refactor and streamline segmentation configuration and inputs Rewrote state hooks and streamlined the configuration input for `PanelSegmentation` to be more verbose and reusable. Included several new input types, including the `InputRange` component which now shows a fixed floating value based on the step provided. The `SegmentationConfig` component now works with dynamic values controlled by `initialConfig`. These changes should improve function usability and make the code more maintainable going forward. * fix various bugs * fix contour delete by upgrade cs3d version * feat(viewport, inputNumber, segmentationConfig, orthanc): Implement minimum and maximum values for input number components, and useBulkDataURI for Orthanc configuration. Compare measurement view planes with absolute viewport view planes in Cornerstone viewport. * update yarn lock
This commit is contained in:
1 parent
69d8e6a191
commit
66863281c4
60 files changed
+2488
-678
No files matched your search
@@ -1,7 +1,16 @@
|
||||
import guid from '../utils/guid.js';
|
||||
import { Vector3 } from 'cornerstone-math';
|
||||
|
||||
const OBJECT = 'object';
|
||||
type Attributes = Record<string, unknown>;
|
||||
type Image = {
|
||||
StudyInstanceUID?: string;
|
||||
getData(): {
|
||||
metadata: {
|
||||
ImagePositionPatient: number[];
|
||||
ImageOrientationPatient: number[];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* This class defines an ImageSet object which will be used across the viewer. This object represents
|
||||
@@ -10,8 +19,14 @@ const OBJECT = 'object';
|
||||
* indiscriminately, but this should be changed).
|
||||
*/
|
||||
class ImageSet {
|
||||
constructor(images) {
|
||||
if (Array.isArray(images) !== true) {
|
||||
images: Image[];
|
||||
uid: string;
|
||||
instances: Image[];
|
||||
instance?: Image;
|
||||
StudyInstanceUID?: string;
|
||||
|
||||
constructor(images: Image[]) {
|
||||
if (!Array.isArray(images)) {
|
||||
throw new Error('ImageSet expects an array of images');
|
||||
}
|
||||
|
||||
@@ -36,41 +51,39 @@ class ImageSet {
|
||||
this.StudyInstanceUID = this.instance?.StudyInstanceUID;
|
||||
}
|
||||
|
||||
getUID() {
|
||||
load: () => Promise<void>;
|
||||
|
||||
getUID(): string {
|
||||
return this.uid;
|
||||
}
|
||||
|
||||
setAttribute(attribute, value) {
|
||||
setAttribute(attribute: string, value: unknown): void {
|
||||
this[attribute] = value;
|
||||
}
|
||||
|
||||
getAttribute(attribute) {
|
||||
getAttribute(attribute: string): unknown {
|
||||
return this[attribute];
|
||||
}
|
||||
|
||||
setAttributes(attributes) {
|
||||
if (typeof attributes === OBJECT && attributes !== null) {
|
||||
const imageSet = this,
|
||||
hasOwn = Object.prototype.hasOwnProperty;
|
||||
for (let attribute in attributes) {
|
||||
if (hasOwn.call(attributes, attribute)) {
|
||||
imageSet[attribute] = attributes[attribute];
|
||||
}
|
||||
setAttributes(attributes: Attributes): void {
|
||||
if (typeof attributes === 'object' && attributes !== null) {
|
||||
for (const [attribute, value] of Object.entries(attributes)) {
|
||||
this[attribute] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getNumImages = () => this.images.length;
|
||||
getNumImages = (): number => this.images.length;
|
||||
|
||||
getImage(index) {
|
||||
getImage(index: number): Image {
|
||||
return this.images[index];
|
||||
}
|
||||
|
||||
sortBy(sortingCallback) {
|
||||
sortBy(sortingCallback: (a: Image, b: Image) => number): Image[] {
|
||||
return this.images.sort(sortingCallback);
|
||||
}
|
||||
|
||||
sortByImagePositionPatient() {
|
||||
sortByImagePositionPatient(): void {
|
||||
const images = this.images;
|
||||
const referenceImagePositionPatient = _getImagePositionPatient(images[0]);
|
||||
|
||||
@@ -94,7 +107,7 @@ class ImageSet {
|
||||
)
|
||||
);
|
||||
|
||||
const distanceImagePairs = images.map(function(image) {
|
||||
const distanceImagePairs = images.map(function(image: Image) {
|
||||
const ippVec = new Vector3(..._getImagePositionPatient(image));
|
||||
const positionVector = refIppVec.clone().sub(ippVec);
|
||||
const distance = positionVector.dot(scanAxisNormal);
|
||||
@@ -41,6 +41,7 @@ export interface Extension {
|
||||
getCommandsModule?: (p: ExtensionParams) => CommandsModule;
|
||||
getViewportModule?: (p: ExtensionParams) => unknown;
|
||||
getUtilityModule?: (p: ExtensionParams) => unknown;
|
||||
getCustomizationModule?: (p: ExtensionParams) => unknown;
|
||||
onModeEnter?: () => void;
|
||||
onModeExit?: () => void;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* RGB color type
|
||||
*/
|
||||
export type RGB = [number, number, number];
|
||||
@@ -12,6 +12,7 @@ export * from './Command';
|
||||
export * from './StudyMetadata';
|
||||
export * from './PanelModule';
|
||||
export * from './IPubSub';
|
||||
export * from './Color';
|
||||
|
||||
/**
|
||||
* Export the types used within the various services and managers, but
|
||||
|
||||
@@ -25,8 +25,8 @@ There are seven events that get publish in `MeasurementService`:
|
||||
| SEGMENTATION_ADDED | Fires when a new segmentation is added to OHIF |
|
||||
| SEGMENTATION_REMOVED | Fires when a segmentation is removed from OHIF |
|
||||
| SEGMENTATION_CONFIGURATION_CHANGED | Fires when a segmentation configuration is changed |
|
||||
| SEGMENT_PIXEL_DATA_CREATED | Fires when a segment group adds its pixel data to the volume |
|
||||
| SEGMENTATION_PIXEL_DATA_CREATED | Fires when the full segmentation volume is filled with its segments |
|
||||
| SEGMENT_LOADING_COMPLETE | Fires when a segment group adds its pixel data to the volume |
|
||||
| SEGMENTATION_LOADING_COMPLETE | Fires when the full segmentation volume is filled with its segments |
|
||||
|
||||
|
||||
## API
|
||||
|
||||
@@ -19,37 +19,60 @@ const sizesClasses = {
|
||||
const InputNumber: React.FC<{
|
||||
value: number;
|
||||
onChange: (value) => void;
|
||||
minValue?: number;
|
||||
maxValue?: number;
|
||||
step: number;
|
||||
size?: string;
|
||||
className?: string;
|
||||
}> = ({ value, onChange, step = 1, className, size = 'sm' }) => {
|
||||
}> = ({
|
||||
value,
|
||||
onChange,
|
||||
step = 1,
|
||||
className,
|
||||
size = 'sm',
|
||||
minValue = 0,
|
||||
maxValue = 100,
|
||||
}) => {
|
||||
const [numberValue, setNumberValue] = useState(value);
|
||||
|
||||
const handleMinMax = useCallback(
|
||||
(value: number) => {
|
||||
if (value > maxValue) {
|
||||
return maxValue;
|
||||
} else if (value < minValue) {
|
||||
return minValue;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
},
|
||||
[maxValue, minValue]
|
||||
);
|
||||
|
||||
const handleChange = useCallback(
|
||||
e => {
|
||||
const numberValue = e.target.value;
|
||||
const numberValue = handleMinMax(Number(e.target.value));
|
||||
setNumberValue(numberValue);
|
||||
onChange(numberValue);
|
||||
},
|
||||
[onChange, setNumberValue]
|
||||
[onChange, setNumberValue, handleMinMax]
|
||||
);
|
||||
|
||||
const handleIncrement = useCallback(
|
||||
e => {
|
||||
const newNum = Number(numberValue) + step;
|
||||
const newNum = handleMinMax(Number(numberValue) + step);
|
||||
setNumberValue(newNum);
|
||||
onChange(newNum);
|
||||
},
|
||||
[onChange, setNumberValue, step, numberValue]
|
||||
[onChange, setNumberValue, step, numberValue, handleMinMax]
|
||||
);
|
||||
|
||||
const handleDecrement = useCallback(
|
||||
e => {
|
||||
const newNum = Number(numberValue) - step;
|
||||
const newNum = handleMinMax(Number(numberValue) - step);
|
||||
setNumberValue(newNum);
|
||||
onChange(newNum);
|
||||
},
|
||||
[onChange, setNumberValue, step, numberValue]
|
||||
[onChange, setNumberValue, step, numberValue, handleMinMax]
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -54,6 +54,9 @@ const InputRange: React.FC<{
|
||||
const rangeValuePercentage =
|
||||
((rangeValue - minValue) / (maxValue - minValue)) * 100;
|
||||
|
||||
const rangeValueForStr =
|
||||
step >= 1 ? rangeValue.toFixed(0) : rangeValue.toFixed(1);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex items-center cursor-pointer space-x-1 ${
|
||||
@@ -82,7 +85,7 @@ const InputRange: React.FC<{
|
||||
component="p"
|
||||
className={classNames('w-8', labelClassName ?? 'text-white')}
|
||||
>
|
||||
{rangeValue}
|
||||
{rangeValueForStr}
|
||||
{unit}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
|
||||
import LoadingIndicatorProgress from '../LoadingIndicatorProgress';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
totalNumbers: number | null;
|
||||
percentComplete: number | null;
|
||||
loadingText?: string;
|
||||
targetText?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A React component that renders a loading indicator but accepts a totalNumbers
|
||||
* and percentComplete to display a more detailed message.
|
||||
*/
|
||||
function LoadingIndicatorTotalPercent({
|
||||
className,
|
||||
totalNumbers,
|
||||
percentComplete,
|
||||
loadingText = 'Loading...',
|
||||
targetText = 'segments',
|
||||
}: Props): JSX.Element {
|
||||
percentComplete = percentComplete !== null ? percentComplete : null;
|
||||
|
||||
const progress = percentComplete !== null ? percentComplete : null;
|
||||
const totalNumbersText = totalNumbers !== null ? `${totalNumbers}` : '';
|
||||
const numTargetsLoadedText =
|
||||
percentComplete !== null
|
||||
? Math.floor((percentComplete * totalNumbers) / 100)
|
||||
: '';
|
||||
|
||||
const textBlock = !totalNumbers ? (
|
||||
<div className="text-white text-sm">{loadingText}</div>
|
||||
) : (
|
||||
<div className="text-white text-sm flex items-baseline space-x-1">
|
||||
<div>Loaded</div>
|
||||
<div>{numTargetsLoadedText}</div>
|
||||
<div>of</div>
|
||||
<div>{totalNumbersText}</div>
|
||||
<div>{targetText}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<LoadingIndicatorProgress
|
||||
className={className}
|
||||
progress={progress}
|
||||
textBlock={textBlock}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default LoadingIndicatorTotalPercent;
|
||||
@@ -0,0 +1,2 @@
|
||||
import LoadingIndicatorTotalPercent from './LoadingIndicatorTotalPercent';
|
||||
export default LoadingIndicatorTotalPercent;
|
||||
@@ -1,27 +1,15 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Icon, InputRange, CheckBox, InputNumber } from '../';
|
||||
import classNames from 'classnames';
|
||||
import { reducer } from './segmentationConfigReducer';
|
||||
|
||||
const ActiveSegmentationConfig = ({
|
||||
config,
|
||||
dispatch,
|
||||
setRenderOutline,
|
||||
setOutlineOpacityActive,
|
||||
setOutlineWidthActive,
|
||||
setRenderFill,
|
||||
setFillAlpha,
|
||||
usePercentage,
|
||||
}) => {
|
||||
const [
|
||||
useOutlineOpacityPercentage,
|
||||
setUseOutlineOpacityPercentage,
|
||||
] = useState(usePercentage);
|
||||
|
||||
const [useFillAlphaPercentage, setUseFillAlphaPercentage] = useState(
|
||||
usePercentage
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex justify-between text-[12px] pt-[13px] px-2">
|
||||
<div className="flex flex-col items-start">
|
||||
@@ -31,32 +19,14 @@ const ActiveSegmentationConfig = ({
|
||||
checked={config.renderOutline}
|
||||
labelClassName="text-[12px] pl-1 pt-1"
|
||||
className="mb-[9px]"
|
||||
onChange={value => {
|
||||
dispatch({
|
||||
type: 'RENDER_OUTLINE',
|
||||
payload: {
|
||||
value,
|
||||
},
|
||||
});
|
||||
|
||||
setRenderOutline(value);
|
||||
}}
|
||||
onChange={setRenderOutline}
|
||||
/>
|
||||
<CheckBox
|
||||
label="Fill"
|
||||
checked={config.renderFill}
|
||||
labelClassName="text-[12px] pl-1 pt-1"
|
||||
className="mb-[9px]"
|
||||
onChange={value => {
|
||||
dispatch({
|
||||
type: 'RENDER_FILL',
|
||||
payload: {
|
||||
value,
|
||||
},
|
||||
});
|
||||
|
||||
setRenderFill(value);
|
||||
}}
|
||||
onChange={setRenderFill}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -64,23 +34,9 @@ const ActiveSegmentationConfig = ({
|
||||
<div className="text-[#b3b3b3] text-[10px] mb-[12px]">Opacity</div>
|
||||
<InputRange
|
||||
minValue={0}
|
||||
maxValue={usePercentage ? 100 : 1}
|
||||
value={
|
||||
useOutlineOpacityPercentage
|
||||
? config.outlineOpacity * 100
|
||||
: config.outlineOpacity
|
||||
}
|
||||
onChange={value => {
|
||||
setUseOutlineOpacityPercentage(false);
|
||||
dispatch({
|
||||
type: 'SET_OUTLINE_OPACITY',
|
||||
payload: {
|
||||
value: value,
|
||||
},
|
||||
});
|
||||
|
||||
setOutlineOpacityActive(value);
|
||||
}}
|
||||
maxValue={100}
|
||||
value={config.outlineOpacity * 100}
|
||||
onChange={setOutlineOpacityActive}
|
||||
step={1}
|
||||
containerClassName="mt-[4px] mb-[9px]"
|
||||
inputClassName="w-[64px]"
|
||||
@@ -89,21 +45,9 @@ const ActiveSegmentationConfig = ({
|
||||
/>
|
||||
<InputRange
|
||||
minValue={0}
|
||||
maxValue={usePercentage ? 100 : 1}
|
||||
value={
|
||||
useFillAlphaPercentage ? config.fillAlpha * 100 : config.fillAlpha
|
||||
}
|
||||
onChange={value => {
|
||||
setUseFillAlphaPercentage(false);
|
||||
dispatch({
|
||||
type: 'SET_FILL_ALPHA',
|
||||
payload: {
|
||||
value,
|
||||
},
|
||||
});
|
||||
|
||||
setFillAlpha(value);
|
||||
}}
|
||||
maxValue={100}
|
||||
value={config.fillAlpha * 100}
|
||||
onChange={setFillAlpha}
|
||||
step={1}
|
||||
containerClassName="mt-[4px] mb-[9px]"
|
||||
inputClassName="w-[64px]"
|
||||
@@ -116,16 +60,9 @@ const ActiveSegmentationConfig = ({
|
||||
<div className="text-[#b3b3b3] text-[10px] mb-[12px]">Size</div>
|
||||
<InputNumber
|
||||
value={config.outlineWidthActive}
|
||||
onChange={value => {
|
||||
dispatch({
|
||||
type: 'SET_OUTLINE_WIDTH',
|
||||
payload: {
|
||||
value,
|
||||
},
|
||||
});
|
||||
|
||||
setOutlineWidthActive(value);
|
||||
}}
|
||||
onChange={setOutlineWidthActive}
|
||||
minValue={0}
|
||||
maxValue={10}
|
||||
className="-mt-1"
|
||||
/>
|
||||
</div>
|
||||
@@ -135,16 +72,9 @@ const ActiveSegmentationConfig = ({
|
||||
|
||||
const InactiveSegmentationConfig = ({
|
||||
config,
|
||||
dispatch,
|
||||
setRenderInactiveSegmentations,
|
||||
setFillAlphaInactive,
|
||||
usePercentage,
|
||||
}) => {
|
||||
const [
|
||||
useFillAlphaInactivePercentage,
|
||||
setUseFillInactivePercentage,
|
||||
] = useState(usePercentage);
|
||||
|
||||
return (
|
||||
<div className="px-2">
|
||||
<CheckBox
|
||||
@@ -152,39 +82,16 @@ const InactiveSegmentationConfig = ({
|
||||
checked={config.renderInactiveSegmentations}
|
||||
labelClassName="text-[12px] pt-1"
|
||||
className="mb-[9px]"
|
||||
onChange={value => {
|
||||
dispatch({
|
||||
type: 'RENDER_INACTIVE_SEGMENTATIONS',
|
||||
payload: {
|
||||
value,
|
||||
},
|
||||
});
|
||||
|
||||
setRenderInactiveSegmentations(value);
|
||||
}}
|
||||
onChange={setRenderInactiveSegmentations}
|
||||
/>
|
||||
|
||||
<div className="flex pl-4 items-center space-x-2">
|
||||
<span className="text-[10px] text-[#b3b3b3]">Opacity</span>
|
||||
<InputRange
|
||||
minValue={0}
|
||||
maxValue={usePercentage ? 100 : 1}
|
||||
value={
|
||||
useFillAlphaInactivePercentage
|
||||
? config.fillAlphaInactive * 100
|
||||
: config.fillAlphaInactive
|
||||
}
|
||||
onChange={value => {
|
||||
setUseFillInactivePercentage(false);
|
||||
dispatch({
|
||||
type: 'SET_FILL_ALPHA_INACTIVE',
|
||||
payload: {
|
||||
value: value,
|
||||
},
|
||||
});
|
||||
|
||||
setFillAlphaInactive(value);
|
||||
}}
|
||||
maxValue={100}
|
||||
value={config.fillAlphaInactive * 100}
|
||||
onChange={setFillAlphaInactive}
|
||||
step={1}
|
||||
containerClassName="mt-[4px]"
|
||||
inputClassName="w-[64px]"
|
||||
@@ -206,11 +113,7 @@ const SegmentationConfig = ({
|
||||
setRenderInactiveSegmentations,
|
||||
setRenderOutline,
|
||||
}) => {
|
||||
const [config, dispatch] = React.useReducer(
|
||||
reducer,
|
||||
segmentationConfig.initialConfig
|
||||
);
|
||||
|
||||
const { initialConfig } = segmentationConfig;
|
||||
const [isMinimized, setIsMinimized] = useState(true);
|
||||
return (
|
||||
<div className="bg-primary-dark">
|
||||
@@ -238,14 +141,12 @@ const SegmentationConfig = ({
|
||||
{!isMinimized && (
|
||||
<div>
|
||||
<ActiveSegmentationConfig
|
||||
config={config}
|
||||
dispatch={dispatch}
|
||||
config={initialConfig}
|
||||
setFillAlpha={setFillAlpha}
|
||||
setOutlineWidthActive={setOutlineWidthActive}
|
||||
setOutlineOpacityActive={setOutlineOpacityActive}
|
||||
setRenderFill={setRenderFill}
|
||||
setRenderOutline={setRenderOutline}
|
||||
usePercentage={segmentationConfig.usePercentage}
|
||||
/>
|
||||
{/* A small line */}
|
||||
<div className="h-[1px] bg-[#212456] mb-[8px] mx-1"></div>
|
||||
@@ -259,11 +160,9 @@ const SegmentationConfig = ({
|
||||
</span>
|
||||
</div>
|
||||
<InactiveSegmentationConfig
|
||||
config={config}
|
||||
dispatch={dispatch}
|
||||
config={initialConfig}
|
||||
setRenderInactiveSegmentations={setRenderInactiveSegmentations}
|
||||
setFillAlphaInactive={setFillAlphaInactive}
|
||||
usePercentage={segmentationConfig.usePercentage}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -4,30 +4,6 @@ import Icon from '../Icon';
|
||||
import SegmentationGroup from './SegmentationGroup';
|
||||
import SegmentationConfig from './SegmentationConfig';
|
||||
|
||||
const GetSegmentationConfig = ({
|
||||
setFillAlpha,
|
||||
setFillAlphaInactive,
|
||||
setOutlineWidthActive,
|
||||
setRenderFill,
|
||||
setRenderInactiveSegmentations,
|
||||
setRenderOutline,
|
||||
setOutlineOpacityActive,
|
||||
segmentationConfig,
|
||||
}) => {
|
||||
return (
|
||||
<SegmentationConfig
|
||||
setFillAlpha={setFillAlpha}
|
||||
setFillAlphaInactive={setFillAlphaInactive}
|
||||
setOutlineWidthActive={setOutlineWidthActive}
|
||||
setOutlineOpacityActive={setOutlineOpacityActive}
|
||||
setRenderFill={setRenderFill}
|
||||
setRenderInactiveSegmentations={setRenderInactiveSegmentations}
|
||||
setRenderOutline={setRenderOutline}
|
||||
segmentationConfig={segmentationConfig}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const SegmentationGroupTable = ({
|
||||
segmentations,
|
||||
onSegmentationAdd,
|
||||
@@ -56,10 +32,7 @@ const SegmentationGroupTable = ({
|
||||
}) => {
|
||||
return (
|
||||
<div className="flex flex-col min-h-0 font-inter font-[300]">
|
||||
<GetSegmentationConfig
|
||||
// showAddSegmentation={showAddSegmentation}
|
||||
// onSegmentationAdd={onSegmentationAdd}
|
||||
segmentationConfig={segmentationConfig}
|
||||
<SegmentationConfig
|
||||
setFillAlpha={setFillAlpha}
|
||||
setFillAlphaInactive={setFillAlphaInactive}
|
||||
setOutlineWidthActive={setOutlineWidthActive}
|
||||
@@ -67,6 +40,7 @@ const SegmentationGroupTable = ({
|
||||
setRenderFill={setRenderFill}
|
||||
setRenderInactiveSegmentations={setRenderInactiveSegmentations}
|
||||
setRenderOutline={setRenderOutline}
|
||||
segmentationConfig={segmentationConfig}
|
||||
/>
|
||||
<div className="flex flex-col min-h-0 pr-[1px] mt-1">
|
||||
{!!segmentations.length &&
|
||||
@@ -155,7 +129,6 @@ SegmentationGroupTable.defaultProps = {
|
||||
renderInactiveSegmentations: true,
|
||||
renderOutline: true,
|
||||
},
|
||||
usePercentage: true,
|
||||
},
|
||||
setFillAlpha: () => {},
|
||||
setFillAlphaInactive: () => {},
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
const reducer = (state, action) => {
|
||||
switch (action.type) {
|
||||
case 'RENDER_OUTLINE':
|
||||
return { ...state, renderOutline: action.payload.value };
|
||||
case 'RENDER_FILL':
|
||||
return { ...state, renderFill: action.payload.value };
|
||||
case 'SET_OUTLINE_OPACITY':
|
||||
return { ...state, outlineOpacity: action.payload.value };
|
||||
case 'SET_OUTLINE_WIDTH':
|
||||
return { ...state, outlineWidth: action.payload.value };
|
||||
case 'SET_FILL_ALPHA':
|
||||
return { ...state, fillAlpha: action.payload.value };
|
||||
case 'SET_FILL_ALPHA_INACTIVE':
|
||||
return { ...state, fillAlphaInactive: action.payload.value };
|
||||
case 'RENDER_INACTIVE_SEGMENTATIONS':
|
||||
return { ...state, renderInactiveSegmentations: action.payload.value };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export { reducer };
|
||||
@@ -68,6 +68,7 @@ import InputRange from './InputRange';
|
||||
import InputNumber from './InputNumber';
|
||||
import CheckBox from './CheckBox';
|
||||
import LoadingIndicatorProgress from './LoadingIndicatorProgress';
|
||||
import LoadingIndicatorTotalPercent from './LoadingIndicatorTotalPercent';
|
||||
import ViewportActionBar from './ViewportActionBar';
|
||||
|
||||
export {
|
||||
@@ -104,6 +105,7 @@ export {
|
||||
LegacyCinePlayer,
|
||||
LegacyViewportActionBar,
|
||||
LoadingIndicatorProgress,
|
||||
LoadingIndicatorTotalPercent,
|
||||
MeasurementTable,
|
||||
Modal,
|
||||
NavBar,
|
||||
|
||||
@@ -65,6 +65,7 @@ export {
|
||||
LegacyCinePlayer,
|
||||
LegacyViewportActionBar,
|
||||
LoadingIndicatorProgress,
|
||||
LoadingIndicatorTotalPercent,
|
||||
MeasurementTable,
|
||||
Modal,
|
||||
NavBar,
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
base = ""
|
||||
build = "yarn run build:viewer:ci"
|
||||
publish = "dist"
|
||||
ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF . ../ui/ ../core/ ../i18n"
|
||||
|
||||
|
||||
# NODE_VERSION in root `.nvmrc` takes priority
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
"@ohif/extension-cornerstone": "^3.0.0",
|
||||
"@ohif/extension-cornerstone-dicom-seg": "^3.0.0",
|
||||
"@ohif/extension-cornerstone-dicom-sr": "^3.0.0",
|
||||
"@ohif/extension-cornerstone-dicom-rt": "^3.0.0",
|
||||
"@ohif/extension-default": "^3.0.0",
|
||||
"@ohif/extension-dicom-pdf": "^3.0.1",
|
||||
"@ohif/extension-dicom-video": "^3.0.1",
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
{
|
||||
"packageName": "@ohif/extension-cornerstone-dicom-seg",
|
||||
"version": "3.0.0"
|
||||
},
|
||||
{
|
||||
"packageName": "@ohif/extension-cornerstone-dicom-rt",
|
||||
"version": "3.0.0"
|
||||
}
|
||||
],
|
||||
"modes": [
|
||||
@@ -45,4 +49,4 @@
|
||||
],
|
||||
"modesFactory": [],
|
||||
"umd": []
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ window.config = {
|
||||
supportsWildcard: true,
|
||||
staticWado: true,
|
||||
singlepart: 'bulkdata,video,pdf',
|
||||
useBulkDataURI: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ window.config = {
|
||||
imageRendering: 'wadors',
|
||||
thumbnailRendering: 'wadors',
|
||||
enableStudyLazyLoad: true,
|
||||
useBulkDataURI: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -16,13 +16,14 @@ window.config = {
|
||||
sourceName: 'dicomweb',
|
||||
configuration: {
|
||||
name: 'DCM4CHEE',
|
||||
wadoUriRoot: 'http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/wado',
|
||||
qidoRoot: 'http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||
wadoRoot: 'http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||
wadoUriRoot: 'http://localhost/dcm4chee-arc/aets/DCM4CHEE/wado',
|
||||
qidoRoot: 'http://localhost/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||
wadoRoot: 'http://localhost/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||
qidoSupportsIncludeField: true,
|
||||
imageRendering: 'wadors',
|
||||
enableStudyLazyLoad: true,
|
||||
thumbnailRendering: 'wadors',
|
||||
useBulkDataURI: false,
|
||||
requestOptions: {
|
||||
auth: 'admin:admin',
|
||||
},
|
||||
|
||||
@@ -25,6 +25,7 @@ window.config = {
|
||||
imageRendering: 'wadors',
|
||||
thumbnailRendering: 'wadors',
|
||||
enableStudyLazyLoad: true,
|
||||
useBulkDataURI: false,
|
||||
supportsFuzzyMatching: true,
|
||||
supportsWildcard: true,
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user