larvitar 0.18.2 → 1.2.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 (229) hide show
  1. package/.github/workflows/deploy.yml +3 -12
  2. package/MIGRATION.md +25 -0
  3. package/README.md +28 -27
  4. package/docs/documentation/Mixins.polygonSegmentationMixin%20-%20segmentation%20operations%20for%20polyline.html +171 -0
  5. package/docs/documentation/Tools.Annotation.ContoursTool.html +218 -0
  6. package/docs/documentation/Tools.Annotation.DiameterTool.html +219 -0
  7. package/docs/documentation/Tools.Annotation.SeedsTool.html +214 -0
  8. package/docs/documentation/Tools.Brush.BrushTool.html +218 -0
  9. package/docs/documentation/Tools.Brush.ThresholdsBrushTool.html +218 -0
  10. package/docs/documentation/Tools.PolylineScissorsTool.html +218 -0
  11. package/docs/documentation/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  12. package/docs/documentation/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  13. package/docs/documentation/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  14. package/docs/documentation/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  15. package/docs/documentation/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  16. package/docs/documentation/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  17. package/docs/documentation/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  18. package/docs/documentation/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  19. package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  20. package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
  21. package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  22. package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  23. package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  24. package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  25. package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
  26. package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  27. package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  28. package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  29. package/docs/documentation/global.html +1303 -0
  30. package/docs/documentation/imageAnonymization.js.html +245 -0
  31. package/docs/documentation/imageColormaps.js.html +283 -0
  32. package/docs/documentation/imageContours.js.html +278 -0
  33. package/docs/documentation/imageIo.js.html +291 -0
  34. package/docs/documentation/imageLayers.js.html +188 -0
  35. package/docs/documentation/imageLoading.js.html +297 -0
  36. package/docs/documentation/imageParsing.js.html +385 -0
  37. package/docs/documentation/imagePresets.js.html +207 -0
  38. package/docs/documentation/imageRendering.js.html +849 -0
  39. package/docs/documentation/imageReslice.js.html +162 -0
  40. package/docs/documentation/imageStore.js.html +360 -0
  41. package/docs/documentation/imageTools.js.html +784 -0
  42. package/docs/documentation/imageUtils.js.html +1609 -0
  43. package/docs/documentation/image_colormaps.js.html +283 -0
  44. package/docs/documentation/image_contours.js.html +279 -0
  45. package/docs/documentation/image_io.js.html +288 -0
  46. package/docs/documentation/image_layers.js.html +188 -0
  47. package/docs/documentation/image_loading.js.html +294 -0
  48. package/docs/documentation/image_parsing.js.html +391 -0
  49. package/docs/documentation/image_presets.js.html +207 -0
  50. package/docs/documentation/image_rendering.js.html +845 -0
  51. package/docs/documentation/image_reslice.js.html +164 -0
  52. package/docs/documentation/image_store.js.html +359 -0
  53. package/docs/documentation/image_tools.js.html +792 -0
  54. package/docs/documentation/image_utils.js.html +1609 -0
  55. package/docs/documentation/index.html +175 -0
  56. package/docs/documentation/loaders_commonLoader.js.html +306 -0
  57. package/docs/documentation/loaders_dicomLoader.js.html +130 -0
  58. package/docs/documentation/loaders_fileLoader.js.html +155 -0
  59. package/docs/documentation/loaders_multiframeLoader.js.html +443 -0
  60. package/docs/documentation/loaders_niftiLoader.js.html +150 -0
  61. package/docs/documentation/loaders_nrrdLoader.js.html +545 -0
  62. package/docs/documentation/loaders_resliceLoader.js.html +258 -0
  63. package/docs/documentation/module-imaging_contours.html +954 -0
  64. package/docs/documentation/module-imaging_imageAnonymization.html +544 -0
  65. package/docs/documentation/module-imaging_imageColormaps.html +1012 -0
  66. package/docs/documentation/module-imaging_imageContours.html +954 -0
  67. package/docs/documentation/module-imaging_imageIo.html +1057 -0
  68. package/docs/documentation/module-imaging_imageLayers.html +904 -0
  69. package/docs/documentation/module-imaging_imageLoading.html +1301 -0
  70. package/docs/documentation/module-imaging_imageParsing.html +1356 -0
  71. package/docs/documentation/module-imaging_imagePresets.html +679 -0
  72. package/docs/documentation/module-imaging_imageRendering.html +3223 -0
  73. package/docs/documentation/module-imaging_imageReslice.html +413 -0
  74. package/docs/documentation/module-imaging_imageStore-Larvitar_Store.html +284 -0
  75. package/docs/documentation/module-imaging_imageStore.html +1560 -0
  76. package/docs/documentation/module-imaging_imageTools.html +3617 -0
  77. package/docs/documentation/module-imaging_imageUtils.html +7253 -0
  78. package/docs/documentation/module-imaging_io.html +1057 -0
  79. package/docs/documentation/module-imaging_layers.html +904 -0
  80. package/docs/documentation/module-imaging_loading.html +1301 -0
  81. package/docs/documentation/module-imaging_parsing.html +1375 -0
  82. package/docs/documentation/module-imaging_presets.html +679 -0
  83. package/docs/documentation/module-imaging_rendering.html +8094 -0
  84. package/docs/documentation/module-imaging_reslice.html +411 -0
  85. package/docs/documentation/module-imaging_store-Larvitar_Store.html +284 -0
  86. package/docs/documentation/module-imaging_store.html +1537 -0
  87. package/docs/documentation/module-imaging_strategies_eraseFreehand.html +708 -0
  88. package/docs/documentation/module-imaging_strategies_fillFreehand.html +708 -0
  89. package/docs/documentation/module-imaging_tools.html +3617 -0
  90. package/docs/documentation/module-imaging_tools_custom_contourTool.html +207 -0
  91. package/docs/documentation/module-imaging_tools_custom_diameterTool.html +205 -0
  92. package/docs/documentation/module-imaging_tools_custom_editMaskTool.html +205 -0
  93. package/docs/documentation/module-imaging_tools_custom_polygonScissorsTool.html +203 -0
  94. package/docs/documentation/module-imaging_tools_custom_thresholdBrushTool.html +684 -0
  95. package/docs/documentation/module-imaging_tools_default.html +205 -0
  96. package/docs/documentation/module-imaging_tools_interaction.html +530 -0
  97. package/docs/documentation/module-imaging_tools_io.html +832 -0
  98. package/docs/documentation/module-imaging_tools_main.html +2028 -0
  99. package/docs/documentation/module-imaging_tools_polygonSegmentationMixin.html +567 -0
  100. package/docs/documentation/module-imaging_tools_segmentation.html +3586 -0
  101. package/docs/documentation/module-imaging_tools_state.html +494 -0
  102. package/docs/documentation/module-imaging_utils.html +7253 -0
  103. package/docs/documentation/module-loaders_commonLoader.html +1313 -0
  104. package/docs/documentation/module-loaders_dicomLoader.html +522 -0
  105. package/docs/documentation/module-loaders_fileLoader.html +593 -0
  106. package/docs/documentation/module-loaders_multiframeLoader.html +1169 -0
  107. package/docs/documentation/module-loaders_niftiLoader.html +565 -0
  108. package/docs/documentation/module-loaders_nrrdLoader.html +1459 -0
  109. package/docs/documentation/module-loaders_resliceLoader.html +590 -0
  110. package/docs/documentation/module-monitors_memory.html +980 -0
  111. package/docs/documentation/module-tools_default.html +740 -0
  112. package/docs/documentation/module.exports_module.exports.html +203 -0
  113. package/docs/documentation/monitors_memory.js.html +189 -0
  114. package/docs/documentation/parsers_nrrd.js.html +569 -0
  115. package/docs/documentation/scripts/collapse.js +20 -0
  116. package/docs/documentation/scripts/linenumber.js +25 -0
  117. package/docs/documentation/scripts/nav.js +12 -0
  118. package/docs/documentation/scripts/polyfill.js +4 -0
  119. package/docs/documentation/scripts/prettify/Apache-License-2.0.txt +202 -0
  120. package/docs/documentation/scripts/prettify/lang-css.js +2 -0
  121. package/docs/documentation/scripts/prettify/prettify.js +28 -0
  122. package/docs/documentation/scripts/search.js +83 -0
  123. package/docs/documentation/styles/jsdoc.css +765 -0
  124. package/docs/documentation/styles/prettify.css +80 -0
  125. package/docs/documentation/tools_contourTool.js.html +1963 -0
  126. package/docs/documentation/tools_custom_contourTool.js.html +1968 -0
  127. package/docs/documentation/tools_custom_diameterTool.js.html +225 -0
  128. package/docs/documentation/tools_custom_editMaskTool.js.html +225 -0
  129. package/docs/documentation/tools_custom_polylineScissorsTool.js.html +143 -0
  130. package/docs/documentation/tools_custom_thresholdsBrushTool.js.html +245 -0
  131. package/docs/documentation/tools_default.js.html +576 -0
  132. package/docs/documentation/tools_diameterTool.js.html +219 -0
  133. package/docs/documentation/tools_editMaskTool.js.html +219 -0
  134. package/docs/documentation/tools_interaction.js.html +258 -0
  135. package/docs/documentation/tools_io.js.html +297 -0
  136. package/docs/documentation/tools_main.js.html +443 -0
  137. package/docs/documentation/tools_polygonSegmentationMixin.js.html +329 -0
  138. package/docs/documentation/tools_polylineScissorsTool.js.html +136 -0
  139. package/docs/documentation/tools_seedTool.js.html +423 -0
  140. package/docs/documentation/tools_segmentation.js.html +558 -0
  141. package/docs/documentation/tools_state.js.html +163 -0
  142. package/docs/documentation/tools_strategies_eraseFreehand.js.html +160 -0
  143. package/docs/documentation/tools_strategies_fillFreehand.js.html +163 -0
  144. package/docs/documentation/tools_thresholdsBrushTool.js.html +239 -0
  145. package/docs/documentation/tools_tools.default.js.html +569 -0
  146. package/docs/documentation/tools_tools.interaction.js.html +251 -0
  147. package/docs/documentation/tools_tools.io.js.html +288 -0
  148. package/docs/documentation/tools_tools.main.js.html +442 -0
  149. package/docs/documentation/tools_tools.segmentation.js.html +445 -0
  150. package/docs/documentation/tools_tools.state.js.html +157 -0
  151. package/docs/examples/base.html +170 -0
  152. package/docs/examples/colorMaps.html +181 -0
  153. package/docs/examples/defaultTools.html +246 -0
  154. package/docs/examples/demo/anon1 +0 -0
  155. package/docs/examples/demo/anon10 +0 -0
  156. package/docs/examples/demo/anon11 +0 -0
  157. package/docs/examples/demo/anon12 +0 -0
  158. package/docs/examples/demo/anon13 +0 -0
  159. package/docs/examples/demo/anon14 +0 -0
  160. package/docs/examples/demo/anon15 +0 -0
  161. package/docs/examples/demo/anon16 +0 -0
  162. package/docs/examples/demo/anon17 +0 -0
  163. package/docs/examples/demo/anon18 +0 -0
  164. package/docs/examples/demo/anon19 +0 -0
  165. package/docs/examples/demo/anon2 +0 -0
  166. package/docs/examples/demo/anon20 +0 -0
  167. package/docs/examples/demo/anon21 +0 -0
  168. package/docs/examples/demo/anon22 +0 -0
  169. package/docs/examples/demo/anon23 +0 -0
  170. package/docs/examples/demo/anon24 +0 -0
  171. package/docs/examples/demo/anon3 +0 -0
  172. package/docs/examples/demo/anon4 +0 -0
  173. package/docs/examples/demo/anon5 +0 -0
  174. package/docs/examples/demo/anon6 +0 -0
  175. package/docs/examples/demo/anon7 +0 -0
  176. package/docs/examples/demo/anon8 +0 -0
  177. package/docs/examples/demo/anon9 +0 -0
  178. package/docs/examples/demo/example.nrrd +0 -0
  179. package/docs/examples/demo/segmentation.nrrd +0 -0
  180. package/docs/examples/demo/xa_integris.dcm +0 -0
  181. package/docs/examples/index.html +129 -0
  182. package/docs/examples/larvitar.js +108623 -0
  183. package/docs/examples/layers.html +250 -0
  184. package/docs/examples/masks.html +273 -0
  185. package/docs/examples/multiframe.html +200 -0
  186. package/docs/examples/nrrd.html +96 -0
  187. package/docs/examples/reslice.html +174 -0
  188. package/docs/index.html +92 -0
  189. package/imaging/dataDictionary.json +21865 -21865
  190. package/imaging/imageAnonymization.js +161 -0
  191. package/imaging/{image_colormaps.js → imageColormaps.js} +2 -2
  192. package/imaging/{image_contours.js → imageContours.js} +1 -2
  193. package/imaging/{image_io.js → imageIo.js} +18 -15
  194. package/imaging/{image_layers.js → imageLayers.js} +2 -2
  195. package/imaging/{image_loading.js → imageLoading.js} +9 -6
  196. package/imaging/imageParsing.js +301 -0
  197. package/imaging/{image_presets.js → imagePresets.js} +2 -2
  198. package/imaging/{image_rendering.js → imageRendering.js} +36 -32
  199. package/imaging/imageReslice.js +78 -0
  200. package/imaging/{image_store.js → imageStore.js} +8 -7
  201. package/imaging/{image_tools.js → imageTools.js} +15 -23
  202. package/imaging/{image_utils.js → imageUtils.js} +1 -1
  203. package/imaging/loaders/commonLoader.js +1 -1
  204. package/imaging/loaders/dicomLoader.js +1 -1
  205. package/imaging/loaders/fileLoader.js +2 -2
  206. package/imaging/loaders/multiframeLoader.js +6 -2
  207. package/imaging/loaders/nrrdLoader.js +11 -7
  208. package/imaging/tools/{contourTool.js → custom/contourTool.js} +25 -20
  209. package/imaging/tools/{diameterTool.js → custom/diameterTool.js} +9 -3
  210. package/imaging/tools/{editMaskTool.js → custom/editMaskTool.js} +7 -1
  211. package/imaging/tools/{polylineScissorsTool.js → custom/polylineScissorsTool.js} +12 -5
  212. package/imaging/tools/{seedTool.js → custom/seedTool.js} +3 -3
  213. package/imaging/tools/{thresholdsBrushTool.js → custom/thresholdsBrushTool.js} +7 -1
  214. package/imaging/tools/{tools.default.js → default.js} +10 -3
  215. package/imaging/tools/{tools.interaction.js → interaction.js} +13 -6
  216. package/imaging/tools/{tools.io.js → io.js} +15 -6
  217. package/imaging/tools/{tools.main.js → main.js} +16 -14
  218. package/imaging/tools/polygonSegmentationMixin.js +8 -4
  219. package/imaging/tools/{tools.segmentation.js → segmentation.js} +171 -58
  220. package/imaging/tools/segmentations.md +38 -0
  221. package/imaging/tools/setLabelMap3D.js +248 -0
  222. package/imaging/tools/{tools.state.js → state.js} +7 -1
  223. package/imaging/tools/strategies/eraseFreehand.js +8 -9
  224. package/imaging/tools/strategies/fillFreehand.js +8 -9
  225. package/index.js +44 -39
  226. package/modules/vuex/larvitar.js +13 -3
  227. package/package.json +13 -10
  228. package/imaging/image_parsing.js +0 -307
  229. package/imaging/image_reslice.js +0 -80
