@cornerstonejs/tools 1.12.1 → 1.13.0
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/cjs/store/ToolGroupManager/ToolGroup.d.ts +3 -3
- package/dist/cjs/store/ToolGroupManager/ToolGroup.js.map +1 -1
- package/dist/cjs/tools/annotation/AngleTool.d.ts +0 -1
- package/dist/cjs/tools/annotation/AngleTool.js +11 -10
- package/dist/cjs/tools/annotation/AngleTool.js.map +1 -1
- package/dist/cjs/tools/annotation/BidirectionalTool.d.ts +0 -1
- package/dist/cjs/tools/annotation/BidirectionalTool.js +14 -13
- package/dist/cjs/tools/annotation/BidirectionalTool.js.map +1 -1
- package/dist/cjs/tools/annotation/CircleROITool.d.ts +0 -1
- package/dist/cjs/tools/annotation/CircleROITool.js +39 -51
- package/dist/cjs/tools/annotation/CircleROITool.js.map +1 -1
- package/dist/cjs/tools/annotation/CobbAngleTool.d.ts +0 -1
- package/dist/cjs/tools/annotation/CobbAngleTool.js +11 -10
- package/dist/cjs/tools/annotation/CobbAngleTool.js.map +1 -1
- package/dist/cjs/tools/annotation/DragProbeTool.js +13 -1
- package/dist/cjs/tools/annotation/DragProbeTool.js.map +1 -1
- package/dist/cjs/tools/annotation/EllipticalROITool.d.ts +0 -1
- package/dist/cjs/tools/annotation/EllipticalROITool.js +33 -45
- package/dist/cjs/tools/annotation/EllipticalROITool.js.map +1 -1
- package/dist/cjs/tools/annotation/LengthTool.d.ts +0 -1
- package/dist/cjs/tools/annotation/LengthTool.js +11 -10
- package/dist/cjs/tools/annotation/LengthTool.js.map +1 -1
- package/dist/cjs/tools/annotation/PlanarFreehandROITool.d.ts +0 -1
- package/dist/cjs/tools/annotation/PlanarFreehandROITool.js +34 -42
- package/dist/cjs/tools/annotation/PlanarFreehandROITool.js.map +1 -1
- package/dist/cjs/tools/annotation/ProbeTool.d.ts +0 -1
- package/dist/cjs/tools/annotation/ProbeTool.js +13 -12
- package/dist/cjs/tools/annotation/ProbeTool.js.map +1 -1
- package/dist/cjs/tools/annotation/RectangleROITool.d.ts +0 -1
- package/dist/cjs/tools/annotation/RectangleROITool.js +31 -47
- package/dist/cjs/tools/annotation/RectangleROITool.js.map +1 -1
- package/dist/cjs/tools/base/AnnotationTool.d.ts +2 -1
- package/dist/cjs/tools/base/AnnotationTool.js +10 -2
- package/dist/cjs/tools/base/AnnotationTool.js.map +1 -1
- package/dist/cjs/types/CalculatorTypes.d.ts +6 -0
- package/dist/cjs/types/CalculatorTypes.js +3 -0
- package/dist/cjs/types/CalculatorTypes.js.map +1 -0
- package/dist/cjs/types/IToolGroup.d.ts +3 -2
- package/dist/cjs/types/ToolProps.d.ts +5 -1
- package/dist/cjs/types/index.d.ts +3 -2
- package/dist/cjs/utilities/math/basic/BasicStatsCalculator.d.ts +14 -0
- package/dist/cjs/utilities/math/basic/BasicStatsCalculator.js +44 -0
- package/dist/cjs/utilities/math/basic/BasicStatsCalculator.js.map +1 -0
- package/dist/cjs/utilities/math/basic/Calculator.d.ts +8 -0
- package/dist/cjs/utilities/math/basic/Calculator.js +6 -0
- package/dist/cjs/utilities/math/basic/Calculator.js.map +1 -0
- package/dist/cjs/utilities/math/basic/index.d.ts +3 -0
- package/dist/cjs/utilities/math/basic/index.js +11 -0
- package/dist/cjs/utilities/math/basic/index.js.map +1 -0
- package/dist/cjs/utilities/math/index.d.ts +2 -1
- package/dist/cjs/utilities/math/index.js +3 -1
- package/dist/cjs/utilities/math/index.js.map +1 -1
- package/dist/cjs/utilities/math/vec2/liangBarksyClip.d.ts +1 -1
- package/dist/cjs/utilities/pointInShapeCallback.d.ts +7 -1
- package/dist/cjs/utilities/pointInShapeCallback.js +6 -1
- package/dist/cjs/utilities/pointInShapeCallback.js.map +1 -1
- package/dist/esm/store/ToolGroupManager/ToolGroup.d.ts +3 -3
- package/dist/esm/store/ToolGroupManager/ToolGroup.js.map +1 -1
- package/dist/esm/tools/annotation/AngleTool.d.ts +0 -1
- package/dist/esm/tools/annotation/AngleTool.js +11 -10
- package/dist/esm/tools/annotation/AngleTool.js.map +1 -1
- package/dist/esm/tools/annotation/BidirectionalTool.d.ts +0 -1
- package/dist/esm/tools/annotation/BidirectionalTool.js +14 -13
- package/dist/esm/tools/annotation/BidirectionalTool.js.map +1 -1
- package/dist/esm/tools/annotation/CircleROITool.d.ts +0 -1
- package/dist/esm/tools/annotation/CircleROITool.js +38 -51
- package/dist/esm/tools/annotation/CircleROITool.js.map +1 -1
- package/dist/esm/tools/annotation/CobbAngleTool.d.ts +0 -1
- package/dist/esm/tools/annotation/CobbAngleTool.js +11 -10
- package/dist/esm/tools/annotation/CobbAngleTool.js.map +1 -1
- package/dist/esm/tools/annotation/DragProbeTool.js +13 -1
- package/dist/esm/tools/annotation/DragProbeTool.js.map +1 -1
- package/dist/esm/tools/annotation/EllipticalROITool.d.ts +0 -1
- package/dist/esm/tools/annotation/EllipticalROITool.js +32 -45
- package/dist/esm/tools/annotation/EllipticalROITool.js.map +1 -1
- package/dist/esm/tools/annotation/LengthTool.d.ts +0 -1
- package/dist/esm/tools/annotation/LengthTool.js +11 -10
- package/dist/esm/tools/annotation/LengthTool.js.map +1 -1
- package/dist/esm/tools/annotation/PlanarFreehandROITool.d.ts +0 -1
- package/dist/esm/tools/annotation/PlanarFreehandROITool.js +33 -42
- package/dist/esm/tools/annotation/PlanarFreehandROITool.js.map +1 -1
- package/dist/esm/tools/annotation/ProbeTool.d.ts +0 -1
- package/dist/esm/tools/annotation/ProbeTool.js +13 -12
- package/dist/esm/tools/annotation/ProbeTool.js.map +1 -1
- package/dist/esm/tools/annotation/RectangleROITool.d.ts +0 -1
- package/dist/esm/tools/annotation/RectangleROITool.js +30 -47
- package/dist/esm/tools/annotation/RectangleROITool.js.map +1 -1
- package/dist/esm/tools/base/AnnotationTool.d.ts +2 -1
- package/dist/esm/tools/base/AnnotationTool.js +9 -2
- package/dist/esm/tools/base/AnnotationTool.js.map +1 -1
- package/dist/esm/types/CalculatorTypes.d.ts +6 -0
- package/dist/esm/types/CalculatorTypes.js +2 -0
- package/dist/esm/types/CalculatorTypes.js.map +1 -0
- package/dist/esm/types/IToolGroup.d.ts +3 -2
- package/dist/esm/types/ToolProps.d.ts +5 -1
- package/dist/esm/types/index.d.ts +3 -2
- package/dist/esm/utilities/math/basic/BasicStatsCalculator.d.ts +14 -0
- package/dist/esm/utilities/math/basic/BasicStatsCalculator.js +36 -0
- package/dist/esm/utilities/math/basic/BasicStatsCalculator.js.map +1 -0
- package/dist/esm/utilities/math/basic/Calculator.d.ts +8 -0
- package/dist/esm/utilities/math/basic/Calculator.js +4 -0
- package/dist/esm/utilities/math/basic/Calculator.js.map +1 -0
- package/dist/esm/utilities/math/basic/index.d.ts +3 -0
- package/dist/esm/utilities/math/basic/index.js +4 -0
- package/dist/esm/utilities/math/basic/index.js.map +1 -0
- package/dist/esm/utilities/math/index.d.ts +2 -1
- package/dist/esm/utilities/math/index.js +2 -1
- package/dist/esm/utilities/math/index.js.map +1 -1
- package/dist/esm/utilities/math/vec2/liangBarksyClip.d.ts +1 -1
- package/dist/esm/utilities/pointInShapeCallback.d.ts +7 -1
- package/dist/esm/utilities/pointInShapeCallback.js +6 -1
- package/dist/esm/utilities/pointInShapeCallback.js.map +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/index.js.map +1 -1
- package/package.json +3 -3
- package/src/store/ToolGroupManager/ToolGroup.ts +4 -3
- package/src/tools/annotation/AngleTool.ts +15 -15
- package/src/tools/annotation/BidirectionalTool.ts +21 -22
- package/src/tools/annotation/CircleROITool.ts +64 -87
- package/src/tools/annotation/CobbAngleTool.ts +15 -15
- package/src/tools/annotation/DragProbeTool.ts +19 -1
- package/src/tools/annotation/EllipticalROITool.ts +47 -70
- package/src/tools/annotation/LengthTool.ts +16 -16
- package/src/tools/annotation/PlanarFreehandROITool.ts +36 -49
- package/src/tools/annotation/ProbeTool.ts +20 -18
- package/src/tools/annotation/RectangleROITool.ts +51 -74
- package/src/tools/base/AnnotationTool.ts +16 -1
- package/src/types/CalculatorTypes.ts +7 -0
- package/src/types/IToolGroup.ts +6 -3
- package/src/types/ToolProps.ts +7 -1
- package/src/types/index.ts +9 -1
- package/src/utilities/math/basic/BasicStatsCalculator.ts +60 -0
- package/src/utilities/math/basic/Calculator.ts +8 -0
- package/src/utilities/math/basic/index.ts +4 -0
- package/src/utilities/math/index.ts +10 -1
- package/src/utilities/pointInShapeCallback.ts +15 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/tools",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "Cornerstone3D Tools",
|
|
5
5
|
"main": "dist/umd/index.js",
|
|
6
6
|
"types": "dist/esm/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"webpack:watch": "webpack --mode development --progress --watch --config ./.webpack/webpack.dev.js"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@cornerstonejs/core": "^1.
|
|
32
|
+
"@cornerstonejs/core": "^1.13.0",
|
|
33
33
|
"lodash.clonedeep": "4.5.0",
|
|
34
34
|
"lodash.get": "^4.4.2"
|
|
35
35
|
},
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"type": "individual",
|
|
53
53
|
"url": "https://ohif.org/donate"
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "64173701acdeb7097e6ae4122606138065ebcecc"
|
|
56
56
|
}
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
IToolGroup,
|
|
21
21
|
SetToolBindingsType,
|
|
22
22
|
ToolOptionsType,
|
|
23
|
+
ToolConfiguration,
|
|
23
24
|
} from '../../types';
|
|
24
25
|
|
|
25
26
|
import { MouseCursor, SVGMouseCursor } from '../../cursors';
|
|
@@ -87,9 +88,9 @@ export default class ToolGroup implements IToolGroup {
|
|
|
87
88
|
* to set the tool to be active or passive or in other states.
|
|
88
89
|
*
|
|
89
90
|
* @param toolName - string
|
|
90
|
-
* @param configuration - Tool configuration objects
|
|
91
|
+
* @param configuration - Tool configuration objects and a custom statistics calculator if needed
|
|
91
92
|
*/
|
|
92
|
-
addTool(toolName: string, configuration = {}): void {
|
|
93
|
+
addTool(toolName: string, configuration: ToolConfiguration = {}): void {
|
|
93
94
|
const toolDefinition = state.tools[toolName];
|
|
94
95
|
const hasToolName = typeof toolName !== 'undefined' && toolName !== '';
|
|
95
96
|
const localToolInstance = this.toolOptions[toolName];
|
|
@@ -605,7 +606,7 @@ export default class ToolGroup implements IToolGroup {
|
|
|
605
606
|
*/
|
|
606
607
|
public setToolConfiguration(
|
|
607
608
|
toolName: string,
|
|
608
|
-
configuration:
|
|
609
|
+
configuration: ToolConfiguration,
|
|
609
610
|
overwrite?: boolean
|
|
610
611
|
): boolean {
|
|
611
612
|
if (this._toolInstances[toolName] === undefined) {
|
|
@@ -74,6 +74,7 @@ class AngleTool extends AnnotationTool {
|
|
|
74
74
|
configuration: {
|
|
75
75
|
shadow: true,
|
|
76
76
|
preventHandleOutsideImage: false,
|
|
77
|
+
getTextLines: defaultGetTextLines,
|
|
77
78
|
},
|
|
78
79
|
}
|
|
79
80
|
) {
|
|
@@ -744,7 +745,7 @@ class AngleTool extends AnnotationTool {
|
|
|
744
745
|
continue;
|
|
745
746
|
}
|
|
746
747
|
|
|
747
|
-
const textLines = this.
|
|
748
|
+
const textLines = this.configuration.getTextLines(data, targetId);
|
|
748
749
|
|
|
749
750
|
if (!data.handles.textBox.hasMoved) {
|
|
750
751
|
// linked to the vertex by default
|
|
@@ -783,20 +784,6 @@ class AngleTool extends AnnotationTool {
|
|
|
783
784
|
return renderStatus;
|
|
784
785
|
};
|
|
785
786
|
|
|
786
|
-
// text line for the current active angle annotation
|
|
787
|
-
_getTextLines(data, targetId) {
|
|
788
|
-
const cachedVolumeStats = data.cachedStats[targetId];
|
|
789
|
-
const { angle } = cachedVolumeStats;
|
|
790
|
-
|
|
791
|
-
if (angle === undefined) {
|
|
792
|
-
return;
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
const textLines = [`${roundNumber(angle)} ${String.fromCharCode(176)}`];
|
|
796
|
-
|
|
797
|
-
return textLines;
|
|
798
|
-
}
|
|
799
|
-
|
|
800
787
|
_calculateCachedStats(annotation, renderingEngine, enabledElement) {
|
|
801
788
|
const data = annotation.data;
|
|
802
789
|
const { viewportId, renderingEngineId } = enabledElement;
|
|
@@ -841,5 +828,18 @@ class AngleTool extends AnnotationTool {
|
|
|
841
828
|
}
|
|
842
829
|
}
|
|
843
830
|
|
|
831
|
+
function defaultGetTextLines(data, targetId): string[] {
|
|
832
|
+
const cachedVolumeStats = data.cachedStats[targetId];
|
|
833
|
+
const { angle } = cachedVolumeStats;
|
|
834
|
+
|
|
835
|
+
if (angle === undefined) {
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
const textLines = [`${roundNumber(angle)} ${String.fromCharCode(176)}`];
|
|
840
|
+
|
|
841
|
+
return textLines;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
844
|
AngleTool.toolName = 'Angle';
|
|
845
845
|
export default AngleTool;
|
|
@@ -91,6 +91,7 @@ const { transformWorldToIndex } = csUtils;
|
|
|
91
91
|
*
|
|
92
92
|
* Read more in the Docs section of the website.
|
|
93
93
|
*/
|
|
94
|
+
|
|
94
95
|
class BidirectionalTool extends AnnotationTool {
|
|
95
96
|
static toolName;
|
|
96
97
|
|
|
@@ -115,6 +116,7 @@ class BidirectionalTool extends AnnotationTool {
|
|
|
115
116
|
supportedInteractionTypes: ['Mouse', 'Touch'],
|
|
116
117
|
configuration: {
|
|
117
118
|
preventHandleOutsideImage: false,
|
|
119
|
+
getTextLines: defaultGetTextLines,
|
|
118
120
|
},
|
|
119
121
|
}
|
|
120
122
|
) {
|
|
@@ -1160,7 +1162,7 @@ class BidirectionalTool extends AnnotationTool {
|
|
|
1160
1162
|
|
|
1161
1163
|
renderStatus = true;
|
|
1162
1164
|
|
|
1163
|
-
const textLines = this.
|
|
1165
|
+
const textLines = this.configuration.getTextLines(data, targetId);
|
|
1164
1166
|
|
|
1165
1167
|
if (!textLines || textLines.length === 0) {
|
|
1166
1168
|
continue;
|
|
@@ -1243,27 +1245,6 @@ class BidirectionalTool extends AnnotationTool {
|
|
|
1243
1245
|
return wouldPutThroughShortAxis;
|
|
1244
1246
|
};
|
|
1245
1247
|
|
|
1246
|
-
/**
|
|
1247
|
-
* get text box content
|
|
1248
|
-
*/
|
|
1249
|
-
_getTextLines = (data, targetId) => {
|
|
1250
|
-
const { cachedStats } = data;
|
|
1251
|
-
const { length, width, unit } = cachedStats[targetId];
|
|
1252
|
-
|
|
1253
|
-
if (length === undefined) {
|
|
1254
|
-
return;
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
|
-
// spaceBetweenSlices & pixelSpacing &
|
|
1258
|
-
// magnitude in each direction? Otherwise, this is "px"?
|
|
1259
|
-
const textLines = [
|
|
1260
|
-
`L: ${roundNumber(length)} ${unit}`,
|
|
1261
|
-
`W: ${roundNumber(width)} ${unit}`,
|
|
1262
|
-
];
|
|
1263
|
-
|
|
1264
|
-
return textLines;
|
|
1265
|
-
};
|
|
1266
|
-
|
|
1267
1248
|
_calculateLength(pos1, pos2) {
|
|
1268
1249
|
const dx = pos1[0] - pos2[0];
|
|
1269
1250
|
const dy = pos1[1] - pos2[1];
|
|
@@ -1351,5 +1332,23 @@ class BidirectionalTool extends AnnotationTool {
|
|
|
1351
1332
|
};
|
|
1352
1333
|
}
|
|
1353
1334
|
|
|
1335
|
+
function defaultGetTextLines(data, targetId): string[] {
|
|
1336
|
+
const { cachedStats } = data;
|
|
1337
|
+
const { length, width, unit } = cachedStats[targetId];
|
|
1338
|
+
|
|
1339
|
+
if (length === undefined) {
|
|
1340
|
+
return;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
// spaceBetweenSlices & pixelSpacing &
|
|
1344
|
+
// magnitude in each direction? Otherwise, this is "px"?
|
|
1345
|
+
const textLines = [
|
|
1346
|
+
`L: ${roundNumber(length)} ${unit}`,
|
|
1347
|
+
`W: ${roundNumber(width)} ${unit}`,
|
|
1348
|
+
];
|
|
1349
|
+
|
|
1350
|
+
return textLines;
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1354
1353
|
BidirectionalTool.toolName = 'Bidirectional';
|
|
1355
1354
|
export default BidirectionalTool;
|
|
@@ -68,6 +68,7 @@ import {
|
|
|
68
68
|
getCanvasCircleRadius,
|
|
69
69
|
} from '../../utilities/math/circle';
|
|
70
70
|
import { pointInEllipse } from '../../utilities/math/ellipse';
|
|
71
|
+
import { BasicStatsCalculator } from '../../utilities/math/basic';
|
|
71
72
|
|
|
72
73
|
const { transformWorldToIndex } = csUtils;
|
|
73
74
|
|
|
@@ -117,8 +118,10 @@ const { transformWorldToIndex } = csUtils;
|
|
|
117
118
|
*
|
|
118
119
|
* Read more in the Docs section of the website.
|
|
119
120
|
*/
|
|
121
|
+
|
|
120
122
|
class CircleROITool extends AnnotationTool {
|
|
121
123
|
static toolName;
|
|
124
|
+
|
|
122
125
|
touchDragCallback: any;
|
|
123
126
|
mouseDragCallback: any;
|
|
124
127
|
_throttledCalculateCachedStats: any;
|
|
@@ -143,6 +146,8 @@ class CircleROITool extends AnnotationTool {
|
|
|
143
146
|
// Radius of the circle to draw at the center point of the circle.
|
|
144
147
|
// Set this zero(0) in order not to draw the circle.
|
|
145
148
|
centerPointRadius: 0,
|
|
149
|
+
getTextLines: defaultGetTextLines,
|
|
150
|
+
statsCalculator: BasicStatsCalculator,
|
|
146
151
|
},
|
|
147
152
|
}
|
|
148
153
|
) {
|
|
@@ -821,7 +826,7 @@ class CircleROITool extends AnnotationTool {
|
|
|
821
826
|
|
|
822
827
|
renderStatus = true;
|
|
823
828
|
|
|
824
|
-
const textLines = this.
|
|
829
|
+
const textLines = this.configuration.getTextLines(data, targetId);
|
|
825
830
|
if (!textLines || textLines.length === 0) {
|
|
826
831
|
continue;
|
|
827
832
|
}
|
|
@@ -865,52 +870,6 @@ class CircleROITool extends AnnotationTool {
|
|
|
865
870
|
return renderStatus;
|
|
866
871
|
};
|
|
867
872
|
|
|
868
|
-
_getTextLines = (data, targetId: string): string[] => {
|
|
869
|
-
const cachedVolumeStats = data.cachedStats[targetId];
|
|
870
|
-
const {
|
|
871
|
-
radius,
|
|
872
|
-
radiusUnit,
|
|
873
|
-
area,
|
|
874
|
-
mean,
|
|
875
|
-
stdDev,
|
|
876
|
-
max,
|
|
877
|
-
isEmptyArea,
|
|
878
|
-
Modality,
|
|
879
|
-
areaUnit,
|
|
880
|
-
modalityUnit,
|
|
881
|
-
} = cachedVolumeStats;
|
|
882
|
-
|
|
883
|
-
const textLines: string[] = [];
|
|
884
|
-
|
|
885
|
-
if (radius) {
|
|
886
|
-
const radiusLine = isEmptyArea
|
|
887
|
-
? `Radius: Oblique not supported`
|
|
888
|
-
: `Radius: ${roundNumber(radius)} ${radiusUnit}`;
|
|
889
|
-
textLines.push(radiusLine);
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
if (area) {
|
|
893
|
-
const areaLine = isEmptyArea
|
|
894
|
-
? `Area: Oblique not supported`
|
|
895
|
-
: `Area: ${roundNumber(area)} ${areaUnit}`;
|
|
896
|
-
textLines.push(areaLine);
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
if (mean) {
|
|
900
|
-
textLines.push(`Mean: ${roundNumber(mean)} ${modalityUnit}`);
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
if (max) {
|
|
904
|
-
textLines.push(`Max: ${roundNumber(max)} ${modalityUnit}`);
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
if (stdDev) {
|
|
908
|
-
textLines.push(`Std Dev: ${roundNumber(stdDev)} ${modalityUnit}`);
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
return textLines;
|
|
912
|
-
};
|
|
913
|
-
|
|
914
873
|
_calculateCachedStats = (
|
|
915
874
|
annotation,
|
|
916
875
|
viewport,
|
|
@@ -1011,57 +970,29 @@ class CircleROITool extends AnnotationTool {
|
|
|
1011
970
|
(worldHeight / aspect / scale / 2)
|
|
1012
971
|
);
|
|
1013
972
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
const meanMaxCalculator = ({ value: newValue }) => {
|
|
1020
|
-
if (newValue > max) {
|
|
1021
|
-
max = newValue;
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
mean += newValue;
|
|
1025
|
-
count += 1;
|
|
1026
|
-
};
|
|
1027
|
-
|
|
1028
|
-
pointInShapeCallback(
|
|
1029
|
-
imageData,
|
|
1030
|
-
(pointLPS, pointIJK) => pointInEllipse(ellipseObj, pointLPS),
|
|
1031
|
-
meanMaxCalculator,
|
|
1032
|
-
boundsIJK
|
|
973
|
+
const modalityUnit = getModalityUnit(
|
|
974
|
+
metadata.Modality,
|
|
975
|
+
annotation.metadata.referencedImageId,
|
|
976
|
+
modalityUnitOptions
|
|
1033
977
|
);
|
|
1034
978
|
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
const stdCalculator = ({ value }) => {
|
|
1038
|
-
const valueMinusMean = value - mean;
|
|
1039
|
-
|
|
1040
|
-
stdDev += valueMinusMean * valueMinusMean;
|
|
1041
|
-
};
|
|
1042
|
-
|
|
1043
|
-
pointInShapeCallback(
|
|
979
|
+
const pointsInShape = pointInShapeCallback(
|
|
1044
980
|
imageData,
|
|
1045
981
|
(pointLPS, pointIJK) => pointInEllipse(ellipseObj, pointLPS),
|
|
1046
|
-
|
|
982
|
+
this.configuration.statsCalculator.statsCallback,
|
|
1047
983
|
boundsIJK
|
|
1048
984
|
);
|
|
1049
985
|
|
|
1050
|
-
|
|
1051
|
-
stdDev = Math.sqrt(stdDev);
|
|
1052
|
-
|
|
1053
|
-
const modalityUnit = getModalityUnit(
|
|
1054
|
-
metadata.Modality,
|
|
1055
|
-
annotation.metadata.referencedImageId,
|
|
1056
|
-
modalityUnitOptions
|
|
1057
|
-
);
|
|
986
|
+
const stats = this.configuration.statsCalculator.getStatistics();
|
|
1058
987
|
|
|
1059
988
|
cachedStats[targetId] = {
|
|
1060
989
|
Modality: metadata.Modality,
|
|
1061
990
|
area,
|
|
1062
|
-
mean,
|
|
1063
|
-
max,
|
|
1064
|
-
stdDev,
|
|
991
|
+
mean: stats[1]?.value,
|
|
992
|
+
max: stats[0]?.value,
|
|
993
|
+
stdDev: stats[2]?.value,
|
|
994
|
+
statsArray: stats,
|
|
995
|
+
pointsInShape: pointsInShape,
|
|
1065
996
|
isEmptyArea,
|
|
1066
997
|
areaUnit: getCalibratedAreaUnits(null, image),
|
|
1067
998
|
radius: worldWidth / 2 / scale,
|
|
@@ -1102,5 +1033,51 @@ class CircleROITool extends AnnotationTool {
|
|
|
1102
1033
|
};
|
|
1103
1034
|
}
|
|
1104
1035
|
|
|
1036
|
+
function defaultGetTextLines(data, targetId): string[] {
|
|
1037
|
+
const cachedVolumeStats = data.cachedStats[targetId];
|
|
1038
|
+
const {
|
|
1039
|
+
radius,
|
|
1040
|
+
radiusUnit,
|
|
1041
|
+
area,
|
|
1042
|
+
mean,
|
|
1043
|
+
stdDev,
|
|
1044
|
+
max,
|
|
1045
|
+
isEmptyArea,
|
|
1046
|
+
Modality,
|
|
1047
|
+
areaUnit,
|
|
1048
|
+
modalityUnit,
|
|
1049
|
+
} = cachedVolumeStats;
|
|
1050
|
+
|
|
1051
|
+
const textLines: string[] = [];
|
|
1052
|
+
|
|
1053
|
+
if (radius) {
|
|
1054
|
+
const radiusLine = isEmptyArea
|
|
1055
|
+
? `Radius: Oblique not supported`
|
|
1056
|
+
: `Radius: ${roundNumber(radius)} ${radiusUnit}`;
|
|
1057
|
+
textLines.push(radiusLine);
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
if (area) {
|
|
1061
|
+
const areaLine = isEmptyArea
|
|
1062
|
+
? `Area: Oblique not supported`
|
|
1063
|
+
: `Area: ${roundNumber(area)} ${areaUnit}`;
|
|
1064
|
+
textLines.push(areaLine);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
if (mean) {
|
|
1068
|
+
textLines.push(`Mean: ${roundNumber(mean)} ${modalityUnit}`);
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
if (max) {
|
|
1072
|
+
textLines.push(`Max: ${roundNumber(max)} ${modalityUnit}`);
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
if (stdDev) {
|
|
1076
|
+
textLines.push(`Std Dev: ${roundNumber(stdDev)} ${modalityUnit}`);
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
return textLines;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1105
1082
|
CircleROITool.toolName = 'CircleROI';
|
|
1106
1083
|
export default CircleROITool;
|
|
@@ -75,6 +75,7 @@ class CobbAngleTool extends AnnotationTool {
|
|
|
75
75
|
configuration: {
|
|
76
76
|
shadow: true,
|
|
77
77
|
preventHandleOutsideImage: false,
|
|
78
|
+
getTextLines: defaultGetTextLines,
|
|
78
79
|
},
|
|
79
80
|
}
|
|
80
81
|
) {
|
|
@@ -769,7 +770,7 @@ class CobbAngleTool extends AnnotationTool {
|
|
|
769
770
|
continue;
|
|
770
771
|
}
|
|
771
772
|
|
|
772
|
-
const textLines = this.
|
|
773
|
+
const textLines = this.configuration.getTextLines(data, targetId);
|
|
773
774
|
|
|
774
775
|
if (!data.handles.textBox.hasMoved) {
|
|
775
776
|
const canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates);
|
|
@@ -807,20 +808,6 @@ class CobbAngleTool extends AnnotationTool {
|
|
|
807
808
|
return renderStatus;
|
|
808
809
|
};
|
|
809
810
|
|
|
810
|
-
// text line for the current active angle annotation
|
|
811
|
-
_getTextLines(data, targetId) {
|
|
812
|
-
const cachedVolumeStats = data.cachedStats[targetId];
|
|
813
|
-
const { angle } = cachedVolumeStats;
|
|
814
|
-
|
|
815
|
-
if (angle === undefined) {
|
|
816
|
-
return;
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
const textLines = [`${angle.toFixed(2)} ${String.fromCharCode(176)}`];
|
|
820
|
-
|
|
821
|
-
return textLines;
|
|
822
|
-
}
|
|
823
|
-
|
|
824
811
|
_calculateCachedStats(annotation, renderingEngine, enabledElement) {
|
|
825
812
|
const data = annotation.data;
|
|
826
813
|
const { viewportId, renderingEngineId } = enabledElement;
|
|
@@ -886,5 +873,18 @@ class CobbAngleTool extends AnnotationTool {
|
|
|
886
873
|
}
|
|
887
874
|
}
|
|
888
875
|
|
|
876
|
+
function defaultGetTextLines(data, targetId): string[] {
|
|
877
|
+
const cachedVolumeStats = data.cachedStats[targetId];
|
|
878
|
+
const { angle } = cachedVolumeStats;
|
|
879
|
+
|
|
880
|
+
if (angle === undefined) {
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
const textLines = [`${angle.toFixed(2)} ${String.fromCharCode(176)}`];
|
|
885
|
+
|
|
886
|
+
return textLines;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
889
|
CobbAngleTool.toolName = 'CobbAngle';
|
|
890
890
|
export default CobbAngleTool;
|
|
@@ -44,6 +44,7 @@ class DragProbeTool extends ProbeTool {
|
|
|
44
44
|
configuration: {
|
|
45
45
|
shadow: true,
|
|
46
46
|
preventHandleOutsideImage: false,
|
|
47
|
+
getTextLines: defaultGetTextLines,
|
|
47
48
|
},
|
|
48
49
|
}
|
|
49
50
|
) {
|
|
@@ -205,7 +206,7 @@ class DragProbeTool extends ProbeTool {
|
|
|
205
206
|
|
|
206
207
|
renderStatus = true;
|
|
207
208
|
|
|
208
|
-
const textLines = this.
|
|
209
|
+
const textLines = this.configuration.getTextLines(data, targetId);
|
|
209
210
|
if (textLines) {
|
|
210
211
|
const textCanvasCoordinates = [
|
|
211
212
|
canvasCoordinates[0] + 6,
|
|
@@ -227,5 +228,22 @@ class DragProbeTool extends ProbeTool {
|
|
|
227
228
|
};
|
|
228
229
|
}
|
|
229
230
|
|
|
231
|
+
function defaultGetTextLines(data, targetId): string[] {
|
|
232
|
+
const cachedVolumeStats = data.cachedStats[targetId];
|
|
233
|
+
const { index, value, modalityUnit } = cachedVolumeStats;
|
|
234
|
+
|
|
235
|
+
if (value === undefined) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const textLines = [];
|
|
240
|
+
|
|
241
|
+
textLines.push(`(${index[0]}, ${index[1]}, ${index[2]})`);
|
|
242
|
+
|
|
243
|
+
textLines.push(`${value.toFixed(2)} ${modalityUnit}`);
|
|
244
|
+
|
|
245
|
+
return textLines;
|
|
246
|
+
}
|
|
247
|
+
|
|
230
248
|
DragProbeTool.toolName = 'DragProbe';
|
|
231
249
|
export default DragProbeTool;
|
|
@@ -66,6 +66,7 @@ import {
|
|
|
66
66
|
getModalityUnit,
|
|
67
67
|
} from '../../utilities/getModalityUnit';
|
|
68
68
|
import { isViewportPreScaled } from '../../utilities/viewport/isViewportPreScaled';
|
|
69
|
+
import { BasicStatsCalculator } from '../../utilities/math/basic';
|
|
69
70
|
|
|
70
71
|
const { transformWorldToIndex } = csUtils;
|
|
71
72
|
|
|
@@ -115,8 +116,10 @@ const { transformWorldToIndex } = csUtils;
|
|
|
115
116
|
*
|
|
116
117
|
* Read more in the Docs section of the website.
|
|
117
118
|
*/
|
|
119
|
+
|
|
118
120
|
class EllipticalROITool extends AnnotationTool {
|
|
119
121
|
static toolName;
|
|
122
|
+
|
|
120
123
|
touchDragCallback: any;
|
|
121
124
|
mouseDragCallback: any;
|
|
122
125
|
_throttledCalculateCachedStats: any;
|
|
@@ -145,6 +148,8 @@ class EllipticalROITool extends AnnotationTool {
|
|
|
145
148
|
// Radius of the circle to draw at the center point of the ellipse.
|
|
146
149
|
// Set this zero(0) in order not to draw the circle.
|
|
147
150
|
centerPointRadius: 0,
|
|
151
|
+
getTextLines: defaultGetTextLines,
|
|
152
|
+
statsCalculator: BasicStatsCalculator,
|
|
148
153
|
},
|
|
149
154
|
}
|
|
150
155
|
) {
|
|
@@ -945,7 +950,7 @@ class EllipticalROITool extends AnnotationTool {
|
|
|
945
950
|
|
|
946
951
|
renderStatus = true;
|
|
947
952
|
|
|
948
|
-
const textLines = this.
|
|
953
|
+
const textLines = this.configuration.getTextLines(data, targetId);
|
|
949
954
|
if (!textLines || textLines.length === 0) {
|
|
950
955
|
continue;
|
|
951
956
|
}
|
|
@@ -989,35 +994,6 @@ class EllipticalROITool extends AnnotationTool {
|
|
|
989
994
|
return renderStatus;
|
|
990
995
|
};
|
|
991
996
|
|
|
992
|
-
_getTextLines = (data, targetId: string): string[] => {
|
|
993
|
-
const cachedVolumeStats = data.cachedStats[targetId];
|
|
994
|
-
const { area, mean, stdDev, max, isEmptyArea, areaUnit, modalityUnit } =
|
|
995
|
-
cachedVolumeStats;
|
|
996
|
-
|
|
997
|
-
const textLines: string[] = [];
|
|
998
|
-
|
|
999
|
-
if (area) {
|
|
1000
|
-
const areaLine = isEmptyArea
|
|
1001
|
-
? `Area: Oblique not supported`
|
|
1002
|
-
: `Area: ${roundNumber(area)} ${areaUnit}`;
|
|
1003
|
-
textLines.push(areaLine);
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
if (mean) {
|
|
1007
|
-
textLines.push(`Mean: ${roundNumber(mean)} ${modalityUnit}`);
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
if (max) {
|
|
1011
|
-
textLines.push(`Max: ${roundNumber(max)} ${modalityUnit}`);
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
if (stdDev) {
|
|
1015
|
-
textLines.push(`Std Dev: ${roundNumber(stdDev)} ${modalityUnit}`);
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
return textLines;
|
|
1019
|
-
};
|
|
1020
|
-
|
|
1021
997
|
_calculateCachedStats = (
|
|
1022
998
|
annotation,
|
|
1023
999
|
viewport,
|
|
@@ -1116,57 +1092,29 @@ class EllipticalROITool extends AnnotationTool {
|
|
|
1116
1092
|
scale /
|
|
1117
1093
|
scale;
|
|
1118
1094
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
const meanMaxCalculator = ({ value: newValue }) => {
|
|
1125
|
-
if (newValue > max) {
|
|
1126
|
-
max = newValue;
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
mean += newValue;
|
|
1130
|
-
count += 1;
|
|
1131
|
-
};
|
|
1132
|
-
|
|
1133
|
-
pointInShapeCallback(
|
|
1134
|
-
imageData,
|
|
1135
|
-
(pointLPS, pointIJK) => pointInEllipse(ellipseObj, pointLPS),
|
|
1136
|
-
meanMaxCalculator,
|
|
1137
|
-
boundsIJK
|
|
1095
|
+
const modalityUnit = getModalityUnit(
|
|
1096
|
+
metadata.Modality,
|
|
1097
|
+
annotation.metadata.referencedImageId,
|
|
1098
|
+
modalityUnitOptions
|
|
1138
1099
|
);
|
|
1139
1100
|
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
const stdCalculator = ({ value }) => {
|
|
1143
|
-
const valueMinusMean = value - mean;
|
|
1144
|
-
|
|
1145
|
-
stdDev += valueMinusMean * valueMinusMean;
|
|
1146
|
-
};
|
|
1147
|
-
|
|
1148
|
-
pointInShapeCallback(
|
|
1101
|
+
const pointsInShape = pointInShapeCallback(
|
|
1149
1102
|
imageData,
|
|
1150
1103
|
(pointLPS, pointIJK) => pointInEllipse(ellipseObj, pointLPS),
|
|
1151
|
-
|
|
1104
|
+
this.configuration.statsCalculator.statsCallback,
|
|
1152
1105
|
boundsIJK
|
|
1153
1106
|
);
|
|
1154
1107
|
|
|
1155
|
-
|
|
1156
|
-
stdDev = Math.sqrt(stdDev);
|
|
1157
|
-
|
|
1158
|
-
const modalityUnit = getModalityUnit(
|
|
1159
|
-
metadata.Modality,
|
|
1160
|
-
annotation.metadata.referencedImageId,
|
|
1161
|
-
modalityUnitOptions
|
|
1162
|
-
);
|
|
1108
|
+
const stats = this.configuration.statsCalculator.getStatistics();
|
|
1163
1109
|
|
|
1164
1110
|
cachedStats[targetId] = {
|
|
1165
1111
|
Modality: metadata.Modality,
|
|
1166
1112
|
area,
|
|
1167
|
-
mean,
|
|
1168
|
-
max,
|
|
1169
|
-
stdDev,
|
|
1113
|
+
mean: stats[1]?.value,
|
|
1114
|
+
max: stats[0]?.value,
|
|
1115
|
+
stdDev: stats[2]?.value,
|
|
1116
|
+
statsArray: stats,
|
|
1117
|
+
pointsInShape: pointsInShape,
|
|
1170
1118
|
isEmptyArea,
|
|
1171
1119
|
areaUnit: getCalibratedAreaUnits(null, image),
|
|
1172
1120
|
modalityUnit,
|
|
@@ -1248,5 +1196,34 @@ class EllipticalROITool extends AnnotationTool {
|
|
|
1248
1196
|
}
|
|
1249
1197
|
}
|
|
1250
1198
|
|
|
1199
|
+
function defaultGetTextLines(data, targetId): string[] {
|
|
1200
|
+
const cachedVolumeStats = data.cachedStats[targetId];
|
|
1201
|
+
const { area, mean, stdDev, max, isEmptyArea, areaUnit, modalityUnit } =
|
|
1202
|
+
cachedVolumeStats;
|
|
1203
|
+
|
|
1204
|
+
const textLines: string[] = [];
|
|
1205
|
+
|
|
1206
|
+
if (area) {
|
|
1207
|
+
const areaLine = isEmptyArea
|
|
1208
|
+
? `Area: Oblique not supported`
|
|
1209
|
+
: `Area: ${roundNumber(area)} ${areaUnit}`;
|
|
1210
|
+
textLines.push(areaLine);
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
if (mean) {
|
|
1214
|
+
textLines.push(`Mean: ${roundNumber(mean)} ${modalityUnit}`);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
if (max) {
|
|
1218
|
+
textLines.push(`Max: ${roundNumber(max)} ${modalityUnit}`);
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
if (stdDev) {
|
|
1222
|
+
textLines.push(`Std Dev: ${roundNumber(stdDev)} ${modalityUnit}`);
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
return textLines;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1251
1228
|
EllipticalROITool.toolName = 'EllipticalROI';
|
|
1252
1229
|
export default EllipticalROITool;
|