feat(measurements): add CircleROI Tool (#3211)
* [refactor] measurement service mapping files - rename to .ts files * [fix] RectangleROI - measurement service mapping _getReport() function - tool name fix * [feat] added CircleROI tool from updated cornerstone3D * [refactor] fix for typescript strong typing warnings * [feat] cornerstone-dicom-sr extension - added CircleROI tool * [feat] added toolbar button for CircleROI tool * [doc] doc updates for CircleROI tool * [update] library - dcmjs to 0.29.5 * [fix] roundNumber() function when given strings * [fix] refactor after upgrading conerstonejs library 0.49.0 * yarn.lock file change
This commit is contained in:
parent
83b4606357
commit
47c25f4364
@ -36,7 +36,7 @@
|
|||||||
"@ohif/extension-cornerstone": "^3.0.0",
|
"@ohif/extension-cornerstone": "^3.0.0",
|
||||||
"@ohif/extension-measurement-tracking": "^3.0.0",
|
"@ohif/extension-measurement-tracking": "^3.0.0",
|
||||||
"@ohif/ui": "^2.0.0",
|
"@ohif/ui": "^2.0.0",
|
||||||
"dcmjs": "^0.29.4",
|
"dcmjs": "^0.29.5",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.9",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
BidirectionalTool,
|
BidirectionalTool,
|
||||||
CobbAngleTool,
|
CobbAngleTool,
|
||||||
EllipticalROITool,
|
EllipticalROITool,
|
||||||
|
CircleROITool,
|
||||||
LengthTool,
|
LengthTool,
|
||||||
PlanarFreehandROITool,
|
PlanarFreehandROITool,
|
||||||
} from '@cornerstonejs/tools';
|
} from '@cornerstonejs/tools';
|
||||||
@ -24,6 +25,7 @@ export default function init({
|
|||||||
addToolInstance(toolNames.SRLength, LengthTool, {});
|
addToolInstance(toolNames.SRLength, LengthTool, {});
|
||||||
addToolInstance(toolNames.SRBidirectional, BidirectionalTool);
|
addToolInstance(toolNames.SRBidirectional, BidirectionalTool);
|
||||||
addToolInstance(toolNames.SREllipticalROI, EllipticalROITool);
|
addToolInstance(toolNames.SREllipticalROI, EllipticalROITool);
|
||||||
|
addToolInstance(toolNames.SRCircleROI, CircleROITool);
|
||||||
addToolInstance(toolNames.SRArrowAnnotate, ArrowAnnotateTool);
|
addToolInstance(toolNames.SRArrowAnnotate, ArrowAnnotateTool);
|
||||||
addToolInstance(toolNames.SRAngle, AngleTool);
|
addToolInstance(toolNames.SRAngle, AngleTool);
|
||||||
// TODO - fix the SR display of Cobb Angle, as it joins the two lines
|
// TODO - fix the SR display of Cobb Angle, as it joins the two lines
|
||||||
@ -40,6 +42,7 @@ export default function init({
|
|||||||
SRLength: dashedLine,
|
SRLength: dashedLine,
|
||||||
SRBidirectional: dashedLine,
|
SRBidirectional: dashedLine,
|
||||||
SREllipticalROI: dashedLine,
|
SREllipticalROI: dashedLine,
|
||||||
|
SRCircleROI: dashedLine,
|
||||||
SRArrowAnnotate: dashedLine,
|
SRArrowAnnotate: dashedLine,
|
||||||
SRCobbAngle: dashedLine,
|
SRCobbAngle: dashedLine,
|
||||||
SRAngle: dashedLine,
|
SRAngle: dashedLine,
|
||||||
|
|||||||
@ -5,6 +5,7 @@ const toolNames = {
|
|||||||
SRLength: 'SRLength',
|
SRLength: 'SRLength',
|
||||||
SRBidirectional: 'SRBidirectional',
|
SRBidirectional: 'SRBidirectional',
|
||||||
SREllipticalROI: 'SREllipticalROI',
|
SREllipticalROI: 'SREllipticalROI',
|
||||||
|
SRCircleROI: 'SRCircleROI',
|
||||||
SRArrowAnnotate: 'SRArrowAnnotate',
|
SRArrowAnnotate: 'SRArrowAnnotate',
|
||||||
SRAngle: 'SRAngle',
|
SRAngle: 'SRAngle',
|
||||||
SRCobbAngle: 'SRCobbAngle',
|
SRCobbAngle: 'SRCobbAngle',
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
"@ohif/core": "^3.0.0",
|
"@ohif/core": "^3.0.0",
|
||||||
"@ohif/ui": "^2.0.0",
|
"@ohif/ui": "^2.0.0",
|
||||||
"cornerstone-wado-image-loader": "^4.13.0",
|
"cornerstone-wado-image-loader": "^4.13.0",
|
||||||
"dcmjs": "^0.29.4",
|
"dcmjs": "^0.29.5",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.9",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import {
|
|||||||
LengthTool,
|
LengthTool,
|
||||||
RectangleROITool,
|
RectangleROITool,
|
||||||
EllipticalROITool,
|
EllipticalROITool,
|
||||||
|
CircleROITool,
|
||||||
BidirectionalTool,
|
BidirectionalTool,
|
||||||
ArrowAnnotateTool,
|
ArrowAnnotateTool,
|
||||||
DragProbeTool,
|
DragProbeTool,
|
||||||
@ -41,6 +42,7 @@ export default function initCornerstoneTools(configuration = {}) {
|
|||||||
addTool(LengthTool);
|
addTool(LengthTool);
|
||||||
addTool(RectangleROITool);
|
addTool(RectangleROITool);
|
||||||
addTool(EllipticalROITool);
|
addTool(EllipticalROITool);
|
||||||
|
addTool(CircleROITool);
|
||||||
addTool(BidirectionalTool);
|
addTool(BidirectionalTool);
|
||||||
addTool(ArrowAnnotateTool);
|
addTool(ArrowAnnotateTool);
|
||||||
addTool(DragProbeTool);
|
addTool(DragProbeTool);
|
||||||
@ -83,6 +85,7 @@ const toolNames = {
|
|||||||
Probe: ProbeTool.toolName,
|
Probe: ProbeTool.toolName,
|
||||||
RectangleROI: RectangleROITool.toolName,
|
RectangleROI: RectangleROITool.toolName,
|
||||||
EllipticalROI: EllipticalROITool.toolName,
|
EllipticalROI: EllipticalROITool.toolName,
|
||||||
|
CircleROI: CircleROITool.toolName,
|
||||||
Bidirectional: BidirectionalTool.toolName,
|
Bidirectional: BidirectionalTool.toolName,
|
||||||
Angle: AngleTool.toolName,
|
Angle: AngleTool.toolName,
|
||||||
CobbAngle: CobbAngleTool.toolName,
|
CobbAngle: CobbAngleTool.toolName,
|
||||||
|
|||||||
@ -24,6 +24,7 @@ const initMeasurementService = (
|
|||||||
Length,
|
Length,
|
||||||
Bidirectional,
|
Bidirectional,
|
||||||
EllipticalROI,
|
EllipticalROI,
|
||||||
|
CircleROI,
|
||||||
ArrowAnnotate,
|
ArrowAnnotate,
|
||||||
Angle,
|
Angle,
|
||||||
CobbAngle,
|
CobbAngle,
|
||||||
@ -78,6 +79,14 @@ const initMeasurementService = (
|
|||||||
EllipticalROI.toMeasurement
|
EllipticalROI.toMeasurement
|
||||||
);
|
);
|
||||||
|
|
||||||
|
measurementService.addMapping(
|
||||||
|
csTools3DVer1MeasurementSource,
|
||||||
|
'CircleROI',
|
||||||
|
CircleROI.matchingCriteria,
|
||||||
|
CircleROI.toAnnotation,
|
||||||
|
CircleROI.toMeasurement
|
||||||
|
);
|
||||||
|
|
||||||
measurementService.addMapping(
|
measurementService.addMapping(
|
||||||
csTools3DVer1MeasurementSource,
|
csTools3DVer1MeasurementSource,
|
||||||
'ArrowAnnotate',
|
'ArrowAnnotate',
|
||||||
|
|||||||
@ -0,0 +1,228 @@
|
|||||||
|
import SUPPORTED_TOOLS from './constants/supportedTools';
|
||||||
|
import getSOPInstanceAttributes from './utils/getSOPInstanceAttributes';
|
||||||
|
import getModalityUnit from './utils/getModalityUnit';
|
||||||
|
import { utils } from '@ohif/core';
|
||||||
|
|
||||||
|
const CircleROI = {
|
||||||
|
toAnnotation: measurement => {},
|
||||||
|
toMeasurement: (
|
||||||
|
csToolsEventDetail,
|
||||||
|
DisplaySetService,
|
||||||
|
CornerstoneViewportService,
|
||||||
|
getValueTypeFromToolType
|
||||||
|
) => {
|
||||||
|
const { annotation, viewportId } = csToolsEventDetail;
|
||||||
|
const { metadata, data, annotationUID } = annotation;
|
||||||
|
|
||||||
|
if (!metadata || !data) {
|
||||||
|
console.warn('Length tool: Missing metadata or data');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { toolName, referencedImageId, FrameOfReferenceUID } = metadata;
|
||||||
|
const validToolType = SUPPORTED_TOOLS.includes(toolName);
|
||||||
|
|
||||||
|
if (!validToolType) {
|
||||||
|
throw new Error('Tool not supported');
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
SOPInstanceUID,
|
||||||
|
SeriesInstanceUID,
|
||||||
|
StudyInstanceUID,
|
||||||
|
} = getSOPInstanceAttributes(
|
||||||
|
referencedImageId,
|
||||||
|
CornerstoneViewportService,
|
||||||
|
viewportId
|
||||||
|
);
|
||||||
|
|
||||||
|
let displaySet;
|
||||||
|
|
||||||
|
if (SOPInstanceUID) {
|
||||||
|
displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
|
||||||
|
SOPInstanceUID,
|
||||||
|
SeriesInstanceUID
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
displaySet = DisplaySetService.getDisplaySetsForSeries(SeriesInstanceUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { points } = data.handles;
|
||||||
|
|
||||||
|
const mappedAnnotations = getMappedAnnotations(
|
||||||
|
annotation,
|
||||||
|
DisplaySetService
|
||||||
|
);
|
||||||
|
|
||||||
|
const displayText = getDisplayText(mappedAnnotations, displaySet);
|
||||||
|
const getReport = () =>
|
||||||
|
_getReport(mappedAnnotations, points, FrameOfReferenceUID);
|
||||||
|
|
||||||
|
return {
|
||||||
|
uid: annotationUID,
|
||||||
|
SOPInstanceUID,
|
||||||
|
FrameOfReferenceUID,
|
||||||
|
points,
|
||||||
|
metadata,
|
||||||
|
referenceSeriesUID: SeriesInstanceUID,
|
||||||
|
referenceStudyUID: StudyInstanceUID,
|
||||||
|
frameNumber: mappedAnnotations[0]?.frameNumber || 1,
|
||||||
|
toolName: metadata.toolName,
|
||||||
|
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
||||||
|
label: data.label,
|
||||||
|
displayText: displayText,
|
||||||
|
data: data.cachedStats,
|
||||||
|
type: getValueTypeFromToolType(toolName),
|
||||||
|
getReport,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function getMappedAnnotations(annotation, DisplaySetService) {
|
||||||
|
const { metadata, data } = annotation;
|
||||||
|
const { cachedStats } = data;
|
||||||
|
const { referencedImageId } = metadata;
|
||||||
|
const targets = Object.keys(cachedStats);
|
||||||
|
|
||||||
|
if (!targets.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const annotations = [];
|
||||||
|
Object.keys(cachedStats).forEach(targetId => {
|
||||||
|
const targetStats = cachedStats[targetId];
|
||||||
|
|
||||||
|
if (!referencedImageId) {
|
||||||
|
// Todo: Non-acquisition plane measurement mapping not supported yet
|
||||||
|
throw new Error(
|
||||||
|
'Non-acquisition plane measurement mapping not supported'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
SOPInstanceUID,
|
||||||
|
SeriesInstanceUID,
|
||||||
|
frameNumber,
|
||||||
|
} = getSOPInstanceAttributes(referencedImageId);
|
||||||
|
|
||||||
|
const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
|
||||||
|
SOPInstanceUID,
|
||||||
|
SeriesInstanceUID,
|
||||||
|
frameNumber
|
||||||
|
);
|
||||||
|
|
||||||
|
const { SeriesNumber } = displaySet;
|
||||||
|
const { mean, stdDev, max, area, Modality } = targetStats;
|
||||||
|
const unit = getModalityUnit(Modality);
|
||||||
|
|
||||||
|
annotations.push({
|
||||||
|
SeriesInstanceUID,
|
||||||
|
SOPInstanceUID,
|
||||||
|
SeriesNumber,
|
||||||
|
frameNumber,
|
||||||
|
Modality,
|
||||||
|
unit,
|
||||||
|
mean,
|
||||||
|
stdDev,
|
||||||
|
max,
|
||||||
|
area,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return annotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This function is used to convert the measurement data to a format that is
|
||||||
|
suitable for the report generation (e.g. for the csv report). The report
|
||||||
|
returns a list of columns and corresponding values.
|
||||||
|
*/
|
||||||
|
function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
|
||||||
|
const columns = [];
|
||||||
|
const values = [];
|
||||||
|
|
||||||
|
// Add Type
|
||||||
|
columns.push('AnnotationType');
|
||||||
|
values.push('Cornerstone:CircleROI');
|
||||||
|
|
||||||
|
mappedAnnotations.forEach(annotation => {
|
||||||
|
const { mean, stdDev, max, area, unit } = annotation;
|
||||||
|
|
||||||
|
if (!mean || !unit || !max || !area) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
columns.push(
|
||||||
|
`max (${unit})`,
|
||||||
|
`mean (${unit})`,
|
||||||
|
`std (${unit})`,
|
||||||
|
`area (mm2)`
|
||||||
|
);
|
||||||
|
values.push(max, mean, stdDev, area);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (FrameOfReferenceUID) {
|
||||||
|
columns.push('FrameOfReferenceUID');
|
||||||
|
values.push(FrameOfReferenceUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (points) {
|
||||||
|
columns.push('points');
|
||||||
|
// points has the form of [[x1, y1, z1], [x2, y2, z2], ...]
|
||||||
|
// convert it to string of [[x1 y1 z1];[x2 y2 z2];...]
|
||||||
|
// so that it can be used in the csv report
|
||||||
|
values.push(points.map(p => p.join(' ')).join(';'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
columns,
|
||||||
|
values,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDisplayText(mappedAnnotations, displaySet) {
|
||||||
|
if (!mappedAnnotations || !mappedAnnotations.length) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const displayText = [];
|
||||||
|
|
||||||
|
// Area is the same for all series
|
||||||
|
const { area, SOPInstanceUID, frameNumber } = mappedAnnotations[0];
|
||||||
|
|
||||||
|
const instance = displaySet.images.find(
|
||||||
|
image => image.SOPInstanceUID === SOPInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
|
let InstanceNumber;
|
||||||
|
if (instance) {
|
||||||
|
InstanceNumber = instance.InstanceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
||||||
|
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
||||||
|
|
||||||
|
// Area sometimes becomes undefined if `preventHandleOutsideImage` is off.
|
||||||
|
const roundedArea = utils.roundNumber(area || 0, 2);
|
||||||
|
displayText.push(`${roundedArea} mm<sup>2</sup>`);
|
||||||
|
|
||||||
|
// Todo: we need a better UI for displaying all these information
|
||||||
|
mappedAnnotations.forEach(mappedAnnotation => {
|
||||||
|
const { unit, max, SeriesNumber } = mappedAnnotation;
|
||||||
|
|
||||||
|
let maxStr = '';
|
||||||
|
if (max) {
|
||||||
|
const roundedMax = utils.roundNumber(max, 2);
|
||||||
|
maxStr = `Max: ${roundedMax} <small>${unit}</small> `;
|
||||||
|
}
|
||||||
|
|
||||||
|
const str = `${maxStr}(S:${SeriesNumber}${instanceText}${frameText})`;
|
||||||
|
if (!displayText.includes(str)) {
|
||||||
|
displayText.push(str);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return displayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CircleROI;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import SUPPORTED_TOOLS from './constants/supportedTools';
|
import SUPPORTED_TOOLS from './constants/supportedTools';
|
||||||
import getSOPInstanceAttributes from './utils/getSOPInstanceAttributes';
|
import getSOPInstanceAttributes from './utils/getSOPInstanceAttributes';
|
||||||
import { displaySetService, utils } from '@ohif/core';
|
import { utils } from '@ohif/core';
|
||||||
|
|
||||||
const Length = {
|
const Length = {
|
||||||
toAnnotation: measurement => {},
|
toAnnotation: measurement => {},
|
||||||
@ -32,15 +32,12 @@ const Length = {
|
|||||||
throw new Error('Tool not supported');
|
throw new Error('Tool not supported');
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } =
|
||||||
SOPInstanceUID,
|
getSOPInstanceAttributes(
|
||||||
SeriesInstanceUID,
|
referencedImageId,
|
||||||
StudyInstanceUID,
|
cornerstoneViewportService,
|
||||||
} = getSOPInstanceAttributes(
|
viewportId
|
||||||
referencedImageId,
|
);
|
||||||
cornerstoneViewportService,
|
|
||||||
viewportId
|
|
||||||
);
|
|
||||||
|
|
||||||
let displaySet;
|
let displaySet;
|
||||||
|
|
||||||
@ -104,11 +101,8 @@ function getMappedAnnotations(annotation, displaySetService) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
|
||||||
SOPInstanceUID,
|
getSOPInstanceAttributes(referencedImageId);
|
||||||
SeriesInstanceUID,
|
|
||||||
frameNumber,
|
|
||||||
} = getSOPInstanceAttributes(referencedImageId);
|
|
||||||
|
|
||||||
const displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
|
const displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
|
||||||
SOPInstanceUID,
|
SOPInstanceUID,
|
||||||
@ -179,12 +173,8 @@ function getDisplayText(mappedAnnotations, displaySet) {
|
|||||||
const displayText = [];
|
const displayText = [];
|
||||||
|
|
||||||
// Area is the same for all series
|
// Area is the same for all series
|
||||||
const {
|
const { length, SeriesNumber, SOPInstanceUID, frameNumber } =
|
||||||
length,
|
mappedAnnotations[0];
|
||||||
SeriesNumber,
|
|
||||||
SOPInstanceUID,
|
|
||||||
frameNumber,
|
|
||||||
} = mappedAnnotations[0];
|
|
||||||
|
|
||||||
const instance = displaySet.images.find(
|
const instance = displaySet.images.find(
|
||||||
image => image.SOPInstanceUID === SOPInstanceUID
|
image => image.SOPInstanceUID === SOPInstanceUID
|
||||||
@ -4,7 +4,7 @@ import getModalityUnit from './utils/getModalityUnit';
|
|||||||
import { utils } from '@ohif/core';
|
import { utils } from '@ohif/core';
|
||||||
|
|
||||||
const RectangleROI = {
|
const RectangleROI = {
|
||||||
toAnnotation: measurement => { },
|
toAnnotation: measurement => {},
|
||||||
toMeasurement: (
|
toMeasurement: (
|
||||||
csToolsEventDetail,
|
csToolsEventDetail,
|
||||||
DisplaySetService,
|
DisplaySetService,
|
||||||
@ -26,15 +26,12 @@ const RectangleROI = {
|
|||||||
throw new Error('Tool not supported');
|
throw new Error('Tool not supported');
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const { SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID } =
|
||||||
SOPInstanceUID,
|
getSOPInstanceAttributes(
|
||||||
SeriesInstanceUID,
|
referencedImageId,
|
||||||
StudyInstanceUID,
|
CornerstoneViewportService,
|
||||||
} = getSOPInstanceAttributes(
|
viewportId
|
||||||
referencedImageId,
|
);
|
||||||
CornerstoneViewportService,
|
|
||||||
viewportId
|
|
||||||
);
|
|
||||||
|
|
||||||
let displaySet;
|
let displaySet;
|
||||||
|
|
||||||
@ -99,11 +96,8 @@ function getMappedAnnotations(annotation, DisplaySetService) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const { SOPInstanceUID, SeriesInstanceUID, frameNumber } =
|
||||||
SOPInstanceUID,
|
getSOPInstanceAttributes(referencedImageId);
|
||||||
SeriesInstanceUID,
|
|
||||||
frameNumber,
|
|
||||||
} = getSOPInstanceAttributes(referencedImageId);
|
|
||||||
|
|
||||||
const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
|
const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
|
||||||
SOPInstanceUID,
|
SOPInstanceUID,
|
||||||
@ -143,7 +137,7 @@ function _getReport(mappedAnnotations, points, FrameOfReferenceUID) {
|
|||||||
|
|
||||||
// Add Type
|
// Add Type
|
||||||
columns.push('AnnotationType');
|
columns.push('AnnotationType');
|
||||||
values.push('Cornerstone:EllipticalROI');
|
values.push('Cornerstone:RectangleROI');
|
||||||
|
|
||||||
mappedAnnotations.forEach(annotation => {
|
mappedAnnotations.forEach(annotation => {
|
||||||
const { mean, stdDev, max, area, unit } = annotation;
|
const { mean, stdDev, max, area, unit } = annotation;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
export default [
|
export default [
|
||||||
'Length',
|
'Length',
|
||||||
'EllipticalROI',
|
'EllipticalROI',
|
||||||
|
'CircleROI',
|
||||||
'Bidirectional',
|
'Bidirectional',
|
||||||
'ArrowAnnotate',
|
'ArrowAnnotate',
|
||||||
'Angle',
|
'Angle',
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { MeasurementService } from '@ohif/core';
|
|||||||
import Length from './Length';
|
import Length from './Length';
|
||||||
import Bidirectional from './Bidirectional';
|
import Bidirectional from './Bidirectional';
|
||||||
import EllipticalROI from './EllipticalROI';
|
import EllipticalROI from './EllipticalROI';
|
||||||
|
import CircleROI from './CircleROI';
|
||||||
import ArrowAnnotate from './ArrowAnnotate';
|
import ArrowAnnotate from './ArrowAnnotate';
|
||||||
import CobbAngle from './CobbAngle';
|
import CobbAngle from './CobbAngle';
|
||||||
import Angle from './Angle';
|
import Angle from './Angle';
|
||||||
@ -25,6 +26,7 @@ const measurementServiceMappingsFactory = (
|
|||||||
const {
|
const {
|
||||||
POLYLINE,
|
POLYLINE,
|
||||||
ELLIPSE,
|
ELLIPSE,
|
||||||
|
CIRCLE,
|
||||||
RECTANGLE,
|
RECTANGLE,
|
||||||
BIDIRECTIONAL,
|
BIDIRECTIONAL,
|
||||||
POINT,
|
POINT,
|
||||||
@ -37,6 +39,7 @@ const measurementServiceMappingsFactory = (
|
|||||||
const TOOL_TYPE_TO_VALUE_TYPE = {
|
const TOOL_TYPE_TO_VALUE_TYPE = {
|
||||||
Length: POLYLINE,
|
Length: POLYLINE,
|
||||||
EllipticalROI: ELLIPSE,
|
EllipticalROI: ELLIPSE,
|
||||||
|
CircleROI: CIRCLE,
|
||||||
RectangleROI: RECTANGLE,
|
RectangleROI: RECTANGLE,
|
||||||
PlanarFreehandROI: POLYLINE,
|
PlanarFreehandROI: POLYLINE,
|
||||||
Bidirectional: BIDIRECTIONAL,
|
Bidirectional: BIDIRECTIONAL,
|
||||||
@ -104,6 +107,22 @@ const measurementServiceMappingsFactory = (
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
CircleROI: {
|
||||||
|
toAnnotation: CircleROI.toAnnotation,
|
||||||
|
toMeasurement: csToolsAnnotation =>
|
||||||
|
CircleROI.toMeasurement(
|
||||||
|
csToolsAnnotation,
|
||||||
|
displaySetService,
|
||||||
|
cornerstoneViewportService,
|
||||||
|
_getValueTypeFromToolType
|
||||||
|
),
|
||||||
|
matchingCriteria: [
|
||||||
|
{
|
||||||
|
valueType: MeasurementService.VALUE_TYPES.CIRCLE,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
RectangleROI: {
|
RectangleROI: {
|
||||||
toAnnotation: RectangleROI.toAnnotation,
|
toAnnotation: RectangleROI.toAnnotation,
|
||||||
toMeasurement: csToolsAnnotation =>
|
toMeasurement: csToolsAnnotation =>
|
||||||
|
|||||||
@ -13,8 +13,8 @@ import * as cornerstone from '@cornerstonejs/core';
|
|||||||
*/
|
*/
|
||||||
export default function getSOPInstanceAttributes(
|
export default function getSOPInstanceAttributes(
|
||||||
imageId,
|
imageId,
|
||||||
cornerstoneViewportService,
|
cornerstoneViewportService = undefined,
|
||||||
viewportId
|
viewportId = undefined
|
||||||
) {
|
) {
|
||||||
if (imageId) {
|
if (imageId) {
|
||||||
return _getUIDFromImageID(imageId);
|
return _getUIDFromImageID(imageId);
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^3.0.0",
|
"@ohif/core": "^3.0.0",
|
||||||
"@ohif/i18n": "^1.0.0",
|
"@ohif/i18n": "^1.0.0",
|
||||||
"dcmjs": "^0.29.4",
|
"dcmjs": "^0.29.5",
|
||||||
"dicomweb-client": "^0.8.4",
|
"dicomweb-client": "^0.8.4",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^3.0.0",
|
"@ohif/core": "^3.0.0",
|
||||||
"@ohif/ui": "^2.0.0",
|
"@ohif/ui": "^2.0.0",
|
||||||
"dcmjs": "^0.29.4",
|
"dcmjs": "^0.29.5",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.9",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^3.0.0",
|
"@ohif/core": "^3.0.0",
|
||||||
"@ohif/ui": "^2.0.0",
|
"@ohif/ui": "^2.0.0",
|
||||||
"dcmjs": "^0.29.4",
|
"dcmjs": "^0.29.5",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.9",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
"@cornerstonejs/core": "^0.40.0",
|
"@cornerstonejs/core": "^0.40.0",
|
||||||
"@cornerstonejs/tools": "^0.60.1",
|
"@cornerstonejs/tools": "^0.60.1",
|
||||||
"@ohif/extension-cornerstone-dicom-sr": "^3.0.0",
|
"@ohif/extension-cornerstone-dicom-sr": "^3.0.0",
|
||||||
"dcmjs": "^0.29.4",
|
"dcmjs": "^0.29.5",
|
||||||
"lodash.debounce": "^4.17.21",
|
"lodash.debounce": "^4.17.21",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^3.0.0",
|
"@ohif/core": "^3.0.0",
|
||||||
"@ohif/ui": "^2.0.0",
|
"@ohif/ui": "^2.0.0",
|
||||||
"dcmjs": "^0.29.4",
|
"dcmjs": "^0.29.5",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.9",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
|
|||||||
@ -81,6 +81,7 @@ function modeFactory({ modeConfiguration }) {
|
|||||||
{ toolName: toolNames.Bidirectional },
|
{ toolName: toolNames.Bidirectional },
|
||||||
{ toolName: toolNames.Probe },
|
{ toolName: toolNames.Probe },
|
||||||
{ toolName: toolNames.EllipticalROI },
|
{ toolName: toolNames.EllipticalROI },
|
||||||
|
{ toolName: toolNames.CircleROI },
|
||||||
{ toolName: toolNames.RectangleROI },
|
{ toolName: toolNames.RectangleROI },
|
||||||
{ toolName: toolNames.StackScroll },
|
{ toolName: toolNames.StackScroll },
|
||||||
{ toolName: toolNames.CalibrationLine },
|
{ toolName: toolNames.CalibrationLine },
|
||||||
@ -134,11 +135,8 @@ function modeFactory({ modeConfiguration }) {
|
|||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
onModeExit: ({ servicesManager }) => {
|
onModeExit: ({ servicesManager }) => {
|
||||||
const {
|
const { toolGroupService, measurementService, toolbarService } =
|
||||||
toolGroupService,
|
servicesManager.services;
|
||||||
measurementService,
|
|
||||||
toolbarService,
|
|
||||||
} = servicesManager.services;
|
|
||||||
|
|
||||||
toolGroupService.destroy();
|
toolGroupService.destroy();
|
||||||
},
|
},
|
||||||
|
|||||||
@ -130,6 +130,21 @@ const toolbarButtons = [
|
|||||||
],
|
],
|
||||||
'Ellipse Tool'
|
'Ellipse Tool'
|
||||||
),
|
),
|
||||||
|
_createToolButton(
|
||||||
|
'CircleROI',
|
||||||
|
'tool-circle',
|
||||||
|
'Circle',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'CircleROI',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Circle Tool'
|
||||||
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -32,6 +32,7 @@ function initDefaultToolGroup(
|
|||||||
{ toolName: toolNames.Bidirectional },
|
{ toolName: toolNames.Bidirectional },
|
||||||
{ toolName: toolNames.DragProbe },
|
{ toolName: toolNames.DragProbe },
|
||||||
{ toolName: toolNames.EllipticalROI },
|
{ toolName: toolNames.EllipticalROI },
|
||||||
|
{ toolName: toolNames.CircleROI },
|
||||||
{ toolName: toolNames.RectangleROI },
|
{ toolName: toolNames.RectangleROI },
|
||||||
{ toolName: toolNames.StackScroll },
|
{ toolName: toolNames.StackScroll },
|
||||||
{ toolName: toolNames.Angle },
|
{ toolName: toolNames.Angle },
|
||||||
@ -110,6 +111,7 @@ function initSRToolGroup(extensionManager, toolGroupService, commandsManager) {
|
|||||||
{ toolName: SRToolNames.SRArrowAnnotate },
|
{ toolName: SRToolNames.SRArrowAnnotate },
|
||||||
{ toolName: SRToolNames.SRBidirectional },
|
{ toolName: SRToolNames.SRBidirectional },
|
||||||
{ toolName: SRToolNames.SREllipticalROI },
|
{ toolName: SRToolNames.SREllipticalROI },
|
||||||
|
{ toolName: SRToolNames.SRCircleROI },
|
||||||
],
|
],
|
||||||
enabled: [
|
enabled: [
|
||||||
{
|
{
|
||||||
@ -170,6 +172,7 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) {
|
|||||||
{ toolName: toolNames.Bidirectional },
|
{ toolName: toolNames.Bidirectional },
|
||||||
{ toolName: toolNames.DragProbe },
|
{ toolName: toolNames.DragProbe },
|
||||||
{ toolName: toolNames.EllipticalROI },
|
{ toolName: toolNames.EllipticalROI },
|
||||||
|
{ toolName: toolNames.CircleROI },
|
||||||
{ toolName: toolNames.RectangleROI },
|
{ toolName: toolNames.RectangleROI },
|
||||||
{ toolName: toolNames.StackScroll },
|
{ toolName: toolNames.StackScroll },
|
||||||
{ toolName: toolNames.Angle },
|
{ toolName: toolNames.Angle },
|
||||||
|
|||||||
@ -200,6 +200,29 @@ const toolbarButtons = [
|
|||||||
],
|
],
|
||||||
'Ellipse Tool'
|
'Ellipse Tool'
|
||||||
),
|
),
|
||||||
|
_createToolButton(
|
||||||
|
'CircleROI',
|
||||||
|
'tool-circle',
|
||||||
|
'Circle',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'CircleROI',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'SRCircleROI',
|
||||||
|
toolGroupId: 'SRToolGroup',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Circle Tool'
|
||||||
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -32,6 +32,7 @@ function initDefaultToolGroup(
|
|||||||
{ toolName: toolNames.Bidirectional },
|
{ toolName: toolNames.Bidirectional },
|
||||||
{ toolName: toolNames.DragProbe },
|
{ toolName: toolNames.DragProbe },
|
||||||
{ toolName: toolNames.EllipticalROI },
|
{ toolName: toolNames.EllipticalROI },
|
||||||
|
{ toolName: toolNames.CircleROI },
|
||||||
{ toolName: toolNames.RectangleROI },
|
{ toolName: toolNames.RectangleROI },
|
||||||
{ toolName: toolNames.StackScroll },
|
{ toolName: toolNames.StackScroll },
|
||||||
{ toolName: toolNames.Angle },
|
{ toolName: toolNames.Angle },
|
||||||
@ -113,6 +114,7 @@ function initSRToolGroup(extensionManager, toolGroupService, commandsManager) {
|
|||||||
{ toolName: SRToolNames.SRArrowAnnotate },
|
{ toolName: SRToolNames.SRArrowAnnotate },
|
||||||
{ toolName: SRToolNames.SRBidirectional },
|
{ toolName: SRToolNames.SRBidirectional },
|
||||||
{ toolName: SRToolNames.SREllipticalROI },
|
{ toolName: SRToolNames.SREllipticalROI },
|
||||||
|
{ toolName: SRToolNames.SRCircleROI },
|
||||||
],
|
],
|
||||||
enabled: [
|
enabled: [
|
||||||
{
|
{
|
||||||
@ -173,6 +175,7 @@ function initMPRToolGroup(extensionManager, toolGroupService, commandsManager) {
|
|||||||
{ toolName: toolNames.Bidirectional },
|
{ toolName: toolNames.Bidirectional },
|
||||||
{ toolName: toolNames.DragProbe },
|
{ toolName: toolNames.DragProbe },
|
||||||
{ toolName: toolNames.EllipticalROI },
|
{ toolName: toolNames.EllipticalROI },
|
||||||
|
{ toolName: toolNames.CircleROI },
|
||||||
{ toolName: toolNames.RectangleROI },
|
{ toolName: toolNames.RectangleROI },
|
||||||
{ toolName: toolNames.StackScroll },
|
{ toolName: toolNames.StackScroll },
|
||||||
{ toolName: toolNames.Angle },
|
{ toolName: toolNames.Angle },
|
||||||
|
|||||||
@ -208,6 +208,29 @@ const toolbarButtons = [
|
|||||||
],
|
],
|
||||||
'Ellipse Tool'
|
'Ellipse Tool'
|
||||||
),
|
),
|
||||||
|
_createToolButton(
|
||||||
|
'CircleROI',
|
||||||
|
'tool-circle',
|
||||||
|
'Circle',
|
||||||
|
[
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'CircleROI',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandName: 'setToolActive',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'SRCircleROI',
|
||||||
|
toolGroupId: 'SRToolGroup',
|
||||||
|
},
|
||||||
|
context: 'CORNERSTONE',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'Circle Tool'
|
||||||
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -173,6 +173,20 @@ const toolbarButtons = [
|
|||||||
],
|
],
|
||||||
'Ellipse Tool'
|
'Ellipse Tool'
|
||||||
),
|
),
|
||||||
|
_createToolButton(
|
||||||
|
'CircleROI',
|
||||||
|
'tool-circle',
|
||||||
|
'Circle',
|
||||||
|
[
|
||||||
|
..._createCommands('setToolActive', 'CircleROI', [
|
||||||
|
toolGroupIds.CT,
|
||||||
|
toolGroupIds.PT,
|
||||||
|
toolGroupIds.Fusion,
|
||||||
|
// toolGroupIds.MPR,
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
'Circle Tool'
|
||||||
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -299,8 +313,7 @@ const toolbarButtons = [
|
|||||||
commandName: 'displayNotification',
|
commandName: 'displayNotification',
|
||||||
commandOptions: {
|
commandOptions: {
|
||||||
title: 'RectangleROI Threshold Tip',
|
title: 'RectangleROI Threshold Tip',
|
||||||
text:
|
text: 'RectangleROI Threshold tool should be used on PT Axial Viewport',
|
||||||
'RectangleROI Threshold tool should be used on PT Axial Viewport',
|
|
||||||
type: 'info',
|
type: 'info',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.20.13",
|
"@babel/runtime": "^7.20.13",
|
||||||
"dcmjs": "^0.29.4",
|
"dcmjs": "^0.29.5",
|
||||||
"dicomweb-client": "^0.8.4",
|
"dicomweb-client": "^0.8.4",
|
||||||
"isomorphic-base64": "^1.0.2",
|
"isomorphic-base64": "^1.0.2",
|
||||||
"lodash.merge": "^4.6.1",
|
"lodash.merge": "^4.6.1",
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* @param {string | number} value
|
||||||
|
* @param {number} decimals
|
||||||
|
*/
|
||||||
function _round(value, decimals) {
|
function _round(value, decimals) {
|
||||||
return Number(value.toFixed(decimals));
|
return Number(value).toFixed(decimals);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default _round;
|
export default _round;
|
||||||
|
|||||||
@ -184,6 +184,16 @@ to create `MeasurementTools` nested button
|
|||||||
toolName: 'EllipticalRoi',
|
toolName: 'EllipticalRoi',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Circle tool
|
||||||
|
{
|
||||||
|
id: 'CircleROI',
|
||||||
|
icon: 'tool-circle',
|
||||||
|
label: 'Circle',
|
||||||
|
type: 'tool',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'CircleROI',
|
||||||
|
}
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -210,6 +210,16 @@ to create `MeasurementTools` nested button
|
|||||||
toolName: 'EllipticalRoi',
|
toolName: 'EllipticalRoi',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Circle tool
|
||||||
|
{
|
||||||
|
id: 'CircleROI',
|
||||||
|
icon: 'tool-circle',
|
||||||
|
label: 'Circle',
|
||||||
|
type: 'tool',
|
||||||
|
commandOptions: {
|
||||||
|
toolName: 'CircleROI',
|
||||||
|
}
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
3
platform/ui/src/assets/icons/tool-circle.svg
Normal file
3
platform/ui/src/assets/icons/tool-circle.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||||
|
<circle stroke="currentColor" fill="none" stroke-width="2" cx="16" cy="16" r="14" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 157 B |
@ -81,6 +81,7 @@ import toolWindow from './../../assets/icons/tool-window-level.svg';
|
|||||||
import toolAnnotate from './../../assets/icons/tool-annotate.svg';
|
import toolAnnotate from './../../assets/icons/tool-annotate.svg';
|
||||||
import toolBidirectional from './../../assets/icons/tool-bidirectional.svg';
|
import toolBidirectional from './../../assets/icons/tool-bidirectional.svg';
|
||||||
import toolElipse from './../../assets/icons/tool-elipse.svg';
|
import toolElipse from './../../assets/icons/tool-elipse.svg';
|
||||||
|
import toolCircle from './../../assets/icons/tool-circle.svg';
|
||||||
import toolLength from './../../assets/icons/tool-length.svg';
|
import toolLength from './../../assets/icons/tool-length.svg';
|
||||||
import toolStackScroll from './../../assets/icons/tool-stack-scroll.svg';
|
import toolStackScroll from './../../assets/icons/tool-stack-scroll.svg';
|
||||||
import toolMagnify from './../../assets/icons/tool-magnify.svg';
|
import toolMagnify from './../../assets/icons/tool-magnify.svg';
|
||||||
@ -199,6 +200,7 @@ const ICONS = {
|
|||||||
'tool-annotate': toolAnnotate,
|
'tool-annotate': toolAnnotate,
|
||||||
'tool-bidirectional': toolBidirectional,
|
'tool-bidirectional': toolBidirectional,
|
||||||
'tool-elipse': toolElipse,
|
'tool-elipse': toolElipse,
|
||||||
|
'tool-circle': toolCircle,
|
||||||
'tool-length': toolLength,
|
'tool-length': toolLength,
|
||||||
'tool-stack-scroll': toolStackScroll,
|
'tool-stack-scroll': toolStackScroll,
|
||||||
'tool-magnify': toolMagnify,
|
'tool-magnify': toolMagnify,
|
||||||
|
|||||||
@ -66,7 +66,7 @@
|
|||||||
"core-js": "^3.16.1",
|
"core-js": "^3.16.1",
|
||||||
"cornerstone-math": "^0.1.9",
|
"cornerstone-math": "^0.1.9",
|
||||||
"cornerstone-wado-image-loader": "^4.13.0",
|
"cornerstone-wado-image-loader": "^4.13.0",
|
||||||
"dcmjs": "^0.29.4",
|
"dcmjs": "^0.29.5",
|
||||||
"detect-gpu": "^4.0.16",
|
"detect-gpu": "^4.0.16",
|
||||||
"dicom-parser": "^1.8.9",
|
"dicom-parser": "^1.8.9",
|
||||||
"dotenv-webpack": "^1.7.0",
|
"dotenv-webpack": "^1.7.0",
|
||||||
|
|||||||
14
yarn.lock
14
yarn.lock
@ -9247,21 +9247,9 @@ dayjs@^1.10.4:
|
|||||||
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2"
|
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2"
|
||||||
integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==
|
integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==
|
||||||
|
|
||||||
dcmjs@^0.29.4:
|
|
||||||
version "0.29.4"
|
|
||||||
resolved "https://registry.npmjs.org/dcmjs/-/dcmjs-0.29.4.tgz#3fb13945611979f756bc91b3f199fd87b4eabdb4"
|
|
||||||
integrity sha512-PzD6C4oB7v/AVTIPbkS6D6hjgVcSW7+T+DsxFpkD1xcEgU4qjGM16WGEHH3ZAPDBF0Xgm2d9FXUu/lXZIyfmow==
|
|
||||||
dependencies:
|
|
||||||
"@babel/runtime-corejs2" "^7.17.8"
|
|
||||||
gl-matrix "^3.1.0"
|
|
||||||
lodash.clonedeep "^4.5.0"
|
|
||||||
loglevelnext "^3.0.1"
|
|
||||||
ndarray "^1.0.19"
|
|
||||||
pako "^2.0.4"
|
|
||||||
|
|
||||||
dcmjs@^0.29.5:
|
dcmjs@^0.29.5:
|
||||||
version "0.29.5"
|
version "0.29.5"
|
||||||
resolved "https://registry.npmjs.org/dcmjs/-/dcmjs-0.29.5.tgz#3e2311fc47aafc70f21e236ad89e2ff9ba6589fd"
|
resolved "https://registry.yarnpkg.com/dcmjs/-/dcmjs-0.29.5.tgz#3e2311fc47aafc70f21e236ad89e2ff9ba6589fd"
|
||||||
integrity sha512-CcLo3pwitf9JhhvW3/icCraxUhaIKJRyOys9XJlBBDn5TQskyJzxgveLKejcryHn4DooqlJPeMuM4ixdPFEERQ==
|
integrity sha512-CcLo3pwitf9JhhvW3/icCraxUhaIKJRyOys9XJlBBDn5TQskyJzxgveLKejcryHn4DooqlJPeMuM4ixdPFEERQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime-corejs2" "^7.17.8"
|
"@babel/runtime-corejs2" "^7.17.8"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user