Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d20dd89

Browse files
committedDec 20, 2024
feat(LabelTool): add label tool
fixes cornerstonejs#1716
1 parent 1732887 commit d20dd89

File tree

7 files changed

+639
-0
lines changed

7 files changed

+639
-0
lines changed
 

‎packages/tools/examples/dynamicallyAddAnnotations/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
ArrowAnnotateTool,
1818
CircleROITool,
1919
EllipticalROITool,
20+
LabelTool,
2021
LengthTool,
2122
ProbeTool,
2223
RectangleROITool,
@@ -32,6 +33,7 @@ console.debug(
3233
);
3334

3435
const tools = [
36+
LabelTool,
3537
AngleTool,
3638
ArrowAnnotateTool,
3739
EllipticalROITool,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { getEnabledElementByViewportId, utilities } from '@cornerstonejs/core';
2+
import type { Point2 } from '@cornerstonejs/core/types';
3+
import { LabelTool } from '@cornerstonejs/tools';
4+
import { typeToIdMap, typeToStartIdMap, typeToEndIdMap } from './constants';
5+
6+
function getInputValue(form: HTMLFormElement, inputId: string): number {
7+
return Number((form.querySelector(`#${inputId}`) as HTMLInputElement).value);
8+
}
9+
10+
function getCoordinates(
11+
form: HTMLFormElement,
12+
type: 'canvas' | 'image'
13+
): Point2 {
14+
const position: Point2 = [
15+
getInputValue(form, `${typeToStartIdMap[type]}-1`),
16+
getInputValue(form, `${typeToStartIdMap[type]}-2`),
17+
];
18+
return position;
19+
}
20+
21+
function createFormElement(): HTMLFormElement {
22+
const form = document.createElement('form');
23+
form.style.marginBottom = '10px';
24+
25+
['canvas', 'image'].forEach((coordType) => {
26+
form.innerHTML += `
27+
<label style="margin-right: 20px;">${
28+
coordType.charAt(0).toUpperCase() + coordType.slice(1)
29+
} Coords: Start [${coordType === 'canvas' ? 'x, y' : 'i, j'}]:</label>
30+
<input style="width:40px" type="number" id="${coordType}-start-1" placeholder="${
31+
coordType === 'canvas' ? 'x' : 'i'
32+
}" value="10">
33+
<input style="width:40px" type="number" id="${coordType}-start-2" placeholder="${
34+
coordType === 'canvas' ? 'y' : 'j'
35+
}" value="10">
36+
<label style="margin-left: 52px; margin-right: 21px;">Text:</label>
37+
<input style="width:100px" type="text" id="${coordType}-text" placeholder="My Annotation" value="">
38+
<br>
39+
<button style="margin-left: 52px;" type="button" id="${coordType}-stack">Add Stack</button>
40+
<button type="button" id="${coordType}-volume">Add Volume</button>
41+
<br><br>
42+
`;
43+
});
44+
45+
return form;
46+
}
47+
48+
function addButtonListeners(form: HTMLFormElement): void {
49+
const buttons = form.querySelectorAll('button');
50+
buttons.forEach((button) => {
51+
button.addEventListener('click', () => {
52+
const [type, viewportType] = button.id.split('-') as [
53+
'canvas' | 'image',
54+
keyof typeof typeToIdMap
55+
];
56+
const enabledElement = getEnabledElementByViewportId(
57+
typeToIdMap[viewportType]
58+
);
59+
const viewport = enabledElement.viewport;
60+
const coords = getCoordinates(form, type);
61+
const textInput = form.querySelector(`#${type}-text`) as HTMLInputElement;
62+
const text = textInput ? textInput.value : '';
63+
const currentImageId = viewport.getCurrentImageId() as string;
64+
65+
const position =
66+
type === 'image'
67+
? utilities.imageToWorldCoords(currentImageId, coords)
68+
: viewport.canvasToWorld(coords);
69+
70+
console.log('Adding label at:', position);
71+
72+
LabelTool.hydrate(viewport.id, position, text);
73+
});
74+
});
75+
}
76+
77+
export function createLabelToolUI(): HTMLFormElement {
78+
const form = createFormElement();
79+
addButtonListeners(form);
80+
return form;
81+
}

‎packages/tools/examples/dynamicallyAddAnnotations/toolSpecificUI.ts

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { createProbeToolUI } from './probeToolUI';
66
import { createRectangleROIToolUI } from './rectangleROIToolUI';
77
import { createCircleROIToolUI } from './circleROIToolUI';
88
import { createSplineROIToolUI } from './splineROIToolUI';
9+
import { createLabelToolUI } from './labelToolUI';
910

1011
interface ToolUIConfig {
1112
toolName: string;
@@ -31,6 +32,9 @@ function createToolUI(toolName: string, config: ToolUIConfig): ToolUI | null {
3132
case 'EllipticalROI':
3233
forms = [createEllipseROIToolUI()];
3334
break;
35+
case 'Label':
36+
forms = [createLabelToolUI()];
37+
break;
3438
case 'Length':
3539
forms = [createLengthToolUI()];
3640
break;

‎packages/tools/src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
StackScrollTool,
3333
PlanarRotateTool,
3434
MIPJumpToClickTool,
35+
LabelTool,
3536
LengthTool,
3637
HeightTool,
3738
ProbeTool,
@@ -106,6 +107,7 @@ export {
106107
PlanarRotateTool,
107108
MIPJumpToClickTool,
108109
// Annotation Tools
110+
LabelTool,
109111
LengthTool,
110112
HeightTool,
111113
CrosshairsTool,

‎packages/tools/src/tools/annotation/LabelTool.ts

+539
Large diffs are not rendered by default.

‎packages/tools/src/tools/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import VolumeRotateTool from './VolumeRotateTool';
2020

2121
// Annotation tools
2222
import BidirectionalTool from './annotation/BidirectionalTool';
23+
import LabelTool from './annotation/LabelTool';
2324
import LengthTool from './annotation/LengthTool';
2425
import HeightTool from './annotation/HeightTool';
2526
import ProbeTool from './annotation/ProbeTool';
@@ -81,6 +82,7 @@ export {
8182
OverlayGridTool,
8283
SegmentationIntersectionTool,
8384
BidirectionalTool,
85+
LabelTool,
8486
LengthTool,
8587
HeightTool,
8688
ProbeTool,

‎packages/tools/src/types/ToolSpecificAnnotationTypes.ts

+9
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,15 @@ export interface ArrowAnnotation extends Annotation {
358358
};
359359
}
360360

361+
export interface LabelAnnotation extends Annotation {
362+
data: {
363+
text: string;
364+
handles: {
365+
points: Types.Point3[];
366+
};
367+
};
368+
}
369+
361370
export interface AngleAnnotation extends Annotation {
362371
data: {
363372
handles: {

0 commit comments

Comments
 (0)
Please sign in to comment.