larvitar 1.4.0 → 1.5.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.
@@ -1,23 +1,24 @@
1
1
  name: CI-docs
2
2
 
3
- # Controls when the action will run. Triggers the workflow on push or pull request
4
- # events but only for the master branch
5
3
  on:
6
- push:
7
- branches: [master]
4
+ pull_request:
5
+ types:
6
+ - opened
7
+ - reopened
8
+ - synchronize
8
9
 
9
- # A workflow run is made up of one or more jobs that can run sequentially or in parallel
10
10
  jobs:
11
- # First job, build package
12
11
  build:
13
- # The type of runner that the job will run on
14
12
  runs-on: ubuntu-latest
15
13
 
16
- # Steps represent a sequence of tasks that will be executed as part of the job
17
14
  steps:
18
- # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
15
+ # CLone repo at current branch
19
16
  - name: Clone repo
20
17
  uses: actions/checkout@v2
18
+ with:
19
+ persist-credentials: false
20
+ ref: ${{ github.head_ref }}
21
+ token: ${{ secrets.GIT_TOKEN }}
21
22
 
22
23
  # Setup node environment
23
24
  - name: Setup Node.js environment
@@ -42,10 +43,13 @@ jobs:
42
43
  run: |
43
44
  yarn generate-docs
44
45
 
45
- # Commit Package and Docs
46
+ # Commit docs on current branch (update pull request)
46
47
  - name: Commit docs
47
- run: |
48
- git config --global user.name 'Mattia-gh-action'
49
- git config --global user.email 'ronzim@users.noreply.github.com'
50
- git commit --allow-empty -am "Automated docs generation"
51
- git push
48
+ uses: actions-js/push@master
49
+ with:
50
+ github_token: ${{ secrets.GITHUB_TOKEN }}
51
+ message: "Update docs"
52
+ branch: ${{ github.head_ref }}
53
+ empty: true
54
+
55
+
package/README.md CHANGED
@@ -6,9 +6,9 @@
6
6
 
7
7
  ## Dicom Image Toolkit for CornerstoneJS
8
8
 
9
- ### Current version: 1.4.0
9
+ ### Current version: 1.5.0
10
10
 
11
- ### Latest Published Release: 1.4.0
11
+ ### Latest Published Release: 1.5.0
12
12
 
13
13
  This library provides common DICOM functionalities to be used in web-applications: it's wrapper that simplifies the use of cornerstone-js environment.
