larvitar 2.1.7 → 2.1.9
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/dist/larvitar.js
CHANGED
|
@@ -156822,6 +156822,7 @@ const buildDataAsync = function (series, time, resolve, reject) {
|
|
|
156822
156822
|
}
|
|
156823
156823
|
let data = new typedArray(len);
|
|
156824
156824
|
let offsetData = 0;
|
|
156825
|
+
series.imageIds = (0, imageUtils_1.getSortedStack)(series, ["imagePosition"], true);
|
|
156825
156826
|
let imageIds = series.imageIds.slice();
|
|
156826
156827
|
imageStore_1.default.addSeriesId(series.seriesUID, series.imageIds);
|
|
156827
156828
|
function runFillPixelData(data) {
|
|
@@ -160570,7 +160571,7 @@ let sortStackCallback = function (seriesData, imageId, method) {
|
|
|
160570
160571
|
if (v3 <= v1 && v3 <= v2) {
|
|
160571
160572
|
sortIndex = 2;
|
|
160572
160573
|
}
|
|
160573
|
-
if (
|
|
160574
|
+
if (sortIndex === -1) {
|
|
160574
160575
|
throw new Error("Invalid sort index");
|
|
160575
160576
|
}
|
|
160576
160577
|
return p[sortIndex];
|
|
@@ -163225,6 +163226,633 @@ function revTidMask(metadataInfo, imageIds, index) {
|
|
|
163225
163226
|
}
|
|
163226
163227
|
|
|
163227
163228
|
|
|
163229
|
+
/***/ }),
|
|
163230
|
+
|
|
163231
|
+
/***/ 2775:
|
|
163232
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
163233
|
+
|
|
163234
|
+
"use strict";
|
|
163235
|
+
|
|
163236
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
163237
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
163238
|
+
};
|
|
163239
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
163240
|
+
//external imports
|
|
163241
|
+
const plotly_js_dist_min_1 = __importDefault(__webpack_require__(2479));
|
|
163242
|
+
const cornerstone_core_1 = __importDefault(__webpack_require__(7371));
|
|
163243
|
+
const cornerstone_tools_1 = __importDefault(__webpack_require__(4030));
|
|
163244
|
+
const getToolState = cornerstone_tools_1.default.getToolState;
|
|
163245
|
+
const toolColors = cornerstone_tools_1.default.toolColors;
|
|
163246
|
+
const draw = cornerstone_tools_1.default.importInternal("drawing/draw");
|
|
163247
|
+
const drawLine = cornerstone_tools_1.default.importInternal("drawing/drawLine");
|
|
163248
|
+
const setShadow = cornerstone_tools_1.default.importInternal("drawing/setShadow");
|
|
163249
|
+
const getNewContext = cornerstone_tools_1.default.importInternal("drawing/getNewContext");
|
|
163250
|
+
const drawHandles = cornerstone_tools_1.default.importInternal("drawing/drawHandles");
|
|
163251
|
+
const { lengthCursor } = cornerstone_tools_1.default.importInternal("tools/cursors");
|
|
163252
|
+
const throttle = cornerstone_tools_1.default.importInternal("util/throttle");
|
|
163253
|
+
const getModule = cornerstone_tools_1.default.getModule;
|
|
163254
|
+
const getPixelSpacing = cornerstone_tools_1.default.importInternal("util/getPixelSpacing");
|
|
163255
|
+
const lineSegDistance = cornerstone_tools_1.default.importInternal("util/lineSegDistance");
|
|
163256
|
+
const BaseAnnotationTool = cornerstone_tools_1.default.importInternal("base/BaseAnnotationTool");
|
|
163257
|
+
const default_1 = __webpack_require__(6694);
|
|
163258
|
+
// import cornerstoneTools from "cornerstone-tools";
|
|
163259
|
+
class LengthPlotTool extends BaseAnnotationTool {
|
|
163260
|
+
constructor(props = {}) {
|
|
163261
|
+
const defaultProps = {
|
|
163262
|
+
name: "LengthPlot",
|
|
163263
|
+
supportedInteractionTypes: ["Mouse"],
|
|
163264
|
+
svgCursor: lengthCursor,
|
|
163265
|
+
configuration: {
|
|
163266
|
+
drawHandles: true,
|
|
163267
|
+
drawHandlesOnHover: false,
|
|
163268
|
+
hideHandlesIfMoving: false,
|
|
163269
|
+
renderDashed: false,
|
|
163270
|
+
digits: 2,
|
|
163271
|
+
offset: 15
|
|
163272
|
+
}
|
|
163273
|
+
};
|
|
163274
|
+
super(props, defaultProps);
|
|
163275
|
+
this.name = "LengthPlot";
|
|
163276
|
+
this.plotlydata = [];
|
|
163277
|
+
this.measuring = false;
|
|
163278
|
+
this.configuration = {
|
|
163279
|
+
drawHandles: true,
|
|
163280
|
+
drawHandlesOnHover: false,
|
|
163281
|
+
hideHandlesIfMoving: false,
|
|
163282
|
+
renderDashed: false,
|
|
163283
|
+
digits: 2,
|
|
163284
|
+
offset: 15
|
|
163285
|
+
};
|
|
163286
|
+
this.eventData;
|
|
163287
|
+
this.datahandles;
|
|
163288
|
+
this.abovehandles;
|
|
163289
|
+
this.belowhandles;
|
|
163290
|
+
this.plotlydata = [];
|
|
163291
|
+
this.measuring = false;
|
|
163292
|
+
this.handleMouseUp = this.handleMouseUp.bind(this);
|
|
163293
|
+
this.throttledUpdateCachedStats = throttle(this.updateCachedStats, 110);
|
|
163294
|
+
}
|
|
163295
|
+
getRandomColor() {
|
|
163296
|
+
const letters = "0123456789ABCDEF";
|
|
163297
|
+
let color = "#";
|
|
163298
|
+
for (let i = 0; i < 6; i++) {
|
|
163299
|
+
color += letters[Math.floor(Math.random() * 16)];
|
|
163300
|
+
}
|
|
163301
|
+
return color;
|
|
163302
|
+
}
|
|
163303
|
+
handleMouseUp() {
|
|
163304
|
+
this.measuring = false;
|
|
163305
|
+
const eventData = this.eventData;
|
|
163306
|
+
const handleData = (handles) => {
|
|
163307
|
+
const points = this.getPointsAlongLine(handles.start, handles.end, getPixelSpacing(eventData.image).colPixelSpacing);
|
|
163308
|
+
const pixelValues = this.getPixelValuesAlongLine(handles.start, points, getPixelSpacing(eventData.image).colPixelSpacing, eventData);
|
|
163309
|
+
let color = "green";
|
|
163310
|
+
return { points, pixelValues, color };
|
|
163311
|
+
};
|
|
163312
|
+
const aboveResults = handleData(this.abovehandles);
|
|
163313
|
+
aboveResults.color = "red";
|
|
163314
|
+
const belowResults = handleData(this.belowhandles);
|
|
163315
|
+
belowResults.color = "blue";
|
|
163316
|
+
const data = [handleData(this.datahandles), aboveResults, belowResults];
|
|
163317
|
+
this.createPlot(...data);
|
|
163318
|
+
}
|
|
163319
|
+
createNewMeasurement(eventData) {
|
|
163320
|
+
this.eventData = eventData;
|
|
163321
|
+
clearToolData(eventData.element, this.name);
|
|
163322
|
+
eventData.element.addEventListener("mouseup", () => this.handleMouseUp());
|
|
163323
|
+
this.measuring = true;
|
|
163324
|
+
const goodEventData = eventData && eventData.currentPoints && eventData.currentPoints.image;
|
|
163325
|
+
if (!goodEventData) {
|
|
163326
|
+
console.error(`required eventData not supplied to tool ${this.name}'s createNewMeasurement`);
|
|
163327
|
+
return;
|
|
163328
|
+
}
|
|
163329
|
+
let color = "green";
|
|
163330
|
+
const { x, y } = eventData.currentPoints.image;
|
|
163331
|
+
return {
|
|
163332
|
+
visible: true,
|
|
163333
|
+
active: true,
|
|
163334
|
+
color: color,
|
|
163335
|
+
invalidated: true,
|
|
163336
|
+
handles: {
|
|
163337
|
+
start: {
|
|
163338
|
+
x,
|
|
163339
|
+
y,
|
|
163340
|
+
highlight: true,
|
|
163341
|
+
active: false
|
|
163342
|
+
},
|
|
163343
|
+
end: {
|
|
163344
|
+
x,
|
|
163345
|
+
y,
|
|
163346
|
+
highlight: true,
|
|
163347
|
+
active: true
|
|
163348
|
+
},
|
|
163349
|
+
textBox: {
|
|
163350
|
+
active: false,
|
|
163351
|
+
hasMoved: false,
|
|
163352
|
+
movesIndependently: false,
|
|
163353
|
+
drawnIndependently: true,
|
|
163354
|
+
allowedOutsideImage: true,
|
|
163355
|
+
hasBoundingBox: true
|
|
163356
|
+
}
|
|
163357
|
+
}
|
|
163358
|
+
};
|
|
163359
|
+
}
|
|
163360
|
+
pointNearTool(element, data, coords) {
|
|
163361
|
+
const hasStartAndEndHandles = data && data.handles && data.handles.start && data.handles.end;
|
|
163362
|
+
const validParameters = hasStartAndEndHandles;
|
|
163363
|
+
if (!validParameters) {
|
|
163364
|
+
console.warn(`invalid parameters supplied to tool ${this.name}'s pointNearTool`);
|
|
163365
|
+
return false;
|
|
163366
|
+
}
|
|
163367
|
+
if (data.visible === false) {
|
|
163368
|
+
return false;
|
|
163369
|
+
}
|
|
163370
|
+
return (lineSegDistance(element, data.handles.start, data.handles.end, coords) <
|
|
163371
|
+
25);
|
|
163372
|
+
}
|
|
163373
|
+
updateCachedStats(image, element, data) {
|
|
163374
|
+
const { rowPixelSpacing, colPixelSpacing } = getPixelSpacing(image);
|
|
163375
|
+
const dx = (data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1);
|
|
163376
|
+
const dy = (data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1);
|
|
163377
|
+
const length = Math.sqrt(dx * dx + dy * dy);
|
|
163378
|
+
data.length = length;
|
|
163379
|
+
data.invalidated = false;
|
|
163380
|
+
}
|
|
163381
|
+
renderToolData(evt) {
|
|
163382
|
+
const eventData = evt.detail;
|
|
163383
|
+
const { element } = eventData;
|
|
163384
|
+
const { handleRadius, drawHandlesOnHover, hideHandlesIfMoving, renderDashed } = this.configuration;
|
|
163385
|
+
const toolData = getToolState(evt.currentTarget, this.name);
|
|
163386
|
+
if (!toolData) {
|
|
163387
|
+
return;
|
|
163388
|
+
}
|
|
163389
|
+
const context = getNewContext(eventData.canvasContext.canvas);
|
|
163390
|
+
const lineDash = getModule("globalConfiguration").configuration
|
|
163391
|
+
.lineDash;
|
|
163392
|
+
let start;
|
|
163393
|
+
let end;
|
|
163394
|
+
for (let i = 0; i < toolData.data.length; i++) {
|
|
163395
|
+
const data = toolData.data[i];
|
|
163396
|
+
if (data.visible === false) {
|
|
163397
|
+
continue;
|
|
163398
|
+
}
|
|
163399
|
+
draw(context, (context) => {
|
|
163400
|
+
setShadow(context, this.configuration);
|
|
163401
|
+
const color = toolColors.getColorIfActive(data);
|
|
163402
|
+
const lineOptions = { color };
|
|
163403
|
+
if (renderDashed) {
|
|
163404
|
+
lineOptions.lineDash = lineDash;
|
|
163405
|
+
}
|
|
163406
|
+
start = data.handles.start;
|
|
163407
|
+
end = data.handles.end;
|
|
163408
|
+
data.handles.end.y = data.handles.start.y;
|
|
163409
|
+
drawLine(context, element, data.handles.start, data.handles.end, lineOptions);
|
|
163410
|
+
const offset = default_1.DEFAULT_TOOLS["LengthPlot"].offset === this.configuration.offset ||
|
|
163411
|
+
default_1.DEFAULT_TOOLS["LengthPlot"].offset === undefined
|
|
163412
|
+
? this.configuration.offset
|
|
163413
|
+
: default_1.DEFAULT_TOOLS["LengthPlot"].offset; //offset customisable
|
|
163414
|
+
//const offset = this.configuration.offset;
|
|
163415
|
+
const aboveHandles = {
|
|
163416
|
+
start: { x: start.x, y: start.y - offset },
|
|
163417
|
+
end: { x: end.x, y: end.y - offset }
|
|
163418
|
+
};
|
|
163419
|
+
const belowHandles = {
|
|
163420
|
+
start: { x: start.x, y: start.y + offset },
|
|
163421
|
+
end: { x: end.x, y: end.y + offset }
|
|
163422
|
+
};
|
|
163423
|
+
const abovelineOptions = { color: "red" };
|
|
163424
|
+
const belowlineOptions = { color: "blue" };
|
|
163425
|
+
drawLine(context, element, aboveHandles.start, aboveHandles.end, abovelineOptions);
|
|
163426
|
+
drawLine(context, element, belowHandles.start, belowHandles.end, belowlineOptions);
|
|
163427
|
+
const handleOptions = {
|
|
163428
|
+
color,
|
|
163429
|
+
handleRadius,
|
|
163430
|
+
drawHandlesIfActive: drawHandlesOnHover,
|
|
163431
|
+
hideHandlesIfMoving
|
|
163432
|
+
};
|
|
163433
|
+
const abovehandleOptions = {
|
|
163434
|
+
color: abovelineOptions.color,
|
|
163435
|
+
handleRadius,
|
|
163436
|
+
drawHandlesIfActive: drawHandlesOnHover,
|
|
163437
|
+
hideHandlesIfMoving
|
|
163438
|
+
};
|
|
163439
|
+
const belowhandleOptions = {
|
|
163440
|
+
color: belowlineOptions.color,
|
|
163441
|
+
handleRadius,
|
|
163442
|
+
drawHandlesIfActive: drawHandlesOnHover,
|
|
163443
|
+
hideHandlesIfMoving
|
|
163444
|
+
};
|
|
163445
|
+
if (this.configuration.drawHandles) {
|
|
163446
|
+
drawHandles(context, eventData, data.handles, handleOptions);
|
|
163447
|
+
this.datahandles = data.handles;
|
|
163448
|
+
this.abovehandles = aboveHandles;
|
|
163449
|
+
this.belowhandles = belowHandles;
|
|
163450
|
+
drawHandles(context, eventData, aboveHandles, abovehandleOptions);
|
|
163451
|
+
drawHandles(context, eventData, belowHandles, belowhandleOptions);
|
|
163452
|
+
}
|
|
163453
|
+
});
|
|
163454
|
+
}
|
|
163455
|
+
}
|
|
163456
|
+
getPointsAlongLine(startHandle, endHandle, colPixelSpacing) {
|
|
163457
|
+
let points = [];
|
|
163458
|
+
const addPoints = (start, end, step) => {
|
|
163459
|
+
const startX = Math.floor(start.x) + 1;
|
|
163460
|
+
const numPoints = Math.floor(end.x) - startX;
|
|
163461
|
+
points = new Array(numPoints + 1);
|
|
163462
|
+
for (let i = 0; i <= numPoints; i++) {
|
|
163463
|
+
points[i] = (startX + i) * step;
|
|
163464
|
+
}
|
|
163465
|
+
};
|
|
163466
|
+
if (endHandle.x > startHandle.x) {
|
|
163467
|
+
addPoints(startHandle, endHandle, colPixelSpacing);
|
|
163468
|
+
}
|
|
163469
|
+
if (endHandle.x < startHandle.x) {
|
|
163470
|
+
addPoints(endHandle, startHandle, colPixelSpacing);
|
|
163471
|
+
}
|
|
163472
|
+
return points;
|
|
163473
|
+
}
|
|
163474
|
+
getPixelValuesAlongLine(startHandle, points, colPixelSpacing, eventData) {
|
|
163475
|
+
const pixelValues = new Array(points.length);
|
|
163476
|
+
const yPoint = Math.floor(startHandle.y);
|
|
163477
|
+
const addPixelValues = (xPoints, startIndex) => {
|
|
163478
|
+
const pixelValuesBatch = cornerstone_core_1.default.getStoredPixels(eventData.element, xPoints[0], yPoint, xPoints.length, 1);
|
|
163479
|
+
for (let i = 0; i < pixelValuesBatch.length; i++) {
|
|
163480
|
+
pixelValues[startIndex + i] = pixelValuesBatch[i];
|
|
163481
|
+
}
|
|
163482
|
+
};
|
|
163483
|
+
for (let i = 0; i < points.length; i++) {
|
|
163484
|
+
const xPoint = Math.floor(points[i] / colPixelSpacing);
|
|
163485
|
+
addPixelValues([xPoint], i);
|
|
163486
|
+
}
|
|
163487
|
+
return pixelValues;
|
|
163488
|
+
}
|
|
163489
|
+
createPlot(...dataSets) {
|
|
163490
|
+
const traces = dataSets.map(({ points, pixelValues, color }) => ({
|
|
163491
|
+
x: points,
|
|
163492
|
+
y: pixelValues,
|
|
163493
|
+
type: "lines",
|
|
163494
|
+
line: {
|
|
163495
|
+
color
|
|
163496
|
+
}
|
|
163497
|
+
}));
|
|
163498
|
+
this.plotlydata = traces;
|
|
163499
|
+
const allXValues = dataSets.flatMap(dataSet => dataSet.points);
|
|
163500
|
+
const allYValues = dataSets.flatMap(dataSet => dataSet.pixelValues);
|
|
163501
|
+
const layout = {
|
|
163502
|
+
xaxis: {
|
|
163503
|
+
range: [Math.min(...allXValues), Math.max(...allXValues)],
|
|
163504
|
+
title: "position (mm)"
|
|
163505
|
+
},
|
|
163506
|
+
yaxis: {
|
|
163507
|
+
range: [Math.min(...allYValues), Math.max(...allYValues)],
|
|
163508
|
+
title: "GreyScaleValue (HU)"
|
|
163509
|
+
},
|
|
163510
|
+
title: "GreyScaleValues vs position",
|
|
163511
|
+
responsive: true
|
|
163512
|
+
};
|
|
163513
|
+
const myPlotDiv = document.getElementById("myPlot");
|
|
163514
|
+
plotly_js_dist_min_1.default.react(myPlotDiv, traces, layout);
|
|
163515
|
+
}
|
|
163516
|
+
clearPlotlyData() {
|
|
163517
|
+
const myPlotDiv = document.getElementById("myPlot");
|
|
163518
|
+
plotly_js_dist_min_1.default.purge(myPlotDiv);
|
|
163519
|
+
this.plotlydata = [];
|
|
163520
|
+
}
|
|
163521
|
+
}
|
|
163522
|
+
exports["default"] = LengthPlotTool;
|
|
163523
|
+
function clearToolData(element, toolName) {
|
|
163524
|
+
const toolData = getToolState(element, toolName);
|
|
163525
|
+
if (toolData && toolData.data && toolData.data.length > 0) {
|
|
163526
|
+
toolData.data.forEach((data) => {
|
|
163527
|
+
data.visible = false;
|
|
163528
|
+
});
|
|
163529
|
+
}
|
|
163530
|
+
}
|
|
163531
|
+
//to set custom offset do this: DEFAULT_TOOLS["LengthPlot"].offset=parseInt(document.getElementById("offset").value,10)
|
|
163532
|
+
//create plot in viewport in layeout doable like this:
|
|
163533
|
+
//const currentDiv = eventData.element //viewport element
|
|
163534
|
+
//const newDiv = document.createElement("div");
|
|
163535
|
+
//newDiv.id=currentDiv.id+"-Plotly"
|
|
163536
|
+
//newDiv.style="width: 100%; max-width: 600px; height: 500px;"
|
|
163537
|
+
//currentDiv.appendChild(newDiv);
|
|
163538
|
+
//offsetInput=document.createElement("input");
|
|
163539
|
+
// Set the attributes for the input element
|
|
163540
|
+
//offsetInput.type = "number";
|
|
163541
|
+
//offsetInput.classList.add("manualInput");
|
|
163542
|
+
//offsetInput.id = currentDiv.id+"-offset";
|
|
163543
|
+
//offsetInput.placeholder = "offset";
|
|
163544
|
+
//newDiv.appendChild(offsetInput);
|
|
163545
|
+
|
|
163546
|
+
|
|
163547
|
+
/***/ }),
|
|
163548
|
+
|
|
163549
|
+
/***/ 893:
|
|
163550
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
163551
|
+
|
|
163552
|
+
"use strict";
|
|
163553
|
+
|
|
163554
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
163555
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
163556
|
+
};
|
|
163557
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
163558
|
+
//external imports
|
|
163559
|
+
const plotly_js_dist_min_1 = __importDefault(__webpack_require__(2479));
|
|
163560
|
+
const cornerstone_core_1 = __importDefault(__webpack_require__(7371));
|
|
163561
|
+
const cornerstone_tools_1 = __importDefault(__webpack_require__(4030));
|
|
163562
|
+
const getToolState = cornerstone_tools_1.default.getToolState; //check
|
|
163563
|
+
const toolColors = cornerstone_tools_1.default.toolColors;
|
|
163564
|
+
const draw = cornerstone_tools_1.default.importInternal("drawing/draw");
|
|
163565
|
+
const drawLine = cornerstone_tools_1.default.importInternal("drawing/drawLine");
|
|
163566
|
+
const setShadow = cornerstone_tools_1.default.importInternal("drawing/setShadow");
|
|
163567
|
+
const getNewContext = cornerstone_tools_1.default.importInternal("drawing/getNewContext");
|
|
163568
|
+
const drawHandles = cornerstone_tools_1.default.importInternal("drawing/drawHandles");
|
|
163569
|
+
const { lengthCursor } = cornerstone_tools_1.default.importInternal("tools/cursors");
|
|
163570
|
+
const throttle = cornerstone_tools_1.default.importInternal("util/throttle");
|
|
163571
|
+
const getModule = cornerstone_tools_1.default.getModule;
|
|
163572
|
+
const getPixelSpacing = cornerstone_tools_1.default.importInternal("util/getPixelSpacing");
|
|
163573
|
+
const lineSegDistance = cornerstone_tools_1.default.importInternal("util/lineSegDistance");
|
|
163574
|
+
const BaseAnnotationTool = cornerstone_tools_1.default.importInternal("base/BaseAnnotationTool");
|
|
163575
|
+
/**
|
|
163576
|
+
* @public
|
|
163577
|
+
* @class LengthTool
|
|
163578
|
+
* @memberof Tools.Annotation
|
|
163579
|
+
* @classdesc Tool for measuring distances.
|
|
163580
|
+
* @extends Tools.Base.BaseAnnotationTool
|
|
163581
|
+
*/
|
|
163582
|
+
class ManualLengthPlotTool extends BaseAnnotationTool {
|
|
163583
|
+
constructor(props = {}) {
|
|
163584
|
+
const defaultProps = {
|
|
163585
|
+
name: "HorizontalTool",
|
|
163586
|
+
supportedInteractionTypes: ["Mouse"],
|
|
163587
|
+
svgCursor: lengthCursor,
|
|
163588
|
+
configuration: {
|
|
163589
|
+
drawHandles: true,
|
|
163590
|
+
drawHandlesOnHover: false,
|
|
163591
|
+
hideHandlesIfMoving: false,
|
|
163592
|
+
renderDashed: false,
|
|
163593
|
+
digits: 2
|
|
163594
|
+
}
|
|
163595
|
+
};
|
|
163596
|
+
super(props, defaultProps);
|
|
163597
|
+
this.name = "ManualLengthPlot";
|
|
163598
|
+
this.plotlydata = [];
|
|
163599
|
+
this.measuring = false;
|
|
163600
|
+
this.lineNumber = null;
|
|
163601
|
+
this.greenlineY = null;
|
|
163602
|
+
this.newMeasurement = false;
|
|
163603
|
+
this.configuration = {
|
|
163604
|
+
drawHandles: true,
|
|
163605
|
+
drawHandlesOnHover: false,
|
|
163606
|
+
hideHandlesIfMoving: false,
|
|
163607
|
+
renderDashed: false,
|
|
163608
|
+
digits: 2
|
|
163609
|
+
};
|
|
163610
|
+
this.handleMouseUp = () => {
|
|
163611
|
+
const eventData = this.eventData;
|
|
163612
|
+
const { element } = eventData;
|
|
163613
|
+
//const toolData: ToolData = getToolState(element, this.name);
|
|
163614
|
+
const points = this.getPointsAlongLine(this.datahandles.start, this.datahandles.end, getPixelSpacing(eventData.image).colPixelSpacing);
|
|
163615
|
+
const pixelValues = this.getPixelValuesAlongLine(this.datahandles.start, points, getPixelSpacing(eventData.image).colPixelSpacing, eventData);
|
|
163616
|
+
// Plot the graph using the extracted points and pixel values
|
|
163617
|
+
this.createPlot(points, pixelValues);
|
|
163618
|
+
};
|
|
163619
|
+
this.handleMouseUp = this.handleMouseUp.bind(this);
|
|
163620
|
+
// Add event listeners to start and stop measurements
|
|
163621
|
+
this.throttledUpdateCachedStats = throttle(this.updateCachedStats, 110);
|
|
163622
|
+
}
|
|
163623
|
+
getColor(y) {
|
|
163624
|
+
let color = "red";
|
|
163625
|
+
if (this.lineNumber === null || this.lineNumber === 3) {
|
|
163626
|
+
color = "green";
|
|
163627
|
+
this.greenlineY = y;
|
|
163628
|
+
this.lineNumber = 1;
|
|
163629
|
+
}
|
|
163630
|
+
else if (y > this.greenlineY) {
|
|
163631
|
+
color = this.color === "blue" ? "red" : "blue";
|
|
163632
|
+
this.lineNumber = this.lineNumber + 1;
|
|
163633
|
+
}
|
|
163634
|
+
else if (y < this.greenlineY) {
|
|
163635
|
+
color = this.color === "red" ? "blue" : "red";
|
|
163636
|
+
this.lineNumber = this.lineNumber + 1;
|
|
163637
|
+
}
|
|
163638
|
+
return color;
|
|
163639
|
+
}
|
|
163640
|
+
clearCanvasAndPlot(eventData) {
|
|
163641
|
+
// Clear the canvas
|
|
163642
|
+
const { element } = eventData;
|
|
163643
|
+
const toolData = getToolState(element, this.name);
|
|
163644
|
+
if (toolData && toolData.data && toolData.data.length > 0) {
|
|
163645
|
+
toolData.data.forEach((data) => {
|
|
163646
|
+
data.visible = false;
|
|
163647
|
+
});
|
|
163648
|
+
}
|
|
163649
|
+
// Clear the Plotly plot
|
|
163650
|
+
const myPlotDiv = document.getElementById("myPlot");
|
|
163651
|
+
plotly_js_dist_min_1.default.purge(myPlotDiv);
|
|
163652
|
+
this.plotlydata = [];
|
|
163653
|
+
}
|
|
163654
|
+
createNewMeasurement(eventData) {
|
|
163655
|
+
this.newMeasurement = true;
|
|
163656
|
+
if (this.lineNumber === 3) {
|
|
163657
|
+
this.clearCanvasAndPlot(eventData);
|
|
163658
|
+
}
|
|
163659
|
+
eventData.element.addEventListener("mouseup", () => this.handleMouseUp());
|
|
163660
|
+
this.eventData = eventData;
|
|
163661
|
+
const goodEventData = eventData && eventData.currentPoints && eventData.currentPoints.image;
|
|
163662
|
+
if (!goodEventData) {
|
|
163663
|
+
console.error(`required eventData not supplied to tool ${this.name}'s createNewMeasurement`);
|
|
163664
|
+
return;
|
|
163665
|
+
}
|
|
163666
|
+
const { x, y } = eventData.currentPoints.image;
|
|
163667
|
+
let color = this.getColor(y);
|
|
163668
|
+
this.color = color;
|
|
163669
|
+
return {
|
|
163670
|
+
visible: true,
|
|
163671
|
+
active: true,
|
|
163672
|
+
color: color,
|
|
163673
|
+
invalidated: true,
|
|
163674
|
+
handles: {
|
|
163675
|
+
start: {
|
|
163676
|
+
x,
|
|
163677
|
+
y,
|
|
163678
|
+
highlight: true,
|
|
163679
|
+
active: false
|
|
163680
|
+
},
|
|
163681
|
+
end: {
|
|
163682
|
+
x,
|
|
163683
|
+
y,
|
|
163684
|
+
highlight: true,
|
|
163685
|
+
active: true
|
|
163686
|
+
},
|
|
163687
|
+
textBox: {
|
|
163688
|
+
active: false,
|
|
163689
|
+
hasMoved: false,
|
|
163690
|
+
movesIndependently: false,
|
|
163691
|
+
drawnIndependently: true,
|
|
163692
|
+
allowedOutsideImage: true,
|
|
163693
|
+
hasBoundingBox: true
|
|
163694
|
+
}
|
|
163695
|
+
}
|
|
163696
|
+
};
|
|
163697
|
+
}
|
|
163698
|
+
/**
|
|
163699
|
+
*
|
|
163700
|
+
*
|
|
163701
|
+
* @param {*} element
|
|
163702
|
+
* @param {*} data
|
|
163703
|
+
* @param {*} coords
|
|
163704
|
+
* @returns {Boolean}
|
|
163705
|
+
*/
|
|
163706
|
+
pointNearTool(element, data, coords) {
|
|
163707
|
+
const hasStartAndEndHandles = data && data.handles && data.handles.start && data.handles.end;
|
|
163708
|
+
const validParameters = hasStartAndEndHandles;
|
|
163709
|
+
if (!validParameters) {
|
|
163710
|
+
console.warn(`invalid parameters supplied to tool ${this.name}'s pointNearTool`);
|
|
163711
|
+
return false;
|
|
163712
|
+
}
|
|
163713
|
+
if (data.visible === false) {
|
|
163714
|
+
return false;
|
|
163715
|
+
}
|
|
163716
|
+
return (lineSegDistance(element, data.handles.start, data.handles.end, coords) <
|
|
163717
|
+
25);
|
|
163718
|
+
}
|
|
163719
|
+
updateCachedStats(image, element, data) {
|
|
163720
|
+
const { rowPixelSpacing, colPixelSpacing } = getPixelSpacing(image);
|
|
163721
|
+
// Set rowPixelSpacing and columnPixelSpacing to 1 if they are undefined (or zero)
|
|
163722
|
+
const dx = (data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1);
|
|
163723
|
+
const dy = (data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1);
|
|
163724
|
+
// Calculate the length, and create the text variable with the millimeters or pixels suffix
|
|
163725
|
+
const length = Math.sqrt(dx * dx + dy * dy);
|
|
163726
|
+
// Store the length inside the tool for outside access
|
|
163727
|
+
data.length = length;
|
|
163728
|
+
data.invalidated = false;
|
|
163729
|
+
}
|
|
163730
|
+
renderToolData(evt) {
|
|
163731
|
+
const eventData = evt.detail;
|
|
163732
|
+
const { image, element } = eventData;
|
|
163733
|
+
const { handleRadius, drawHandlesOnHover, hideHandlesIfMoving, renderDashed } = this.configuration;
|
|
163734
|
+
const toolData = getToolState(evt.currentTarget, this.name);
|
|
163735
|
+
if (!toolData) {
|
|
163736
|
+
return;
|
|
163737
|
+
}
|
|
163738
|
+
// We have tool data for this element - iterate over each one and draw it
|
|
163739
|
+
const context = getNewContext(eventData.canvasContext.canvas);
|
|
163740
|
+
const lineDash = getModule("globalConfiguration").configuration
|
|
163741
|
+
.lineDash;
|
|
163742
|
+
let start;
|
|
163743
|
+
let end;
|
|
163744
|
+
for (let i = 0; i < toolData.data.length; i++) {
|
|
163745
|
+
const data = toolData.data[i];
|
|
163746
|
+
if (data.visible === false) {
|
|
163747
|
+
continue;
|
|
163748
|
+
}
|
|
163749
|
+
draw(context, (context) => {
|
|
163750
|
+
// Configurable shadow
|
|
163751
|
+
setShadow(context, this.configuration);
|
|
163752
|
+
const color = toolColors.getColorIfActive(data);
|
|
163753
|
+
if (data.active) {
|
|
163754
|
+
this.color = color;
|
|
163755
|
+
this.datahandles = data.handles;
|
|
163756
|
+
}
|
|
163757
|
+
const lineOptions = { color };
|
|
163758
|
+
if (renderDashed) {
|
|
163759
|
+
lineOptions.lineDash = lineDash;
|
|
163760
|
+
}
|
|
163761
|
+
start = data.handles.start;
|
|
163762
|
+
end = data.handles.end;
|
|
163763
|
+
data.handles.end.y = data.handles.start.y;
|
|
163764
|
+
// Draw the measurement line
|
|
163765
|
+
drawLine(context, element, data.handles.start, data.handles.end, lineOptions);
|
|
163766
|
+
// Draw the handles
|
|
163767
|
+
const handleOptions = {
|
|
163768
|
+
color,
|
|
163769
|
+
handleRadius,
|
|
163770
|
+
drawHandlesIfActive: drawHandlesOnHover,
|
|
163771
|
+
hideHandlesIfMoving
|
|
163772
|
+
};
|
|
163773
|
+
if (this.configuration.drawHandles) {
|
|
163774
|
+
drawHandles(context, eventData, data.handles, handleOptions);
|
|
163775
|
+
}
|
|
163776
|
+
this.currentuuid = data.uuid;
|
|
163777
|
+
// Update textbox stats
|
|
163778
|
+
if (data.invalidated === true) {
|
|
163779
|
+
if (data.length) {
|
|
163780
|
+
this.throttledUpdateCachedStats(image, element, data);
|
|
163781
|
+
}
|
|
163782
|
+
else {
|
|
163783
|
+
this.updateCachedStats(image, element, data);
|
|
163784
|
+
}
|
|
163785
|
+
}
|
|
163786
|
+
});
|
|
163787
|
+
}
|
|
163788
|
+
}
|
|
163789
|
+
getPointsAlongLine(startHandle, endHandle, colPixelSpacing) {
|
|
163790
|
+
const points = [];
|
|
163791
|
+
const numPoints = Math.floor(endHandle.x) - Math.floor(startHandle.x);
|
|
163792
|
+
let x = Math.floor(startHandle.x) + 1;
|
|
163793
|
+
points.push(x * colPixelSpacing);
|
|
163794
|
+
for (let i = 0; i < numPoints; i++) {
|
|
163795
|
+
x = x + 1;
|
|
163796
|
+
points.push(x * colPixelSpacing); //from pixels to mm
|
|
163797
|
+
}
|
|
163798
|
+
return points;
|
|
163799
|
+
}
|
|
163800
|
+
getPixelValuesAlongLine(startHandle, points, colPixelSpacing, eventData) {
|
|
163801
|
+
const pixelValues = [];
|
|
163802
|
+
const yPoint = Math.floor(startHandle.y); // Adjust this if needed
|
|
163803
|
+
for (let i = 0; i < points.length; i++) {
|
|
163804
|
+
const xPoint = Math.floor(points[i] / colPixelSpacing);
|
|
163805
|
+
const pixelValue = cornerstone_core_1.default.getStoredPixels(eventData.element, xPoint, yPoint, 1, 1)[0];
|
|
163806
|
+
// Use cornerstone to get pixel value at the specified location
|
|
163807
|
+
//const pixelValue = cornerstone.getPixelValue(image, xPoint, yPoint);
|
|
163808
|
+
pixelValues.push(pixelValue);
|
|
163809
|
+
}
|
|
163810
|
+
return pixelValues;
|
|
163811
|
+
}
|
|
163812
|
+
createPlot(points, pixelValues) {
|
|
163813
|
+
// Create a new trace for each measurement
|
|
163814
|
+
const trace = {
|
|
163815
|
+
x: points,
|
|
163816
|
+
y: pixelValues,
|
|
163817
|
+
type: "lines",
|
|
163818
|
+
line: {
|
|
163819
|
+
color: this.color
|
|
163820
|
+
}
|
|
163821
|
+
};
|
|
163822
|
+
// Add the trace to the existing data array
|
|
163823
|
+
if (this.newMeasurement) {
|
|
163824
|
+
this.plotlydata.push(trace);
|
|
163825
|
+
}
|
|
163826
|
+
else {
|
|
163827
|
+
const indexOfExistentData = this.plotlydata.findIndex(obj => obj.line.color === this.color);
|
|
163828
|
+
this.plotlydata[indexOfExistentData] = trace;
|
|
163829
|
+
}
|
|
163830
|
+
const data = [...this.plotlydata];
|
|
163831
|
+
// Combine all traces into a single data array
|
|
163832
|
+
// Adjust the axis range based on all data
|
|
163833
|
+
const allXValues = data.flatMap(trace => trace.x);
|
|
163834
|
+
const allYValues = data.flatMap(trace => trace.y);
|
|
163835
|
+
const layout = {
|
|
163836
|
+
xaxis: {
|
|
163837
|
+
range: [Math.min(...allXValues), Math.max(...allXValues)],
|
|
163838
|
+
title: "position (mm)"
|
|
163839
|
+
},
|
|
163840
|
+
yaxis: {
|
|
163841
|
+
range: [Math.min(...allYValues), Math.max(...allYValues)],
|
|
163842
|
+
title: "GreyScaleValue (HU)"
|
|
163843
|
+
},
|
|
163844
|
+
title: "GreyScaleValues vs position",
|
|
163845
|
+
responsive: true
|
|
163846
|
+
};
|
|
163847
|
+
// Display using Plotly
|
|
163848
|
+
const myPlotDiv = document.getElementById("myPlot");
|
|
163849
|
+
plotly_js_dist_min_1.default.react(myPlotDiv, data, layout);
|
|
163850
|
+
this.newMeasurement = false;
|
|
163851
|
+
}
|
|
163852
|
+
}
|
|
163853
|
+
exports["default"] = ManualLengthPlotTool;
|
|
163854
|
+
|
|
163855
|
+
|
|
163228
163856
|
/***/ }),
|
|
163229
163857
|
|
|
163230
163858
|
/***/ 4585:
|
|
@@ -163857,12 +164485,13 @@ exports.registerExternalTool = exports.setDefaultToolsProps = exports.getDefault
|
|
|
163857
164485
|
*/
|
|
163858
164486
|
const lodash_1 = __webpack_require__(6486);
|
|
163859
164487
|
const thresholdsBrushTool_1 = __importDefault(__webpack_require__(7073));
|
|
163860
|
-
// import Slice4DScrollMouseWheelTool from "./custom/4dSliceScrollTool";
|
|
163861
164488
|
const polylineScissorsTool_1 = __importDefault(__webpack_require__(8990));
|
|
163862
164489
|
const rectangleRoiOverlayTool_1 = __importDefault(__webpack_require__(1828));
|
|
163863
164490
|
const ellipticalRoiOverlayTool_1 = __importDefault(__webpack_require__(3211));
|
|
163864
164491
|
const BorderMagnifyTool_1 = __importDefault(__webpack_require__(7819));
|
|
163865
164492
|
const customMouseWheelScrollTool_1 = __importDefault(__webpack_require__(4585));
|
|
164493
|
+
const LengthPlotTool_1 = __importDefault(__webpack_require__(2775));
|
|
164494
|
+
const ManualLengthPlotTool_1 = __importDefault(__webpack_require__(893));
|
|
163866
164495
|
/**
|
|
163867
164496
|
* These tools are added with `addDefaultTools()`
|
|
163868
164497
|
*/
|
|
@@ -164068,6 +164697,42 @@ const DEFAULT_TOOLS = {
|
|
|
164068
164697
|
cleanable: true,
|
|
164069
164698
|
class: "LengthTool"
|
|
164070
164699
|
},
|
|
164700
|
+
LengthPlot: {
|
|
164701
|
+
name: "LengthPlot",
|
|
164702
|
+
viewports: "all",
|
|
164703
|
+
configuration: {
|
|
164704
|
+
drawHandles: true,
|
|
164705
|
+
drawHandlesOnHover: false,
|
|
164706
|
+
hideHandlesIfMoving: false,
|
|
164707
|
+
renderDashed: false,
|
|
164708
|
+
digits: 2,
|
|
164709
|
+
offset: 15
|
|
164710
|
+
},
|
|
164711
|
+
options: {
|
|
164712
|
+
mouseButtonMask: 1,
|
|
164713
|
+
supportedInteractionTypes: ["Mouse"]
|
|
164714
|
+
},
|
|
164715
|
+
cleanable: true,
|
|
164716
|
+
class: "LengthPlotTool"
|
|
164717
|
+
},
|
|
164718
|
+
ManualLengthPlot: {
|
|
164719
|
+
name: "ManualLengthPlot",
|
|
164720
|
+
viewports: "all",
|
|
164721
|
+
configuration: {
|
|
164722
|
+
drawHandles: true,
|
|
164723
|
+
drawHandlesOnHover: false,
|
|
164724
|
+
hideHandlesIfMoving: false,
|
|
164725
|
+
renderDashed: false,
|
|
164726
|
+
digits: 2,
|
|
164727
|
+
offset: 15
|
|
164728
|
+
},
|
|
164729
|
+
options: {
|
|
164730
|
+
mouseButtonMask: 1,
|
|
164731
|
+
supportedInteractionTypes: ["Mouse"]
|
|
164732
|
+
},
|
|
164733
|
+
cleanable: true,
|
|
164734
|
+
class: "ManualLengthPlotTool"
|
|
164735
|
+
},
|
|
164071
164736
|
Angle: {
|
|
164072
164737
|
name: "Angle",
|
|
164073
164738
|
viewports: "all",
|
|
@@ -164298,7 +164963,9 @@ const dvTools = {
|
|
|
164298
164963
|
RectangleRoiOverlayTool: rectangleRoiOverlayTool_1.default,
|
|
164299
164964
|
EllipticalRoiOverlayTool: ellipticalRoiOverlayTool_1.default,
|
|
164300
164965
|
BorderMagnifyTool: BorderMagnifyTool_1.default,
|
|
164301
|
-
CustomMouseWheelScrollTool: customMouseWheelScrollTool_1.default
|
|
164966
|
+
CustomMouseWheelScrollTool: customMouseWheelScrollTool_1.default,
|
|
164967
|
+
LengthPlotTool: LengthPlotTool_1.default,
|
|
164968
|
+
ManualLengthPlotTool: ManualLengthPlotTool_1.default
|
|
164302
164969
|
};
|
|
164303
164970
|
exports.dvTools = dvTools;
|
|
164304
164971
|
/**
|
|
@@ -166847,7 +167514,7 @@ module.exports = JSON.parse('{"x00000000":{"tag":"x00000000","vr":"UL","vm":"1",
|
|
|
166847
167514
|
/***/ ((module) => {
|
|
166848
167515
|
|
|
166849
167516
|
"use strict";
|
|
166850
|
-
module.exports = JSON.parse('{"name":"larvitar","keywords":["DICOM","imaging","medical","cornerstone"],"version":"2.1.
|
|
167517
|
+
module.exports = JSON.parse('{"name":"larvitar","keywords":["DICOM","imaging","medical","cornerstone"],"version":"2.1.9","description":"typescript library for parsing, loading, rendering and interacting with DICOM images","repository":{"url":"https://github.com/dvisionlab/Larvitar.git","type":"git"},"main":"dist/larvitar.js","types":"dist/index.d.ts","files":["dist","imaging/**/*.d.ts"],"scripts":{"coverage":"typescript-coverage-report","generate-docs":"node_modules/.bin/jsdoc -c jsdoc.json","build":"webpack --config ./bundler/webpack.prod.js && cp ./dist/larvitar.js ./docs/examples/larvitar.js","dev":"webpack --progress --config ./bundler/webpack.dev.js && cp ./dist/larvitar.js ./docs/examples/larvitar.js","dev-wip":"webpack serve --config ./bundler/webpack.dev-wip.js"},"author":"Simone Manini <simone.manini@dvisionlab.com> (https://www.dvisionlab.com)","contributors":["Mattia Ronzoni <mattia.ronzoni@dvisionlab.com> (https://www.dvisionlab.com)","Sara Zanchi <sara.zanchi@dvisionlab.com> (https://www.dvisionlab.com)","Ale Re <ale.re@dvisionlab.com> (https://www.dvisionlab.com)","Laura Borghesi Re <laura.borghesi@dvisionlab.com> (https://www.dvisionlab.com)"],"license":"MIT","dependencies":{"@rollup/plugin-commonjs":"^17.1.0","cornerstone-core":"^2.6.1","cornerstone-file-image-loader":"^0.3.0","cornerstone-tools":"^6.0.7","cornerstone-wado-image-loader":"^4.13.2","cornerstone-web-image-loader":"^2.1.1","crypto-js":"^4.1.1","dicom-character-set":"^1.0.3","dicom-parser":"^1.8.13","docdash":"^1.2.0","hammerjs":"^2.0.8","jpeg-lossless-decoder-js":"^2.0.7","keycode-js":"^3.1.0","lodash":"^4.17.15","pako":"^1.0.10","papaparse":"^5.3.0","pdfjs-dist":"^3.8.162","plotly.js-dist-min":"^2.27.1","uuid":"^8.3.2"},"devDependencies":{"@babel/core":"^7.21.8","@types/cornerstone-core":"^2.3.0","@types/crypto-js":"^4.1.1","@types/hammerjs":"^2.0.41","@types/lodash":"^4.14.192","@types/papaparse":"^5.3.7","@types/pdfjs-dist":"^2.10.378","@types/plotly.js":"^2.12.30","@types/plotly.js-dist-min":"^2.3.4","@types/uuid":"^9.0.1","babel-loader":"^9.1.2","clean-webpack-plugin":"^4.0.0","copy-webpack-plugin":"^11.0.0","fs":"^0.0.1-security","html-loader":"^4.2.0","html-webpack-plugin":"^5.5.0","ip":"^1.1.8","jsdoc":"^3.6.4","portfinder-sync":"^0.0.2","ts-loader":"^9.4.2","typescript":"^5.0.2","typescript-coverage-report":"^0.7.0","webpack":"^5.76.3","webpack-bundle-analyzer":"^4.8.0","webpack-cli":"^5.0.1","webpack-dev-server":"^4.13.1"}}');
|
|
166851
167518
|
|
|
166852
167519
|
/***/ })
|
|
166853
167520
|
|