larvitar 1.5.8 → 1.5.10

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,9 +6,8 @@
6
6
 
7
7
  ## Dicom Image Toolkit for CornerstoneJS
8
8
 
9
- ### Current version: 1.5.8
10
-
11
- ### Latest Published Release: 1.5.8
9
+ ### Current version: 1.5.10
10
+ ### Latest Published Release: 1.5.10
12
11
 
13
12
  This library provides common DICOM functionalities to be used in web-applications: it's wrapper that simplifies the use of cornerstone-js environment.
14
13
  Orthogonal multiplanar reformat is included as well as custom loader/exporter for nrrd files and [Vuex](https://vuex.vuejs.org/) custom integration.
@@ -40,6 +39,7 @@ Orthogonal multiplanar reformat is included as well as custom loader/exporter fo
40
39
  - `tools/custom/editMaskTool` is a custom cornerstone tool for 2D visualization of segmentation masks with brush functionalities
41
40
  - `tools/custom/seedTool` is a custom cornerstone tool for 2D interactive seeding with custom colors and labels
42
41
  - `tools/custom/thresholdsBrushTool` is a custom cornerstone tool for handling thresholds in a brush tool
42
+ - `tools/custom/Slice4DScrollMouseWheel` is a custom cornerstone tool for handling navigation of slices in a 4D DICOM series
43
43
  - `tools/default` default tools map and configuration
44
44
  - `tools/io` import and export functionalities for tools
45
45
  - `tools/main` tools main functionalities
@@ -3,6 +3,7 @@
3
3
  * for data config store.
4
4
  */
5
5
 
6
+ import { defineVue } from "../modules/vuex/larvitar";
6
7
  import larvitar from "../modules/vuex/larvitar";
7
8
 
8
9
  // external libraries
@@ -312,7 +313,7 @@ export function initLarvitarStore(vuexStore, vuexModule, registerModule, _Vue) {
312
313
  if (vuexStore) {
313
314
  larvitar_store = new Larvitar_Store(vuexStore, vuexModule);
314
315
  if (registerModule) {
315
- larvitar.defineVue(_Vue);
316
+ defineVue(_Vue);
316
317
  vuexStore.registerModule(vuexModule, larvitar);
317
318
  }
318
319
  } else {
@@ -0,0 +1,145 @@
1
+ /** @module imaging/tools/custom/4dSliceScrollTool
2
+ * @desc This file provides functionalities for an alternative scroll tool
3
+ * to handle 4d exam and navigate to the correct slice
4
+ *
5
+ *
6
+ */
7
+
8
+ // external libraries
9
+ import cornerstoneTools from "cornerstone-tools";
10
+ const external = cornerstoneTools.external;
11
+
12
+ const BaseTool = cornerstoneTools.importInternal("base/BaseTool");
13
+ const scroll = cornerstoneTools.importInternal("util/scroll");
14
+ const scrollToIndex = cornerstoneTools.importInternal("util/scrollToIndex");
15
+ const getToolState = cornerstoneTools.getToolState;
16
+ const clip = cornerstoneTools.importInternal("util/clip");
17
+
18
+ /**
19
+ * @public
20
+ * @class 4DScrollMouseWheelTool
21
+ * @memberof Tools
22
+ *
23
+ * @classdesc Tool for scrolling through a series using the mouse wheel.
24
+ * @extends Tools.Base.BaseTool
25
+ */
26
+ export default class Slice4DScrollMouseWheelTool extends BaseTool {
27
+ constructor(props = {}) {
28
+ const defaultProps = {
29
+ name: 'Slice4DScrollMouseWheel',
30
+ supportedInteractionTypes: ['MouseWheel'],
31
+ configuration: {
32
+ loop: false,
33
+ allowSkipping: true,
34
+ invert: false,
35
+ },
36
+ };
37
+ console.log('building wheel tool');
38
+ super(props, defaultProps);
39
+ }
40
+
41
+ mouseWheelCallback(evt) {
42
+ const { direction: images, element } = evt.detail;
43
+ const { loop, allowSkipping, invert, framesNumber } = this.configuration;
44
+ const direction = invert ? (images * framesNumber)*(-1) : (images * framesNumber);
45
+ console.log('wheel callback');
46
+ console.log('Images ', images);
47
+ console.log('Direction ', direction);
48
+ scroll(element, direction, loop, allowSkipping);
49
+ // scroll4DSlices(element, direction, loop, allowSkipping);
50
+ }
51
+ }
52
+ /**
53
+ * Scrolls through the slice of a 4D stack.
54
+ * @export @public @method
55
+ * @name scroll4DSlices
56
+ *
57
+ * @param {HTMLElement} element The element to scroll.
58
+ * @param {number} images The number of images to scroll through.
59
+ * @param {type} [loop = false] Whether to loop the scrolling.
60
+ * @param {type} [allowSkipping = true] Whether frames can be skipped.
61
+ * @returns {void}
62
+ */
63
+ const scroll4DSlices = function(element, images, loop, allowSkipping, framesNumber) {
64
+ const toolData = getToolState(element, 'stack');
65
+
66
+ if (!toolData || !toolData.data || !toolData.data.length) {
67
+ return;
68
+ }
69
+
70
+ const stackData = toolData.data[0];
71
+
72
+ if (!stackData.pending) {
73
+ stackData.pending = [];
74
+ }
75
+
76
+ let newImageIdIndex = stackData.currentImageIdIndex + images ;//+ 1 + framesNumber;
77
+ console.log('currentImageIdIndex', stackData.currentImageIdIndex)
78
+ console.log('newImageIdIndex calculated ', newImageIdIndex);
79
+ if (loop) {
80
+ const nbImages = stackData.imageIds.length;
81
+ newImageIdIndex %= nbImages;
82
+ } else {
83
+ newImageIdIndex = clip(newImageIdIndex, 0, stackData.imageIds.length - 1);
84
+ console.log('newImageIdIndex after clip ', newImageIdIndex);
85
+ }
86
+
87
+ if (allowSkipping) {
88
+ scrollToIndex(element, newImageIdIndex);
89
+ } else {
90
+ const pendingEvent = {
91
+ index: newImageIdIndex,
92
+ };
93
+
94
+ stackData.pending.push(pendingEvent);
95
+ scrollWithoutSkipping(stackData, pendingEvent, element);
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Recursively scrolls the stack until the desired image is reached.
101
+ * @private
102
+ * @method
103
+ * @name scrollWithoutSkipping
104
+ *
105
+ * @param {type} stackData Data object containing information about the stack.
106
+ * @param {Object} pendingEvent The event to process next.
107
+ * @param {HTMLElement} element The element being scrolled through.
108
+ * @returns {void}
109
+ */
110
+ function scrollWithoutSkipping(stackData, pendingEvent, element) {
111
+ if (stackData.pending[0] === pendingEvent) {
112
+ if (stackData.currentImageIdIndex === pendingEvent.index) {
113
+ stackData.pending.splice(stackData.pending.indexOf(pendingEvent), 1);
114
+
115
+ if (stackData.pending.length > 0) {
116
+ scrollWithoutSkipping(stackData, stackData.pending[0], element);
117
+ }
118
+
119
+ return;
120
+ }
121
+
122
+ const newImageHandler = function(event) {
123
+ const index = stackData.imageIds.indexOf(event.detail.image.imageId);
124
+
125
+ if (index === pendingEvent.index) {
126
+ stackData.pending.splice(stackData.pending.indexOf(pendingEvent), 1);
127
+ element.removeEventListener(
128
+ external.cornerstone.EVENTS.NEW_IMAGE,
129
+ newImageHandler
130
+ );
131
+
132
+ if (stackData.pending.length > 0) {
133
+ scrollWithoutSkipping(stackData, stackData.pending[0], element);
134
+ }
135
+ }
136
+ };
137
+
138
+ element.addEventListener(
139
+ external.cornerstone.EVENTS.NEW_IMAGE,
140
+ newImageHandler
141
+ );
142
+
143
+ scrollToIndex(element, pendingEvent.index);
144
+ }
145
+ }
@@ -27,6 +27,7 @@
27
27
 
28
28
  import { filter, isArray } from "lodash";
29
29
  import ThresholdsBrushTool from "./custom/thresholdsBrushTool";
30
+ import Slice4DScrollMouseWheelTool from "./custom/4dSliceScrollTool";
30
31
  import PolylineScissorsTool from "./custom/polylineScissorsTool";
31
32
 
32
33
  /**
@@ -108,9 +109,23 @@ const DEFAULT_TOOLS = {
108
109
  invert: false
109
110
  },
110
111
  cleanable: false,
111
- defaultActive: true,
112
+ defaultActive: false,
112
113
  class: "StackScrollMouseWheelTool"
113
114
  },
115
+ Slice4DScrollMouseWheel: {
116
+ name: "Slice4DScrollMouseWheel",
117
+ viewports: "all",
118
+ configuration: {
119
+ loop: false, // default false
120
+ allowSkipping: false, // default true
121
+ invert: false,
122
+ framesNumber: 1
123
+ },
124
+ options: {},
125
+ cleanable: false,
126
+ defaultActive: true,
127
+ class: "Slice4DScrollMouseWheelTool"
128
+ },
114
129
  Pan: {
115
130
  name: "Pan",
116
131
  viewports: "all",
@@ -398,7 +413,8 @@ const DEFAULT_TOOLS = {
398
413
  */
399
414
  const dvTools = {
400
415
  ThresholdsBrushTool: ThresholdsBrushTool,
401
- PolylineScissorsTool: PolylineScissorsTool
416
+ PolylineScissorsTool: PolylineScissorsTool,
417
+ Slice4DScrollMouseWheelTool: Slice4DScrollMouseWheelTool
402
418
  };
403
419
 
404
420
  /**
@@ -489,4 +505,4 @@ export {
489
505
  dvTools,
490
506
  getDefaultToolsByType,
491
507
  setDefaultToolsProps
492
- };
508
+ };
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "medical",
7
7
  "cornerstone"
8
8
  ],
9
- "version": "1.5.8",
9
+ "version": "1.5.10",
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",