14
14
  Orthogonal multiplanar reformat is included as well as custom loader/exporter for nrrd files and [Vuex](https://vuex.vuejs.org/) custom integration.
@@ -270,7 +270,7 @@ let parseFile = function (file) {
270
270
  reject(dataSet.warnings);
271
271
  } else {
272
272
  let pixelDataElement = dataSet.elements.x7fe00010;
273
-
273
+ let SOPUID = metadata["x00080016"];
274
274
  if (pixelDataElement) {
275
275
  // done, pixelDataElement found
276
276
  let instanceUID = metadata["x00080018"] || randomId();
@@ -323,6 +323,29 @@ let parseFile = function (file) {
323
323
  imageObject.metadata.length = pixelDataElement.length;
324
324
  imageObject.metadata.repr = getPixelRepresentation(dataSet);
325
325
  resolve(imageObject);
326
+ } else if (SOPUID == "1.2.840.10008.5.1.4.1.1.104.1") {
327
+ let pdfObject = {
328
+ // data needed for rendering
329
+ file: file,
330
+ dataSet: dataSet
331
+ };
332
+ pdfObject.metadata = metadata;
333
+ pdfObject.metadata.seriesUID = seriesInstanceUID;
334
+ pdfObject.instanceUID = metadata["x00080018"] || randomId();
335
+ pdfObject.metadata.studyUID = metadata["x0020000d"];
336
+ pdfObject.metadata.accessionNumber = metadata["x00080050"];
337
+ pdfObject.metadata.studyDescription = metadata["x00081030"];
338
+ pdfObject.metadata.patientName = metadata["x00100010"];
339
+ pdfObject.metadata.patientBirthdate = metadata["x00100030"];
340
+ pdfObject.metadata.seriesDate = metadata["x00080021"];
341
+ pdfObject.metadata.seriesModality =
342
+ metadata["x00080060"].toLowerCase();
343
+ pdfObject.metadata.mimeType = metadata["x00420012"];
344
+ pdfObject.metadata.is4D = false;
345
+ pdfObject.metadata.numberOfFrames = 0;
346
+ pdfObject.metadata.numberOfSlices = 0;
347
+ pdfObject.metadata.numberOfTemporalPositions = 0;
348
+ resolve(pdfObject);
326
349
  } else {
327
350
  // done, no pixelData
328
351
  reject("no pixelData");
@@ -115,6 +115,44 @@ export function loadAndCacheImages(series, callback) {
115
115
  });
116
116
  }
117
117
 
118
+ /**
119
+ * Render a PDF from a DICOM Encapsulated PDF
120
+ * @instance
121
+ * @function renderDICOMPDF
122
+ * @param {Object} image - The image PDF object
123
+ * @param {String} elementId - The html div id used for rendering or its DOM HTMLElement
124
+ * @returns {Promise} - Return a promise which will resolve when image is displayed
125
+ */
126
+ export const renderDICOMPDF = function (image, elementId) {
127
+ let element = isElement(elementId)
128
+ ? elementId
129
+ : document.getElementById(elementId);
130
+ if (!element) {
131
+ console.error("invalid html element: " + elementId);
132
+ return;
133
+ }
134
+ const SOPUID = image.dataSet.string("x00080016");
135
+ if (SOPUID === "1.2.840.10008.5.1.4.1.1.104.1") {
136
+ let fileTag = image.dataSet.elements.x00420011;
137
+ let pdfByteArray = image.dataSet.byteArray.slice(
138
+ fileTag.dataOffset,
139
+ fileTag.dataOffset + fileTag.length
140
+ );
141
+ let PDF = new Blob([pdfByteArray], { type: "application/pdf" });
142
+ let fileURL = URL.createObjectURL(PDF);
143
+ element.innerHTML =
144
+ '<object data="' +
145
+ fileURL +
146
+ '" type="application/pdf" width="100%" height="100%"></object>';
147
+ fileTag = null;
148
+ pdfByteArray = null;
149
+ PDF = null;
150
+ fileURL = null;
151
+ } else {
152
+ throw new Error("This is not a DICOM with a PDF");
153
+ }
154
+ };
155
+
118
156
  /**
119
157
  * Render an image (png or jpg) from File on a html div using cornerstone
120
158
  * @instance
@@ -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";
@@ -31,7 +33,8 @@ let onKeyUpFn = null;
31
33
  * Setup mouse handler modifiers and keyboard shortcuts:
32
34
  * register a tool on right button and another one
33
35
  * when pressing a modifier (ctrl/shift/alt) + right button
34
- * The activation take place on all active viewports
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)
35
38
  * Improvements could be:
36
39
  * - "restore previous active tool" instead of passed "default" tool
37
40
  * - manage left button (an idea could be to cycle over object keys for both buttons)
@@ -57,6 +60,9 @@ export function addMouseKeyHandlers(config) {
57
60
  return false;
58
61
  });
59
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
+
60
66
  // Define behaviour on key down: activate registered tool
61
67
  function onKeyDown(evt) {
62
68
  // keyboard shortcuts (activate on left mouse button)
@@ -71,7 +77,17 @@ export function addMouseKeyHandlers(config) {
71
77
  .filter(key => keyCodes[key] == evt.keyCode)
72
78
  .pop();
73
79
  if (config.debug) console.log("active", config.keyboard_shortcuts[key]);
74
- setToolActive(config.keyboard_shortcuts[key], { mouseButtonMask: 1 });
80
+ const viewports = allViewports.filter(viewport =>
81
+ cornerstoneTools.getToolForElement(
82
+ viewport,
83
+ config.keyboard_shortcuts[key]
84
+ )
85
+ );
86
+ setToolActive(
87
+ config.keyboard_shortcuts[key],
88
+ { mouseButtonMask: 1 },
89
+ viewports.map(v => v.id)
90
+ );
75
91
  document.addEventListener("keydown", onKeyDown, { once: true });
76
92
  }
77
93
  // right drag + shift
@@ -81,7 +97,18 @@ export function addMouseKeyHandlers(config) {
81
97
  evt.keyCode == keyCodes.KEY_SHIFT
82
98
  ) {
83
99
  if (config.debug) console.log("active", config.mouse_button_right.shift);
84
- setToolActive(config.mouse_button_right.shift, { mouseButtonMask: 2 });
100
+ const viewports = allViewports.filter(viewport =>
101
+ cornerstoneTools.getToolForElement(
102
+ viewport,
103
+ config.mouse_button_right.shift
104
+ )
105
+ );
106
+
107
+ setToolActive(
108
+ config.mouse_button_right.shift,
109
+ { mouseButtonMask: 2 },
110
+ viewports.map(v => v.id)
111
+ );
85
112
  document.addEventListener("keyup", onKeyUp, { once: true });
86
113
  }
87
114
  // right drag + ctrl
@@ -91,7 +118,18 @@ export function addMouseKeyHandlers(config) {
91
118
  evt.keyCode == keyCodes.KEY_CONTROL
92
119
  ) {
93
120
  if (config.debug) console.log("active", config.mouse_button_right.ctrl);
94
- setToolActive(config.mouse_button_right.ctrl, { mouseButtonMask: 2 });
121
+ const viewports = allViewports.filter(viewport =>
122
+ cornerstoneTools.getToolForElement(
123
+ viewport,
124
+ config.mouse_button_right.ctrl
125
+ )
126
+ );
127
+
128
+ setToolActive(
129
+ config.mouse_button_right.ctrl,
130
+ { mouseButtonMask: 2 },
131
+ viewports.map(v => v.id)
132
+ );
95
133
  document.addEventListener("keyup", onKeyUp, { once: true });
96
134
  }
97
135
  // leave default
@@ -105,17 +143,48 @@ export function addMouseKeyHandlers(config) {
105
143
  function onKeyUp(e) {
106
144
  if (config.debug)
107
145
  console.log("active default", config.mouse_button_right.default);
108
- setToolActive(config.mouse_button_right.default, { mouseButtonMask: 2 });
146
+ const viewports = allViewports.filter(viewport =>
147
+ cornerstoneTools.getToolForElement(
148
+ viewport,
149
+ config.mouse_button_right.default
150
+ )
151
+ );
152
+ setToolActive(
153
+ config.mouse_button_right.default,
154
+ { mouseButtonMask: 2 },
155
+ viewports.map(v => v.id)
156
+ );
109
157
  document.addEventListener("keydown", onKeyDown, { once: true });
110
158
  }
111
159
 
112
- // activate default, if any
160
+ // activate default on mouse right, if any
113
161
  if (config.mouse_button_right && config.mouse_button_right.default) {
114
- setToolActive(config.mouse_button_right.default, { mouseButtonMask: 2 });
162
+ const viewports = allViewports.filter(viewport =>
163
+ cornerstoneTools.getToolForElement(
164
+ viewport,
165
+ config.mouse_button_right.default
166
+ )
167
+ );
168
+ setToolActive(
169
+ config.mouse_button_right.default,
170
+ { mouseButtonMask: 2 },
171
+ viewports.map(v => v.id)
172
+ );
115
173
  }
116
174
 
175
+ // activate default on mouse left, if any
117
176
  if (config.mouse_button_left && config.mouse_button_left.default) {
118
- setToolActive(config.mouse_button_left.default, { mouseButtonMask: 1 });
177
+ const viewports = allViewports.filter(viewport =>
178
+ cornerstoneTools.getToolForElement(
179
+ viewport,
180
+ config.mouse_button_left.default
181
+ )
182
+ );
183
+ setToolActive(
184
+ config.mouse_button_left.default,
185
+ { mouseButtonMask: 1 },
186
+ viewports.map(v => v.id)
187
+ );
119
188
  }
120
189
 
121
190
  document.addEventListener("keydown", onKeyDown, { once: true });
package/index.js CHANGED
@@ -78,6 +78,7 @@ import {
78
78
  clearImageCache,
79
79
  loadAndCacheImages,
80
80
  renderFileImage,
81
+ renderDICOMPDF,
81
82
  renderWebImage,
82
83
  disableViewport,
83
84
  unloadViewport,
@@ -273,6 +274,7 @@ export {
273
274
  clearImageCache,
274
275
  loadAndCacheImages,
275
276
  renderFileImage,
277
+ renderDICOMPDF,
276
278
  renderWebImage,
277
279
  disableViewport,
278
280
  unloadViewport,
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "medical",
7
7
  "cornerstone"
8
8
  ],
9
- "version": "1.4.0",
9
+ "version": "1.5.0",
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
+ }