larvitar 2.0.5 → 2.0.7
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 +2 -2
- package/dist/imaging/imageRendering.d.ts +1 -71
- package/dist/imaging/imageStore.d.ts +5 -0
- package/dist/imaging/loaders/commonLoader.d.ts +4 -4
- package/dist/imaging/loaders/nrrdLoader.d.ts +1 -51
- package/dist/larvitar.js +13 -1
- package/dist/larvitar.js.map +1 -1
- package/imaging/tools/types.d.ts +19 -19
- package/imaging/types.d.ts +110 -2
- package/package.json +7 -2
- package/.github/workflows/build-docs.yml +0 -59
- package/.github/workflows/codeql-analysis.yml +0 -71
- package/.github/workflows/deploy.yml +0 -37
- package/.vscode/settings.json +0 -4
- package/CODE_OF_CONDUCT.md +0 -76
- package/MIGRATION.md +0 -25
- package/bundler/webpack.common.js +0 -27
- package/bundler/webpack.dev.js +0 -23
- package/bundler/webpack.prod.js +0 -19
- package/decs.d.ts +0 -12
- package/dist/imaging/MetaDataReadable.d.ts +0 -41
- package/dist/imaging/MetaDataTypes.d.ts +0 -3489
- package/imaging/dataDictionary.json +0 -21866
- package/imaging/imageAnonymization.ts +0 -135
- package/imaging/imageColormaps.ts +0 -217
- package/imaging/imageContours.ts +0 -196
- package/imaging/imageIo.ts +0 -251
- package/imaging/imageLayers.ts +0 -121
- package/imaging/imageLoading.ts +0 -299
- package/imaging/imageParsing.ts +0 -444
- package/imaging/imagePresets.ts +0 -156
- package/imaging/imageRendering.ts +0 -1091
- package/imaging/imageReslice.ts +0 -87
- package/imaging/imageStore.ts +0 -487
- package/imaging/imageTags.ts +0 -609
- package/imaging/imageTools.js +0 -708
- package/imaging/imageUtils.ts +0 -1079
- package/imaging/loaders/commonLoader.ts +0 -275
- package/imaging/loaders/dicomLoader.ts +0 -66
- package/imaging/loaders/fileLoader.ts +0 -71
- package/imaging/loaders/multiframeLoader.ts +0 -435
- package/imaging/loaders/nrrdLoader.ts +0 -630
- package/imaging/loaders/resliceLoader.ts +0 -205
- package/imaging/monitors/memory.ts +0 -151
- package/imaging/monitors/performance.ts +0 -34
- package/imaging/parsers/ecg.ts +0 -54
- package/imaging/parsers/nrrd.js +0 -485
- package/imaging/tools/custom/4dSliceScrollTool.js +0 -146
- package/imaging/tools/custom/BorderMagnifyTool.js +0 -99
- package/imaging/tools/custom/contourTool.js +0 -1884
- package/imaging/tools/custom/diameterTool.js +0 -141
- package/imaging/tools/custom/editMaskTool.js +0 -141
- package/imaging/tools/custom/ellipticalRoiOverlayTool.js +0 -534
- package/imaging/tools/custom/polygonSegmentationMixin.js +0 -245
- package/imaging/tools/custom/polylineScissorsTool.js +0 -59
- package/imaging/tools/custom/rectangleRoiOverlayTool.js +0 -564
- package/imaging/tools/custom/seedTool.js +0 -342
- package/imaging/tools/custom/setLabelMap3D.ts +0 -242
- package/imaging/tools/custom/thresholdsBrushTool.js +0 -161
- package/imaging/tools/default.ts +0 -594
- package/imaging/tools/interaction.ts +0 -266
- package/imaging/tools/io.ts +0 -229
- package/imaging/tools/main.ts +0 -427
- package/imaging/tools/segmentation.ts +0 -532
- package/imaging/tools/segmentations.md +0 -38
- package/imaging/tools/state.ts +0 -74
- package/imaging/tools/strategies/eraseFreehand.js +0 -76
- package/imaging/tools/strategies/fillFreehand.js +0 -79
- package/imaging/tools/strategies/index.js +0 -2
- package/imaging/waveforms/ecg.ts +0 -191
- package/index.ts +0 -431
- package/jsdoc.json +0 -52
- package/rollup.config.js +0 -51
- package/template/.gitkeep +0 -0
- package/tsconfig.json +0 -102
- /package/imaging/{MetaDataReadable.ts → MetaDataReadable.d.ts} +0 -0
- /package/imaging/{MetaDataTypes.ts → MetaDataTypes.d.ts} +0 -0
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
/** @module imaging/tools/interaction
|
|
2
|
-
* @desc This file provides functionalities for
|
|
3
|
-
* tools interactions
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// external libraries
|
|
7
|
-
import { throttle } from "lodash";
|
|
8
|
-
import * as keyCodes from "keycode-js";
|
|
9
|
-
import cornerstone from "cornerstone-core";
|
|
10
|
-
import cornerstoneTools from "cornerstone-tools";
|
|
11
|
-
|
|
12
|
-
// internal libraries
|
|
13
|
-
import { DEFAULT_MOUSE_KEYS } from "./default";
|
|
14
|
-
import { setToolActive } from "./main";
|
|
15
|
-
import { isElement } from "../imageUtils";
|
|
16
|
-
import store, { set as setStore } from "../imageStore";
|
|
17
|
-
import { updateViewportData } from "../imageRendering";
|
|
18
|
-
import type { ToolMouseKeys } from "./types";
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* TOOLS INTERACTIONS TODOS:
|
|
22
|
-
* - enable touch controls
|
|
23
|
-
* - rework active tools / ui labels sync (we can get all active tools from cornerstoneTools state, then check the button / input method to update the correct label, or update all props scale, translation and voi)
|
|
24
|
-
* - use config to setup all interactions (mouse left/right, keyboard shortcuts, touch inputs)
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Global event callbacks
|
|
29
|
-
*/
|
|
30
|
-
let onKeyDownFn: ((evt: KeyboardEvent) => void) | null = null;
|
|
31
|
-
let onKeyUpFn: ((evt: KeyboardEvent) => void) | null = null;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Setup mouse handler modifiers and keyboard shortcuts:
|
|
35
|
-
* register a tool on right button and another one
|
|
36
|
-
* when pressing a modifier (ctrl/shift/alt) + right button
|
|
37
|
-
* The activation take place on all active viewports (we added a check to activate only on viewports
|
|
38
|
-
* in which the tool has been added previously)
|
|
39
|
-
* Improvements could be:
|
|
40
|
-
* - "restore previous active tool" instead of passed "default" tool
|
|
41
|
-
* - manage left button (an idea could be to cycle over object keys for both buttons)
|
|
42
|
-
* - possibility to change modifier keys
|
|
43
|
-
* @param {Object} config - see tools/default
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
export function addMouseKeyHandlers(config: ToolMouseKeys) {
|
|
47
|
-
if (!config) {
|
|
48
|
-
config = DEFAULT_MOUSE_KEYS;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (onKeyDownFn) {
|
|
52
|
-
document.removeEventListener("keydown", onKeyDownFn);
|
|
53
|
-
}
|
|
54
|
-
if (onKeyUpFn) {
|
|
55
|
-
document.removeEventListener("keyup", onKeyUpFn);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Prevent context menu on right click
|
|
59
|
-
document.addEventListener("contextmenu", evt => {
|
|
60
|
-
evt.preventDefault();
|
|
61
|
-
return false;
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// get all enabled viewports. Then, filter only viewport in which the target tool had been added previously.
|
|
65
|
-
let allViewports = cornerstone.getEnabledElements().map(enel => enel.element);
|
|
66
|
-
|
|
67
|
-
// Define behaviour on key down: activate registered tool
|
|
68
|
-
function onKeyDown(evt: KeyboardEvent) {
|
|
69
|
-
// keyboard shortcuts (activate on left mouse button)
|
|
70
|
-
let codes = config.keyboard_shortcuts
|
|
71
|
-
? Object.keys(config.keyboard_shortcuts).map(
|
|
72
|
-
// @ts-ignore
|
|
73
|
-
key => keyCodes[key]
|
|
74
|
-
)
|
|
75
|
-
: [];
|
|
76
|
-
|
|
77
|
-
if (codes.includes(evt.keyCode) && evt.altKey) {
|
|
78
|
-
evt.preventDefault(); // avoid browser menu selections
|
|
79
|
-
|
|
80
|
-
let key = Object.keys(config.keyboard_shortcuts)
|
|
81
|
-
// @ts-ignore
|
|
82
|
-
.filter(key => keyCodes[key] == evt.keyCode) // TODO keyCode is deprecated
|
|
83
|
-
.pop();
|
|
84
|
-
|
|
85
|
-
if (!key) {
|
|
86
|
-
console.warn("Key not found in config.keyboard_shortcuts");
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
let toolName = config.keyboard_shortcuts[key];
|
|
91
|
-
|
|
92
|
-
if (config.debug) console.log("active", toolName);
|
|
93
|
-
|
|
94
|
-
const viewports = allViewports.filter(viewport =>
|
|
95
|
-
cornerstoneTools.getToolForElement(viewport, toolName)
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
setToolActive(
|
|
99
|
-
toolName,
|
|
100
|
-
{ mouseButtonMask: 1 },
|
|
101
|
-
viewports.map(v => v.id)
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
document.addEventListener("keydown", onKeyDown, { once: true });
|
|
105
|
-
}
|
|
106
|
-
// right drag + shift
|
|
107
|
-
else if (
|
|
108
|
-
config.mouse_button_right &&
|
|
109
|
-
config.mouse_button_right.shift &&
|
|
110
|
-
evt.keyCode == keyCodes.KEY_SHIFT
|
|
111
|
-
) {
|
|
112
|
-
if (config.debug) console.log("active", config.mouse_button_right.shift);
|
|
113
|
-
const viewports = allViewports.filter(viewport =>
|
|
114
|
-
cornerstoneTools.getToolForElement(
|
|
115
|
-
viewport,
|
|
116
|
-
config.mouse_button_right.shift
|
|
117
|
-
)
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
setToolActive(
|
|
121
|
-
config.mouse_button_right.shift,
|
|
122
|
-
{ mouseButtonMask: 2 },
|
|
123
|
-
viewports.map(v => v.id)
|
|
124
|
-
);
|
|
125
|
-
document.addEventListener("keyup", onKeyUp, { once: true });
|
|
126
|
-
}
|
|
127
|
-
// right drag + ctrl
|
|
128
|
-
else if (
|
|
129
|
-
config.mouse_button_right &&
|
|
130
|
-
config.mouse_button_right.ctrl &&
|
|
131
|
-
evt.keyCode == keyCodes.KEY_CONTROL
|
|
132
|
-
) {
|
|
133
|
-
if (config.debug) console.log("active", config.mouse_button_right.ctrl);
|
|
134
|
-
const viewports = allViewports.filter(viewport =>
|
|
135
|
-
cornerstoneTools.getToolForElement(
|
|
136
|
-
viewport,
|
|
137
|
-
config.mouse_button_right.ctrl
|
|
138
|
-
)
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
setToolActive(
|
|
142
|
-
config.mouse_button_right.ctrl,
|
|
143
|
-
{ mouseButtonMask: 2 },
|
|
144
|
-
viewports.map(v => v.id)
|
|
145
|
-
);
|
|
146
|
-
document.addEventListener("keyup", onKeyUp, { once: true });
|
|
147
|
-
}
|
|
148
|
-
// leave default
|
|
149
|
-
else {
|
|
150
|
-
document.addEventListener("keydown", onKeyDown, { once: true });
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Define behaviour on key up: restore original tool
|
|
156
|
-
function onKeyUp(e: KeyboardEvent) {
|
|
157
|
-
if (config.debug)
|
|
158
|
-
console.log("active default", config.mouse_button_right.default);
|
|
159
|
-
const viewports = allViewports.filter(viewport =>
|
|
160
|
-
cornerstoneTools.getToolForElement(
|
|
161
|
-
viewport,
|
|
162
|
-
config.mouse_button_right.default
|
|
163
|
-
)
|
|
164
|
-
);
|
|
165
|
-
setToolActive(
|
|
166
|
-
config.mouse_button_right.default,
|
|
167
|
-
{ mouseButtonMask: 2 },
|
|
168
|
-
viewports.map(v => v.id)
|
|
169
|
-
);
|
|
170
|
-
document.addEventListener("keydown", onKeyDown, { once: true });
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// activate default on mouse right, if any
|
|
174
|
-
if (config.mouse_button_right && config.mouse_button_right.default) {
|
|
175
|
-
const viewports = allViewports.filter(viewport =>
|
|
176
|
-
cornerstoneTools.getToolForElement(
|
|
177
|
-
viewport,
|
|
178
|
-
config.mouse_button_right.default
|
|
179
|
-
)
|
|
180
|
-
);
|
|
181
|
-
setToolActive(
|
|
182
|
-
config.mouse_button_right.default,
|
|
183
|
-
{ mouseButtonMask: 2 },
|
|
184
|
-
viewports.map(v => v.id)
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// activate default on mouse left, if any
|
|
189
|
-
if (config.mouse_button_left && config.mouse_button_left.default) {
|
|
190
|
-
const viewports = allViewports.filter(viewport =>
|
|
191
|
-
cornerstoneTools.getToolForElement(
|
|
192
|
-
viewport,
|
|
193
|
-
config.mouse_button_left.default
|
|
194
|
-
)
|
|
195
|
-
);
|
|
196
|
-
setToolActive(
|
|
197
|
-
config.mouse_button_left.default,
|
|
198
|
-
{ mouseButtonMask: 1 },
|
|
199
|
-
viewports.map(v => v.id)
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
document.addEventListener("keydown", onKeyDown, { once: true });
|
|
204
|
-
|
|
205
|
-
onKeyDownFn = onKeyDown;
|
|
206
|
-
onKeyUpFn = onKeyUp;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
*
|
|
211
|
-
*/
|
|
212
|
-
export function removeMouseKeyHandlers() {
|
|
213
|
-
if (!onKeyDownFn) return;
|
|
214
|
-
document.removeEventListener("keydown", onKeyDownFn);
|
|
215
|
-
onKeyDownFn = null;
|
|
216
|
-
onKeyUpFn = null;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Add event handlers to mouse move
|
|
221
|
-
* @instance
|
|
222
|
-
* @function toggleMouseHandlers
|
|
223
|
-
* @param {String | HTMLElement} elementId - The html div id used for rendering or its DOM HTMLElement
|
|
224
|
-
* @param {Boolean} disable - If true disable handlers, default is false
|
|
225
|
-
*/
|
|
226
|
-
export const toggleMouseToolsListeners = function (
|
|
227
|
-
elementId: string | HTMLElement,
|
|
228
|
-
disable: boolean
|
|
229
|
-
) {
|
|
230
|
-
let element = isElement(elementId)
|
|
231
|
-
? (elementId as HTMLElement)
|
|
232
|
-
: document.getElementById(elementId as string);
|
|
233
|
-
if (!element) {
|
|
234
|
-
console.error("invalid html element: " + elementId);
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// mouse move handler (throttled)
|
|
239
|
-
let mouseMoveHandler = throttle(function (evt) {
|
|
240
|
-
let activeTool =
|
|
241
|
-
evt.detail.buttons == 1
|
|
242
|
-
? store.get("leftActiveTool")
|
|
243
|
-
: store.get("rightActiveTool");
|
|
244
|
-
updateViewportData(evt.srcElement.id, evt.detail.viewport, activeTool);
|
|
245
|
-
}, 250);
|
|
246
|
-
|
|
247
|
-
// mouse wheel handler
|
|
248
|
-
function mouseWheelHandler(evt: any) {
|
|
249
|
-
// TODO-ts fix type (should be a cornerstoneTools event type)
|
|
250
|
-
// @mronzoni does cornerstoneTools have a type for this event?
|
|
251
|
-
setStore(["sliceId", evt.target.id, evt.detail.newImageIdIndex]);
|
|
252
|
-
updateViewportData(evt.srcElement.id, evt.detail, "mouseWheel");
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if (disable) {
|
|
256
|
-
element.removeEventListener("cornerstonetoolsmousedrag", mouseMoveHandler);
|
|
257
|
-
element.removeEventListener(
|
|
258
|
-
"cornerstonetoolsstackscroll",
|
|
259
|
-
mouseWheelHandler
|
|
260
|
-
);
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
element.addEventListener("cornerstonetoolsmousedrag", mouseMoveHandler);
|
|
265
|
-
element.addEventListener("cornerstonetoolsstackscroll", mouseWheelHandler);
|
|
266
|
-
};
|
package/imaging/tools/io.ts
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
/** @module imaging/tools/io
|
|
2
|
-
* @desc This file provides functionalities for
|
|
3
|
-
* tools input/output
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// external libraries
|
|
7
|
-
import cornerstone from "cornerstone-core";
|
|
8
|
-
import cornerstoneTools from "cornerstone-tools";
|
|
9
|
-
import { each, map, assign, invert } from "lodash";
|
|
10
|
-
import { unparse } from "papaparse";
|
|
11
|
-
|
|
12
|
-
// internal libraries
|
|
13
|
-
import { setToolEnabled } from "./main";
|
|
14
|
-
import type { ToolState } from "./types";
|
|
15
|
-
import { fileManager } from "../loaders/fileLoader";
|
|
16
|
-
|
|
17
|
-
declare global {
|
|
18
|
-
interface Document {
|
|
19
|
-
documentMode?: any;
|
|
20
|
-
}
|
|
21
|
-
interface Navigator {
|
|
22
|
-
msSaveBlob?: (blob: any, defaultName?: string) => boolean;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Load annotation from json object
|
|
28
|
-
* @param {Object} jsonData - The previously saved tools state
|
|
29
|
-
*/
|
|
30
|
-
export const loadAnnotations = function (jsonData: ToolState) {
|
|
31
|
-
// restore saved tool state
|
|
32
|
-
cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(
|
|
33
|
-
jsonData
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
// set all found tools to passive
|
|
37
|
-
let toolsInState: Set<string> = new Set();
|
|
38
|
-
for (let imageId in jsonData) {
|
|
39
|
-
for (let toolName in jsonData[imageId]) {
|
|
40
|
-
toolsInState.add(toolName);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
toolsInState.forEach(toolName => {
|
|
45
|
-
// TODO-ts fix 'null' this after setToolEnabled is typed @mronzoni
|
|
46
|
-
setToolEnabled(toolName);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
let enabledElementIds = map(
|
|
50
|
-
cornerstone.getEnabledElements(),
|
|
51
|
-
e => e.element.id
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
// FIXME error if called when image is not loaded
|
|
55
|
-
for (let elementId of enabledElementIds) {
|
|
56
|
-
let element = document.getElementById(elementId);
|
|
57
|
-
if (!element) {
|
|
58
|
-
console.warn(`Element ${elementId} not found`);
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
cornerstone.updateImage(element);
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Save annotations from current stack, download as json file if requested
|
|
67
|
-
* @param {bool} download - True to download json
|
|
68
|
-
* @param {string} filename - The json file name, @default state.json
|
|
69
|
-
*/
|
|
70
|
-
export const saveAnnotations = function (
|
|
71
|
-
download: boolean,
|
|
72
|
-
filename = "state.json"
|
|
73
|
-
) {
|
|
74
|
-
let currentToolState =
|
|
75
|
-
cornerstoneTools.globalImageIdSpecificToolStateManager.saveToolState();
|
|
76
|
-
if (download) {
|
|
77
|
-
// Convert JSON Array to string.
|
|
78
|
-
var json_string = JSON.stringify(currentToolState);
|
|
79
|
-
downloadFile(json_string, filename);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return currentToolState;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Save annotation from current stack, download as csv file
|
|
87
|
-
* containing only useful informations for user
|
|
88
|
-
*/
|
|
89
|
-
export const exportAnnotations = function (
|
|
90
|
-
manager: typeof fileManager,
|
|
91
|
-
filename = "annotations.csv"
|
|
92
|
-
) {
|
|
93
|
-
let currentToolState =
|
|
94
|
-
cornerstoneTools.globalImageIdSpecificToolStateManager.saveToolState();
|
|
95
|
-
let { fieldsArr: fields, data } = generateCSV(manager, currentToolState);
|
|
96
|
-
let csvstring = unparse({ fields, data });
|
|
97
|
-
downloadFile(csvstring, filename);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
*
|
|
102
|
-
* @param {*} stringContent
|
|
103
|
-
* @param {*} filename
|
|
104
|
-
*/
|
|
105
|
-
function downloadFile(stringContent: string, filename: string) {
|
|
106
|
-
// Convert string to BLOB.
|
|
107
|
-
var blob = new Blob([stringContent], { type: "text/plain;charset=utf-8" });
|
|
108
|
-
//Check the Browser.
|
|
109
|
-
var isIE = false || !!document.documentMode;
|
|
110
|
-
if (isIE && window.navigator.msSaveBlob) {
|
|
111
|
-
window.navigator.msSaveBlob(blob, filename);
|
|
112
|
-
} else {
|
|
113
|
-
var url = window.URL || window.webkitURL;
|
|
114
|
-
let link = url.createObjectURL(blob);
|
|
115
|
-
var a = document.createElement("a");
|
|
116
|
-
a.download = filename;
|
|
117
|
-
a.href = link;
|
|
118
|
-
document.body.appendChild(a);
|
|
119
|
-
a.click();
|
|
120
|
-
document.body.removeChild(a);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
*
|
|
126
|
-
* @param {*} allToolState
|
|
127
|
-
*/
|
|
128
|
-
export function generateCSV(
|
|
129
|
-
manager: typeof fileManager,
|
|
130
|
-
allToolState: ToolState
|
|
131
|
-
) {
|
|
132
|
-
let fields: Set<string> = new Set();
|
|
133
|
-
fields.add("imagePath");
|
|
134
|
-
fields.add("toolName");
|
|
135
|
-
let data: Object[] = [];
|
|
136
|
-
each(allToolState, (imageToolState, imageId) => {
|
|
137
|
-
// convert imageId to imagePath
|
|
138
|
-
let imagePath = invert(manager)[imageId];
|
|
139
|
-
each(imageToolState, (toolState, toolName) => {
|
|
140
|
-
// extract useful information from tool state
|
|
141
|
-
let extractedData = extractToolInfo(toolName, toolState.data);
|
|
142
|
-
each(extractedData, singledata => {
|
|
143
|
-
data.push(assign({ imagePath, toolName }, singledata));
|
|
144
|
-
// add all keys into fields set
|
|
145
|
-
each(Object.keys(singledata), k => fields.add(k));
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
let fieldsArr: string[] = Array.from(fields);
|
|
151
|
-
|
|
152
|
-
return {
|
|
153
|
-
fieldsArr,
|
|
154
|
-
data
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
*
|
|
160
|
-
* @param {*} toolData
|
|
161
|
-
*/
|
|
162
|
-
function extractToolInfo(
|
|
163
|
-
toolName: string,
|
|
164
|
-
toolData: ToolState["imageId"][keyof ToolState["imageId"]]
|
|
165
|
-
) {
|
|
166
|
-
let dataArray: Object[] = [];
|
|
167
|
-
switch (toolName) {
|
|
168
|
-
case "RectangleRoi":
|
|
169
|
-
case "EllipticalRoi":
|
|
170
|
-
// This is an example for "length" tool, needs to be generalised
|
|
171
|
-
dataArray = map(toolData, data => {
|
|
172
|
-
return {
|
|
173
|
-
color: data.color,
|
|
174
|
-
x1: data.handles.start.x,
|
|
175
|
-
y1: data.handles.start.y,
|
|
176
|
-
x2: data.handles.end.x,
|
|
177
|
-
y2: data.handles.end.y,
|
|
178
|
-
length: data.length,
|
|
179
|
-
unit: data.unit,
|
|
180
|
-
textBox_x: data.textBox ? data.textBox.x : null,
|
|
181
|
-
textBox_y: data.textBox ? data.textBox.y : null,
|
|
182
|
-
boundingBox_w: data.textBox ? data.textBox.boundingBox.width : null,
|
|
183
|
-
boundingBox_h: data.textBox ? data.textBox.boundingBox.height : null,
|
|
184
|
-
boundingBox_l: data.textBox ? data.textBox.boundingBox.left : null,
|
|
185
|
-
boundingBox_t: data.textBox ? data.textBox.boundingBox.top : null
|
|
186
|
-
};
|
|
187
|
-
});
|
|
188
|
-
break;
|
|
189
|
-
case "FreehandRoi":
|
|
190
|
-
dataArray = map(toolData, data => {
|
|
191
|
-
return {
|
|
192
|
-
color: data.color,
|
|
193
|
-
// TODO how to export arrays ?
|
|
194
|
-
// x: map(data.handles.points, "x"),
|
|
195
|
-
// y: map(data.handles.points, "y"),
|
|
196
|
-
length: data.length,
|
|
197
|
-
unit: data.unit,
|
|
198
|
-
textBox_x: data.textBox ? data.textBox.x : null,
|
|
199
|
-
textBox_y: data.textBox ? data.textBox.y : null,
|
|
200
|
-
polyBoundingBox_h: data.polyBoundingBox.height,
|
|
201
|
-
polyBoundingBox_l: data.polyBoundingBox.left,
|
|
202
|
-
polyBoundingBox_t: data.polyBoundingBox.top,
|
|
203
|
-
polyBoundingBox_w: data.polyBoundingBox.width
|
|
204
|
-
};
|
|
205
|
-
});
|
|
206
|
-
break;
|
|
207
|
-
case "ArrowAnnotate":
|
|
208
|
-
dataArray = map(toolData, data => {
|
|
209
|
-
return {
|
|
210
|
-
color: data.color ? data.color : null,
|
|
211
|
-
text: data.text,
|
|
212
|
-
x1: data.handles.start.x,
|
|
213
|
-
y1: data.handles.start.y,
|
|
214
|
-
x2: data.handles.end.x,
|
|
215
|
-
y2: data.handles.end.y,
|
|
216
|
-
textBox_x: data.textBox ? data.textBox.x : null,
|
|
217
|
-
textBox_y: data.textBox ? data.textBox.y : null,
|
|
218
|
-
boundingBox_w: data.textBox ? data.textBox.boundingBox.width : null,
|
|
219
|
-
boundingBox_h: data.textBox ? data.textBox.boundingBox.height : null,
|
|
220
|
-
boundingBox_l: data.textBox ? data.textBox.boundingBox.left : null,
|
|
221
|
-
boundingBox_t: data.textBox ? data.textBox.boundingBox.top : null
|
|
222
|
-
};
|
|
223
|
-
});
|
|
224
|
-
break;
|
|
225
|
-
default:
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return dataArray;
|
|
229
|
-
}
|