larvitar 1.3.4 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,11 +6,9 @@
6
6
 
7
7
  ## Dicom Image Toolkit for CornerstoneJS
8
8
 
9
- ### Current version: 1.3.4
9
+ ### Current version: 1.4.1
10
10
 
11
- ### Latest Stable version: 1.3.4
12
-
13
- ### Latest Published Release: 1.3.4
11
+ ### Latest Published Release: 1.4.1
14
12
 
15
13
  This library provides common DICOM functionalities to be used in web-applications: it's wrapper that simplifies the use of cornerstone-js environment.
16
14
  Orthogonal multiplanar reformat is included as well as custom loader/exporter for nrrd files and [Vuex](https://vuex.vuejs.org/) custom integration.
@@ -90,3 +88,9 @@ Full documentation and examples are available at http://www.dvisionlab.com/Larvi
90
88
  # Build package
91
89
 
92
90
  `yarn build-lib`
91
+
92
+ # Development
93
+
94
+ Use `yarn dev-lib` to have `rollup` hot-reload (live recompiling the library).
95
+ In order to test functionalities you can modify the library import path in an example (see the `docs/examples` folder) to use the recompiled bundle in `dist/`, then serve the .html file with VSCode extension [LiveServer](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) or other similar tools.
96
+ Once you are done, upgrade the version, build the library and copy it to the `docs/examples` folder. This file must be included into the commit, while docs will be compiled by the Github action.
@@ -78,11 +78,10 @@ export const readFile = function (entry) {
78
78
  * @instance
79
79
  * @function parseDataSet
80
80
  * @param {Object} dataSet - dicom parser dataSet object
81
- * @param {Array} metadata - Initialized metadata object
81
+ * @param {Object} metadata - Initialized metadata object
82
82
  * @param {Array} customFilter - Optional filter: {tags:[], frameId: 0}
83
83
  */
84
- // This function iterates through dataSet recursively and adds new HTML strings
85
- // to the output array passed into it
84
+ // This function iterates through dataSet recursively and store tag values into metadata object
86
85
  export const parseDataSet = function (dataSet, metadata, customFilter) {
87
86
  // customFilter= {tags:[], frameId:xxx}
88
87
  // the dataSet.elements object contains properties for each element parsed. The name of the property
@@ -113,7 +112,18 @@ export const parseDataSet = function (dataSet, metadata, customFilter) {
113
112
  }
114
113
  } else {
115
114
  let tagValue = parseTag(dataSet, propertyName, element);
116
- metadata[propertyName] = tagValue;
115
+
116
+ // identify duplicated tags (keep the first occurency and store the others in another tag eg x00280010_uuid)
117
+ if (metadata[propertyName] !== undefined) {
118
+ console.debug(
119
+ `Identified duplicated tag "${propertyName}", values are:`,
120
+ metadata[propertyName],
121
+ tagValue
122
+ );
123
+ metadata[propertyName + "_" + uuidv4()] = tagValue;
124
+ } else {
125
+ metadata[propertyName] = tagValue;
126
+ }
117
127
  }
118
128
  }
119
129
  } catch (err) {
@@ -1,6 +1,9 @@
1
1
  /** @module imaging/imageTools
2
2
  * @desc This file provides functionalities for
3
3
  * interacting with cornerstone tools
4
+ * DEPRECATION WARNING: these are legacy functions
5
+ * that will be removed soon. Use the corresponding
6
+ * functions in /tools/main.js instead.
4
7
  */
5
8
 
6
9
  // external libraries
@@ -277,6 +280,7 @@ export const clearMeasurements = function () {
277
280
  * @param {Object} options - The custom options. @default from tools/default.js
278
281
  * @param {String} activeViewport - The active viewport (if "all", viewports array will be used)
279
282
  * @param {Array} viewports - The hmtl element id to be used for tool initialization.
283
+ * @deprecated (OBSOLETE)
280
284
  */
281
285
  export const setToolActive = function (
282
286
  toolName,
@@ -304,10 +308,11 @@ export const setToolActive = function (
304
308
 
305
309
  /**
306
310
  * Set Tool "disabled" on all elements (ie, not rendered) & refresh cornerstone elements
307
- * @function setToolActive
311
+ * @function setToolDisabled
308
312
  * @param {String} toolName - The tool name.
309
313
  * @param {String} activeViewport - The active viewport (if "all", viewports array will be used)
310
314
  * @param {Array} viewports - The hmtl element id to be used for tool initialization.
315
+ * @deprecated (OBSOLETE)
311
316
  */
312
317
  export const setToolDisabled = function (toolName, activeViewport, viewports) {
313
318
  cornerstoneTools.setToolDisabled(toolName);
@@ -332,6 +337,7 @@ export const setToolDisabled = function (toolName, activeViewport, viewports) {
332
337
  * @param {String} toolName - The tool name.
333
338
  * @param {String} activeViewport - The active viewport (if "all", viewports array will be used)
334
339
  * @param {Array} viewports - The hmtl element id to be used for tool initialization.
340
+ * @deprecated (OBSOLETE)
335
341
  */
336
342
  export const setToolEnabled = function (toolName, activeViewport, viewports) {
337
343
  cornerstoneTools.setToolEnabled(toolName);
@@ -356,6 +362,7 @@ export const setToolEnabled = function (toolName, activeViewport, viewports) {
356
362
  * @param {String} toolName - The tool name.
357
363
  * @param {String} activeViewport - The active viewport (if "all", viewports array will be used)
358
364
  * @param {Array} viewports - The hmtl element id to be used for tool initialization.
365
+ * @deprecated (OBSOLETE)
359
366
  */
360
367
  export const setToolPassive = function (toolName, activeViewport, viewports) {
361
368
  cornerstoneTools.setToolPassive(toolName);
@@ -6,6 +6,8 @@
6
6
  // external libraries
7
7
  import { throttle } from "lodash";
8
8
  import * as keyCodes from "keycode-js";
9
+ import cornerstone from "cornerstone-core";
10
+ import cornerstoneTools from "cornerstone-tools/dist/cornerstoneTools.js";
9
11
 
10
12
  // internal libraries
11
13
  import { DEFAULT_MOUSE_KEYS } from "./default";
@@ -22,27 +24,46 @@ import { updateViewportData } from "../imageRendering";
22
24
  */
23
25
 
24
26
  /**
25
- * Setup mouse handler modifiers and keyboard shortcuts
26
- * NOTE: at the moment only mouse right button is affected
27
+ * Global event callbacks
28
+ */
29
+ let onKeyDownFn = null;
30
+ let onKeyUpFn = null;
31
+
32
+ /**
33
+ * Setup mouse handler modifiers and keyboard shortcuts:
34
+ * register a tool on right button and another one
35
+ * when pressing a modifier (ctrl/shift/alt) + right button
36
+ * The activation take place on all active viewports (we added a check to activate only on viewports
37
+ * in which the tool has been added previously)
27
38
  * Improvements could be:
28
39
  * - "restore previous active tool" instead of passed "default" tool
29
40
  * - manage left button (an idea could be to cycle over object keys for both buttons)
30
41
  * - possibility to change modifier keys
31
42
  * @param {Object} config - see tools/default
32
- * @param {Array} viewports - The hmtl element ids to be used for tool activation.
33
43
  */
34
44
 
35
- export function addMouseKeyHandlers(config, viewports) {
45
+ export function addMouseKeyHandlers(config) {
36
46
  if (!config) {
37
47
  config = DEFAULT_MOUSE_KEYS;
38
48
  }
39
49
 
50
+ if (onKeyDownFn) {
51
+ document.removeEventListener("keydown", onKeyDownFn);
52
+ }
53
+ if (onKeyUpFn) {
54
+ document.removeEventListener("keyup", onKeyUpFn);
55
+ }
56
+
40
57
  // Prevent context menu on right click
41
58
  document.addEventListener("contextmenu", evt => {
42
59
  evt.preventDefault();
43
60
  return false;
44
61
  });
45
62
 
63
+ // get all enabled viewports. Then, filter only viewport in which the target tool had been added previously.
64
+ let allViewports = cornerstone.getEnabledElements().map(enel => enel.element);
65
+
66
+ // Define behaviour on key down: activate registered tool
46
67
  function onKeyDown(evt) {
47
68
  // keyboard shortcuts (activate on left mouse button)
48
69
  let codes = config.keyboard_shortcuts
@@ -56,10 +77,16 @@ export function addMouseKeyHandlers(config, viewports) {
56
77
  .filter(key => keyCodes[key] == evt.keyCode)
57
78
  .pop();
58
79
  if (config.debug) console.log("active", config.keyboard_shortcuts[key]);
80
+ const viewports = allViewports.filter(viewport =>
81
+ cornerstoneTools.getToolForElement(
82
+ viewport,
83
+ config.keyboard_shortcuts[key]
84
+ )
85
+ );
59
86
  setToolActive(
60
87
  config.keyboard_shortcuts[key],
61
88
  { mouseButtonMask: 1 },
62
- viewports
89
+ viewports.map(v => v.id)
63
90
  );
64
91
  document.addEventListener("keydown", onKeyDown, { once: true });
65
92
  }
@@ -70,10 +97,17 @@ export function addMouseKeyHandlers(config, viewports) {
70
97
  evt.keyCode == keyCodes.KEY_SHIFT
71
98
  ) {
72
99
  if (config.debug) console.log("active", config.mouse_button_right.shift);
100
+ const viewports = allViewports.filter(viewport =>
101
+ cornerstoneTools.getToolForElement(
102
+ viewport,
103
+ config.mouse_button_right.shift
104
+ )
105
+ );
106
+
73
107
  setToolActive(
74
108
  config.mouse_button_right.shift,
75
109
  { mouseButtonMask: 2 },
76
- viewports
110
+ viewports.map(v => v.id)
77
111
  );
78
112
  document.addEventListener("keyup", onKeyUp, { once: true });
79
113
  }
@@ -84,10 +118,17 @@ export function addMouseKeyHandlers(config, viewports) {
84
118
  evt.keyCode == keyCodes.KEY_CONTROL
85
119
  ) {
86
120
  if (config.debug) console.log("active", config.mouse_button_right.ctrl);
121
+ const viewports = allViewports.filter(viewport =>
122
+ cornerstoneTools.getToolForElement(
123
+ viewport,
124
+ config.mouse_button_right.ctrl
125
+ )
126
+ );
127
+
87
128
  setToolActive(
88
129
  config.mouse_button_right.ctrl,
89
130
  { mouseButtonMask: 2 },
90
- viewports
131
+ viewports.map(v => v.id)
91
132
  );
92
133
  document.addEventListener("keyup", onKeyUp, { once: true });
93
134
  }
@@ -98,36 +139,67 @@ export function addMouseKeyHandlers(config, viewports) {
98
139
  }
99
140
  }
100
141
 
142
+ // Define behaviour on key up: restore original tool
101
143
  function onKeyUp(e) {
102
144
  if (config.debug)
103
145
  console.log("active default", config.mouse_button_right.default);
146
+ const viewports = allViewports.filter(viewport =>
147
+ cornerstoneTools.getToolForElement(
148
+ viewport,
149
+ config.mouse_button_right.default
150
+ )
151
+ );
104
152
  setToolActive(
105
153
  config.mouse_button_right.default,
106
154
  { mouseButtonMask: 2 },
107
- viewports
155
+ viewports.map(v => v.id)
108
156
  );
109
157
  document.addEventListener("keydown", onKeyDown, { once: true });
110
158
  }
111
159
 
112
- // activate default, if any
113
-
160
+ // activate default on mouse right, if any
114
161
  if (config.mouse_button_right && config.mouse_button_right.default) {
162
+ const viewports = allViewports.filter(viewport =>
163
+ cornerstoneTools.getToolForElement(
164
+ viewport,
165
+ config.mouse_button_right.default
166
+ )
167
+ );
115
168
  setToolActive(
116
169
  config.mouse_button_right.default,
117
170
  { mouseButtonMask: 2 },
118
- viewports
171
+ viewports.map(v => v.id)
119
172
  );
120
173
  }
121
174
 
175
+ // activate default on mouse left, if any
122
176
  if (config.mouse_button_left && config.mouse_button_left.default) {
177
+ const viewports = allViewports.filter(viewport =>
178
+ cornerstoneTools.getToolForElement(
179
+ viewport,
180
+ config.mouse_button_left.default
181
+ )
182
+ );
123
183
  setToolActive(
124
184
  config.mouse_button_left.default,
125
185
  { mouseButtonMask: 1 },
126
- viewports
186
+ viewports.map(v => v.id)
127
187
  );
128
188
  }
129
189
 
130
190
  document.addEventListener("keydown", onKeyDown, { once: true });
191
+
192
+ onKeyDownFn = onKeyDown;
193
+ onKeyUpFn = onKeyUp;
194
+ }
195
+
196
+ /**
197
+ *
198
+ */
199
+ export function removeMouseKeyHandlers() {
200
+ document.removeEventListener("keydown", onKeyDownFn);
201
+ onKeyDownFn = null;
202
+ onKeyUpFn = null;
131
203
  }
132
204
 
133
205
  /**
package/index.js CHANGED
@@ -205,6 +205,7 @@ import { saveAnnotations, loadAnnotations } from "./imaging/tools/io";
205
205
 
206
206
  import {
207
207
  addMouseKeyHandlers,
208
+ removeMouseKeyHandlers,
208
209
  toggleMouseToolsListeners
209
210
  } from "./imaging/tools/interaction";
210
211
 
@@ -367,6 +368,7 @@ export {
367
368
  loadAnnotations,
368
369
  // tools/interaction
369
370
  addMouseKeyHandlers,
371
+ removeMouseKeyHandlers,
370
372
  // tools/segmentation
371
373
  initSegmentationModule,
372
374
  addSegmentationMask,
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "medical",
7
7
  "cornerstone"
8
8
  ],
9
- "version": "1.3.4",
9
+ "version": "1.4.1",
10
10
  "description": "javascript library for parsing, loading, rendering and interacting with DICOM images",
11
11
  "repository": {
12
12
  "url": "https://github.com/dvisionlab/Larvitar.git",
@@ -54,4 +54,4 @@
54
54
  "module": "dist/larvitar.js",
55
55
  "browser": "dist/larvitar.js",
56
56
  "type": "module"
57
- }
57
+ }