@cornerstonejs/tools 4.17.0 → 4.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/drawingSvg/draw.js +4 -0
- package/dist/esm/drawingSvg/drawTextBox.js +8 -4
- package/dist/esm/tools/annotation/AngleTool.js +15 -29
- package/dist/esm/tools/annotation/ArrowAnnotateTool.js +9 -28
- package/dist/esm/tools/annotation/BidirectionalTool.js +10 -31
- package/dist/esm/tools/annotation/CircleROITool.js +12 -31
- package/dist/esm/tools/annotation/CobbAngleTool.js +14 -32
- package/dist/esm/tools/annotation/EllipticalROITool.js +11 -31
- package/dist/esm/tools/annotation/HeightTool.js +11 -31
- package/dist/esm/tools/annotation/LengthTool.js +10 -30
- package/dist/esm/tools/annotation/LivewireContourTool.js +20 -20
- package/dist/esm/tools/annotation/PlanarFreehandROITool.js +8 -21
- package/dist/esm/tools/annotation/ProbeTool.js +3 -5
- package/dist/esm/tools/annotation/RectangleROITool.js +10 -30
- package/dist/esm/tools/annotation/SplineROITool.js +20 -20
- package/dist/esm/tools/annotation/UltrasoundDirectionalTool.js +15 -29
- package/dist/esm/tools/base/AnnotationTool.d.ts +11 -0
- package/dist/esm/tools/base/AnnotationTool.js +50 -0
- package/dist/esm/tools/segmentation/CircleROIStartEndThresholdTool.js +15 -31
- package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.js +10 -30
- package/dist/esm/tools/segmentation/SegmentBidirectionalTool.js +10 -32
- package/dist/esm/utilities/drawing/getTextBoxCoordsCanvas.d.ts +1 -1
- package/dist/esm/utilities/drawing/getTextBoxCoordsCanvas.js +113 -3
- package/dist/esm/utilities/drawing/textBoxOverlapRegistry.d.ts +9 -0
- package/dist/esm/utilities/drawing/textBoxOverlapRegistry.js +20 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +3 -3
- package/dist/esm/tools/segmentation/strategies/__tests__/fillCircle.spec.d.ts +0 -1
- package/dist/esm/tools/segmentation/strategies/__tests__/fillCircle.spec.js +0 -27
|
@@ -14,8 +14,6 @@ import registerOpenContourEditLoop from './planarFreehandROITool/openContourEdit
|
|
|
14
14
|
import registerOpenContourEndEditLoop from './planarFreehandROITool/openContourEndEditLoop';
|
|
15
15
|
import registerRenderMethods from './planarFreehandROITool/renderMethods';
|
|
16
16
|
import { triggerAnnotationModified } from '../../stateManagement/annotation/helpers/state';
|
|
17
|
-
import { drawLinkedTextBox } from '../../drawingSvg';
|
|
18
|
-
import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
|
|
19
17
|
import { getLineSegmentIntersectionsCoordinates } from '../../utilities/math/polyline';
|
|
20
18
|
import { isViewportPreScaled } from '../../utilities/viewport/isViewportPreScaled';
|
|
21
19
|
import { BasicStatsCalculator } from '../../utilities/math/basic';
|
|
@@ -213,30 +211,19 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {
|
|
|
213
211
|
viewportId: enabledElement.viewport.id,
|
|
214
212
|
annotationUID: annotation.annotationUID,
|
|
215
213
|
};
|
|
216
|
-
const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
|
|
217
|
-
if (!options.visibility) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
214
|
const textLines = this.configuration.getTextLines(data, targetId);
|
|
221
215
|
if (!textLines || textLines.length === 0) {
|
|
222
216
|
return;
|
|
223
217
|
}
|
|
224
218
|
const canvasCoordinates = data.contour.polyline.map((p) => viewport.worldToCanvas(p));
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const { x: left, y: top, width, height } = boundingBox;
|
|
234
|
-
data.handles.textBox.worldBoundingBox = {
|
|
235
|
-
topLeft: viewport.canvasToWorld([left, top]),
|
|
236
|
-
topRight: viewport.canvasToWorld([left + width, top]),
|
|
237
|
-
bottomLeft: viewport.canvasToWorld([left, top + height]),
|
|
238
|
-
bottomRight: viewport.canvasToWorld([left + width, top + height]),
|
|
239
|
-
};
|
|
219
|
+
this.renderLinkedTextBoxAnnotation({
|
|
220
|
+
enabledElement,
|
|
221
|
+
svgDrawingHelper,
|
|
222
|
+
annotation,
|
|
223
|
+
styleSpecifier,
|
|
224
|
+
textLines,
|
|
225
|
+
canvasCoordinates,
|
|
226
|
+
});
|
|
240
227
|
};
|
|
241
228
|
registerDrawLoop(this);
|
|
242
229
|
registerEditLoopCommon(this);
|
|
@@ -5,6 +5,7 @@ import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateMan
|
|
|
5
5
|
import { triggerAnnotationCompleted, triggerAnnotationModified, } from '../../stateManagement/annotation/helpers/state';
|
|
6
6
|
import { getCalibratedProbeUnitsAndValue } from '../../utilities/getCalibratedUnits';
|
|
7
7
|
import { drawHandles as drawHandlesSvg, drawTextBox as drawTextBoxSvg, } from '../../drawingSvg';
|
|
8
|
+
import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
|
|
8
9
|
import { state } from '../../store/state';
|
|
9
10
|
import { ChangeTypes, Events } from '../../enums';
|
|
10
11
|
import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
|
|
@@ -207,12 +208,9 @@ class ProbeTool extends AnnotationTool {
|
|
|
207
208
|
}
|
|
208
209
|
const textLines = this.configuration.getTextLines(data, targetId);
|
|
209
210
|
if (textLines) {
|
|
210
|
-
const textCanvasCoordinates = [
|
|
211
|
-
canvasCoordinates[0] + this.configuration.textCanvasOffset.x,
|
|
212
|
-
canvasCoordinates[1] + this.configuration.textCanvasOffset.y,
|
|
213
|
-
];
|
|
211
|
+
const textCanvasCoordinates = getTextBoxCoordsCanvas([canvasCoordinates], element, textLines);
|
|
214
212
|
const textUID = '0';
|
|
215
|
-
drawTextBoxSvg(svgDrawingHelper, annotationUID, textUID, textLines,
|
|
213
|
+
drawTextBoxSvg(svgDrawingHelper, annotationUID, textUID, textLines, textCanvasCoordinates, options);
|
|
216
214
|
}
|
|
217
215
|
}
|
|
218
216
|
return renderStatus;
|
|
@@ -7,12 +7,11 @@ import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateMan
|
|
|
7
7
|
import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
|
|
8
8
|
import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
|
|
9
9
|
import { triggerAnnotationCompleted, triggerAnnotationModified, } from '../../stateManagement/annotation/helpers/state';
|
|
10
|
-
import { drawHandles as drawHandlesSvg,
|
|
10
|
+
import { drawHandles as drawHandlesSvg, drawRectByCoordinates as drawRectSvg, } from '../../drawingSvg';
|
|
11
11
|
import { state } from '../../store/state';
|
|
12
12
|
import { ChangeTypes, Events } from '../../enums';
|
|
13
13
|
import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
|
|
14
14
|
import * as rectangle from '../../utilities/math/rectangle';
|
|
15
|
-
import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
|
|
16
15
|
import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
|
|
17
16
|
import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
|
|
18
17
|
import { getPixelValueUnits } from '../../utilities/getPixelValueUnits';
|
|
@@ -396,39 +395,20 @@ class RectangleROITool extends AnnotationTool {
|
|
|
396
395
|
lineWidth,
|
|
397
396
|
}, dataId);
|
|
398
397
|
renderStatus = true;
|
|
399
|
-
const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
|
|
400
|
-
if (!options.visibility) {
|
|
401
|
-
data.handles.textBox = {
|
|
402
|
-
hasMoved: false,
|
|
403
|
-
worldPosition: [0, 0, 0],
|
|
404
|
-
worldBoundingBox: {
|
|
405
|
-
topLeft: [0, 0, 0],
|
|
406
|
-
topRight: [0, 0, 0],
|
|
407
|
-
bottomLeft: [0, 0, 0],
|
|
408
|
-
bottomRight: [0, 0, 0],
|
|
409
|
-
},
|
|
410
|
-
};
|
|
411
|
-
continue;
|
|
412
|
-
}
|
|
413
398
|
const textLines = this.configuration.getTextLines(data, targetId);
|
|
414
399
|
if (!textLines || textLines.length === 0) {
|
|
415
400
|
continue;
|
|
416
401
|
}
|
|
417
|
-
if (!
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
402
|
+
if (!this.renderLinkedTextBoxAnnotation({
|
|
403
|
+
enabledElement,
|
|
404
|
+
svgDrawingHelper,
|
|
405
|
+
annotation,
|
|
406
|
+
styleSpecifier,
|
|
407
|
+
textLines,
|
|
408
|
+
canvasCoordinates,
|
|
409
|
+
})) {
|
|
410
|
+
continue;
|
|
421
411
|
}
|
|
422
|
-
const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
|
|
423
|
-
const textBoxUID = '1';
|
|
424
|
-
const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, options);
|
|
425
|
-
const { x: left, y: top, width, height } = boundingBox;
|
|
426
|
-
data.handles.textBox.worldBoundingBox = {
|
|
427
|
-
topLeft: viewport.canvasToWorld([left, top]),
|
|
428
|
-
topRight: viewport.canvasToWorld([left + width, top]),
|
|
429
|
-
bottomLeft: viewport.canvasToWorld([left, top + height]),
|
|
430
|
-
bottomRight: viewport.canvasToWorld([left + width, top + height]),
|
|
431
|
-
};
|
|
432
412
|
}
|
|
433
413
|
return renderStatus;
|
|
434
414
|
};
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { getEnabledElement, eventTarget, triggerEvent, utilities, getEnabledElementByViewportId, } from '@cornerstonejs/core';
|
|
2
2
|
import { vec3 } from 'gl-matrix';
|
|
3
3
|
import { addAnnotation, getChildAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
|
|
4
|
-
import { drawHandles as drawHandlesSvg, drawPolyline as drawPolylineSvg,
|
|
4
|
+
import { drawHandles as drawHandlesSvg, drawPolyline as drawPolylineSvg, } from '../../drawingSvg';
|
|
5
5
|
import { state } from '../../store/state';
|
|
6
6
|
import { Events, MouseBindings, KeyboardBindings, ChangeTypes, } from '../../enums';
|
|
7
7
|
import * as math from '../../utilities/math';
|
|
8
8
|
import throttle from '../../utilities/throttle';
|
|
9
9
|
import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
|
|
10
|
-
import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
|
|
11
10
|
import { getCalibratedLengthUnitsAndScale } from '../../utilities/getCalibratedUnits';
|
|
12
11
|
import getMouseModifierKey from '../../eventDispatchers/shared/getMouseModifier';
|
|
13
12
|
import { ContourWindingDirection } from '../../types/ContourAnnotation';
|
|
@@ -364,32 +363,33 @@ class SplineROITool extends ContourSegmentationBaseTool {
|
|
|
364
363
|
element.removeEventListener(Events.MOUSE_DOUBLE_CLICK, this._mouseDownCallback);
|
|
365
364
|
element.removeEventListener(Events.TOUCH_TAP, this._mouseDownCallback);
|
|
366
365
|
};
|
|
367
|
-
this._renderStats = (annotation,
|
|
366
|
+
this._renderStats = (annotation, enabledElement, svgDrawingHelper) => {
|
|
368
367
|
const data = annotation.data;
|
|
368
|
+
const { viewport } = enabledElement;
|
|
369
369
|
const targetId = this.getTargetId(viewport);
|
|
370
|
-
if (!data.spline.instance.closed
|
|
370
|
+
if (!data.spline.instance.closed) {
|
|
371
371
|
return;
|
|
372
372
|
}
|
|
373
|
+
const styleSpecifier = {
|
|
374
|
+
toolGroupId: this.toolGroupId,
|
|
375
|
+
toolName: this.getToolName(),
|
|
376
|
+
viewportId: enabledElement.viewport.id,
|
|
377
|
+
annotationUID: annotation.annotationUID,
|
|
378
|
+
};
|
|
373
379
|
const textLines = this.configuration.getTextLines(data, targetId);
|
|
374
380
|
if (!textLines || textLines.length === 0) {
|
|
375
381
|
return;
|
|
376
382
|
}
|
|
377
383
|
const canvasCoordinates = data.handles.points.map((p) => viewport.worldToCanvas(p));
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
data.handles.textBox.worldBoundingBox = {
|
|
388
|
-
topLeft: viewport.canvasToWorld([left, top]),
|
|
389
|
-
topRight: viewport.canvasToWorld([left + width, top]),
|
|
390
|
-
bottomLeft: viewport.canvasToWorld([left, top + height]),
|
|
391
|
-
bottomRight: viewport.canvasToWorld([left + width, top + height]),
|
|
392
|
-
};
|
|
384
|
+
this.renderLinkedTextBoxAnnotation({
|
|
385
|
+
enabledElement,
|
|
386
|
+
svgDrawingHelper,
|
|
387
|
+
annotation,
|
|
388
|
+
styleSpecifier,
|
|
389
|
+
textLines,
|
|
390
|
+
canvasCoordinates,
|
|
391
|
+
textBoxUID: 'textBox',
|
|
392
|
+
});
|
|
393
393
|
};
|
|
394
394
|
this.addControlPointCallback = (evt, annotation) => {
|
|
395
395
|
const { data } = annotation;
|
|
@@ -661,7 +661,7 @@ class SplineROITool extends ContourSegmentationBaseTool {
|
|
|
661
661
|
lineWidth: 1,
|
|
662
662
|
});
|
|
663
663
|
}
|
|
664
|
-
this._renderStats(annotation,
|
|
664
|
+
this._renderStats(annotation, enabledElement, svgDrawingHelper);
|
|
665
665
|
if (this.fireChangeOnUpdate?.annotationUID === annotationUID) {
|
|
666
666
|
this.triggerChangeEvent(annotation, enabledElement, this.fireChangeOnUpdate.changeType, this.fireChangeOnUpdate.contourHoleProcessingEnabled);
|
|
667
667
|
this.fireChangeOnUpdate = null;
|
|
@@ -4,7 +4,7 @@ import { AnnotationTool } from '../base';
|
|
|
4
4
|
import throttle from '../../utilities/throttle';
|
|
5
5
|
import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
|
|
6
6
|
import { triggerAnnotationCompleted, triggerAnnotationModified, } from '../../stateManagement/annotation/helpers/state';
|
|
7
|
-
import { drawHandle as drawHandleSvg, drawLine as drawLineSvg,
|
|
7
|
+
import { drawHandle as drawHandleSvg, drawLine as drawLineSvg, } from '../../drawingSvg';
|
|
8
8
|
import { state } from '../../store/state';
|
|
9
9
|
import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
|
|
10
10
|
import { distanceToPoint } from '../../utilities/math/point';
|
|
@@ -308,36 +308,22 @@ class UltrasoundDirectionalTool extends AnnotationTool {
|
|
|
308
308
|
shadow: this.configuration.shadow,
|
|
309
309
|
}, dataId);
|
|
310
310
|
}
|
|
311
|
-
const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
|
|
312
|
-
if (!options.visibility) {
|
|
313
|
-
data.handles.textBox = {
|
|
314
|
-
hasMoved: false,
|
|
315
|
-
worldPosition: [0, 0, 0],
|
|
316
|
-
worldBoundingBox: {
|
|
317
|
-
topLeft: [0, 0, 0],
|
|
318
|
-
topRight: [0, 0, 0],
|
|
319
|
-
bottomLeft: [0, 0, 0],
|
|
320
|
-
bottomRight: [0, 0, 0],
|
|
321
|
-
},
|
|
322
|
-
};
|
|
323
|
-
continue;
|
|
324
|
-
}
|
|
325
311
|
const textLines = this.configuration.getTextLines(data, targetId, this.configuration);
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
312
|
+
const vertexAnchor = [
|
|
313
|
+
canvasCoordinates[1],
|
|
314
|
+
canvasCoordinates[1],
|
|
315
|
+
];
|
|
316
|
+
if (!this.renderLinkedTextBoxAnnotation({
|
|
317
|
+
enabledElement,
|
|
318
|
+
svgDrawingHelper,
|
|
319
|
+
annotation,
|
|
320
|
+
styleSpecifier,
|
|
321
|
+
textLines,
|
|
322
|
+
canvasCoordinates,
|
|
323
|
+
placementPoints: vertexAnchor,
|
|
324
|
+
})) {
|
|
325
|
+
continue;
|
|
330
326
|
}
|
|
331
|
-
const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
|
|
332
|
-
const textBoxUID = '1';
|
|
333
|
-
const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, options);
|
|
334
|
-
const { x: left, y: top, width, height } = boundingBox;
|
|
335
|
-
data.handles.textBox.worldBoundingBox = {
|
|
336
|
-
topLeft: viewport.canvasToWorld([left, top]),
|
|
337
|
-
topRight: viewport.canvasToWorld([left + width, top]),
|
|
338
|
-
bottomLeft: viewport.canvasToWorld([left, top + height]),
|
|
339
|
-
bottomRight: viewport.canvasToWorld([left + width, top + height]),
|
|
340
|
-
};
|
|
341
327
|
}
|
|
342
328
|
return renderStatus;
|
|
343
329
|
};
|
|
@@ -3,6 +3,7 @@ import type { Types } from '@cornerstonejs/core';
|
|
|
3
3
|
import AnnotationDisplayTool from './AnnotationDisplayTool';
|
|
4
4
|
import type { Annotation, Annotations, EventTypes, ToolHandle, InteractionTypes, ToolProps, PublicToolProps } from '../../types';
|
|
5
5
|
import type { AnnotationStyle, StyleSpecifier } from '../../types/AnnotationStyle';
|
|
6
|
+
import type { SVGDrawingHelper } from '../../types';
|
|
6
7
|
declare abstract class AnnotationTool extends AnnotationDisplayTool {
|
|
7
8
|
protected eventDispatchDetail: {
|
|
8
9
|
viewportId: string;
|
|
@@ -30,6 +31,16 @@ declare abstract class AnnotationTool extends AnnotationDisplayTool {
|
|
|
30
31
|
mouseMoveCallback: (evt: EventTypes.MouseMoveEventType, filteredAnnotations?: Annotations) => boolean;
|
|
31
32
|
getHandleNearImagePoint(element: HTMLDivElement, annotation: Annotation, canvasCoords: Types.Point2, proximity: number): ToolHandle | undefined;
|
|
32
33
|
getLinkedTextBoxStyle(specifications: StyleSpecifier, annotation?: Annotation): Record<string, unknown>;
|
|
34
|
+
protected renderLinkedTextBoxAnnotation(options: {
|
|
35
|
+
enabledElement: Types.IEnabledElement;
|
|
36
|
+
svgDrawingHelper: SVGDrawingHelper;
|
|
37
|
+
annotation: Annotation;
|
|
38
|
+
styleSpecifier: StyleSpecifier;
|
|
39
|
+
textLines: string[];
|
|
40
|
+
canvasCoordinates: Types.Point2[];
|
|
41
|
+
textBoxUID?: string;
|
|
42
|
+
placementPoints?: Types.Point2[];
|
|
43
|
+
}): boolean;
|
|
33
44
|
static isSuvScaled(viewport: Types.IStackViewport | Types.IVolumeViewport, targetId: string, imageId?: string): boolean;
|
|
34
45
|
isSuvScaled: typeof AnnotationTool.isSuvScaled;
|
|
35
46
|
protected getAnnotationStyle(context: {
|
|
@@ -5,6 +5,8 @@ import { isAnnotationLocked } from '../../stateManagement/annotation/annotationL
|
|
|
5
5
|
import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
|
|
6
6
|
import { addAnnotation, removeAnnotation, getAnnotation, } from '../../stateManagement/annotation/annotationState';
|
|
7
7
|
import { triggerAnnotationModified } from '../../stateManagement/annotation/helpers/state';
|
|
8
|
+
import { drawLinkedTextBox } from '../../drawingSvg';
|
|
9
|
+
import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
|
|
8
10
|
import ChangeTypes from '../../enums/ChangeTypes';
|
|
9
11
|
import { setAnnotationSelected } from '../../stateManagement/annotation/annotationSelection';
|
|
10
12
|
import { addContourSegmentationAnnotation } from '../../utilities/contourSegmentation';
|
|
@@ -112,6 +114,54 @@ class AnnotationTool extends AnnotationDisplayTool {
|
|
|
112
114
|
textBoxLinkLineColor: this.getStyle('textBoxLinkLineColor', specifications, annotation),
|
|
113
115
|
};
|
|
114
116
|
}
|
|
117
|
+
renderLinkedTextBoxAnnotation(options) {
|
|
118
|
+
const { enabledElement, svgDrawingHelper, annotation, styleSpecifier, textLines, canvasCoordinates, textBoxUID = '1', placementPoints, } = options;
|
|
119
|
+
const { viewport } = enabledElement;
|
|
120
|
+
const { element } = viewport;
|
|
121
|
+
const { annotationUID, data } = annotation;
|
|
122
|
+
const styleOptions = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
|
|
123
|
+
if (!styleOptions.visibility) {
|
|
124
|
+
data.handles.textBox = {
|
|
125
|
+
hasMoved: false,
|
|
126
|
+
worldPosition: [0, 0, 0],
|
|
127
|
+
worldBoundingBox: {
|
|
128
|
+
topLeft: [0, 0, 0],
|
|
129
|
+
topRight: [0, 0, 0],
|
|
130
|
+
bottomLeft: [0, 0, 0],
|
|
131
|
+
bottomRight: [0, 0, 0],
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
if (!data.handles.textBox) {
|
|
137
|
+
data.handles.textBox = {
|
|
138
|
+
hasMoved: false,
|
|
139
|
+
worldPosition: [0, 0, 0],
|
|
140
|
+
worldBoundingBox: {
|
|
141
|
+
topLeft: [0, 0, 0],
|
|
142
|
+
topRight: [0, 0, 0],
|
|
143
|
+
bottomLeft: [0, 0, 0],
|
|
144
|
+
bottomRight: [0, 0, 0],
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const pointsForPlacement = placementPoints ?? canvasCoordinates;
|
|
149
|
+
if (!data.handles.textBox.hasMoved) {
|
|
150
|
+
const canvasTextBoxCoords = getTextBoxCoordsCanvas(pointsForPlacement, element, textLines);
|
|
151
|
+
data.handles.textBox.worldPosition =
|
|
152
|
+
viewport.canvasToWorld(canvasTextBoxCoords);
|
|
153
|
+
}
|
|
154
|
+
const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
|
|
155
|
+
const boundingBox = drawLinkedTextBox(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, styleOptions);
|
|
156
|
+
const { x: left, y: top, width, height } = boundingBox;
|
|
157
|
+
data.handles.textBox.worldBoundingBox = {
|
|
158
|
+
topLeft: viewport.canvasToWorld([left, top]),
|
|
159
|
+
topRight: viewport.canvasToWorld([left + width, top]),
|
|
160
|
+
bottomLeft: viewport.canvasToWorld([left, top + height]),
|
|
161
|
+
bottomRight: viewport.canvasToWorld([left + width, top + height]),
|
|
162
|
+
};
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
115
165
|
static isSuvScaled(viewport, targetId, imageId) {
|
|
116
166
|
if (viewport instanceof BaseVolumeViewport) {
|
|
117
167
|
const volumeId = csUtils.getVolumeId(targetId);
|
|
@@ -2,10 +2,9 @@ import { StackViewport, cache, getEnabledElement, utilities as csUtils, utilitie
|
|
|
2
2
|
import { vec3 } from 'gl-matrix';
|
|
3
3
|
import { addAnnotation, removeAnnotation, getAnnotations, } from '../../stateManagement/annotation/annotationState';
|
|
4
4
|
import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
|
|
5
|
-
import { drawCircle as drawCircleSvg, drawHandles as drawHandlesSvg,
|
|
5
|
+
import { drawCircle as drawCircleSvg, drawHandles as drawHandlesSvg, } from '../../drawingSvg';
|
|
6
6
|
import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
|
|
7
7
|
import getWorldWidthAndHeightFromTwoPoints from '../../utilities/planar/getWorldWidthAndHeightFromTwoPoints';
|
|
8
|
-
import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
|
|
9
8
|
import throttle from '../../utilities/throttle';
|
|
10
9
|
import debounce from '../../utilities/debounce';
|
|
11
10
|
import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
|
|
@@ -279,40 +278,25 @@ class CircleROIStartEndThresholdTool extends CircleROITool {
|
|
|
279
278
|
}
|
|
280
279
|
renderStatus = true;
|
|
281
280
|
if (this.configuration.showTextBox) {
|
|
282
|
-
const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
|
|
283
|
-
if (!options.visibility) {
|
|
284
|
-
data.handles.textBox = {
|
|
285
|
-
hasMoved: false,
|
|
286
|
-
worldPosition: [0, 0, 0],
|
|
287
|
-
worldBoundingBox: {
|
|
288
|
-
topLeft: [0, 0, 0],
|
|
289
|
-
topRight: [0, 0, 0],
|
|
290
|
-
bottomLeft: [0, 0, 0],
|
|
291
|
-
bottomRight: [0, 0, 0],
|
|
292
|
-
},
|
|
293
|
-
};
|
|
294
|
-
continue;
|
|
295
|
-
}
|
|
296
281
|
const textLines = this.configuration.getTextLines(data, { metadata });
|
|
297
282
|
if (!textLines || textLines.length === 0) {
|
|
298
283
|
continue;
|
|
299
284
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
285
|
+
const linkAnchorPoints = [
|
|
286
|
+
canvasCoordinates[0],
|
|
287
|
+
canvasCoordinates[1],
|
|
288
|
+
];
|
|
289
|
+
if (!this.renderLinkedTextBoxAnnotation({
|
|
290
|
+
enabledElement,
|
|
291
|
+
svgDrawingHelper,
|
|
292
|
+
annotation,
|
|
293
|
+
styleSpecifier,
|
|
294
|
+
textLines,
|
|
295
|
+
canvasCoordinates: linkAnchorPoints,
|
|
296
|
+
placementPoints: canvasCorners,
|
|
297
|
+
})) {
|
|
298
|
+
continue;
|
|
305
299
|
}
|
|
306
|
-
const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
|
|
307
|
-
const textBoxUID = '1';
|
|
308
|
-
const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, [canvasCoordinates[0], canvasCoordinates[1]], {}, options);
|
|
309
|
-
const { x: left, y: top, width, height } = boundingBox;
|
|
310
|
-
data.handles.textBox.worldBoundingBox = {
|
|
311
|
-
topLeft: viewport.canvasToWorld([left, top]),
|
|
312
|
-
topRight: viewport.canvasToWorld([left + width, top]),
|
|
313
|
-
bottomLeft: viewport.canvasToWorld([left, top + height]),
|
|
314
|
-
bottomRight: viewport.canvasToWorld([left + width, top + height]),
|
|
315
|
-
};
|
|
316
300
|
}
|
|
317
301
|
}
|
|
318
302
|
return renderStatus;
|
|
@@ -3,11 +3,10 @@ import { getCalibratedLengthUnitsAndScale } from '../../utilities/getCalibratedU
|
|
|
3
3
|
import { vec3 } from 'gl-matrix';
|
|
4
4
|
import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateManagement';
|
|
5
5
|
import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
|
|
6
|
-
import { drawHandles as drawHandlesSvg, drawRect as drawRectSvg,
|
|
6
|
+
import { drawHandles as drawHandlesSvg, drawRect as drawRectSvg, } from '../../drawingSvg';
|
|
7
7
|
import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
|
|
8
8
|
import throttle from '../../utilities/throttle';
|
|
9
9
|
import debounce from '../../utilities/debounce';
|
|
10
|
-
import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
|
|
11
10
|
import getWorldWidthAndHeightFromCorners from '../../utilities/planar/getWorldWidthAndHeightFromCorners';
|
|
12
11
|
import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
|
|
13
12
|
import { hideElementCursor, resetElementCursor, } from '../../cursors/elementCursor';
|
|
@@ -240,39 +239,20 @@ class RectangleROIStartEndThresholdTool extends RectangleROITool {
|
|
|
240
239
|
});
|
|
241
240
|
renderStatus = true;
|
|
242
241
|
if (this.configuration.showTextBox) {
|
|
243
|
-
const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
|
|
244
|
-
if (!options.visibility) {
|
|
245
|
-
data.handles.textBox = {
|
|
246
|
-
hasMoved: false,
|
|
247
|
-
worldPosition: [0, 0, 0],
|
|
248
|
-
worldBoundingBox: {
|
|
249
|
-
topLeft: [0, 0, 0],
|
|
250
|
-
topRight: [0, 0, 0],
|
|
251
|
-
bottomLeft: [0, 0, 0],
|
|
252
|
-
bottomRight: [0, 0, 0],
|
|
253
|
-
},
|
|
254
|
-
};
|
|
255
|
-
continue;
|
|
256
|
-
}
|
|
257
242
|
const textLines = this.configuration.getTextLines(data, { metadata });
|
|
258
243
|
if (!textLines || textLines.length === 0) {
|
|
259
244
|
continue;
|
|
260
245
|
}
|
|
261
|
-
if (!
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
246
|
+
if (!this.renderLinkedTextBoxAnnotation({
|
|
247
|
+
enabledElement,
|
|
248
|
+
svgDrawingHelper,
|
|
249
|
+
annotation,
|
|
250
|
+
styleSpecifier,
|
|
251
|
+
textLines,
|
|
252
|
+
canvasCoordinates,
|
|
253
|
+
})) {
|
|
254
|
+
continue;
|
|
265
255
|
}
|
|
266
|
-
const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
|
|
267
|
-
const textBoxUID = '1';
|
|
268
|
-
const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, options);
|
|
269
|
-
const { x: left, y: top, width, height } = boundingBox;
|
|
270
|
-
data.handles.textBox.worldBoundingBox = {
|
|
271
|
-
topLeft: viewport.canvasToWorld([left, top]),
|
|
272
|
-
topRight: viewport.canvasToWorld([left + width, top]),
|
|
273
|
-
bottomLeft: viewport.canvasToWorld([left, top + height]),
|
|
274
|
-
bottomRight: viewport.canvasToWorld([left + width, top + height]),
|
|
275
|
-
};
|
|
276
256
|
}
|
|
277
257
|
}
|
|
278
258
|
return renderStatus;
|
|
@@ -2,9 +2,8 @@ import { getEnabledElement, utilities as csUtils, getEnabledElementByViewportId,
|
|
|
2
2
|
import { addAnnotation, getAllAnnotations, getAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
|
|
3
3
|
import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
|
|
4
4
|
import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
|
|
5
|
-
import { drawLine as drawLineSvg, drawHandles as drawHandlesSvg,
|
|
5
|
+
import { drawLine as drawLineSvg, drawHandles as drawHandlesSvg, } from '../../drawingSvg';
|
|
6
6
|
import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
|
|
7
|
-
import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
|
|
8
7
|
import { hideElementCursor } from '../../cursors/elementCursor';
|
|
9
8
|
import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
|
|
10
9
|
import BidirectionalTool from '../annotation/BidirectionalTool';
|
|
@@ -94,41 +93,20 @@ class SegmentBidirectionalTool extends BidirectionalTool {
|
|
|
94
93
|
shadow,
|
|
95
94
|
}, dataId2);
|
|
96
95
|
renderStatus = true;
|
|
97
|
-
const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
|
|
98
|
-
if (!options.visibility) {
|
|
99
|
-
data.handles.textBox = {
|
|
100
|
-
hasMoved: false,
|
|
101
|
-
worldPosition: [0, 0, 0],
|
|
102
|
-
worldBoundingBox: {
|
|
103
|
-
topLeft: [0, 0, 0],
|
|
104
|
-
topRight: [0, 0, 0],
|
|
105
|
-
bottomLeft: [0, 0, 0],
|
|
106
|
-
bottomRight: [0, 0, 0],
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
options.color = color;
|
|
112
96
|
const textLines = this.configuration.getTextLines(data, targetId);
|
|
113
97
|
if (!textLines || textLines.length === 0) {
|
|
114
98
|
continue;
|
|
115
99
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
100
|
+
if (!this.renderLinkedTextBoxAnnotation({
|
|
101
|
+
enabledElement,
|
|
102
|
+
svgDrawingHelper,
|
|
103
|
+
annotation,
|
|
104
|
+
styleSpecifier,
|
|
105
|
+
textLines,
|
|
106
|
+
canvasCoordinates,
|
|
107
|
+
})) {
|
|
108
|
+
continue;
|
|
121
109
|
}
|
|
122
|
-
const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
|
|
123
|
-
const textBoxUID = '1';
|
|
124
|
-
const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, options);
|
|
125
|
-
const { x: left, y: top, width, height } = boundingBox;
|
|
126
|
-
data.handles.textBox.worldBoundingBox = {
|
|
127
|
-
topLeft: viewport.canvasToWorld([left, top]),
|
|
128
|
-
topRight: viewport.canvasToWorld([left + width, top]),
|
|
129
|
-
bottomLeft: viewport.canvasToWorld([left, top + height]),
|
|
130
|
-
bottomRight: viewport.canvasToWorld([left + width, top + height]),
|
|
131
|
-
};
|
|
132
110
|
}
|
|
133
111
|
return renderStatus;
|
|
134
112
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Types } from '@cornerstonejs/core';
|
|
2
|
-
export default function getTextBoxCoordsCanvas(annotationCanvasPoints: Array<Types.Point2>): Types.Point2;
|
|
2
|
+
export default function getTextBoxCoordsCanvas(annotationCanvasPoints: Array<Types.Point2>, element?: HTMLDivElement, textLines?: Array<string>): Types.Point2;
|