@cornerstonejs/tools 1.23.3 → 1.24.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.
Files changed (228) hide show
  1. package/dist/cjs/tools/displayTools/SegmentationDisplayTool.js.map +1 -1
  2. package/dist/cjs/utilities/getVOIMultipliers.d.ts +5 -0
  3. package/dist/cjs/utilities/getVOIMultipliers.js +23 -0
  4. package/dist/cjs/utilities/getVOIMultipliers.js.map +1 -0
  5. package/dist/cjs/utilities/index.d.ts +2 -1
  6. package/dist/cjs/utilities/index.js +3 -1
  7. package/dist/cjs/utilities/index.js.map +1 -1
  8. package/dist/cjs/utilities/math/vec3/interpolateVec3.d.ts +2 -0
  9. package/dist/cjs/utilities/math/vec3/interpolateVec3.js +13 -0
  10. package/dist/cjs/utilities/math/vec3/interpolateVec3.js.map +1 -0
  11. package/dist/cjs/utilities/viewport/isViewportPreScaled.js +2 -1
  12. package/dist/cjs/utilities/viewport/isViewportPreScaled.js.map +1 -1
  13. package/dist/cjs/utilities/voi/colorbar/Colorbar.d.ts +44 -0
  14. package/dist/cjs/utilities/voi/colorbar/Colorbar.js +249 -0
  15. package/dist/cjs/utilities/voi/colorbar/Colorbar.js.map +1 -0
  16. package/dist/cjs/utilities/voi/colorbar/ColorbarCanvas.d.ts +29 -0
  17. package/dist/cjs/utilities/voi/colorbar/ColorbarCanvas.js +184 -0
  18. package/dist/cjs/utilities/voi/colorbar/ColorbarCanvas.js.map +1 -0
  19. package/dist/cjs/utilities/voi/colorbar/ColorbarTicks.d.ts +46 -0
  20. package/dist/cjs/utilities/voi/colorbar/ColorbarTicks.js +286 -0
  21. package/dist/cjs/utilities/voi/colorbar/ColorbarTicks.js.map +1 -0
  22. package/dist/cjs/utilities/voi/colorbar/ViewportColorbar.d.ts +23 -0
  23. package/dist/cjs/utilities/voi/colorbar/ViewportColorbar.js +126 -0
  24. package/dist/cjs/utilities/voi/colorbar/ViewportColorbar.js.map +1 -0
  25. package/dist/cjs/utilities/voi/colorbar/common/areColorbarRangesEqual.d.ts +3 -0
  26. package/dist/cjs/utilities/voi/colorbar/common/areColorbarRangesEqual.js +9 -0
  27. package/dist/cjs/utilities/voi/colorbar/common/areColorbarRangesEqual.js.map +1 -0
  28. package/dist/cjs/utilities/voi/colorbar/common/areColorbarSizesEqual.d.ts +3 -0
  29. package/dist/cjs/utilities/voi/colorbar/common/areColorbarSizesEqual.js +9 -0
  30. package/dist/cjs/utilities/voi/colorbar/common/areColorbarSizesEqual.js.map +1 -0
  31. package/dist/cjs/utilities/voi/colorbar/common/index.d.ts +4 -0
  32. package/dist/cjs/utilities/voi/colorbar/common/index.js +12 -0
  33. package/dist/cjs/utilities/voi/colorbar/common/index.js.map +1 -0
  34. package/dist/cjs/utilities/voi/colorbar/common/isColorbarSizeValid.d.ts +3 -0
  35. package/dist/cjs/utilities/voi/colorbar/common/isColorbarSizeValid.js +9 -0
  36. package/dist/cjs/utilities/voi/colorbar/common/isColorbarSizeValid.js.map +1 -0
  37. package/dist/cjs/utilities/voi/colorbar/common/isRangeTextPositionValid.d.ts +3 -0
  38. package/dist/cjs/utilities/voi/colorbar/common/isRangeTextPositionValid.js +14 -0
  39. package/dist/cjs/utilities/voi/colorbar/common/isRangeTextPositionValid.js.map +1 -0
  40. package/dist/cjs/utilities/voi/colorbar/common/isRangeValid.d.ts +3 -0
  41. package/dist/cjs/utilities/voi/colorbar/common/isRangeValid.js +9 -0
  42. package/dist/cjs/utilities/voi/colorbar/common/isRangeValid.js.map +1 -0
  43. package/dist/cjs/utilities/voi/colorbar/enums/ColorbarRangeTextPosition.d.ts +6 -0
  44. package/dist/cjs/utilities/voi/colorbar/enums/ColorbarRangeTextPosition.js +11 -0
  45. package/dist/cjs/utilities/voi/colorbar/enums/ColorbarRangeTextPosition.js.map +1 -0
  46. package/dist/cjs/utilities/voi/colorbar/enums/index.d.ts +1 -0
  47. package/dist/cjs/utilities/voi/colorbar/enums/index.js +6 -0
  48. package/dist/cjs/utilities/voi/colorbar/enums/index.js.map +1 -0
  49. package/dist/cjs/utilities/voi/colorbar/index.d.ts +6 -0
  50. package/dist/cjs/utilities/voi/colorbar/index.js +33 -0
  51. package/dist/cjs/utilities/voi/colorbar/index.js.map +1 -0
  52. package/dist/cjs/utilities/voi/colorbar/types/ColorbarCanvasProps.d.ts +12 -0
  53. package/dist/cjs/utilities/voi/colorbar/types/ColorbarCanvasProps.js +3 -0
  54. package/dist/cjs/utilities/voi/colorbar/types/ColorbarCanvasProps.js.map +1 -0
  55. package/dist/cjs/utilities/voi/colorbar/types/ColorbarCommonProps.d.ts +11 -0
  56. package/dist/cjs/utilities/voi/colorbar/types/ColorbarCommonProps.js +3 -0
  57. package/dist/cjs/utilities/voi/colorbar/types/ColorbarCommonProps.js.map +1 -0
  58. package/dist/cjs/utilities/voi/colorbar/types/ColorbarImageRange.d.ts +4 -0
  59. package/dist/cjs/utilities/voi/colorbar/types/ColorbarImageRange.js +3 -0
  60. package/dist/cjs/utilities/voi/colorbar/types/ColorbarImageRange.js.map +1 -0
  61. package/dist/cjs/utilities/voi/colorbar/types/ColorbarProps.d.ts +7 -0
  62. package/dist/cjs/utilities/voi/colorbar/types/ColorbarProps.js +3 -0
  63. package/dist/cjs/utilities/voi/colorbar/types/ColorbarProps.js.map +1 -0
  64. package/dist/cjs/utilities/voi/colorbar/types/ColorbarSize.d.ts +4 -0
  65. package/dist/cjs/utilities/voi/colorbar/types/ColorbarSize.js +3 -0
  66. package/dist/cjs/utilities/voi/colorbar/types/ColorbarSize.js.map +1 -0
  67. package/dist/cjs/utilities/voi/colorbar/types/ColorbarTicksProps.d.ts +7 -0
  68. package/dist/cjs/utilities/voi/colorbar/types/ColorbarTicksProps.js +3 -0
  69. package/dist/cjs/utilities/voi/colorbar/types/ColorbarTicksProps.js.map +1 -0
  70. package/dist/cjs/utilities/voi/colorbar/types/ColorbarTicksStyle.d.ts +8 -0
  71. package/dist/cjs/utilities/voi/colorbar/types/ColorbarTicksStyle.js +3 -0
  72. package/dist/cjs/utilities/voi/colorbar/types/ColorbarTicksStyle.js.map +1 -0
  73. package/dist/cjs/utilities/voi/colorbar/types/ColorbarVOIRange.d.ts +2 -0
  74. package/dist/cjs/utilities/voi/colorbar/types/ColorbarVOIRange.js +3 -0
  75. package/dist/cjs/utilities/voi/colorbar/types/ColorbarVOIRange.js.map +1 -0
  76. package/dist/cjs/utilities/voi/colorbar/types/ViewportColorbarProps.d.ts +5 -0
  77. package/dist/cjs/utilities/voi/colorbar/types/ViewportColorbarProps.js +3 -0
  78. package/dist/cjs/utilities/voi/colorbar/types/ViewportColorbarProps.js.map +1 -0
  79. package/dist/cjs/utilities/voi/colorbar/types/index.d.ts +8 -0
  80. package/dist/cjs/utilities/voi/colorbar/types/index.js +3 -0
  81. package/dist/cjs/utilities/voi/colorbar/types/index.js.map +1 -0
  82. package/dist/cjs/utilities/voi/index.d.ts +2 -0
  83. package/dist/cjs/utilities/voi/index.js +29 -0
  84. package/dist/cjs/utilities/voi/index.js.map +1 -0
  85. package/dist/cjs/widgets/Widget.d.ts +17 -0
  86. package/dist/cjs/widgets/Widget.js +71 -0
  87. package/dist/cjs/widgets/Widget.js.map +1 -0
  88. package/dist/cjs/widgets/types/WidgetProps.d.ts +4 -0
  89. package/dist/cjs/widgets/types/WidgetProps.js +3 -0
  90. package/dist/cjs/widgets/types/WidgetProps.js.map +1 -0
  91. package/dist/cjs/widgets/types/WidgetSize.d.ts +4 -0
  92. package/dist/cjs/widgets/types/WidgetSize.js +3 -0
  93. package/dist/cjs/widgets/types/WidgetSize.js.map +1 -0
  94. package/dist/cjs/widgets/types/index.d.ts +2 -0
  95. package/dist/cjs/widgets/types/index.js +3 -0
  96. package/dist/cjs/widgets/types/index.js.map +1 -0
  97. package/dist/esm/tools/displayTools/SegmentationDisplayTool.js.map +1 -1
  98. package/dist/esm/utilities/getVOIMultipliers.d.ts +5 -0
  99. package/dist/esm/utilities/getVOIMultipliers.js +19 -0
  100. package/dist/esm/utilities/getVOIMultipliers.js.map +1 -0
  101. package/dist/esm/utilities/index.d.ts +2 -1
  102. package/dist/esm/utilities/index.js +2 -1
  103. package/dist/esm/utilities/index.js.map +1 -1
  104. package/dist/esm/utilities/math/vec3/interpolateVec3.d.ts +2 -0
  105. package/dist/esm/utilities/math/vec3/interpolateVec3.js +9 -0
  106. package/dist/esm/utilities/math/vec3/interpolateVec3.js.map +1 -0
  107. package/dist/esm/utilities/viewport/isViewportPreScaled.js +2 -1
  108. package/dist/esm/utilities/viewport/isViewportPreScaled.js.map +1 -1
  109. package/dist/esm/utilities/voi/colorbar/Colorbar.d.ts +44 -0
  110. package/dist/esm/utilities/voi/colorbar/Colorbar.js +241 -0
  111. package/dist/esm/utilities/voi/colorbar/Colorbar.js.map +1 -0
  112. package/dist/esm/utilities/voi/colorbar/ColorbarCanvas.d.ts +29 -0
  113. package/dist/esm/utilities/voi/colorbar/ColorbarCanvas.js +177 -0
  114. package/dist/esm/utilities/voi/colorbar/ColorbarCanvas.js.map +1 -0
  115. package/dist/esm/utilities/voi/colorbar/ColorbarTicks.d.ts +46 -0
  116. package/dist/esm/utilities/voi/colorbar/ColorbarTicks.js +281 -0
  117. package/dist/esm/utilities/voi/colorbar/ColorbarTicks.js.map +1 -0
  118. package/dist/esm/utilities/voi/colorbar/ViewportColorbar.d.ts +23 -0
  119. package/dist/esm/utilities/voi/colorbar/ViewportColorbar.js +122 -0
  120. package/dist/esm/utilities/voi/colorbar/ViewportColorbar.js.map +1 -0
  121. package/dist/esm/utilities/voi/colorbar/common/areColorbarRangesEqual.d.ts +3 -0
  122. package/dist/esm/utilities/voi/colorbar/common/areColorbarRangesEqual.js +5 -0
  123. package/dist/esm/utilities/voi/colorbar/common/areColorbarRangesEqual.js.map +1 -0
  124. package/dist/esm/utilities/voi/colorbar/common/areColorbarSizesEqual.d.ts +3 -0
  125. package/dist/esm/utilities/voi/colorbar/common/areColorbarSizesEqual.js +5 -0
  126. package/dist/esm/utilities/voi/colorbar/common/areColorbarSizesEqual.js.map +1 -0
  127. package/dist/esm/utilities/voi/colorbar/common/index.d.ts +4 -0
  128. package/dist/esm/utilities/voi/colorbar/common/index.js +5 -0
  129. package/dist/esm/utilities/voi/colorbar/common/index.js.map +1 -0
  130. package/dist/esm/utilities/voi/colorbar/common/isColorbarSizeValid.d.ts +3 -0
  131. package/dist/esm/utilities/voi/colorbar/common/isColorbarSizeValid.js +5 -0
  132. package/dist/esm/utilities/voi/colorbar/common/isColorbarSizeValid.js.map +1 -0
  133. package/dist/esm/utilities/voi/colorbar/common/isRangeTextPositionValid.d.ts +3 -0
  134. package/dist/esm/utilities/voi/colorbar/common/isRangeTextPositionValid.js +10 -0
  135. package/dist/esm/utilities/voi/colorbar/common/isRangeTextPositionValid.js.map +1 -0
  136. package/dist/esm/utilities/voi/colorbar/common/isRangeValid.d.ts +3 -0
  137. package/dist/esm/utilities/voi/colorbar/common/isRangeValid.js +5 -0
  138. package/dist/esm/utilities/voi/colorbar/common/isRangeValid.js.map +1 -0
  139. package/dist/esm/utilities/voi/colorbar/enums/ColorbarRangeTextPosition.d.ts +6 -0
  140. package/dist/esm/utilities/voi/colorbar/enums/ColorbarRangeTextPosition.js +8 -0
  141. package/dist/esm/utilities/voi/colorbar/enums/ColorbarRangeTextPosition.js.map +1 -0
  142. package/dist/esm/utilities/voi/colorbar/enums/index.d.ts +1 -0
  143. package/dist/esm/utilities/voi/colorbar/enums/index.js +2 -0
  144. package/dist/esm/utilities/voi/colorbar/enums/index.js.map +1 -0
  145. package/dist/esm/utilities/voi/colorbar/index.d.ts +6 -0
  146. package/dist/esm/utilities/voi/colorbar/index.js +5 -0
  147. package/dist/esm/utilities/voi/colorbar/index.js.map +1 -0
  148. package/dist/esm/utilities/voi/colorbar/types/ColorbarCanvasProps.d.ts +12 -0
  149. package/dist/esm/utilities/voi/colorbar/types/ColorbarCanvasProps.js +2 -0
  150. package/dist/esm/utilities/voi/colorbar/types/ColorbarCanvasProps.js.map +1 -0
  151. package/dist/esm/utilities/voi/colorbar/types/ColorbarCommonProps.d.ts +11 -0
  152. package/dist/esm/utilities/voi/colorbar/types/ColorbarCommonProps.js +2 -0
  153. package/dist/esm/utilities/voi/colorbar/types/ColorbarCommonProps.js.map +1 -0
  154. package/dist/esm/utilities/voi/colorbar/types/ColorbarImageRange.d.ts +4 -0
  155. package/dist/esm/utilities/voi/colorbar/types/ColorbarImageRange.js +2 -0
  156. package/dist/esm/utilities/voi/colorbar/types/ColorbarImageRange.js.map +1 -0
  157. package/dist/esm/utilities/voi/colorbar/types/ColorbarProps.d.ts +7 -0
  158. package/dist/esm/utilities/voi/colorbar/types/ColorbarProps.js +2 -0
  159. package/dist/esm/utilities/voi/colorbar/types/ColorbarProps.js.map +1 -0
  160. package/dist/esm/utilities/voi/colorbar/types/ColorbarSize.d.ts +4 -0
  161. package/dist/esm/utilities/voi/colorbar/types/ColorbarSize.js +2 -0
  162. package/dist/esm/utilities/voi/colorbar/types/ColorbarSize.js.map +1 -0
  163. package/dist/esm/utilities/voi/colorbar/types/ColorbarTicksProps.d.ts +7 -0
  164. package/dist/esm/utilities/voi/colorbar/types/ColorbarTicksProps.js +2 -0
  165. package/dist/esm/utilities/voi/colorbar/types/ColorbarTicksProps.js.map +1 -0
  166. package/dist/esm/utilities/voi/colorbar/types/ColorbarTicksStyle.d.ts +8 -0
  167. package/dist/esm/utilities/voi/colorbar/types/ColorbarTicksStyle.js +2 -0
  168. package/dist/esm/utilities/voi/colorbar/types/ColorbarTicksStyle.js.map +1 -0
  169. package/dist/esm/utilities/voi/colorbar/types/ColorbarVOIRange.d.ts +2 -0
  170. package/dist/esm/utilities/voi/colorbar/types/ColorbarVOIRange.js +2 -0
  171. package/dist/esm/utilities/voi/colorbar/types/ColorbarVOIRange.js.map +1 -0
  172. package/dist/esm/utilities/voi/colorbar/types/ViewportColorbarProps.d.ts +5 -0
  173. package/dist/esm/utilities/voi/colorbar/types/ViewportColorbarProps.js +2 -0
  174. package/dist/esm/utilities/voi/colorbar/types/ViewportColorbarProps.js.map +1 -0
  175. package/dist/esm/utilities/voi/colorbar/types/index.d.ts +8 -0
  176. package/dist/esm/utilities/voi/colorbar/types/index.js +2 -0
  177. package/dist/esm/utilities/voi/colorbar/types/index.js.map +1 -0
  178. package/dist/esm/utilities/voi/index.d.ts +2 -0
  179. package/dist/esm/utilities/voi/index.js +3 -0
  180. package/dist/esm/utilities/voi/index.js.map +1 -0
  181. package/dist/esm/widgets/Widget.d.ts +17 -0
  182. package/dist/esm/widgets/Widget.js +67 -0
  183. package/dist/esm/widgets/Widget.js.map +1 -0
  184. package/dist/esm/widgets/types/WidgetProps.d.ts +4 -0
  185. package/dist/esm/widgets/types/WidgetProps.js +2 -0
  186. package/dist/esm/widgets/types/WidgetProps.js.map +1 -0
  187. package/dist/esm/widgets/types/WidgetSize.d.ts +4 -0
  188. package/dist/esm/widgets/types/WidgetSize.js +2 -0
  189. package/dist/esm/widgets/types/WidgetSize.js.map +1 -0
  190. package/dist/esm/widgets/types/index.d.ts +2 -0
  191. package/dist/esm/widgets/types/index.js +2 -0
  192. package/dist/esm/widgets/types/index.js.map +1 -0
  193. package/dist/umd/index.js +1 -1
  194. package/dist/umd/index.js.map +1 -1
  195. package/package.json +3 -3
  196. package/src/tools/displayTools/SegmentationDisplayTool.ts +1 -2
  197. package/src/utilities/getVOIMultipliers.ts +33 -0
  198. package/src/utilities/index.ts +2 -0
  199. package/src/utilities/math/vec3/interpolateVec3.ts +20 -0
  200. package/src/utilities/viewport/isViewportPreScaled.ts +3 -1
  201. package/src/utilities/voi/colorbar/Colorbar.ts +367 -0
  202. package/src/utilities/voi/colorbar/ColorbarCanvas.ts +287 -0
  203. package/src/utilities/voi/colorbar/ColorbarTicks.ts +500 -0
  204. package/src/utilities/voi/colorbar/ViewportColorbar.ts +194 -0
  205. package/src/utilities/voi/colorbar/common/areColorbarRangesEqual.ts +10 -0
  206. package/src/utilities/voi/colorbar/common/areColorbarSizesEqual.ts +7 -0
  207. package/src/utilities/voi/colorbar/common/index.ts +4 -0
  208. package/src/utilities/voi/colorbar/common/isColorbarSizeValid.ts +7 -0
  209. package/src/utilities/voi/colorbar/common/isRangeTextPositionValid.ts +16 -0
  210. package/src/utilities/voi/colorbar/common/isRangeValid.ts +7 -0
  211. package/src/utilities/voi/colorbar/enums/ColorbarRangeTextPosition.ts +11 -0
  212. package/src/utilities/voi/colorbar/enums/index.ts +1 -0
  213. package/src/utilities/voi/colorbar/index.ts +8 -0
  214. package/src/utilities/voi/colorbar/types/ColorbarCanvasProps.ts +14 -0
  215. package/src/utilities/voi/colorbar/types/ColorbarCommonProps.ts +23 -0
  216. package/src/utilities/voi/colorbar/types/ColorbarImageRange.ts +4 -0
  217. package/src/utilities/voi/colorbar/types/ColorbarProps.ts +8 -0
  218. package/src/utilities/voi/colorbar/types/ColorbarSize.ts +4 -0
  219. package/src/utilities/voi/colorbar/types/ColorbarTicksProps.ts +8 -0
  220. package/src/utilities/voi/colorbar/types/ColorbarTicksStyle.ts +8 -0
  221. package/src/utilities/voi/colorbar/types/ColorbarVOIRange.ts +3 -0
  222. package/src/utilities/voi/colorbar/types/ViewportColorbarProps.ts +6 -0
  223. package/src/utilities/voi/colorbar/types/index.ts +8 -0
  224. package/src/utilities/voi/index.ts +3 -0
  225. package/src/widgets/Widget.ts +169 -0
  226. package/src/widgets/types/WidgetProps.ts +4 -0
  227. package/src/widgets/types/WidgetSize.ts +4 -0
  228. package/src/widgets/types/index.ts +2 -0
