Skip to content

Commit

Permalink
fix(rectangle): ROI and Rotation Tool Interaction (RectangleROITool) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
kom482 committed May 15, 2024
1 parent 31481a2 commit 29a3edb
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 56 deletions.
4 changes: 4 additions & 0 deletions common/reviews/api/tools.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,7 @@ declare namespace drawing {
drawPath,
drawLinkedTextBox,
drawRect,
drawRectByCoordinates,
drawTextBox,
drawArrow,
drawRedactionRect,
Expand Down Expand Up @@ -2036,6 +2037,9 @@ function drawPolyline(svgDrawingHelper: SVGDrawingHelper, annotationUID: string,
// @public (undocumented)
function drawRect(svgDrawingHelper: SVGDrawingHelper, annotationUID: string, rectangleUID: string, start: Types_2.Point2, end: Types_2.Point2, options?: {}, dataId?: string): void;

// @public (undocumented)
function drawRectByCoordinates(svgDrawingHelper: SVGDrawingHelper, annotationUID: string, rectangleUID: string, canvasCoordinates: Types_2.Point2[], options?: {}, dataId?: string): void;

// @public (undocumented)
function drawRedactionRect(svgDrawingHelper: any, annotationUID: string, rectangleUID: string, start: any, end: any, options?: {}): void;

Expand Down
67 changes: 14 additions & 53 deletions packages/tools/src/drawingSvg/drawRect.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { Types } from '@cornerstonejs/core';

import _getHash from './_getHash';
import setAttributesIfNecessary from './setAttributesIfNecessary';
import setNewAttributesIfValid from './setNewAttributesIfValid';
import { SVGDrawingHelper } from '../types';
import drawRectByCoordinates from './drawRectByCoordinates';

// This method is obsolete due to not supporting rotation tool. Please use drawRectByCoordinates instead.
// <rect x="120" y="100" width="100" height="100" />
export default function drawRect(
svgDrawingHelper: SVGDrawingHelper,
Expand All @@ -15,56 +15,17 @@ export default function drawRect(
options = {},
dataId = ''
): void {
const {
color,
width: _width,
lineWidth,
lineDash,
} = Object.assign(
{
color: 'rgb(0, 255, 0)',
width: '2',
lineWidth: undefined,
lineDash: undefined,
},
options
const topLeft: Types.Point2 = [start[0], start[1]];
const topRight: Types.Point2 = [end[0], start[1]];
const bottomLeft: Types.Point2 = [start[0], end[1]];
const bottomRight: Types.Point2 = [end[0], end[1]];

drawRectByCoordinates(
svgDrawingHelper,
annotationUID,
rectangleUID,
[topLeft, topRight, bottomLeft, bottomRight],
options,
dataId
);

// for supporting both lineWidth and width options
const strokeWidth = lineWidth || _width;

const svgns = 'http://www.w3.org/2000/svg';
const svgNodeHash = _getHash(annotationUID, 'rect', rectangleUID);
const existingRect = svgDrawingHelper.getSvgNode(svgNodeHash);

const tlhc = [Math.min(start[0], end[0]), Math.min(start[1], end[1])];
const width = Math.abs(start[0] - end[0]);
const height = Math.abs(start[1] - end[1]);

const attributes = {
x: `${tlhc[0]}`,
y: `${tlhc[1]}`,
width: `${width}`,
height: `${height}`,
stroke: color,
fill: 'transparent',
'stroke-width': strokeWidth,
'stroke-dasharray': lineDash,
};

if (existingRect) {
setAttributesIfNecessary(attributes, existingRect);

svgDrawingHelper.setNodeTouched(svgNodeHash);
} else {
const svgRectElement = document.createElementNS(svgns, 'rect');

if (dataId !== '') {
svgRectElement.setAttribute('data-id', dataId);
}

setNewAttributesIfValid(attributes, svgRectElement);

svgDrawingHelper.appendNode(svgRectElement, svgNodeHash);
}
}
87 changes: 87 additions & 0 deletions packages/tools/src/drawingSvg/drawRectByCoordinates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import type { Types } from '@cornerstonejs/core';

import _getHash from './_getHash';
import setAttributesIfNecessary from './setAttributesIfNecessary';
import setNewAttributesIfValid from './setNewAttributesIfValid';
import { SVGDrawingHelper } from '../types';

export default function drawRectByCoordinates(
svgDrawingHelper: SVGDrawingHelper,
annotationUID: string,
rectangleUID: string,
canvasCoordinates: Types.Point2[],
options = {},
dataId = ''
): void {
const {
color,
width: _width,
lineWidth,
lineDash,
} = Object.assign(
{
color: 'rgb(0, 255, 0)',
width: '2',
lineWidth: undefined,
lineDash: undefined,
},
options
);

// for supporting both lineWidth and width options

const strokeWidth = lineWidth || _width;

const svgns = 'http://www.w3.org/2000/svg';
const svgNodeHash = _getHash(annotationUID, 'rect', rectangleUID);
const existingRect = svgDrawingHelper.getSvgNode(svgNodeHash);

const [topLeft, topRight, bottomLeft, bottomRight] = canvasCoordinates;

const width = Math.hypot(topLeft[0] - topRight[0], topLeft[1] - topRight[1]);
const height = Math.hypot(
topLeft[0] - bottomLeft[0],
topLeft[1] - bottomLeft[1]
);

const center = [
(bottomRight[0] + topLeft[0]) / 2,
(bottomRight[1] + topLeft[1]) / 2,
];
const leftEdgeCenter = [
(bottomLeft[0] + topLeft[0]) / 2,
(bottomLeft[1] + topLeft[1]) / 2,
];
const angle =
(Math.atan2(center[1] - leftEdgeCenter[1], center[0] - leftEdgeCenter[0]) *
180) /
Math.PI;

const attributes = {
x: `${center[0] - width / 2}`,
y: `${center[1] - height / 2}`,
width: `${width}`,
height: `${height}`,
stroke: color,
fill: 'transparent',
transform: `rotate(${angle} ${center[0]} ${center[1]})`,
'stroke-width': strokeWidth,
'stroke-dasharray': lineDash,
};

if (existingRect) {
setAttributesIfNecessary(attributes, existingRect);

svgDrawingHelper.setNodeTouched(svgNodeHash);
} else {
const svgRectElement = document.createElementNS(svgns, 'rect');

if (dataId !== '') {
svgRectElement.setAttribute('data-id', dataId);
}

setNewAttributesIfValid(attributes, svgRectElement);

svgDrawingHelper.appendNode(svgRectElement, svgNodeHash);
}
}
2 changes: 2 additions & 0 deletions packages/tools/src/drawingSvg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import drawPolyline from './drawPolyline';
import drawPath from './drawPath';
import drawLinkedTextBox from './drawLinkedTextBox';
import drawRect from './drawRect';
import drawRectByCoordinates from './drawRectByCoordinates';
import drawTextBox from './drawTextBox';
import drawArrow from './drawArrow';
import drawRedactionRect from './drawRedactionRect';
Expand All @@ -27,6 +28,7 @@ export {
drawPath,
drawLinkedTextBox,
drawRect,
drawRectByCoordinates,
drawTextBox,
drawArrow,
drawRedactionRect,
Expand Down
5 changes: 2 additions & 3 deletions packages/tools/src/tools/annotation/RectangleROITool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
import {
drawHandles as drawHandlesSvg,
drawLinkedTextBox as drawLinkedTextBoxSvg,
drawRect as drawRectSvg,
drawRectByCoordinates as drawRectSvg,
} from '../../drawingSvg';
import { state } from '../../store';
import { Events } from '../../enums';
Expand Down Expand Up @@ -748,8 +748,7 @@ class RectangleROITool extends AnnotationTool {
svgDrawingHelper,
annotationUID,
rectangleUID,
canvasCoordinates[0],
canvasCoordinates[3],
canvasCoordinates,
{
color,
lineDash,
Expand Down

0 comments on commit 29a3edb

Please sign in to comment.