@@ -0,0 +1,1968 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+
5
+ <meta charset="utf-8">
6
+ <title>tools/custom/contourTool.js - Larvitar</title>
7
+
8
+ <meta name="description" content="Dicom Image Toolkit for CornestoneJS" />
9
+
10
+ <meta name="keywords" content="imaging, dataviz, medical, cornerstone" />
11
+ <meta name="keyword" content="imaging, dataviz, medical, cornerstone" />
12
+
13
+
14
+
15
+ <script src="scripts/prettify/prettify.js"></script>
16
+ <script src="scripts/prettify/lang-css.js"></script>
17
+ <!--[if lt IE 9]>
18
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
19
+ <![endif]-->
20
+ <link type="text/css" rel="stylesheet" href="styles/prettify.css">
21
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
22
+ <script src="scripts/nav.js" defer></script>
23
+
24
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
25
+ </head>
26
+ <body>
27
+
28
+ <input type="checkbox" id="nav-trigger" class="nav-trigger" />
29
+ <label for="nav-trigger" class="navicon-button x">
30
+ <div class="navicon"></div>
31
+ </label>
32
+
33
+ <label for="nav-trigger" class="overlay"></label>
34
+
35
+ <nav >
36
+
37
+ <input type="text" id="nav-search" placeholder="Search" />
38
+
39
+
40
+ <h2><a href="index.html">Home</a></h2><h2><a href="https://github.com/dvisionlab/Larvitar" target="_blank" class="menu-item" id="repository" >Github repo</a></h2><h3>Classes</h3><ul><li><a href="module-imaging_imageStore-Larvitar_Store.html">imaging/imageStore~Larvitar_Store</a></li><li><a href="module-imaging_tools_custom_polygonScissorsTool.html">imaging/tools/custom/polygonScissorsTool</a></li><li><a href="Tools.Annotation.ContoursTool.html">Tools.Annotation.ContoursTool</a></li><li><a href="Tools.Annotation.DiameterTool.html">Tools.Annotation.DiameterTool</a></li><li><a href="Tools.Brush.BrushTool.html">Tools.Brush.BrushTool</a></li><li><a href="Tools.Brush.ThresholdsBrushTool.html">Tools.Brush.ThresholdsBrushTool</a></li><li><a href="Tools.PolylineScissorsTool.html">Tools.PolylineScissorsTool</a></li></ul><h3>Modules</h3><ul><li><a href="module-imaging_imageAnonymization.html">imaging/imageAnonymization</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageAnonymization.html#anonymize#~anonymize">anonymize</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageAnonymization.html#encrypt#~encrypt">encrypt</a></li></ul></li><li><a href="module-imaging_imageColormaps.html">imaging/imageColormaps</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageColormaps.html#HSVToRGB#.HSVToRGB">HSVToRGB</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageColormaps.html#addColorMap#addColorMap">addColorMap</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageColormaps.html#applyColorMap#applyColorMap">applyColorMap</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageColormaps.html#fillPixelData#fillPixelData">fillPixelData</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageColormaps.html#getColormapsList#getColormapsList">getColormapsList</a></li></ul></li><li><a href="module-imaging_imageContours.html">imaging/imageContours</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageContours.html#extractSlicePoints#extractSlicePoints">extractSlicePoints</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageContours.html#populateContoursObject#populateContoursObject">populateContoursObject</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageContours.html#parseContours#~parseContours">parseContours</a></li></ul></li><li><a href="module-imaging_imageIo.html">imaging/imageIo</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageIo.html#buildData#~buildData">buildData</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageIo.html#buildDataAsync#~buildDataAsync">buildDataAsync</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageIo.html#buildHeader#~buildHeader">buildHeader</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageIo.html#getCachedPixelData#~getCachedPixelData">getCachedPixelData</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageIo.html#importNRRDImage#~importNRRDImage">importNRRDImage</a></li></ul></li><li><a href="module-imaging_imageLayers.html">imaging/imageLayers</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageLayers.html#getActiveLayer#getActiveLayer">getActiveLayer</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageLayers.html#setActiveLayer#setActiveLayer">setActiveLayer</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageLayers.html#updateLayer#updateLayer">updateLayer</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageLayers.html#buildLayers#~buildLayers">buildLayers</a></li></ul></li><li><a href="module-imaging_imageLoading.html">imaging/imageLoading</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageLoading.html#initializeFileImageLoader#initializeFileImageLoader">initializeFileImageLoader</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageLoading.html#initializeImageLoader#initializeImageLoader">initializeImageLoader</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageLoading.html#initializeWebImageLoader#initializeWebImageLoader">initializeWebImageLoader</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageLoading.html#registerMultiFrameImageLoader#registerMultiFrameImageLoader">registerMultiFrameImageLoader</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageLoading.html#registerNRRDImageLoader#registerNRRDImageLoader">registerNRRDImageLoader</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageLoading.html#registerResliceLoader#registerResliceLoader">registerResliceLoader</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageLoading.html#updateLoadedStack#updateLoadedStack">updateLoadedStack</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageLoading.html#isNewInstance#~isNewInstance">isNewInstance</a></li></ul></li><li><a href="module-imaging_imageParsing.html">imaging/imageParsing</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageParsing.html#clearImageParsing#clearImageParsing">clearImageParsing</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageParsing.html#parseDataSet#parseDataSet">parseDataSet</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageParsing.html#readFile#readFile">readFile</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageParsing.html#readFiles#readFiles">readFiles</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageParsing.html#parseFile#~parseFile">parseFile</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageParsing.html#parseFiles#~parseFiles">parseFiles</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageParsing.html#parseNextFile#~parseNextFile">parseNextFile</a></li></ul></li><li><a href="module-imaging_imagePresets.html">imaging/imagePresets</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imagePresets.html#getImagePresets#getImagePresets">getImagePresets</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imagePresets.html#setImageCustomPreset#setImageCustomPreset">setImageCustomPreset</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imagePresets.html#setImagePreset#setImagePreset">setImagePreset</a></li></ul></li><li><a href="module-imaging_imageRendering.html">imaging/imageRendering</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#clearImageCache#clearImageCache">clearImageCache</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#disableViewport#disableViewport">disableViewport</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#flipImageHorizontal#flipImageHorizontal">flipImageHorizontal</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#flipImageVertical#flipImageVertical">flipImageVertical</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#getSeriesData#getSeriesData">getSeriesData</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#invertImage#invertImage">invertImage</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#loadAndCacheImages#loadAndCacheImages">loadAndCacheImages</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#renderImage#renderImage">renderImage</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#renderWebImage#renderWebImage">renderWebImage</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#renderWebImage#renderWebImage">renderWebImage</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#resetViewports#resetViewports">resetViewports</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#resizeViewport#resizeViewport">resizeViewport</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#rotateImageLeft#rotateImageLeft">rotateImageLeft</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#rotateImageRight#rotateImageRight">rotateImageRight</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#storeViewportData#storeViewportData">storeViewportData</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#unloadViewport#unloadViewport">unloadViewport</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#updateImage#updateImage">updateImage</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageRendering.html#updateViewportData#updateViewportData">updateViewportData</a></li></ul></li><li><a href="module-imaging_imageReslice.html">imaging/imageReslice</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageReslice.html#resliceSeries#resliceSeries">resliceSeries</a></li></ul></li><li><a href="module-imaging_imageStore.html">imaging/imageStore</a><ul class='members'><li data-type='member' style='display: none;'><a href="module-imaging_imageStore.html#.larvitar_store">larvitar_store</a></li></ul><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageStore.html#initLarvitarStore#.initLarvitarStore">initLarvitarStore</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageStore.html#addSeriesIds#~addSeriesIds">addSeriesIds</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageStore.html#addViewport#~addViewport">addViewport</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageStore.html#deleteViewport#~deleteViewport">deleteViewport</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageStore.html#disableVuex#~disableVuex">disableVuex</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageStore.html#enableVuex#~enableVuex">enableVuex</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageStore.html#get#~get">get</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageStore.html#removeSeriesIds#~removeSeriesIds">removeSeriesIds</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageStore.html#set#~set">set</a></li></ul></li><li><a href="module-imaging_imageTools.html">imaging/imageTools</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#addContoursTool#~addContoursTool">addContoursTool</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#addDefaultTools#~addDefaultTools">addDefaultTools</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#addDiameterTool#~addDiameterTool">addDiameterTool</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#addMaskEditingTool#~addMaskEditingTool">addMaskEditingTool</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#addSeedsTool#~addSeedsTool">addSeedsTool</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#addStackStateToElement#~addStackStateToElement">addStackStateToElement</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#addToolStateSingleSlice#~addToolStateSingleSlice">addToolStateSingleSlice</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#clearCornerstoneElements#~clearCornerstoneElements">clearCornerstoneElements</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#clearMeasurements#~clearMeasurements">clearMeasurements</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#clearToolStateByName#~clearToolStateByName">clearToolStateByName</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#getCurrentMaskData#~getCurrentMaskData">getCurrentMaskData</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#getToolState#~getToolState">getToolState</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#isToolMissing#~isToolMissing">isToolMissing</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#setSegmentationConfig#~setSegmentationConfig">setSegmentationConfig</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#setToolActive#~setToolActive">setToolActive</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#setToolActive#~setToolActive">setToolActive</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#setToolEnabled#~setToolEnabled">setToolEnabled</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#setToolPassive#~setToolPassive">setToolPassive</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#syncToolStack#~syncToolStack">syncToolStack</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#updateDiameterTool#~updateDiameterTool">updateDiameterTool</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageTools.html#updateStackToolState#~updateStackToolState">updateStackToolState</a></li></ul></li><li><a href="module-imaging_imageUtils.html">imaging/imageUtils</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#formatDate#formatDate">formatDate</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#formatDateTime#formatDateTime">formatDateTime</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getCmprMetadata#getCmprMetadata">getCmprMetadata</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getDICOMTag#getDICOMTag">getDICOMTag</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getDICOMTagCode#getDICOMTagCode">getDICOMTagCode</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getDistanceBetweenSlices#getDistanceBetweenSlices">getDistanceBetweenSlices</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getMaxPixelValue#getMaxPixelValue">getMaxPixelValue</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getMeanValue#getMeanValue">getMeanValue</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getMinPixelValue#getMinPixelValue">getMinPixelValue</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getNormalOrientation#getNormalOrientation">getNormalOrientation</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getPixelRepresentation#getPixelRepresentation">getPixelRepresentation</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getPixelTypedArray#getPixelTypedArray">getPixelTypedArray</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getReslicedIOP#getReslicedIOP">getReslicedIOP</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getReslicedIPP#getReslicedIPP">getReslicedIPP</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getReslicedMetadata#getReslicedMetadata">getReslicedMetadata</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getReslicedPixeldata#getReslicedPixeldata">getReslicedPixeldata</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getReslicedSliceLocation#getReslicedSliceLocation">getReslicedSliceLocation</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getSortedStack#getSortedStack">getSortedStack</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getSortedUIDs#getSortedUIDs">getSortedUIDs</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getTagValue#getTagValue">getTagValue</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getTypedArray#getTypedArray">getTypedArray</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#getTypedArrayFromDataType#getTypedArrayFromDataType">getTypedArrayFromDataType</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#isElement#isElement">isElement</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#isNegativeSign#isNegativeSign">isNegativeSign</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#isStringVr#isStringVr">isStringVr</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#isValidDate#isValidDate">isValidDate</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#parseAgeTag#parseAgeTag">parseAgeTag</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#parseDateTag#parseDateTag">parseDateTag</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#parseDateTimeTag#parseDateTimeTag">parseDateTimeTag</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#parseDICOMFileIDTag#parseDICOMFileIDTag">parseDICOMFileIDTag</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#parsePatientNameTag#parsePatientNameTag">parsePatientNameTag</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#parseTag#parseTag">parseTag</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#parseTimeTag#parseTimeTag">parseTimeTag</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#permuteSignedArrays#permuteSignedArrays">permuteSignedArrays</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#permuteValues#permuteValues">permuteValues</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#rand#rand">rand</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#randomId#randomId">randomId</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#sortStackCallback#sortStackCallback">sortStackCallback</a></li><li data-type='method' style='display: none;'><a href="module-imaging_imageUtils.html#spacingArray#spacingArray">spacingArray</a></li></ul></li><li><a href="module-imaging_strategies_eraseFreehand.html">imaging/strategies/eraseFreehand</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_strategies_eraseFreehand.html#eraseInsideFreehand#.eraseInsideFreehand">eraseInsideFreehand</a></li><li data-type='method' style='display: none;'><a href="module-imaging_strategies_eraseFreehand.html#eraseOutsideFreehand#.eraseOutsideFreehand">eraseOutsideFreehand</a></li><li data-type='method' style='display: none;'><a href="module-imaging_strategies_eraseFreehand.html#eraseFreehand#~eraseFreehand">eraseFreehand</a></li></ul></li><li><a href="module-imaging_strategies_fillFreehand.html">imaging/strategies/fillFreehand</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_strategies_fillFreehand.html#fillInsideFreehand#.fillInsideFreehand">fillInsideFreehand</a></li><li data-type='method' style='display: none;'><a href="module-imaging_strategies_fillFreehand.html#fillOutsideFreehand#.fillOutsideFreehand">fillOutsideFreehand</a></li><li data-type='method' style='display: none;'><a href="module-imaging_strategies_fillFreehand.html#fillFreehand#~fillFreehand">fillFreehand</a></li></ul></li><li><a href="module-imaging_tools_custom_contourTool.html">imaging/tools/custom/contourTool</a></li><li><a href="module-imaging_tools_custom_diameterTool.html">imaging/tools/custom/diameterTool</a></li><li><a href="module-imaging_tools_custom_editMaskTool.html">imaging/tools/custom/editMaskTool</a></li><li><a href="module-imaging_tools_custom_polygonScissorsTool.html">imaging/tools/custom/polygonScissorsTool</a></li><li><a href="module-imaging_tools_custom_thresholdBrushTool.html">imaging/tools/custom/thresholdBrushTool</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_tools_custom_thresholdBrushTool.html#_paint#_paint">_paint</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_custom_thresholdBrushTool.html#getCircleWithThreshold#~getCircleWithThreshold">getCircleWithThreshold</a></li></ul></li><li><a href="module-imaging_tools_default.html">imaging/tools/default</a></li><li><a href="module-imaging_tools_interaction.html">imaging/tools/interaction</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_tools_interaction.html#addMouseKeyHandlers#.addMouseKeyHandlers">addMouseKeyHandlers</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_interaction.html#toggleMouseHandlers#toggleMouseHandlers">toggleMouseHandlers</a></li></ul></li><li><a href="module-imaging_tools_io.html">imaging/tools/io</a><ul class='members'><li data-type='member' style='display: none;'><a href="module-imaging_tools_io.html#.exportAnnotations">exportAnnotations</a></li><li data-type='member' style='display: none;'><a href="module-imaging_tools_io.html#.loadAnnotations">loadAnnotations</a></li><li data-type='member' style='display: none;'><a href="module-imaging_tools_io.html#.saveAnnotations">saveAnnotations</a></li></ul><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_tools_io.html#generateCSV#.generateCSV">generateCSV</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_io.html#download#~download">download</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_io.html#extractToolInfo#~extractToolInfo">extractToolInfo</a></li></ul></li><li><a href="module-imaging_tools_main.html">imaging/tools/main</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#csToolsUpdateImageIndex#.csToolsUpdateImageIndex">csToolsUpdateImageIndex</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#addDefaultTools#~addDefaultTools">addDefaultTools</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#addTool#~addTool">addTool</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#csToolsCreateStack#~csToolsCreateStack">csToolsCreateStack</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#initializeCSTools#~initializeCSTools">initializeCSTools</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#isToolMissing#~isToolMissing">isToolMissing</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#setToolActive#~setToolActive">setToolActive</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#setToolDisabled#~setToolDisabled">setToolDisabled</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#setToolEnabled#~setToolEnabled">setToolEnabled</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#setToolPassive#~setToolPassive">setToolPassive</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#setToolsStyle#~setToolsStyle">setToolsStyle</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_main.html#tryUpdateImage#~tryUpdateImage">tryUpdateImage</a></li></ul></li><li><a href="module-imaging_tools_polygonSegmentationMixin.html">imaging/tools/polygonSegmentationMixin</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_tools_polygonSegmentationMixin.html#_checkIfDrawing#~_checkIfDrawing">_checkIfDrawing</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_polygonSegmentationMixin.html#renderToolData#~renderToolData">renderToolData</a></li></ul></li><li><a href="module-imaging_tools_segmentation.html">imaging/tools/segmentation</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#addSegmentationMask#.addSegmentationMask">addSegmentationMask</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#clearSegmentationState#.clearSegmentationState">clearSegmentationState</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#deleteMask#.deleteMask">deleteMask</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#disableBrushTool#.disableBrushTool">disableBrushTool</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#enableBrushTool#.enableBrushTool">enableBrushTool</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#forceRender#.forceRender">forceRender</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#getActiveLabelmapBuffer#.getActiveLabelmapBuffer">getActiveLabelmapBuffer</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#getLabelColor#.getLabelColor">getLabelColor</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#initSegmentationModule#.initSegmentationModule">initSegmentationModule</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#loadMaskSlice#.loadMaskSlice">loadMaskSlice</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#redoLastStroke#.redoLastStroke">redoLastStroke</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#setActiveLabelmap#.setActiveLabelmap">setActiveLabelmap</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#setActiveLabelOpacity#.setActiveLabelOpacity">setActiveLabelOpacity</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#setActiveSegment#.setActiveSegment">setActiveSegment</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#setBrushProps#.setBrushProps">setBrushProps</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#setInactiveLabelOpacity#.setInactiveLabelOpacity">setInactiveLabelOpacity</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#setLabelColor#.setLabelColor">setLabelColor</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#setMaskProps#.setMaskProps">setMaskProps</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#toggleContourMode#.toggleContourMode">toggleContourMode</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#toggleVisibility#.toggleVisibility">toggleVisibility</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#undoLastStroke#.undoLastStroke">undoLastStroke</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#generateLUT#~generateLUT">generateLUT</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#generateUniformLUT#~generateUniformLUT">generateUniformLUT</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_segmentation.html#HSVtoRGB#~HSVtoRGB">HSVtoRGB</a></li></ul></li><li><a href="module-imaging_tools_state.html">imaging/tools/state</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-imaging_tools_state.html#restoreToolState#~restoreToolState">restoreToolState</a></li><li data-type='method' style='display: none;'><a href="module-imaging_tools_state.html#saveToolState#~saveToolState">saveToolState</a></li></ul></li><li><a href="module-loaders_commonLoader.html">loaders/commonLoader</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-loaders_commonLoader.html#getImageFrame#getImageFrame">getImageFrame</a></li><li data-type='method' style='display: none;'><a href="module-loaders_commonLoader.html#getLarvitarImageTracker#getLarvitarImageTracker">getLarvitarImageTracker</a></li><li data-type='method' style='display: none;'><a href="module-loaders_commonLoader.html#getLarvitarManager#getLarvitarManager">getLarvitarManager</a></li><li data-type='method' style='display: none;'><a href="module-loaders_commonLoader.html#getSeriesDataFromLarvitarManager#getSeriesDataFromLarvitarManager">getSeriesDataFromLarvitarManager</a></li><li data-type='method' style='display: none;'><a href="module-loaders_commonLoader.html#populateLarvitarManager#populateLarvitarManager">populateLarvitarManager</a></li><li data-type='method' style='display: none;'><a href="module-loaders_commonLoader.html#removeSeriesFromLarvitarManager#removeSeriesFromLarvitarManager">removeSeriesFromLarvitarManager</a></li><li data-type='method' style='display: none;'><a href="module-loaders_commonLoader.html#resetLarvitarManager#resetLarvitarManager">resetLarvitarManager</a></li><li data-type='method' style='display: none;'><a href="module-loaders_commonLoader.html#updateLarvitarManager#updateLarvitarManager">updateLarvitarManager</a></li></ul></li><li><a href="module-loaders_dicomLoader.html">loaders/dicomLoader</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-loaders_dicomLoader.html#cacheImages#cacheImages">cacheImages</a></li><li data-type='method' style='display: none;'><a href="module-loaders_dicomLoader.html#getDicomImageId#getDicomImageId">getDicomImageId</a></li></ul></li><li><a href="module-loaders_fileLoader.html">loaders/fileLoader</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-loaders_fileLoader.html#getFileImageId#getFileImageId">getFileImageId</a></li><li data-type='method' style='display: none;'><a href="module-loaders_fileLoader.html#populateFileManager#populateFileManager">populateFileManager</a></li><li data-type='method' style='display: none;'><a href="module-loaders_fileLoader.html#resetFileLoader#resetFileLoader">resetFileLoader</a></li><li data-type='method' style='display: none;'><a href="module-loaders_fileLoader.html#resetFileManager#resetFileManager">resetFileManager</a></li></ul></li><li><a href="module-loaders_multiframeLoader.html">loaders/multiframeLoader</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-loaders_multiframeLoader.html#clearMultiFrameCache#clearMultiFrameCache">clearMultiFrameCache</a></li><li data-type='method' style='display: none;'><a href="module-loaders_multiframeLoader.html#createCustomImage#createCustomImage">createCustomImage</a></li><li data-type='method' style='display: none;'><a href="module-loaders_multiframeLoader.html#getMultiFrameImageId#getMultiFrameImageId">getMultiFrameImageId</a></li><li data-type='method' style='display: none;'><a href="module-loaders_multiframeLoader.html#setPixelDataType#setPixelDataType">setPixelDataType</a></li><li data-type='method' style='display: none;'><a href="module-loaders_multiframeLoader.html#buildMultiFrameImage#~buildMultiFrameImage">buildMultiFrameImage</a></li><li data-type='method' style='display: none;'><a href="module-loaders_multiframeLoader.html#loadMultiFrameImage#~loadMultiFrameImage">loadMultiFrameImage</a></li></ul></li><li><a href="module-loaders_nrrdLoader.html">loaders/nrrdLoader</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-loaders_nrrdLoader.html#buildNrrdImage#buildNrrdImage">buildNrrdImage</a></li><li data-type='method' style='display: none;'><a href="module-loaders_nrrdLoader.html#createCustomImage#createCustomImage">createCustomImage</a></li><li data-type='method' style='display: none;'><a href="module-loaders_nrrdLoader.html#getImageIdFromSlice#getImageIdFromSlice">getImageIdFromSlice</a></li><li data-type='method' style='display: none;'><a href="module-loaders_nrrdLoader.html#getNrrdImageId#getNrrdImageId">getNrrdImageId</a></li><li data-type='method' style='display: none;'><a href="module-loaders_nrrdLoader.html#getNrrdSerieDimensions#getNrrdSerieDimensions">getNrrdSerieDimensions</a></li><li data-type='method' style='display: none;'><a href="module-loaders_nrrdLoader.html#getSliceNumberFromImageId#getSliceNumberFromImageId">getSliceNumberFromImageId</a></li><li data-type='method' style='display: none;'><a href="module-loaders_nrrdLoader.html#loadNrrdImage#loadNrrdImage">loadNrrdImage</a></li></ul></li><li><a href="module-loaders_resliceLoader.html">loaders/resliceLoader</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-loaders_resliceLoader.html#createCustomImage#createCustomImage">createCustomImage</a></li><li data-type='method' style='display: none;'><a href="module-loaders_resliceLoader.html#loadReslicedImage#loadReslicedImage">loadReslicedImage</a></li></ul></li><li><a href="module-monitors_memory.html">monitors/memory</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-monitors_memory.html#checkMemoryAllocation#checkMemoryAllocation">checkMemoryAllocation</a></li><li data-type='method' style='display: none;'><a href="module-monitors_memory.html#checkMemorySupport#checkMemorySupport">checkMemorySupport</a></li><li data-type='method' style='display: none;'><a href="module-monitors_memory.html#getAvailableMemory#getAvailableMemory">getAvailableMemory</a></li><li data-type='method' style='display: none;'><a href="module-monitors_memory.html#getMB#getMB">getMB</a></li><li data-type='method' style='display: none;'><a href="module-monitors_memory.html#getUsedMemory#getUsedMemory">getUsedMemory</a></li><li data-type='method' style='display: none;'><a href="module-monitors_memory.html#setAvailableMemory#setAvailableMemory">setAvailableMemory</a></li></ul></li><li><a href="module-tools_default.html">tools/default</a><ul class='methods'><li data-type='method' style='display: none;'><a href="module-tools_default.html#getDefaultToolsByType#~getDefaultToolsByType">getDefaultToolsByType</a></li><li data-type='method' style='display: none;'><a href="module-tools_default.html#setDefaultToolsProps#~setDefaultToolsProps">setDefaultToolsProps</a></li></ul></li></ul><h3>Events</h3><ul><li><a href="module-imaging_tools_custom_contourTool.ContoursTool.html#event:_drawingDoubleTapClickCallback">imaging/tools/custom/contourTool.ContoursTool#_drawingDoubleTapClickCallback</a></li><li><a href="module-imaging_tools_custom_contourTool.ContoursTool.html#event:_drawingMouseDoubleClickCallback">imaging/tools/custom/contourTool.ContoursTool#_drawingMouseDoubleClickCallback</a></li><li><a href="module-imaging_tools_custom_contourTool.ContoursTool.html#event:_drawingMouseDownCallback">imaging/tools/custom/contourTool.ContoursTool#_drawingMouseDownCallback</a></li><li><a href="module-imaging_tools_custom_contourTool.ContoursTool.html#event:_drawingMouseDragCallback">imaging/tools/custom/contourTool.ContoursTool#_drawingMouseDragCallback</a></li><li><a href="module-imaging_tools_custom_contourTool.ContoursTool.html#event:_drawingMouseMoveCallback">imaging/tools/custom/contourTool.ContoursTool#_drawingMouseMoveCallback</a></li><li><a href="module-imaging_tools_custom_contourTool.ContoursTool.html#event:_drawingMouseUpCallback">imaging/tools/custom/contourTool.ContoursTool#_drawingMouseUpCallback</a></li><li><a href="module-imaging_tools_custom_contourTool.ContoursTool.html#event:_drawingTouchDragCallback">imaging/tools/custom/contourTool.ContoursTool#_drawingTouchDragCallback</a></li><li><a href="module-imaging_tools_custom_contourTool.ContoursTool.html#event:_drawingTouchStartCallback">imaging/tools/custom/contourTool.ContoursTool#_drawingTouchStartCallback</a></li><li><a href="module-imaging_tools_custom_contourTool.ContoursTool.html#event:_editMouseDragCallback">imaging/tools/custom/contourTool.ContoursTool#_editMouseDragCallback</a></li><li><a href="module-imaging_tools_custom_contourTool.ContoursTool.html#event:_editTouchDragCallback">imaging/tools/custom/contourTool.ContoursTool#_editTouchDragCallback</a></li></ul><h3>Mixins</h3><ul><li><a href="Mixins.polygonSegmentationMixin%2520-%2520segmentation%2520operations%2520for%2520polyline.html">Mixins.polygonSegmentationMixin - segmentation operations for polyline</a></li></ul><h3>Global</h3><ul><li><a href="global.html#getSegmentsOnPixelData">getSegmentsOnPixelData</a></li><li><a href="global.html#NRRD_TYPES_TO_TYPEDARRAY">NRRD_TYPES_TO_TYPEDARRAY</a></li><li><a href="global.html">parse</a></li><li><a href="global.html#setLabelmap3DByFirstImageId">setLabelmap3DByFirstImageId</a></li><li><a href="global.html#setLabelmap3DForElement">setLabelmap3DForElement</a></li></ul>
41
+
42
+ </nav>
43
+
44
+ <div id="main">
45
+
46
+ <h1 class="page-title">tools/custom/contourTool.js</h1>
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+ <section>
55
+ <article>
56
+ <pre class="prettyprint source linenums"><code>/** @module imaging/tools/custom/contourTool
57
+ * @desc This file provides functionalities for
58
+ * rendering segmentation contours with a
59
+ * custom cornestone tool
60
+ */
61
+
62
+ // external libraries
63
+ import cornerstone from "cornerstone-core";
64
+ import csTools from "cornerstone-tools";
65
+ import { each, map } from "lodash";
66
+
67
+ // internal libraries
68
+ import { addToolStateSingleSlice } from "../../imageTools";
69
+
70
+ // cornerstone tools imports
71
+ const external = csTools.external;
72
+ const EVENTS = csTools.EVENTS;
73
+ const BaseAnnotationTool = csTools.importInternal("base/BaseAnnotationTool");
74
+ const getToolState = csTools.getToolState;
75
+ const addToolState = csTools.addToolState;
76
+ const removeToolState = csTools.removeToolState;
77
+ const toolStyle = csTools.toolStyle;
78
+ const toolColors = csTools.toolColors;
79
+ const triggerEvent = csTools.importInternal("util/triggerEvent");
80
+ const pointInsideBoundingBox = csTools.importInternal(
81
+ "util/pointInsideBoundingBox"
82
+ );
83
+ const calculateSUV = csTools.importInternal("util/calculateSUV");
84
+ const numbersWithCommas = csTools.importInternal("util/numbersWithCommas");
85
+ const getNewContext = csTools.importInternal("drawing/getNewContext");
86
+ const draw = csTools.importInternal("drawing/draw");
87
+ const drawJoinedLines = csTools.importInternal("drawing/drawJoinedLines");
88
+ const drawHandles = csTools.importInternal("drawing/drawHandles");
89
+ const drawLinkedTextBox = csTools.importInternal("drawing/drawLinkedTextBox");
90
+ const clipToBox = csTools.importInternal("util/clip");
91
+ const freehandRoiCursor = csTools.importInternal("cursors/freehandRoiCursor");
92
+ const getLogger = csTools.importInternal("util/getLogger");
93
+ const throttle = csTools.importInternal("util/throttle");
94
+ const logger = getLogger("tools:annotation:FreehandRoiTool");
95
+ const freehandUtils = csTools.importInternal("util/freehandUtils");
96
+
97
+ // TODO check how to import these
98
+ // const toolCursor = csTools.importInternal("store/setToolCursor");
99
+ // const hideToolCursor = toolCursor.hideToolCursor;
100
+ // const setToolCursor = toolCursor.setToolCursor;
101
+ // const findAndMoveHelpers = csTools.importInternal("util/findAndMoveHelpers");
102
+ // const moveHandleNearImagePoint = findAndMoveHelpers.moveHandleNearImagePoint;
103
+
104
+ const {
105
+ insertOrDelete,
106
+ freehandArea,
107
+ calculateFreehandStatistics,
108
+ freehandIntersect,
109
+ FreehandHandleData
110
+ } = freehandUtils;
111
+
112
+ const state = {
113
+ // Global
114
+ globalTools: {},
115
+ globalToolChangeHistory: [],
116
+ // Tracking
117
+ enabledElements: [],
118
+ tools: [],
119
+ isToolLocked: false,
120
+ activeMultiPartTool: null,
121
+ mousePositionImage: {},
122
+ // Settings
123
+ clickProximity: 6,
124
+ touchProximity: 10,
125
+ handleRadius: 6,
126
+ deleteIfHandleOutsideImage: true,
127
+ preventHandleOutsideImage: false,
128
+ // Cursor
129
+ svgCursorUrl: null
130
+ };
131
+
132
+ /**
133
+ * @public
134
+ * @class ContoursTool
135
+ * @memberof Tools.Annotation
136
+ * @classdesc Tool for drawing a set of contours
137
+ * @extends Tools.Base.BaseAnnotationTool
138
+ */
139
+ export class ContoursTool extends BaseAnnotationTool {
140
+ constructor(props = {}) {
141
+ const defaultProps = {
142
+ name: "ContoursTool",
143
+ supportedInteractionTypes: ["Mouse", "Touch"],
144
+ configuration: defaultFreehandConfiguration(),
145
+ svgCursor: freehandRoiCursor
146
+ };
147
+
148
+ super(props, defaultProps);
149
+
150
+ this.initializeContours(props.contoursParsedData, props.segmentationName);
151
+
152
+ this.isMultiPartTool = true;
153
+
154
+ this._drawing = false;
155
+ this._dragging = false;
156
+ this._modifying = false;
157
+
158
+ // Create bound callback functions for private event loops
159
+ this._drawingMouseDownCallback = this._drawingMouseDownCallback.bind(this);
160
+ this._drawingMouseMoveCallback = this._drawingMouseMoveCallback.bind(this);
161
+ this._drawingMouseDragCallback = this._drawingMouseDragCallback.bind(this);
162
+ this._drawingMouseUpCallback = this._drawingMouseUpCallback.bind(this);
163
+ this._drawingMouseDoubleClickCallback =
164
+ this._drawingMouseDoubleClickCallback.bind(this);
165
+ this._editMouseUpCallback = this._editMouseUpCallback.bind(this);
166
+ this._editMouseDragCallback = this._editMouseDragCallback.bind(this);
167
+
168
+ this._drawingTouchStartCallback =
169
+ this._drawingTouchStartCallback.bind(this);
170
+ this._drawingTouchDragCallback = this._drawingTouchDragCallback.bind(this);
171
+ this._drawingDoubleTapClickCallback =
172
+ this._drawingDoubleTapClickCallback.bind(this);
173
+ this._editTouchDragCallback = this._editTouchDragCallback.bind(this);
174
+
175
+ this.throttledUpdateCachedStats = throttle(this.updateCachedStats, 110);
176
+ }
177
+
178
+ initializeContours(contourData, segmentationName) {
179
+ var elements = cornerstone.getEnabledElements();
180
+ each(elements, el => {
181
+ var slices = contourData[el.element.id][segmentationName];
182
+
183
+ for (var slice in slices) {
184
+ var linesPerSlice =
185
+ contourData[el.element.id][segmentationName][slice].lines;
186
+ var lines = map(linesPerSlice, line => {
187
+ let dataToInject = {
188
+ visible: true,
189
+ active: false,
190
+ invalidated: false,
191
+ color: "#FF0000",
192
+ handles: {
193
+ points: line
194
+ }
195
+ };
196
+ return dataToInject;
197
+ });
198
+
199
+ addToolStateSingleSlice(el.element, "ContoursTool", lines, slice);
200
+ }
201
+ });
202
+ }
203
+
204
+ createNewMeasurement(eventData) {
205
+ const goodEventData =
206
+ eventData &amp;&amp; eventData.currentPoints &amp;&amp; eventData.currentPoints.image;
207
+
208
+ if (!goodEventData) {
209
+ logger.error(
210
+ `required eventData not supplied to tool ${this.name}'s createNewMeasurement`
211
+ );
212
+
213
+ return;
214
+ }
215
+
216
+ const measurementData = {
217
+ visible: true,
218
+ active: true,
219
+ invalidated: true,
220
+ color: undefined,
221
+ handles: {
222
+ points: []
223
+ }
224
+ };
225
+
226
+ measurementData.handles.textBox = {
227
+ active: false,
228
+ hasMoved: false,
229
+ movesIndependently: false,
230
+ drawnIndependently: true,
231
+ allowedOutsideImage: true,
232
+ hasBoundingBox: true
233
+ };
234
+
235
+ return measurementData;
236
+ }
237
+
238
+ /**
239
+ *
240
+ *
241
+ * @param {*} element element
242
+ * @param {*} data data
243
+ * @param {*} coords coords
244
+ * @returns {Boolean}
245
+ */
246
+ pointNearTool(element, data, coords) {
247
+ const validParameters = data &amp;&amp; data.handles &amp;&amp; data.handles.points;
248
+
249
+ if (!validParameters) {
250
+ throw new Error(
251
+ `invalid parameters supplied to tool ${this.name}'s pointNearTool`
252
+ );
253
+ }
254
+
255
+ if (!validParameters || data.visible === false) {
256
+ return false;
257
+ }
258
+
259
+ const isPointNearTool = this._pointNearHandle(element, data, coords);
260
+
261
+ if (isPointNearTool !== undefined) {
262
+ return true;
263
+ }
264
+
265
+ return false;
266
+ }
267
+
268
+ /**
269
+ * @param {*} element
270
+ * @param {*} data
271
+ * @param {*} coords
272
+ * @returns {number} the distance in px from the provided coordinates to the
273
+ * closest rendered portion of the annotation. -1 if the distance cannot be
274
+ * calculated.
275
+ */
276
+ distanceFromPoint(element, data, coords) {
277
+ let distance = Infinity;
278
+
279
+ for (let i = 0; i &lt; data.handles.points.length; i++) {
280
+ const distanceI = external.cornerstoneMath.point.distance(
281
+ data.handles.points[i],
282
+ coords
283
+ );
284
+
285
+ distance = Math.min(distance, distanceI);
286
+ }
287
+
288
+ // If an error caused distance not to be calculated, return -1.
289
+ if (distance === Infinity) {
290
+ return -1;
291
+ }
292
+
293
+ return distance;
294
+ }
295
+
296
+ /**
297
+ * @param {*} element
298
+ * @param {*} data
299
+ * @param {*} coords
300
+ * @returns {number} the distance in canvas units from the provided coordinates to the
301
+ * closest rendered portion of the annotation. -1 if the distance cannot be
302
+ * calculated.
303
+ */
304
+ distanceFromPointCanvas(element, data, coords) {
305
+ let distance = Infinity;
306
+
307
+ if (!data) {
308
+ return -1;
309
+ }
310
+
311
+ const canvasCoords = external.cornerstone.pixelToCanvas(element, coords);
312
+
313
+ const points = data.handles.points;
314
+
315
+ for (let i = 0; i &lt; points.length; i++) {
316
+ const handleCanvas = external.cornerstone.pixelToCanvas(
317
+ element,
318
+ points[i]
319
+ );
320
+
321
+ const distanceI = external.cornerstoneMath.point.distance(
322
+ handleCanvas,
323
+ canvasCoords
324
+ );
325
+
326
+ distance = Math.min(distance, distanceI);
327
+ }
328
+
329
+ // If an error caused distance not to be calculated, return -1.
330
+ if (distance === Infinity) {
331
+ return -1;
332
+ }
333
+
334
+ return distance;
335
+ }
336
+
337
+ /**
338
+ *
339
+ *
340
+ *
341
+ * @param {Object} image image
342
+ * @param {Object} element element
343
+ * @param {Object} data data
344
+ *
345
+ * @returns {void} void
346
+ */
347
+ updateCachedStats(image, element, data) {
348
+ // Define variables for the area and mean/standard deviation
349
+ let meanStdDev, meanStdDevSUV;
350
+
351
+ const seriesModule = external.cornerstone.metaData.get(
352
+ "generalSeriesModule",
353
+ image.imageId
354
+ );
355
+ const modality = seriesModule ? seriesModule.modality : null;
356
+
357
+ const points = data.handles.points;
358
+ // If the data has been invalidated, and the tool is not currently active,
359
+ // We need to calculate it again.
360
+
361
+ // Retrieve the bounds of the ROI in image coordinates
362
+ const bounds = {
363
+ left: points[0].x,
364
+ right: points[0].x,
365
+ bottom: points[0].y,
366
+ top: points[0].x
367
+ };
368
+
369
+ for (let i = 0; i &lt; points.length; i++) {
370
+ bounds.left = Math.min(bounds.left, points[i].x);
371
+ bounds.right = Math.max(bounds.right, points[i].x);
372
+ bounds.bottom = Math.min(bounds.bottom, points[i].y);
373
+ bounds.top = Math.max(bounds.top, points[i].y);
374
+ }
375
+
376
+ const polyBoundingBox = {
377
+ left: bounds.left,
378
+ top: bounds.bottom,
379
+ width: Math.abs(bounds.right - bounds.left),
380
+ height: Math.abs(bounds.top - bounds.bottom)
381
+ };
382
+
383
+ // Store the bounding box information for the text box
384
+ data.polyBoundingBox = polyBoundingBox;
385
+
386
+ // First, make sure this is not a color image, since no mean / standard
387
+ // Deviation will be calculated for color images.
388
+ if (!image.color) {
389
+ // Retrieve the array of pixels that the ROI bounds cover
390
+ const pixels = external.cornerstone.getPixels(
391
+ element,
392
+ polyBoundingBox.left,
393
+ polyBoundingBox.top,
394
+ polyBoundingBox.width,
395
+ polyBoundingBox.height
396
+ );
397
+
398
+ // Calculate the mean &amp; standard deviation from the pixels and the object shape
399
+ meanStdDev = calculateFreehandStatistics.call(
400
+ this,
401
+ pixels,
402
+ polyBoundingBox,
403
+ data.handles.points
404
+ );
405
+
406
+ if (modality === "PT") {
407
+ // If the image is from a PET scan, use the DICOM tags to
408
+ // Calculate the SUV from the mean and standard deviation.
409
+
410
+ // Note that because we are using modality pixel values from getPixels, and
411
+ // The calculateSUV routine also rescales to modality pixel values, we are first
412
+ // Returning the values to storedPixel values before calcuating SUV with them.
413
+ // TODO: Clean this up? Should we add an option to not scale in calculateSUV?
414
+ meanStdDevSUV = {
415
+ mean: calculateSUV(
416
+ image,
417
+ (meanStdDev.mean - image.intercept) / image.slope
418
+ ),
419
+ stdDev: calculateSUV(
420
+ image,
421
+ (meanStdDev.stdDev - image.intercept) / image.slope
422
+ )
423
+ };
424
+ }
425
+
426
+ // If the mean and standard deviation values are sane, store them for later retrieval
427
+ if (meanStdDev &amp;&amp; !isNaN(meanStdDev.mean)) {
428
+ data.meanStdDev = meanStdDev;
429
+ data.meanStdDevSUV = meanStdDevSUV;
430
+ }
431
+ }
432
+
433
+ // Retrieve the pixel spacing values, and if they are not
434
+ // Real non-zero values, set them to 1
435
+ const columnPixelSpacing = image.columnPixelSpacing || 1;
436
+ const rowPixelSpacing = image.rowPixelSpacing || 1;
437
+ const scaling = columnPixelSpacing * rowPixelSpacing;
438
+
439
+ const area = freehandArea(data.handles.points, scaling);
440
+
441
+ // If the area value is sane, store it for later retrieval
442
+ if (!isNaN(area)) {
443
+ data.area = area;
444
+ }
445
+
446
+ // Set the invalidated flag to false so that this data won't automatically be recalculated
447
+ data.invalidated = false;
448
+ }
449
+
450
+ /**
451
+ *
452
+ *
453
+ * @param {*} evt
454
+ * @returns {undefined}
455
+ */
456
+ renderToolData(evt) {
457
+ const eventData = evt.detail;
458
+
459
+ // If we have no toolState for this element, return immediately as there is nothing to do
460
+ const toolState = getToolState(evt.currentTarget, this.name);
461
+
462
+ if (!toolState) {
463
+ return;
464
+ }
465
+
466
+ const { image, element } = eventData;
467
+ const config = this.configuration;
468
+ const seriesModule = external.cornerstone.metaData.get(
469
+ "generalSeriesModule",
470
+ image.imageId
471
+ );
472
+ const modality = seriesModule ? seriesModule.modality : null;
473
+
474
+ // We have tool data for this element - iterate over each one and draw it
475
+ const context = getNewContext(eventData.canvasContext.canvas);
476
+ const lineWidth = toolStyle.getToolWidth();
477
+
478
+ for (let i = 0; i &lt; toolState.data.length; i++) {
479
+ const data = toolState.data[i];
480
+
481
+ if (data.visible === false) {
482
+ continue;
483
+ }
484
+
485
+ draw(context, context => {
486
+ let color = toolColors.getColorIfActive(data);
487
+ let fillColor;
488
+
489
+ if (data.active) {
490
+ if (data.handles.invalidHandlePlacement) {
491
+ color = config.invalidColor;
492
+ fillColor = config.invalidColor;
493
+ } else {
494
+ color = toolColors.getColorIfActive(data);
495
+ fillColor = toolColors.getFillColor();
496
+ }
497
+ } else {
498
+ fillColor = toolColors.getToolColor();
499
+ }
500
+
501
+ if (data.handles.points.length) {
502
+ for (let j = 0; j &lt; data.handles.points.length; j++) {
503
+ const lines = [...data.handles.points[j].lines];
504
+ const points = data.handles.points;
505
+
506
+ if (j === points.length - 1 &amp;&amp; !data.polyBoundingBox) {
507
+ // If it's still being actively drawn, keep the last line to
508
+ // The mouse location
509
+ lines.push(config.mouseLocation.handles.start);
510
+ }
511
+ drawJoinedLines(context, element, data.handles.points[j], lines, {
512
+ color
513
+ });
514
+ }
515
+ }
516
+
517
+ // Draw handles
518
+
519
+ const options = {
520
+ color,
521
+ fill: fillColor
522
+ };
523
+
524
+ if (config.alwaysShowHandles || (data.active &amp;&amp; data.polyBoundingBox)) {
525
+ // Render all handles
526
+ options.handleRadius = config.activeHandleRadius;
527
+ drawHandles(context, eventData, data.handles.points, options);
528
+ }
529
+
530
+ if (data.canComplete) {
531
+ // Draw large handle at the origin if can complete drawing
532
+ options.handleRadius = config.completeHandleRadius;
533
+ const handle = data.handles.points[0];
534
+ drawHandles(context, eventData, [handle], options);
535
+ }
536
+
537
+ if (data.active &amp;&amp; !data.polyBoundingBox) {
538
+ // Draw handle at origin and at mouse if actively drawing
539
+ options.handleRadius = config.activeHandleRadius;
540
+ drawHandles(
541
+ context,
542
+ eventData,
543
+ config.mouseLocation.handles,
544
+ options
545
+ );
546
+
547
+ const firstHandle = data.handles.points[0];
548
+ drawHandles(context, eventData, [firstHandle], options);
549
+ }
550
+
551
+ // Update textbox stats
552
+ if (data.invalidated === true &amp;&amp; !data.active) {
553
+ if (data.meanStdDev &amp;&amp; data.meanStdDevSUV &amp;&amp; data.area) {
554
+ this.throttledUpdateCachedStats(image, element, data);
555
+ } else {
556
+ this.updateCachedStats(image, element, data);
557
+ }
558
+ }
559
+
560
+ // Only render text if polygon ROI has been completed and freehand 'shiftKey' mode was not used:
561
+ if (data.polyBoundingBox &amp;&amp; !data.handles.textBox.freehand) {
562
+ // If the textbox has not been moved by the user, it should be displayed on the right-most
563
+ // Side of the tool.
564
+ if (!data.handles.textBox.hasMoved) {
565
+ // Find the rightmost side of the polyBoundingBox at its vertical center, and place the textbox here
566
+ // Note that this calculates it in image coordinates
567
+ data.handles.textBox.x =
568
+ data.polyBoundingBox.left + data.polyBoundingBox.width;
569
+ data.handles.textBox.y =
570
+ data.polyBoundingBox.top + data.polyBoundingBox.height / 2;
571
+ }
572
+
573
+ const text = textBoxText.call(this, data);
574
+
575
+ drawLinkedTextBox(
576
+ context,
577
+ element,
578
+ data.handles.textBox,
579
+ text,
580
+ data.handles.points,
581
+ textBoxAnchorPoints,
582
+ color,
583
+ lineWidth,
584
+ 0,
585
+ true
586
+ );
587
+ }
588
+ });
589
+ }
590
+
591
+ function textBoxText(data) {
592
+ const { meanStdDev, meanStdDevSUV, area } = data;
593
+ // Define an array to store the rows of text for the textbox
594
+ const textLines = [];
595
+
596
+ // If the mean and standard deviation values are present, display them
597
+ if (meanStdDev &amp;&amp; meanStdDev.mean !== undefined) {
598
+ // If the modality is CT, add HU to denote Hounsfield Units
599
+ let moSuffix = "";
600
+
601
+ if (modality === "CT") {
602
+ moSuffix = "HU";
603
+ }
604
+ data.unit = moSuffix;
605
+
606
+ // Create a line of text to display the mean and any units that were specified (i.e. HU)
607
+ let meanText = `Mean: ${numbersWithCommas(
608
+ meanStdDev.mean.toFixed(2)
609
+ )} ${moSuffix}`;
610
+ // Create a line of text to display the standard deviation and any units that were specified (i.e. HU)
611
+ let stdDevText = `StdDev: ${numbersWithCommas(
612
+ meanStdDev.stdDev.toFixed(2)
613
+ )} ${moSuffix}`;
614
+
615
+ // If this image has SUV values to display, concatenate them to the text line
616
+ if (meanStdDevSUV &amp;&amp; meanStdDevSUV.mean !== undefined) {
617
+ const SUVtext = " SUV: ";
618
+
619
+ meanText +=
620
+ SUVtext + numbersWithCommas(meanStdDevSUV.mean.toFixed(2));
621
+ stdDevText +=
622
+ SUVtext + numbersWithCommas(meanStdDevSUV.stdDev.toFixed(2));
623
+ }
624
+
625
+ // Add these text lines to the array to be displayed in the textbox
626
+ textLines.push(meanText);
627
+ textLines.push(stdDevText);
628
+ }
629
+
630
+ // If the area is a sane value, display it
631
+ if (area) {
632
+ // Determine the area suffix based on the pixel spacing in the image.
633
+ // If pixel spacing is present, use millimeters. Otherwise, use pixels.
634
+ // This uses Char code 178 for a superscript 2
635
+ let suffix = ` mm${String.fromCharCode(178)}`;
636
+
637
+ if (!image.rowPixelSpacing || !image.columnPixelSpacing) {
638
+ suffix = ` pixels${String.fromCharCode(178)}`;
639
+ }
640
+
641
+ // Create a line of text to display the area and its units
642
+ const areaText = `Area: ${numbersWithCommas(area.toFixed(2))}${suffix}`;
643
+
644
+ // Add this text line to the array to be displayed in the textbox
645
+ textLines.push(areaText);
646
+ }
647
+
648
+ return textLines;
649
+ }
650
+
651
+ function textBoxAnchorPoints(handles) {
652
+ return handles;
653
+ }
654
+ }
655
+
656
+ addNewMeasurement(evt) {
657
+ const eventData = evt.detail;
658
+
659
+ this._startDrawing(evt);
660
+ this._addPoint(eventData);
661
+
662
+ preventPropagation(evt);
663
+ }
664
+
665
+ preMouseDownCallback(evt) {
666
+ const eventData = evt.detail;
667
+ const nearby = this._pointNearHandleAllTools(eventData);
668
+
669
+ if (eventData.event.ctrlKey) {
670
+ if (nearby !== undefined &amp;&amp; nearby.handleNearby.hasBoundingBox) {
671
+ // Ctrl + clicked textBox, do nothing but still consume event.
672
+ } else {
673
+ insertOrDelete.call(this, evt, nearby);
674
+ }
675
+
676
+ preventPropagation(evt);
677
+
678
+ return true;
679
+ }
680
+
681
+ return false;
682
+ }
683
+
684
+ handleSelectedCallback(evt, toolData, handle, interactionType = "mouse") {
685
+ const { element } = evt.detail;
686
+ const toolState = getToolState(element, this.name);
687
+ console.info(interactionType);
688
+ // if (handle.hasBoundingBox) {
689
+ // // Use default move handler.
690
+ // moveHandleNearImagePoint(evt, this, toolData, handle, interactionType);
691
+
692
+ // return;
693
+ // }
694
+
695
+ const config = this.configuration;
696
+
697
+ config.dragOrigin = {
698
+ x: handle.x,
699
+ y: handle.y
700
+ };
701
+
702
+ // Iterating over handles of all toolData instances to find the indices of the selected handle
703
+ for (let toolIndex = 0; toolIndex &lt; toolState.data.length; toolIndex++) {
704
+ const points = toolState.data[toolIndex].handles.points;
705
+
706
+ for (let p = 0; p &lt; points.length; p++) {
707
+ if (points[p] === handle) {
708
+ config.currentHandle = p;
709
+ config.currentTool = toolIndex;
710
+ }
711
+ }
712
+ }
713
+
714
+ this._modifying = true;
715
+
716
+ this._activateModify(element);
717
+
718
+ // Interupt eventDispatchers
719
+ preventPropagation(evt);
720
+ }
721
+
722
+ /**
723
+ * Event handler for MOUSE_MOVE during drawing event loop.
724
+ *
725
+ * @event
726
+ * @param {Object} evt - The event.
727
+ * @returns {undefined}
728
+ */
729
+ _drawingMouseMoveCallback(evt) {
730
+ const eventData = evt.detail;
731
+ const { currentPoints, element } = eventData;
732
+ const toolState = getToolState(element, this.name);
733
+
734
+ const config = this.configuration;
735
+ const currentTool = config.currentTool;
736
+
737
+ const data = toolState.data[currentTool];
738
+ const coords = currentPoints.canvas;
739
+
740
+ // Set the mouseLocation handle
741
+ this._getMouseLocation(eventData);
742
+ this._checkInvalidHandleLocation(data, eventData);
743
+
744
+ // Mouse move -> Polygon Mode
745
+ const handleNearby = this._pointNearHandle(element, data, coords);
746
+ const points = data.handles.points;
747
+ // If there is a handle nearby to snap to
748
+ // (and it's not the actual mouse handle)
749
+
750
+ if (
751
+ handleNearby !== undefined &amp;&amp;
752
+ !handleNearby.hasBoundingBox &amp;&amp;
753
+ handleNearby &lt; points.length - 1
754
+ ) {
755
+ config.mouseLocation.handles.start.x = points[handleNearby].x;
756
+ config.mouseLocation.handles.start.y = points[handleNearby].y;
757
+ }
758
+
759
+ // Force onImageRendered
760
+ external.cornerstone.updateImage(element);
761
+ }
762
+
763
+ /**
764
+ * Event handler for MOUSE_DRAG during drawing event loop.
765
+ *
766
+ * @event
767
+ * @param {Object} evt - The event.
768
+ * @returns {undefined}
769
+ */
770
+ _drawingMouseDragCallback(evt) {
771
+ if (!this.options.mouseButtonMask.includes(evt.detail.buttons)) {
772
+ return;
773
+ }
774
+
775
+ this._drawingDrag(evt);
776
+ }
777
+
778
+ /**
779
+ * Event handler for TOUCH_DRAG during drawing event loop.
780
+ *
781
+ * @event
782
+ * @param {Object} evt - The event.
783
+ * @returns {undefined}
784
+ */
785
+ _drawingTouchDragCallback(evt) {
786
+ this._drawingDrag(evt);
787
+ }
788
+
789
+ _drawingDrag(evt) {
790
+ const eventData = evt.detail;
791
+ const { element } = eventData;
792
+
793
+ const toolState = getToolState(element, this.name);
794
+
795
+ const config = this.configuration;
796
+ const currentTool = config.currentTool;
797
+
798
+ const data = toolState.data[currentTool];
799
+
800
+ // Set the mouseLocation handle
801
+ this._getMouseLocation(eventData);
802
+ this._checkInvalidHandleLocation(data, eventData);
803
+ this._addPointPencilMode(eventData, data.handles.points);
804
+ this._dragging = true;
805
+
806
+ // Force onImageRendered
807
+ external.cornerstone.updateImage(element);
808
+ }
809
+
810
+ /**
811
+ * Event handler for MOUSE_UP during drawing event loop.
812
+ *
813
+ * @event
814
+ * @param {Object} evt - The event.
815
+ * @returns {undefined}
816
+ */
817
+ _drawingMouseUpCallback(evt) {
818
+ const { element } = evt.detail;
819
+
820
+ if (!this._dragging) {
821
+ return;
822
+ }
823
+
824
+ this._dragging = false;
825
+
826
+ const config = this.configuration;
827
+ const currentTool = config.currentTool;
828
+ const toolState = getToolState(element, this.name);
829
+ const data = toolState.data[currentTool];
830
+
831
+ if (!freehandIntersect.end(data.handles.points) &amp;&amp; data.canComplete) {
832
+ const lastHandlePlaced = config.currentHandle;
833
+
834
+ this._endDrawing(element, lastHandlePlaced);
835
+ }
836
+
837
+ preventPropagation(evt);
838
+
839
+ return;
840
+ }
841
+
842
+ /**
843
+ * Event handler for MOUSE_DOWN during drawing event loop.
844
+ *
845
+ * @event
846
+ * @param {Object} evt - The event.
847
+ * @returns {undefined}
848
+ */
849
+ _drawingMouseDownCallback(evt) {
850
+ const eventData = evt.detail;
851
+ const { buttons, currentPoints, element } = eventData;
852
+
853
+ if (!this.options.mouseButtonMask.includes(buttons)) {
854
+ return;
855
+ }
856
+
857
+ const coords = currentPoints.canvas;
858
+
859
+ const config = this.configuration;
860
+ const currentTool = config.currentTool;
861
+ const toolState = getToolState(element, this.name);
862
+ const data = toolState.data[currentTool];
863
+
864
+ const handleNearby = this._pointNearHandle(element, data, coords);
865
+
866
+ if (!freehandIntersect.end(data.handles.points) &amp;&amp; data.canComplete) {
867
+ const lastHandlePlaced = config.currentHandle;
868
+
869
+ this._endDrawing(element, lastHandlePlaced);
870
+ } else if (handleNearby === undefined) {
871
+ this._addPoint(eventData);
872
+ }
873
+
874
+ preventPropagation(evt);
875
+
876
+ return;
877
+ }
878
+
879
+ /**
880
+ * Event handler for TOUCH_START during drawing event loop.
881
+ *
882
+ * @event
883
+ * @param {Object} evt - The event.
884
+ * @returns {undefined}
885
+ */
886
+ _drawingTouchStartCallback(evt) {
887
+ const eventData = evt.detail;
888
+ const { currentPoints, element } = eventData;
889
+
890
+ const coords = currentPoints.canvas;
891
+
892
+ const config = this.configuration;
893
+ const currentTool = config.currentTool;
894
+ const toolState = getToolState(element, this.name);
895
+ const data = toolState.data[currentTool];
896
+
897
+ const handleNearby = this._pointNearHandle(element, data, coords);
898
+
899
+ if (!freehandIntersect.end(data.handles.points) &amp;&amp; data.canComplete) {
900
+ const lastHandlePlaced = config.currentHandle;
901
+
902
+ this._endDrawing(element, lastHandlePlaced);
903
+ } else if (handleNearby === undefined) {
904
+ this._addPoint(eventData);
905
+ }
906
+
907
+ preventPropagation(evt);
908
+
909
+ return;
910
+ }
911
+
912
+ /** Ends the active drawing loop and completes the polygon.
913
+ *
914
+ * @public
915
+ * @param {Object} element - The element on which the roi is being drawn.
916
+ * @returns {null}
917
+ */
918
+ completeDrawing(element) {
919
+ if (!this._drawing) {
920
+ return;
921
+ }
922
+ const toolState = getToolState(element, this.name);
923
+ const config = this.configuration;
924
+ const data = toolState.data[config.currentTool];
925
+
926
+ if (
927
+ !freehandIntersect.end(data.handles.points) &amp;&amp;
928
+ data.handles.points.length >= 2
929
+ ) {
930
+ const lastHandlePlaced = config.currentHandle;
931
+
932
+ data.polyBoundingBox = {};
933
+ this._endDrawing(element, lastHandlePlaced);
934
+ }
935
+ }
936
+
937
+ /**
938
+ * Event handler for MOUSE_DOUBLE_CLICK during drawing event loop.
939
+ *
940
+ * @event
941
+ * @param {Object} evt - The event.
942
+ * @returns {undefined}
943
+ */
944
+ _drawingMouseDoubleClickCallback(evt) {
945
+ const { element } = evt.detail;
946
+
947
+ this.completeDrawing(element);
948
+
949
+ preventPropagation(evt);
950
+ }
951
+
952
+ /**
953
+ * Event handler for DOUBLE_TAP during drawing event loop.
954
+ *
955
+ * @event
956
+ * @param {Object} evt - The event.
957
+ * @returns {undefined}
958
+ */
959
+ _drawingDoubleTapClickCallback(evt) {
960
+ const { element } = evt.detail;
961
+
962
+ this.completeDrawing(element);
963
+
964
+ preventPropagation(evt);
965
+ }
966
+
967
+ /**
968
+ * Event handler for MOUSE_DRAG during handle drag event loop.
969
+ *
970
+ * @event
971
+ * @param {Object} evt - The event.
972
+ * @returns {undefined}
973
+ */
974
+ _editMouseDragCallback(evt) {
975
+ const eventData = evt.detail;
976
+ const { element, buttons } = eventData;
977
+
978
+ if (!this.options.mouseButtonMask.includes(buttons)) {
979
+ return;
980
+ }
981
+
982
+ const toolState = getToolState(element, this.name);
983
+
984
+ const config = this.configuration;
985
+ const data = toolState.data[config.currentTool];
986
+ const currentHandle = config.currentHandle;
987
+ const points = data.handles.points;
988
+ let handleIndex = -1;
989
+
990
+ // Set the mouseLocation handle
991
+ this._getMouseLocation(eventData);
992
+
993
+ data.handles.invalidHandlePlacement = freehandIntersect.modify(
994
+ points,
995
+ currentHandle
996
+ );
997
+ data.active = true;
998
+ data.highlight = true;
999
+ points[currentHandle].x = config.mouseLocation.handles.start.x;
1000
+ points[currentHandle].y = config.mouseLocation.handles.start.y;
1001
+
1002
+ handleIndex = this._getPrevHandleIndex(currentHandle, points);
1003
+
1004
+ if (currentHandle >= 0) {
1005
+ const lastLineIndex = points[handleIndex].lines.length - 1;
1006
+ const lastLine = points[handleIndex].lines[lastLineIndex];
1007
+
1008
+ lastLine.x = config.mouseLocation.handles.start.x;
1009
+ lastLine.y = config.mouseLocation.handles.start.y;
1010
+ }
1011
+
1012
+ // Update the image
1013
+ external.cornerstone.updateImage(element);
1014
+ }
1015
+
1016
+ /**
1017
+ * Event handler for TOUCH_DRAG during handle drag event loop.
1018
+ *
1019
+ * @event
1020
+ * @param {Object} evt - The event.
1021
+ * @returns {void}
1022
+ */
1023
+ _editTouchDragCallback(evt) {
1024
+ const eventData = evt.detail;
1025
+ const { element } = eventData;
1026
+
1027
+ const toolState = getToolState(element, this.name);
1028
+
1029
+ const config = this.configuration;
1030
+ const data = toolState.data[config.currentTool];
1031
+ const currentHandle = config.currentHandle;
1032
+ const points = data.handles.points;
1033
+ let handleIndex = -1;
1034
+
1035
+ // Set the mouseLocation handle
1036
+ this._getMouseLocation(eventData);
1037
+
1038
+ data.handles.invalidHandlePlacement = freehandIntersect.modify(
1039
+ points,
1040
+ currentHandle
1041
+ );
1042
+ data.active = true;
1043
+ data.highlight = true;
1044
+ points[currentHandle].x = config.mouseLocation.handles.start.x;
1045
+ points[currentHandle].y = config.mouseLocation.handles.start.y;
1046
+
1047
+ handleIndex = this._getPrevHandleIndex(currentHandle, points);
1048
+
1049
+ if (currentHandle >= 0) {
1050
+ const lastLineIndex = points[handleIndex].lines.length - 1;
1051
+ const lastLine = points[handleIndex].lines[lastLineIndex];
1052
+
1053
+ lastLine.x = config.mouseLocation.handles.start.x;
1054
+ lastLine.y = config.mouseLocation.handles.start.y;
1055
+ }
1056
+
1057
+ // Update the image
1058
+ external.cornerstone.updateImage(element);
1059
+ }
1060
+
1061
+ /**
1062
+ * Returns the previous handle to the current one.
1063
+ * @param {Number} currentHandle - the current handle index
1064
+ * @param {Array} points - the handles Array of the freehand data
1065
+ * @returns {Number} - The index of the previos handle
1066
+ */
1067
+ _getPrevHandleIndex(currentHandle, points) {
1068
+ if (currentHandle === 0) {
1069
+ return points.length - 1;
1070
+ }
1071
+
1072
+ return currentHandle - 1;
1073
+ }
1074
+
1075
+ /**
1076
+ * Event handler for MOUSE_UP during handle drag event loop.
1077
+ *
1078
+ * @private
1079
+ * @param {Object} evt - The event.
1080
+ * @returns {undefined}
1081
+ */
1082
+ _editMouseUpCallback(evt) {
1083
+ const eventData = evt.detail;
1084
+ const { element } = eventData;
1085
+ const toolState = getToolState(element, this.name);
1086
+
1087
+ this._deactivateModify(element);
1088
+
1089
+ this._dropHandle(eventData, toolState);
1090
+ this._endDrawing(element);
1091
+
1092
+ external.cornerstone.updateImage(element);
1093
+ }
1094
+
1095
+ /**
1096
+ * Places a handle of the freehand tool if the new location is valid.
1097
+ * If the new location is invalid the handle snaps back to its previous position.
1098
+ *
1099
+ * @private
1100
+ * @param {Object} eventData - Data object associated with the event.
1101
+ * @param {Object} toolState - The data associated with the freehand tool.
1102
+ * @modifies {toolState}
1103
+ * @returns {undefined}
1104
+ */
1105
+ _dropHandle(eventData, toolState) {
1106
+ const config = this.configuration;
1107
+ const currentTool = config.currentTool;
1108
+ const handles = toolState.data[currentTool].handles;
1109
+ const points = handles.points;
1110
+
1111
+ // Don't allow the line being modified to intersect other lines
1112
+ if (handles.invalidHandlePlacement) {
1113
+ const currentHandle = config.currentHandle;
1114
+ const currentHandleData = points[currentHandle];
1115
+ let previousHandleData;
1116
+
1117
+ if (currentHandle === 0) {
1118
+ const lastHandleID = points.length - 1;
1119
+
1120
+ previousHandleData = points[lastHandleID];
1121
+ } else {
1122
+ previousHandleData = points[currentHandle - 1];
1123
+ }
1124
+
1125
+ // Snap back to previous position
1126
+ currentHandleData.x = config.dragOrigin.x;
1127
+ currentHandleData.y = config.dragOrigin.y;
1128
+ previousHandleData.lines[0] = currentHandleData;
1129
+
1130
+ handles.invalidHandlePlacement = false;
1131
+ }
1132
+ }
1133
+
1134
+ /**
1135
+ * Begining of drawing loop when tool is active and a click event happens far
1136
+ * from existing handles.
1137
+ *
1138
+ * @private
1139
+ * @param {Object} evt - The event.
1140
+ * @returns {undefined}
1141
+ */
1142
+ _startDrawing(evt) {
1143
+ const eventData = evt.detail;
1144
+ const measurementData = this.createNewMeasurement(eventData);
1145
+ const { element } = eventData;
1146
+ const config = this.configuration;
1147
+ let interactionType;
1148
+
1149
+ if (evt.type === EVENTS.MOUSE_DOWN_ACTIVATE) {
1150
+ interactionType = "Mouse";
1151
+ } else if (evt.type === EVENTS.TOUCH_START_ACTIVE) {
1152
+ interactionType = "Touch";
1153
+ }
1154
+ this._activateDraw(element, interactionType);
1155
+ this._getMouseLocation(eventData);
1156
+
1157
+ addToolState(element, this.name, measurementData);
1158
+
1159
+ const toolState = getToolState(element, this.name);
1160
+
1161
+ config.currentTool = toolState.data.length - 1;
1162
+
1163
+ this._activeDrawingToolReference = toolState.data[config.currentTool];
1164
+ }
1165
+
1166
+ /**
1167
+ * Adds a point on mouse click in polygon mode.
1168
+ *
1169
+ * @private
1170
+ * @param {Object} eventData - data object associated with an event.
1171
+ * @returns {undefined}
1172
+ */
1173
+ _addPoint(eventData) {
1174
+ const { currentPoints, element } = eventData;
1175
+ const toolState = getToolState(element, this.name);
1176
+
1177
+ // Get the toolState from the last-drawn polygon
1178
+ const config = this.configuration;
1179
+ const data = toolState.data[config.currentTool];
1180
+
1181
+ if (data.handles.invalidHandlePlacement) {
1182
+ return;
1183
+ }
1184
+
1185
+ const newHandleData = new FreehandHandleData(currentPoints.image);
1186
+
1187
+ // If this is not the first handle
1188
+ if (data.handles.points.length) {
1189
+ // Add the line from the current handle to the new handle
1190
+ data.handles.points[config.currentHandle - 1].lines.push(
1191
+ currentPoints.image
1192
+ );
1193
+ }
1194
+
1195
+ // Add the new handle
1196
+ data.handles.points.push(newHandleData);
1197
+
1198
+ // Increment the current handle value
1199
+ config.currentHandle += 1;
1200
+
1201
+ // Force onImageRendered to fire
1202
+ external.cornerstone.updateImage(element);
1203
+ this.fireModifiedEvent(element, data);
1204
+ }
1205
+
1206
+ /**
1207
+ * If in pencilMode, check the mouse position is farther than the minimum
1208
+ * distance between points, then add a point.
1209
+ *
1210
+ * @private
1211
+ * @param {Object} eventData - Data object associated with an event.
1212
+ * @param {Object} points - Data object associated with the tool.
1213
+ * @returns {undefined}
1214
+ */
1215
+ _addPointPencilMode(eventData, points) {
1216
+ const config = this.configuration;
1217
+ const { element } = eventData;
1218
+ const mousePoint = config.mouseLocation.handles.start;
1219
+
1220
+ const handleFurtherThanMinimumSpacing = handle =>
1221
+ this._isDistanceLargerThanSpacing(element, handle, mousePoint);
1222
+
1223
+ if (points.every(handleFurtherThanMinimumSpacing)) {
1224
+ this._addPoint(eventData);
1225
+ }
1226
+ }
1227
+
1228
+ /**
1229
+ * Ends the active drawing loop and completes the polygon.
1230
+ *
1231
+ * @private
1232
+ * @param {Object} element - The element on which the roi is being drawn.
1233
+ * @param {Object} handleNearby - the handle nearest to the mouse cursor.
1234
+ * @returns {undefined}
1235
+ */
1236
+ _endDrawing(element, handleNearby) {
1237
+ const toolState = getToolState(element, this.name);
1238
+ const config = this.configuration;
1239
+ const data = toolState.data[config.currentTool];
1240
+
1241
+ data.active = false;
1242
+ data.highlight = false;
1243
+ data.handles.invalidHandlePlacement = false;
1244
+
1245
+ // Connect the end handle to the origin handle
1246
+ if (handleNearby !== undefined) {
1247
+ const points = data.handles.points;
1248
+
1249
+ points[config.currentHandle - 1].lines.push(points[0]);
1250
+ }
1251
+
1252
+ if (this._modifying) {
1253
+ this._modifying = false;
1254
+ data.invalidated = true;
1255
+ }
1256
+
1257
+ // Reset the current handle
1258
+ config.currentHandle = 0;
1259
+ config.currentTool = -1;
1260
+ data.canComplete = false;
1261
+
1262
+ if (this._drawing) {
1263
+ this._deactivateDraw(element);
1264
+ }
1265
+
1266
+ external.cornerstone.updateImage(element);
1267
+
1268
+ this.fireModifiedEvent(element, data);
1269
+ this.fireCompletedEvent(element, data);
1270
+ }
1271
+
1272
+ /**
1273
+ * Returns a handle of a particular tool if it is close to the mouse cursor
1274
+ *
1275
+ * @private
1276
+ * @param {Object} element - The element on which the roi is being drawn.
1277
+ * @param {Object} data Data object associated with the tool.
1278
+ * @param {*} coords
1279
+ * @returns {Number|Object|Boolean}
1280
+ */
1281
+ _pointNearHandle(element, data, coords) {
1282
+ if (data.handles === undefined || data.handles.points === undefined) {
1283
+ return;
1284
+ }
1285
+
1286
+ if (data.visible === false) {
1287
+ return;
1288
+ }
1289
+
1290
+ for (let i = 0; i &lt; data.handles.points.length; i++) {
1291
+ const handleCanvas = external.cornerstone.pixelToCanvas(
1292
+ element,
1293
+ data.handles.points[i]
1294
+ );
1295
+
1296
+ if (external.cornerstoneMath.point.distance(handleCanvas, coords) &lt; 6) {
1297
+ return i;
1298
+ }
1299
+ }
1300
+
1301
+ // Check to see if mouse in bounding box of textbox
1302
+ if (data.handles.textBox) {
1303
+ if (pointInsideBoundingBox(data.handles.textBox, coords)) {
1304
+ return data.handles.textBox;
1305
+ }
1306
+ }
1307
+ }
1308
+
1309
+ /**
1310
+ * Returns a handle if it is close to the mouse cursor (all tools)
1311
+ *
1312
+ * @private
1313
+ * @param {Object} eventData - data object associated with an event.
1314
+ * @returns {Object}
1315
+ */
1316
+ _pointNearHandleAllTools(eventData) {
1317
+ const { currentPoints, element } = eventData;
1318
+ const coords = currentPoints.canvas;
1319
+ const toolState = getToolState(element, this.name);
1320
+
1321
+ if (!toolState) {
1322
+ return;
1323
+ }
1324
+
1325
+ let handleNearby;
1326
+
1327
+ for (let toolIndex = 0; toolIndex &lt; toolState.data.length; toolIndex++) {
1328
+ handleNearby = this._pointNearHandle(
1329
+ element,
1330
+ toolState.data[toolIndex],
1331
+ coords
1332
+ );
1333
+ if (handleNearby !== undefined) {
1334
+ return {
1335
+ handleNearby,
1336
+ toolIndex
1337
+ };
1338
+ }
1339
+ }
1340
+ }
1341
+
1342
+ /**
1343
+ * Gets the current mouse location and stores it in the configuration object.
1344
+ *
1345
+ * @private
1346
+ * @param {Object} eventData The data assoicated with the event.
1347
+ * @returns {undefined}
1348
+ */
1349
+ _getMouseLocation(eventData) {
1350
+ const { currentPoints, image } = eventData;
1351
+ // Set the mouseLocation handle
1352
+ const config = this.configuration;
1353
+
1354
+ config.mouseLocation.handles.start.x = currentPoints.image.x;
1355
+ config.mouseLocation.handles.start.y = currentPoints.image.y;
1356
+ clipToBox(config.mouseLocation.handles.start, image);
1357
+ }
1358
+
1359
+ /**
1360
+ * Returns true if the proposed location of a new handle is invalid.
1361
+ *
1362
+ * @private
1363
+ * @param {Object} data Data object associated with the tool.
1364
+ * @param {Object} eventData The data assoicated with the event.
1365
+ * @returns {Boolean}
1366
+ */
1367
+ _checkInvalidHandleLocation(data, eventData) {
1368
+ if (data.handles.points.length &lt; 2) {
1369
+ return true;
1370
+ }
1371
+
1372
+ let invalidHandlePlacement;
1373
+
1374
+ if (this._dragging) {
1375
+ invalidHandlePlacement = this._checkHandlesPencilMode(data, eventData);
1376
+ } else {
1377
+ invalidHandlePlacement = this._checkHandlesPolygonMode(data, eventData);
1378
+ }
1379
+
1380
+ data.handles.invalidHandlePlacement = invalidHandlePlacement;
1381
+ }
1382
+
1383
+ /**
1384
+ * Returns true if the proposed location of a new handle is invalid (in polygon mode).
1385
+ *
1386
+ * @private
1387
+ *
1388
+ * @param {Object} data - data object associated with the tool.
1389
+ * @param {Object} eventData The data assoicated with the event.
1390
+ * @returns {Boolean}
1391
+ */
1392
+ _checkHandlesPolygonMode(data, eventData) {
1393
+ const config = this.configuration;
1394
+ const { element } = eventData;
1395
+ const mousePoint = config.mouseLocation.handles.start;
1396
+ const points = data.handles.points;
1397
+ let invalidHandlePlacement = false;
1398
+
1399
+ data.canComplete = false;
1400
+
1401
+ const mouseAtOriginHandle =
1402
+ this._isDistanceSmallerThanCompleteSpacingCanvas(
1403
+ element,
1404
+ points[0],
1405
+ mousePoint
1406
+ );
1407
+
1408
+ if (
1409
+ mouseAtOriginHandle &amp;&amp;
1410
+ !freehandIntersect.end(points) &amp;&amp;
1411
+ points.length > 2
1412
+ ) {
1413
+ data.canComplete = true;
1414
+ invalidHandlePlacement = false;
1415
+ } else {
1416
+ invalidHandlePlacement = freehandIntersect.newHandle(mousePoint, points);
1417
+ }
1418
+
1419
+ return invalidHandlePlacement;
1420
+ }
1421
+
1422
+ /**
1423
+ * Returns true if the proposed location of a new handle is invalid (in pencilMode).
1424
+ *
1425
+ * @private
1426
+ * @param {Object} data - data object associated with the tool.
1427
+ * @param {Object} eventData The data associated with the event.
1428
+ * @returns {Boolean}
1429
+ */
1430
+ _checkHandlesPencilMode(data, eventData) {
1431
+ const config = this.configuration;
1432
+ const mousePoint = config.mouseLocation.handles.start;
1433
+ const points = data.handles.points;
1434
+ let invalidHandlePlacement = freehandIntersect.newHandle(
1435
+ mousePoint,
1436
+ points
1437
+ );
1438
+
1439
+ if (invalidHandlePlacement === false) {
1440
+ invalidHandlePlacement = this._invalidHandlePencilMode(data, eventData);
1441
+ }
1442
+
1443
+ return invalidHandlePlacement;
1444
+ }
1445
+
1446
+ /**
1447
+ * Returns true if the mouse position is far enough from previous points (in pencilMode).
1448
+ *
1449
+ * @private
1450
+ * @param {Object} data - data object associated with the tool.
1451
+ * @param {Object} eventData The data associated with the event.
1452
+ * @returns {Boolean}
1453
+ */
1454
+ _invalidHandlePencilMode(data, eventData) {
1455
+ const config = this.configuration;
1456
+ const { element } = eventData;
1457
+ const mousePoint = config.mouseLocation.handles.start;
1458
+ const points = data.handles.points;
1459
+
1460
+ const mouseAtOriginHandle =
1461
+ this._isDistanceSmallerThanCompleteSpacingCanvas(
1462
+ element,
1463
+ points[0],
1464
+ mousePoint
1465
+ );
1466
+
1467
+ if (mouseAtOriginHandle) {
1468
+ data.canComplete = true;
1469
+
1470
+ return false;
1471
+ }
1472
+
1473
+ data.canComplete = false;
1474
+
1475
+ // Compare with all other handles appart from the last one
1476
+ for (let i = 1; i &lt; points.length - 1; i++) {
1477
+ if (this._isDistanceSmallerThanSpacing(element, points[i], mousePoint)) {
1478
+ return true;
1479
+ }
1480
+ }
1481
+
1482
+ return false;
1483
+ }
1484
+
1485
+ /**
1486
+ * Returns true if two points are closer than this.configuration.spacing.
1487
+ *
1488
+ * @private
1489
+ * @param {Object} element The element on which the roi is being drawn.
1490
+ * @param {Object} p1 The first point, in pixel space.
1491
+ * @param {Object} p2 The second point, in pixel space.
1492
+ * @returns {boolean} True if the distance is smaller than the
1493
+ * allowed canvas spacing.
1494
+ */
1495
+ _isDistanceSmallerThanCompleteSpacingCanvas(element, p1, p2) {
1496
+ const p1Canvas = external.cornerstone.pixelToCanvas(element, p1);
1497
+ const p2Canvas = external.cornerstone.pixelToCanvas(element, p2);
1498
+
1499
+ let completeHandleRadius;
1500
+
1501
+ if (this._drawingInteractionType === "Mouse") {
1502
+ completeHandleRadius = this.configuration.completeHandleRadius;
1503
+ } else if (this._drawingInteractionType === "Touch") {
1504
+ completeHandleRadius = this.configuration.completeHandleRadiusTouch;
1505
+ }
1506
+
1507
+ return this._compareDistanceToSpacing(
1508
+ element,
1509
+ p1Canvas,
1510
+ p2Canvas,
1511
+ "&lt;",
1512
+ completeHandleRadius
1513
+ );
1514
+ }
1515
+
1516
+ /**
1517
+ * Returns true if two points are closer than this.configuration.spacing.
1518
+ *
1519
+ * @private
1520
+ * @param {Object} element The element on which the roi is being drawn.
1521
+ * @param {Object} p1 The first point, in pixel space.
1522
+ * @param {Object} p2 The second point, in pixel space.
1523
+ * @returns {boolean} True if the distance is smaller than the
1524
+ * allowed canvas spacing.
1525
+ */
1526
+ _isDistanceSmallerThanSpacing(element, p1, p2) {
1527
+ return this._compareDistanceToSpacing(element, p1, p2, "&lt;");
1528
+ }
1529
+
1530
+ /**
1531
+ * Returns true if two points are farther than this.configuration.spacing.
1532
+ *
1533
+ * @private
1534
+ * @param {Object} element The element on which the roi is being drawn.
1535
+ * @param {Object} p1 The first point, in pixel space.
1536
+ * @param {Object} p2 The second point, in pixel space.
1537
+ * @returns {boolean} True if the distance is smaller than the
1538
+ * allowed canvas spacing.
1539
+ */
1540
+ _isDistanceLargerThanSpacing(element, p1, p2) {
1541
+ return this._compareDistanceToSpacing(element, p1, p2, ">");
1542
+ }
1543
+
1544
+ /**
1545
+ * Compares the distance between two points to this.configuration.spacing.
1546
+ *
1547
+ * @private
1548
+ * @param {Object} element The element on which the roi is being drawn.
1549
+ * @param {Object} p1 The first point, in pixel space.
1550
+ * @param {Object} p2 The second point, in pixel space.
1551
+ * @param {string} comparison The comparison to make.
1552
+ * @param {number} spacing The allowed canvas spacing
1553
+ * @returns {boolean} True if the distance is smaller than the
1554
+ * allowed canvas spacing.
1555
+ */
1556
+ _compareDistanceToSpacing(
1557
+ element,
1558
+ p1,
1559
+ p2,
1560
+ comparison = ">",
1561
+ spacing = this.configuration.spacing
1562
+ ) {
1563
+ if (comparison === ">") {
1564
+ return external.cornerstoneMath.point.distance(p1, p2) > spacing;
1565
+ }
1566
+
1567
+ return external.cornerstoneMath.point.distance(p1, p2) &lt; spacing;
1568
+ }
1569
+
1570
+ /**
1571
+ * Adds drawing loop event listeners.
1572
+ *
1573
+ * @private
1574
+ * @param {Object} element - The viewport element to add event listeners to.
1575
+ * @param {string} interactionType - The interactionType used for the loop.
1576
+ * @modifies {element}
1577
+ * @returns {undefined}
1578
+ */
1579
+ _activateDraw(element, interactionType = "Mouse") {
1580
+ this._drawing = true;
1581
+ this._drawingInteractionType = interactionType;
1582
+
1583
+ state.isMultiPartToolActive = true;
1584
+ // hideToolCursor(this.element);
1585
+
1586
+ // Polygonal Mode
1587
+ element.addEventListener(EVENTS.MOUSE_DOWN, this._drawingMouseDownCallback);
1588
+ element.addEventListener(EVENTS.MOUSE_MOVE, this._drawingMouseMoveCallback);
1589
+ element.addEventListener(
1590
+ EVENTS.MOUSE_DOUBLE_CLICK,
1591
+ this._drawingMouseDoubleClickCallback
1592
+ );
1593
+
1594
+ // Drag/Pencil Mode
1595
+ element.addEventListener(EVENTS.MOUSE_DRAG, this._drawingMouseDragCallback);
1596
+ element.addEventListener(EVENTS.MOUSE_UP, this._drawingMouseUpCallback);
1597
+
1598
+ // Touch
1599
+ element.addEventListener(
1600
+ EVENTS.TOUCH_START,
1601
+ this._drawingMouseMoveCallback
1602
+ );
1603
+ element.addEventListener(
1604
+ EVENTS.TOUCH_START,
1605
+ this._drawingTouchStartCallback
1606
+ );
1607
+
1608
+ element.addEventListener(EVENTS.TOUCH_DRAG, this._drawingTouchDragCallback);
1609
+ element.addEventListener(EVENTS.TOUCH_END, this._drawingMouseUpCallback);
1610
+ element.addEventListener(
1611
+ EVENTS.DOUBLE_TAP,
1612
+ this._drawingDoubleTapClickCallback
1613
+ );
1614
+
1615
+ external.cornerstone.updateImage(element);
1616
+ }
1617
+
1618
+ /**
1619
+ * Removes drawing loop event listeners.
1620
+ *
1621
+ * @private
1622
+ * @param {Object} element - The viewport element to add event listeners to.
1623
+ * @modifies {element}
1624
+ * @returns {undefined}
1625
+ */
1626
+ _deactivateDraw(element) {
1627
+ this._drawing = false;
1628
+ state.isMultiPartToolActive = false;
1629
+ this._activeDrawingToolReference = null;
1630
+ this._drawingInteractionType = null;
1631
+ // setToolCursor(this.element, this.svgCursor);
1632
+
1633
+ element.removeEventListener(
1634
+ EVENTS.MOUSE_DOWN,
1635
+ this._drawingMouseDownCallback
1636
+ );
1637
+ element.removeEventListener(
1638
+ EVENTS.MOUSE_MOVE,
1639
+ this._drawingMouseMoveCallback
1640
+ );
1641
+ element.removeEventListener(
1642
+ EVENTS.MOUSE_DOUBLE_CLICK,
1643
+ this._drawingMouseDoubleClickCallback
1644
+ );
1645
+ element.removeEventListener(
1646
+ EVENTS.MOUSE_DRAG,
1647
+ this._drawingMouseDragCallback
1648
+ );
1649
+ element.removeEventListener(EVENTS.MOUSE_UP, this._drawingMouseUpCallback);
1650
+
1651
+ // Touch
1652
+ element.removeEventListener(
1653
+ EVENTS.TOUCH_START,
1654
+ this._drawingTouchStartCallback
1655
+ );
1656
+ element.removeEventListener(
1657
+ EVENTS.TOUCH_DRAG,
1658
+ this._drawingTouchDragCallback
1659
+ );
1660
+ element.removeEventListener(
1661
+ EVENTS.TOUCH_START,
1662
+ this._drawingMouseMoveCallback
1663
+ );
1664
+ element.removeEventListener(EVENTS.TOUCH_END, this._drawingMouseUpCallback);
1665
+
1666
+ external.cornerstone.updateImage(element);
1667
+ }
1668
+
1669
+ /**
1670
+ * Adds modify loop event listeners.
1671
+ *
1672
+ * @private
1673
+ * @param {Object} element - The viewport element to add event listeners to.
1674
+ * @modifies {element}
1675
+ * @returns {undefined}
1676
+ */
1677
+ _activateModify(element) {
1678
+ state.isToolLocked = true;
1679
+
1680
+ element.addEventListener(EVENTS.MOUSE_UP, this._editMouseUpCallback);
1681
+ element.addEventListener(EVENTS.MOUSE_DRAG, this._editMouseDragCallback);
1682
+ element.addEventListener(EVENTS.MOUSE_CLICK, this._editMouseUpCallback);
1683
+
1684
+ element.addEventListener(EVENTS.TOUCH_END, this._editMouseUpCallback);
1685
+ element.addEventListener(EVENTS.TOUCH_DRAG, this._editTouchDragCallback);
1686
+
1687
+ external.cornerstone.updateImage(element);
1688
+ }
1689
+
1690
+ /**
1691
+ * Removes modify loop event listeners.
1692
+ *
1693
+ * @private
1694
+ * @param {Object} element - The viewport element to add event listeners to.
1695
+ * @modifies {element}
1696
+ * @returns {undefined}
1697
+ */
1698
+ _deactivateModify(element) {
1699
+ state.isToolLocked = false;
1700
+
1701
+ element.removeEventListener(EVENTS.MOUSE_UP, this._editMouseUpCallback);
1702
+ element.removeEventListener(EVENTS.MOUSE_DRAG, this._editMouseDragCallback);
1703
+ element.removeEventListener(EVENTS.MOUSE_CLICK, this._editMouseUpCallback);
1704
+
1705
+ element.removeEventListener(EVENTS.TOUCH_END, this._editMouseUpCallback);
1706
+ element.removeEventListener(EVENTS.TOUCH_DRAG, this._editTouchDragCallback);
1707
+
1708
+ external.cornerstone.updateImage(element);
1709
+ }
1710
+
1711
+ passiveCallback(element) {
1712
+ this._closeToolIfDrawing(element);
1713
+ }
1714
+
1715
+ enabledCallback(element) {
1716
+ this._closeToolIfDrawing(element);
1717
+ }
1718
+
1719
+ disabledCallback(element) {
1720
+ this._closeToolIfDrawing(element);
1721
+ }
1722
+
1723
+ _closeToolIfDrawing(element) {
1724
+ if (this._drawing) {
1725
+ // Actively drawing but changed mode.
1726
+ const config = this.configuration;
1727
+ const lastHandlePlaced = config.currentHandle;
1728
+
1729
+ this._endDrawing(element, lastHandlePlaced);
1730
+ external.cornerstone.updateImage(element);
1731
+ }
1732
+ }
1733
+
1734
+ /**
1735
+ * Fire MEASUREMENT_MODIFIED event on provided element
1736
+ * @param {any} element which freehand data has been modified
1737
+ * @param {any} measurementData the measurment data
1738
+ * @returns {void}
1739
+ */
1740
+ fireModifiedEvent(element, measurementData) {
1741
+ const eventType = EVENTS.MEASUREMENT_MODIFIED;
1742
+ const eventData = {
1743
+ toolName: this.name,
1744
+ element,
1745
+ measurementData
1746
+ };
1747
+
1748
+ triggerEvent(element, eventType, eventData);
1749
+ }
1750
+
1751
+ fireCompletedEvent(element, measurementData) {
1752
+ const eventType = EVENTS.MEASUREMENT_COMPLETED;
1753
+ const eventData = {
1754
+ toolName: this.name,
1755
+ element,
1756
+ measurementData
1757
+ };
1758
+
1759
+ triggerEvent(element, eventType, eventData);
1760
+ }
1761
+
1762
+ // ===================================================================
1763
+ // Public Configuration API. .
1764
+ // ===================================================================
1765
+
1766
+ get spacing() {
1767
+ return this.configuration.spacing;
1768
+ }
1769
+
1770
+ set spacing(value) {
1771
+ if (typeof value !== "number") {
1772
+ throw new Error(
1773
+ "Attempting to set freehand spacing to a value other than a number."
1774
+ );
1775
+ }
1776
+
1777
+ this.configuration.spacing = value;
1778
+ external.cornerstone.updateImage(this.element);
1779
+ }
1780
+
1781
+ get activeHandleRadius() {
1782
+ return this.configuration.activeHandleRadius;
1783
+ }
1784
+
1785
+ set activeHandleRadius(value) {
1786
+ if (typeof value !== "number") {
1787
+ throw new Error(
1788
+ "Attempting to set freehand activeHandleRadius to a value other than a number."
1789
+ );
1790
+ }
1791
+
1792
+ this.configuration.activeHandleRadius = value;
1793
+ external.cornerstone.updateImage(this.element);
1794
+ }
1795
+
1796
+ get completeHandleRadius() {
1797
+ return this.configuration.completeHandleRadius;
1798
+ }
1799
+
1800
+ set completeHandleRadius(value) {
1801
+ if (typeof value !== "number") {
1802
+ throw new Error(
1803
+ "Attempting to set freehand completeHandleRadius to a value other than a number."
1804
+ );
1805
+ }
1806
+
1807
+ this.configuration.completeHandleRadius = value;
1808
+ external.cornerstone.updateImage(this.element);
1809
+ }
1810
+
1811
+ get alwaysShowHandles() {
1812
+ return this.configuration.alwaysShowHandles;
1813
+ }
1814
+
1815
+ set alwaysShowHandles(value) {
1816
+ if (typeof value !== "boolean") {
1817
+ throw new Error(
1818
+ "Attempting to set freehand alwaysShowHandles to a value other than a boolean."
1819
+ );
1820
+ }
1821
+
1822
+ this.configuration.alwaysShowHandles = value;
1823
+ external.cornerstone.updateImage(this.element);
1824
+ }
1825
+
1826
+ get invalidColor() {
1827
+ return this.configuration.invalidColor;
1828
+ }
1829
+
1830
+ set invalidColor(value) {
1831
+ /*
1832
+ It'd be easy to check if the color was e.g. a valid rgba color. However
1833
+ it'd be difficult to check if the color was a named CSS color without
1834
+ bloating the library, so we don't. If the canvas can't intepret the color
1835
+ it'll show up grey.
1836
+ */
1837
+
1838
+ this.configuration.invalidColor = value;
1839
+ external.cornerstone.updateImage(this.element);
1840
+ }
1841
+
1842
+ /**
1843
+ * Ends the active drawing loop and removes the polygon.
1844
+ *
1845
+ * @public
1846
+ * @param {Object} element - The element on which the roi is being drawn.
1847
+ * @returns {null}
1848
+ */
1849
+ cancelDrawing(element) {
1850
+ if (!this._drawing) {
1851
+ return;
1852
+ }
1853
+ const toolState = getToolState(element, this.name);
1854
+
1855
+ const config = this.configuration;
1856
+
1857
+ const data = toolState.data[config.currentTool];
1858
+
1859
+ data.active = false;
1860
+ data.highlight = false;
1861
+ data.handles.invalidHandlePlacement = false;
1862
+
1863
+ // Reset the current handle
1864
+ config.currentHandle = 0;
1865
+ config.currentTool = -1;
1866
+ data.canComplete = false;
1867
+
1868
+ removeToolState(element, this.name, data);
1869
+
1870
+ this._deactivateDraw(element);
1871
+
1872
+ external.cornerstone.updateImage(element);
1873
+ }
1874
+
1875
+ /**
1876
+ * New image event handler.
1877
+ *
1878
+ * @public
1879
+ * @param {Object} evt The event.
1880
+ * @returns {null}
1881
+ */
1882
+ newImageCallback(evt) {
1883
+ const config = this.configuration;
1884
+
1885
+ if (!(this._drawing &amp;&amp; this._activeDrawingToolReference)) {
1886
+ return;
1887
+ }
1888
+
1889
+ // Actively drawing but scrolled to different image.
1890
+
1891
+ const element = evt.detail.element;
1892
+ const data = this._activeDrawingToolReference;
1893
+
1894
+ data.active = false;
1895
+ data.highlight = false;
1896
+ data.handles.invalidHandlePlacement = false;
1897
+
1898
+ // Connect the end handle to the origin handle
1899
+ const points = data.handles.points;
1900
+
1901
+ points[config.currentHandle - 1].lines.push(points[0]);
1902
+
1903
+ // Reset the current handle
1904
+ config.currentHandle = 0;
1905
+ config.currentTool = -1;
1906
+ data.canComplete = false;
1907
+
1908
+ this._deactivateDraw(element);
1909
+
1910
+ external.cornerstone.updateImage(element);
1911
+ }
1912
+ }
1913
+
1914
+ function defaultFreehandConfiguration() {
1915
+ return {
1916
+ mouseLocation: {
1917
+ handles: {
1918
+ start: {
1919
+ highlight: false,
1920
+ active: false
1921
+ }
1922
+ }
1923
+ },
1924
+ spacing: 1,
1925
+ activeHandleRadius: 3,
1926
+ completeHandleRadius: 6,
1927
+ completeHandleRadiusTouch: 28,
1928
+ alwaysShowHandles: false,
1929
+ invalidColor: "#FFFF00",
1930
+ currentHandle: 0,
1931
+ currentTool: -1
1932
+ };
1933
+ }
1934
+
1935
+ function preventPropagation(evt) {
1936
+ evt.stopImmediatePropagation();
1937
+ evt.stopPropagation();
1938
+ evt.preventDefault();
1939
+ }
1940
+ </code></pre>
1941
+ </article>
1942
+ </section>
1943
+
1944
+
1945
+
1946
+
1947
+
1948
+
1949
+ </div>
1950
+
1951
+ <br class="clear">
1952
+
1953
+ <footer>
1954
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.7</a> using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
1955
+ </footer>
1956
+
1957
+ <script>prettyPrint();</script>
1958
+ <script src="scripts/polyfill.js"></script>
1959
+ <script src="scripts/linenumber.js"></script>
1960
+
1961
+ <script src="scripts/search.js" defer></script>
1962
+
1963
+
1964
+ <script src="scripts/collapse.js" defer></script>
1965
+
1966
+
1967
+ </body>
1968
+ </html>