@@ -0,0 +1,500 @@
1
+ import type {
2
+ ColorbarImageRange,
3
+ ColorbarVOIRange,
4
+ ColorbarSize,
5
+ ColorbarTicksProps,
6
+ } from './types';
7
+ import {
8
+ isColorbarSizeValid,
9
+ isRangeValid,
10
+ areColorbarRangesEqual,
11
+ areColorbarSizesEqual,
12
+ } from './common';
13
+ import { ColorbarRangeTextPosition } from './enums/ColorbarRangeTextPosition';
14
+
15
+ const DEFAULTS = {
16
+ FONT: '10px Arial',
17
+ COLOR: 'white',
18
+ TICK_SIZE: 5,
19
+ TICK_WIDTH: 1,
20
+ TICK_LABEL_MARGIN: 3,
21
+ MAX_NUM_TICKS: 8,
22
+
23
+ // Must start with 1 and end with 10
24
+ TICKS_STEPS: [1, 2.5, 5, 10],
25
+ };
26
+
27
+ class ColorbarTicks {
28
+ private _canvas: HTMLCanvasElement;
29
+ private _imageRange: ColorbarImageRange;
30
+ private _voiRange: ColorbarVOIRange;
31
+ private _color: string;
32
+ private _tickSize: number;
33
+ private _tickWidth: number;
34
+ private _labelMargin: number;
35
+ private _maxNumTicks: number;
36
+ private _rangeTextPosition: ColorbarRangeTextPosition;
37
+ private _showFullPixelValueRange: boolean;
38
+ private _font: string;
39
+
40
+ constructor(props: ColorbarTicksProps) {
41
+ ColorbarTicks.validateProps(props);
42
+
43
+ const {
44
+ top = 0,
45
+ left = 0,
46
+ size = { width: 20, height: 100 },
47
+ imageRange = { lower: 0, upper: 1 },
48
+ voiRange = { lower: 0, upper: 1 },
49
+ ticks: ticksProps,
50
+ container,
51
+ showFullPixelValueRange = false,
52
+ } = props;
53
+
54
+ const { style: ticksStyle, position: rangeTextPosition } = ticksProps ?? {};
55
+
56
+ this._imageRange = imageRange;
57
+ this._voiRange = voiRange;
58
+ this._font = ticksStyle?.font ?? DEFAULTS.FONT;
59
+ this._color = ticksStyle?.color ?? DEFAULTS.COLOR;
60
+ this._tickSize = ticksStyle?.tickSize ?? DEFAULTS.TICK_SIZE;
61
+ this._tickWidth = ticksStyle?.tickWidth ?? DEFAULTS.TICK_WIDTH;
62
+ this._labelMargin = ticksStyle?.labelMargin ?? DEFAULTS.TICK_LABEL_MARGIN;
63
+ this._maxNumTicks = ticksStyle?.maxNumTicks ?? DEFAULTS.MAX_NUM_TICKS;
64
+ this._rangeTextPosition =
65
+ rangeTextPosition ?? ColorbarRangeTextPosition.Right;
66
+ this._showFullPixelValueRange = showFullPixelValueRange;
67
+ this._canvas = this._createCanvasElement(size, top, left);
68
+
69
+ if (container) {
70
+ this.appendTo(container);
71
+ }
72
+ }
73
+
74
+ public get size(): ColorbarSize {
75
+ const { width, height } = this._canvas;
76
+ return { width, height };
77
+ }
78
+
79
+ public set size(size: ColorbarSize) {
80
+ const { _canvas: canvas } = this;
81
+
82
+ if (!isColorbarSizeValid(size) || areColorbarSizesEqual(canvas, size)) {
83
+ return;
84
+ }
85
+
86
+ this._setCanvasSize(canvas, size);
87
+ this.render();
88
+ }
89
+
90
+ /**
91
+ * Canvas top position (pixels)
92
+ */
93
+ public get top(): number {
94
+ return Number.parseInt(this._canvas.style.top);
95
+ }
96
+
97
+ /**
98
+ * Change the canvas top position (pixels)
99
+ */
100
+ public set top(top: number) {
101
+ const { _canvas: canvas } = this;
102
+ const currentTop = this.top;
103
+
104
+ if (top === currentTop) {
105
+ return;
106
+ }
107
+
108
+ canvas.style.top = `${top}px`;
109
+ this.render();
110
+ }
111
+
112
+ /**
113
+ * Canvas left position (pixels)
114
+ */
115
+ public get left(): number {
116
+ return Number.parseInt(this._canvas.style.left);
117
+ }
118
+
119
+ /**
120
+ * Change the canvas left position (pixels)
121
+ */
122
+ public set left(left: number) {
123
+ const { _canvas: canvas } = this;
124
+ const currentLeft = this.left;
125
+
126
+ if (left === currentLeft) {
127
+ return;
128
+ }
129
+
130
+ canvas.style.left = `${left}px`;
131
+ this.render();
132
+ }
133
+
134
+ /**
135
+ * Image range
136
+ */
137
+ public get imageRange() {
138
+ return { ...this._imageRange };
139
+ }
140
+
141
+ /**
142
+ * Set the image range that should goes from minPixelValue to maxPixelValue
143
+ */
144
+ public set imageRange(imageRange: ColorbarVOIRange) {
145
+ if (
146
+ !isRangeValid(imageRange) ||
147
+ areColorbarRangesEqual(imageRange, this._imageRange)
148
+ ) {
149
+ return;
150
+ }
151
+
152
+ this._imageRange = imageRange;
153
+ this.render();
154
+ }
155
+
156
+ /**
157
+ * VOI range
158
+ * (lower: wc - ww / 2, upper: wc + ww / 2)
159
+ */
160
+ public get voiRange() {
161
+ return { ...this._voiRange };
162
+ }
163
+
164
+ /**
165
+ * Set the VOI Range
166
+ * (lower: wc - ww / 2, upper: wc + ww / 2)
167
+ */
168
+ public set voiRange(voiRange: ColorbarVOIRange) {
169
+ if (
170
+ !isRangeValid(voiRange) ||
171
+ areColorbarRangesEqual(voiRange, this._voiRange)
172
+ ) {
173
+ return;
174
+ }
175
+
176
+ this._voiRange = voiRange;
177
+ this.render();
178
+ }
179
+
180
+ /**
181
+ * Tick size (pixels)
182
+ */
183
+ public get tickSize(): number {
184
+ return this._tickSize;
185
+ }
186
+
187
+ /**
188
+ * Set the tick size
189
+ */
190
+ public set tickSize(tickSize: number) {
191
+ if (tickSize === this._tickSize) {
192
+ return;
193
+ }
194
+
195
+ this._tickSize = tickSize;
196
+ this.render();
197
+ }
198
+
199
+ /**
200
+ * Tick width (pixels)
201
+ */
202
+ public get tickWidth(): number {
203
+ return this._tickWidth;
204
+ }
205
+
206
+ /**
207
+ * Set the tick width. This width is used as `lineWidth` by CanvasRenderingContext2D.
208
+ *
209
+ * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth
210
+ */
211
+ public set tickWidth(tickWidth: number) {
212
+ if (tickWidth === this._tickWidth) {
213
+ return;
214
+ }
215
+
216
+ this._tickWidth = tickWidth;
217
+ this.render();
218
+ }
219
+
220
+ /**
221
+ * Color used for ticks and labels.
222
+ */
223
+ public get color(): string {
224
+ return this._color;
225
+ }
226
+
227
+ /**
228
+ * Set the color used for ticks and labels. This color is used as `strokeStyle`
229
+ * and `fillStyle` by CanvasRenderingContext2D.
230
+ *
231
+ * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle
232
+ * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle
233
+ */
234
+ public set color(color: string) {
235
+ if (color === this._color) {
236
+ return;
237
+ }
238
+
239
+ this._color = color;
240
+ this.render();
241
+ }
242
+
243
+ /**
244
+ * Return `true` when the ticks displayed are in the range from `imageRange.lower`
245
+ * to `imageRange.upper` or `false` when they are in the range from `voiRange.lower`
246
+ * to `voiRange.upper`
247
+ */
248
+ public get showFullPixelValueRange(): boolean {
249
+ return this._showFullPixelValueRange;
250
+ }
251
+
252
+ /**
253
+ * Change which range should be used when rendering the ticks. Set it to `true`
254
+ * to show from `imageRange.lower` to `imageRange.upper` or `false` show from
255
+ * `voiRange.lower` to `voiRange.upper`.
256
+ */
257
+ public set showFullPixelValueRange(showFullRange: boolean) {
258
+ if (showFullRange === this._showFullPixelValueRange) {
259
+ return;
260
+ }
261
+
262
+ this._showFullPixelValueRange = showFullRange;
263
+ this.render();
264
+ }
265
+
266
+ /**
267
+ * Ticks visibility
268
+ */
269
+ public get visible() {
270
+ return this._canvas.style.display === 'block';
271
+ }
272
+
273
+ /**
274
+ * Show/Hide the ticks
275
+ */
276
+ public set visible(visible) {
277
+ if (visible === this.visible) {
278
+ return;
279
+ }
280
+
281
+ this._canvas.style.display = visible ? 'block' : 'none';
282
+
283
+ if (visible) {
284
+ this.render();
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Append the canvas to its parent element
290
+ * @param container - HTML element where the canvas should be added to
291
+ */
292
+ public appendTo(container: HTMLElement) {
293
+ container.appendChild(this._canvas);
294
+ this.render();
295
+ }
296
+
297
+ private static validateProps(props: ColorbarTicksProps) {
298
+ const { size, imageRange, voiRange } = props;
299
+
300
+ if (size && !isColorbarSizeValid(size)) {
301
+ throw new Error('Invalid "size"');
302
+ }
303
+
304
+ if (imageRange && !isRangeValid(imageRange)) {
305
+ throw new Error('Invalid "imageRange"');
306
+ }
307
+
308
+ if (voiRange && !isRangeValid(voiRange)) {
309
+ throw new Error('Invalid "voiRange"');
310
+ }
311
+ }
312
+
313
+ private _setCanvasSize(canvas: HTMLCanvasElement, size: ColorbarSize) {
314
+ const { width, height } = size;
315
+
316
+ canvas.width = width;
317
+ canvas.height = height;
318
+
319
+ Object.assign(canvas.style, {
320
+ width: `${width}px`,
321
+ height: `${height}px`,
322
+ });
323
+ }
324
+
325
+ private _createCanvasElement(
326
+ size: ColorbarSize,
327
+ top: number,
328
+ left: number
329
+ ): HTMLCanvasElement {
330
+ const canvas = document.createElement('canvas');
331
+
332
+ Object.assign(canvas.style, {
333
+ display: 'none',
334
+ position: 'absolute',
335
+ boxSizing: 'border-box',
336
+ top: `${top}px`,
337
+ left: `${left}px`,
338
+ });
339
+
340
+ this._setCanvasSize(canvas, size);
341
+
342
+ return canvas;
343
+ }
344
+
345
+ /**
346
+ * Calculate how many ticks can be displayed on the screen based on the
347
+ * pre-defined steps (`TICKS_STEPS`) as follow:
348
+ * 1. Calculate what should be the step (`roughStep`) based on the range and
349
+ * the number of desired steps (`maxNumTicks`).
350
+ * 2. Find a number power of 10 (eg: 0.1, 1, 10, 100, etc.) that can be used
351
+ * to multiply `roughStep` and return a number between 1 and 10 which is
352
+ * called `roughtStepNormalized`.
353
+ * 3. Find in the TICKS_STEPS array a number that is bigger than or equal to
354
+ * the `roughtStepNormalized` value (`normalizedStep`).
355
+ * 4. Multiply the `normalizedStep` to move it to the real range.
356
+ *
357
+ * @param range - Range with "lower" and "upper" values
358
+ */
359
+ private _getTicks(range) {
360
+ const { lower, upper } = range;
361
+ const rangeValue = upper - lower;
362
+
363
+ // First approximation based on the max number of ticks
364
+ const roughStep = rangeValue / (this._maxNumTicks - 1);
365
+
366
+ // Normalize rough step to find the normalized one that fits best
367
+ const stepPower = Math.pow(
368
+ 10,
369
+ -Math.floor(Math.log10(Math.abs(roughStep)))
370
+ );
371
+
372
+ // Get a number between 1 and 10
373
+ const roughtStepNormalized = roughStep * stepPower;
374
+
375
+ // Find a normalize step that is greater than or equal to `roughtStepNormalized`
376
+ const normalizedStep = DEFAULTS.TICKS_STEPS.find(
377
+ (n) => n >= roughtStepNormalized
378
+ );
379
+
380
+ // Move `normalizedStep` to the real range
381
+ const step = normalizedStep / stepPower;
382
+
383
+ // Determine the scale limits based on the chosen step.
384
+ const scaleMax = Math.ceil(upper / step) * step;
385
+ const scaleMin = Math.floor(lower / step) * step;
386
+
387
+ // Find a possible tick values for the `step` computed
388
+ const ticksCount = Math.round((scaleMax - scaleMin) / step) + 1;
389
+ const ticks = [];
390
+
391
+ for (let i = 0; i < ticksCount; i++) {
392
+ ticks.push(scaleMin + i * step);
393
+ }
394
+
395
+ return { scaleMin, scaleMax, step, ticks };
396
+ }
397
+
398
+ private _getLeftTickInfo({ position, labelMeasure }) {
399
+ const { width } = this._canvas;
400
+ const labelX =
401
+ width - this.tickSize - labelMeasure.width - this._labelMargin;
402
+ const labelPoint = [labelX, position];
403
+ const tickPoints = {
404
+ start: [width - this._tickSize, position],
405
+ end: [width, position],
406
+ };
407
+
408
+ return { labelPoint, tickPoints };
409
+ }
410
+
411
+ private _getRightTickInfo({ position }) {
412
+ const labelPoint = [this._tickSize + this._labelMargin, position];
413
+ const tickPoints = {
414
+ start: [0, position],
415
+ end: [this._tickSize, position],
416
+ };
417
+
418
+ return { labelPoint, tickPoints };
419
+ }
420
+
421
+ private _getTopTickInfo({ position, labelMeasure }) {
422
+ throw new Error('Not implemented');
423
+ }
424
+
425
+ private _getBottomTickInfo({ position, labelMeasure }) {
426
+ throw new Error('Not implemented');
427
+ }
428
+
429
+ private render() {
430
+ const { _canvas: canvas } = this;
431
+
432
+ if (!canvas.isConnected || !this.visible) {
433
+ return;
434
+ }
435
+
436
+ const { width, height } = canvas;
437
+ const isHorizontal = width >= height;
438
+ const maxCanvasPixelValue = isHorizontal ? width : height;
439
+ const canvasContext = canvas.getContext('2d');
440
+ const { _voiRange: voiRange } = this;
441
+ const range = this._showFullPixelValueRange
442
+ ? this._imageRange
443
+ : { ...voiRange };
444
+ const rangeWidth = range.upper - range.lower;
445
+ const { ticks } = this._getTicks(range);
446
+
447
+ canvasContext.clearRect(0, 0, width, height);
448
+ canvasContext.font = this._font;
449
+ canvasContext.textBaseline = 'middle';
450
+ canvasContext.fillStyle = this._color;
451
+ canvasContext.strokeStyle = this._color;
452
+ canvasContext.lineWidth = this.tickWidth;
453
+
454
+ ticks.forEach((tick) => {
455
+ let position = Math.round(
456
+ maxCanvasPixelValue * ((tick - range.lower) / rangeWidth)
457
+ );
458
+
459
+ // Zero at the bottom and max at the top on vertical colorbars
460
+ if (!isHorizontal) {
461
+ position = height - position;
462
+ }
463
+
464
+ if (position < 0 || position > maxCanvasPixelValue) {
465
+ return;
466
+ }
467
+
468
+ const label = tick.toString();
469
+ const labelMeasure = canvasContext.measureText(label);
470
+ let tickInfo;
471
+
472
+ if (isHorizontal) {
473
+ if (this._rangeTextPosition === ColorbarRangeTextPosition.Top) {
474
+ tickInfo = this._getTopTickInfo({ position, labelMeasure });
475
+ } else {
476
+ tickInfo = this._getBottomTickInfo({ position, labelMeasure });
477
+ }
478
+ } else {
479
+ if (this._rangeTextPosition === ColorbarRangeTextPosition.Left) {
480
+ tickInfo = this._getLeftTickInfo({ position, labelMeasure });
481
+ } else {
482
+ tickInfo = this._getRightTickInfo({ position });
483
+ }
484
+ }
485
+
486
+ const { labelPoint, tickPoints } = tickInfo;
487
+ const { start: tickStart, end: tickEnd } = tickPoints;
488
+
489
+ canvasContext.beginPath();
490
+ canvasContext.moveTo(tickStart[0], tickStart[1]);
491
+ canvasContext.lineTo(tickEnd[0], tickEnd[1]);
492
+ canvasContext.fillText(label, labelPoint[0], labelPoint[1]);
493
+ canvasContext.stroke();
494
+
495
+ return position;
496
+ });
497
+ }
498
+ }
499
+
500
+ export { ColorbarTicks as default, ColorbarTicks };
@@ -0,0 +1,194 @@
1
+ import {
2
+ eventTarget,
3
+ VolumeViewport,
4
+ StackViewport,
5
+ Types,
6
+ Enums,
7
+ utilities,
8
+ getEnabledElement,
9
+ } from '@cornerstonejs/core';
10
+ import { Colorbar } from './Colorbar';
11
+ import type { ViewportColorbarProps, ColorbarVOIRange } from './types';
12
+ import { getVOIMultipliers } from '../../getVOIMultipliers';
13
+
14
+ const { Events } = Enums;
15
+ const defaultImageRange = { lower: -1000, upper: 1000 };
16
+ /**
17
+ * A colorbar associated with a viewport that updates automatically when the
18
+ * viewport VOI changes or when the stack/volume are updated..
19
+ */
20
+ class ViewportColorbar extends Colorbar {
21
+ private _element: HTMLDivElement;
22
+ private _volumeId: string;
23
+
24
+ private _hideTicksTime: number;
25
+ private _hideTicksTimeoutId: number;
26
+
27
+ constructor(props: ViewportColorbarProps) {
28
+ const { element, volumeId } = props;
29
+ const imageRange = ViewportColorbar._getImageRange(element, volumeId);
30
+ const voiRange = ViewportColorbar._getVOIRange(element, volumeId);
31
+
32
+ super({ ...props, imageRange, voiRange });
33
+
34
+ this._element = element;
35
+ this._volumeId = volumeId;
36
+
37
+ this._addCornerstoneEventListener();
38
+ }
39
+
40
+ public get element() {
41
+ return this._element;
42
+ }
43
+
44
+ public get enabledElement() {
45
+ return getEnabledElement(this._element);
46
+ }
47
+
48
+ protected getVOIMultipliers(): [number, number] {
49
+ const { viewport } = this.enabledElement;
50
+ return getVOIMultipliers(viewport, this._volumeId);
51
+ }
52
+
53
+ protected onVoiChange(voiRange: ColorbarVOIRange) {
54
+ super.onVoiChange(voiRange);
55
+
56
+ const { viewport } = this.enabledElement;
57
+
58
+ if (viewport instanceof StackViewport) {
59
+ viewport.setProperties({
60
+ voiRange: voiRange,
61
+ });
62
+ viewport.render();
63
+ } else if (viewport instanceof VolumeViewport) {
64
+ const { _volumeId: volumeId } = this;
65
+ const viewportsContainingVolumeUID = utilities.getViewportsWithVolumeId(
66
+ volumeId,
67
+ viewport.renderingEngineId
68
+ );
69
+
70
+ viewport.setProperties({ voiRange }, volumeId);
71
+ viewportsContainingVolumeUID.forEach((vp) => vp.render());
72
+ }
73
+ }
74
+
75
+ private static _getImageRange(element, volumeId?) {
76
+ const enabledElement = getEnabledElement(element);
77
+ const { viewport } = enabledElement;
78
+
79
+ const actor = volumeId
80
+ ? viewport.getActor(volumeId)
81
+ : viewport.getDefaultActor();
82
+
83
+ if (!actor) {
84
+ return defaultImageRange;
85
+ }
86
+
87
+ const imageData = actor.actor.getMapper().getInputData();
88
+ const imageRange = imageData.getPointData().getScalars().getRange();
89
+
90
+ return imageRange[0] === 0 && imageRange[1] === 0
91
+ ? defaultImageRange
92
+ : { lower: imageRange[0], upper: imageRange[1] };
93
+ }
94
+
95
+ private static _getVOIRange(element, volumeId) {
96
+ const enabledElement = getEnabledElement(element);
97
+ const { viewport } = enabledElement;
98
+
99
+ const volumeActor = volumeId
100
+ ? viewport.getActor(volumeId)
101
+ : viewport.getDefaultActor();
102
+
103
+ if (!volumeActor || !utilities.isImageActor(volumeActor)) {
104
+ return defaultImageRange;
105
+ }
106
+
107
+ const voiRange = (volumeActor.actor as Types.ImageActor)
108
+ .getProperty()
109
+ .getRGBTransferFunction(0)
110
+ .getRange();
111
+
112
+ return voiRange[0] === 0 && voiRange[1] === 0
113
+ ? defaultImageRange
114
+ : { lower: voiRange[0], upper: voiRange[1] };
115
+ }
116
+
117
+ private autoHideTicks = () => {
118
+ // Avoiding calling setTimeout multiple times when manipulating the VOI
119
+ // via WindowLevel tool for better performance
120
+ if (this._hideTicksTimeoutId) {
121
+ return;
122
+ }
123
+
124
+ const timeLeft = this._hideTicksTime - Date.now();
125
+
126
+ if (timeLeft <= 0) {
127
+ this.hideTicks();
128
+ } else {
129
+ this._hideTicksTimeoutId = window.setTimeout(() => {
130
+ // Recursive call until there is no more time left
131
+ this._hideTicksTimeoutId = 0;
132
+ this.autoHideTicks();
133
+ }, timeLeft);
134
+ }
135
+ };
136
+
137
+ private showAndAutoHideTicks(interval = 1000) {
138
+ this._hideTicksTime = Date.now() + interval;
139
+ this.showTicks();
140
+ this.autoHideTicks();
141
+ }
142
+
143
+ private _stackNewImageCallback = () => {
144
+ this.imageRange = ViewportColorbar._getImageRange(this._element);
145
+ };
146
+
147
+ private _imageVolumeModifiedCallback = (
148
+ evt: Types.EventTypes.ImageVolumeModifiedEvent
149
+ ) => {
150
+ const { volumeId } = evt.detail.imageVolume;
151
+
152
+ if (volumeId !== this._volumeId) {
153
+ return;
154
+ }
155
+
156
+ const { _element: element } = this;
157
+ this.imageRange = ViewportColorbar._getImageRange(element, volumeId);
158
+ };
159
+
160
+ private _viewportVOIModifiedCallback = (
161
+ evt: Types.EventTypes.VoiModifiedEvent
162
+ ) => {
163
+ const { viewportId, volumeId, range: voiRange } = evt.detail;
164
+ const { viewport } = this.enabledElement;
165
+
166
+ if (viewportId !== viewport.id || volumeId !== this._volumeId) {
167
+ return;
168
+ }
169
+
170
+ this.voiRange = voiRange;
171
+ this.showAndAutoHideTicks();
172
+ };
173
+
174
+ private _addCornerstoneEventListener() {
175
+ const { _element: element } = this;
176
+
177
+ eventTarget.addEventListener(
178
+ Events.IMAGE_VOLUME_MODIFIED,
179
+ this._imageVolumeModifiedCallback
180
+ );
181
+
182
+ element.addEventListener(
183
+ Events.STACK_NEW_IMAGE,
184
+ this._stackNewImageCallback
185
+ );
186
+
187
+ element.addEventListener(
188
+ Events.VOI_MODIFIED,
189
+ this._viewportVOIModifiedCallback as EventListener
190
+ );
191
+ }
192
+ }
193
+
194
+ export { ViewportColorbar as default, ViewportColorbar };
@@ -0,0 +1,10 @@
1
+ import type { ColorbarImageRange } from '../types/ColorbarImageRange';
2
+
3
+ const areColorbarRangesEqual = (
4
+ a: ColorbarImageRange,
5
+ b: ColorbarImageRange
6
+ ) => {
7
+ return !!a && !!b && a.lower === b.lower && a.upper === b.upper;
8
+ };
9
+
10
+ export { areColorbarRangesEqual as default, areColorbarRangesEqual };
@@ -0,0 +1,7 @@
1
+ import type { ColorbarSize } from '../types/ColorbarSize';
2
+
3
+ const areColorbarSizesEqual = (a: ColorbarSize, b: ColorbarSize) => {
4
+ return !!a && !!b && a.width === b.width && a.height === b.height;
5
+ };
6
+
7
+ export { areColorbarSizesEqual as default, areColorbarSizesEqual };
@@ -0,0 +1,4 @@
1
+ export { isRangeValid } from './isRangeValid';
2
+ export { isColorbarSizeValid } from './isColorbarSizeValid';
3
+ export { areColorbarRangesEqual } from './areColorbarRangesEqual';
4
+ export { areColorbarSizesEqual } from './areColorbarSizesEqual';