larvitar 2.1.8 → 2.1.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/dist/larvitar.js CHANGED
@@ -158687,6 +158687,7 @@ const storeViewportData = function (image, elementId, viewport, data) {
158687
158687
  (0, imageStore_1.set)(["isTimeserie", elementId, data.isTimeserie]);
158688
158688
  (0, imageStore_1.set)(["isPDF", elementId, false]);
158689
158689
  (0, imageStore_1.set)(["waveform", elementId, data.waveform]);
158690
+ (0, imageStore_1.set)(["dsa", elementId, data.dsa]);
158690
158691
  };
158691
158692
  exports.storeViewportData = storeViewportData;
158692
158693
  /**
@@ -158856,6 +158857,7 @@ const getSeriesData = function (series, defaultProps) {
158856
158857
  data.isColor = series.color;
158857
158858
  data.isPDF = series.isPDF;
158858
158859
  data.waveform = series.waveform;
158860
+ data.dsa = series.dsa ? true : false;
158859
158861
  if (instance) {
158860
158862
  data.rows = instance.metadata.x00280010;
158861
158863
  data.cols = instance.metadata.x00280011;
@@ -159028,6 +159030,7 @@ const DEFAULT_VIEWPORT = {
159028
159030
  isDSAEnabled: false,
159029
159031
  isPDF: false,
159030
159032
  waveform: false,
159033
+ dsa: false,
159031
159034
  viewport: {
159032
159035
  scale: 0.0,
159033
159036
  rotation: 0.0,
@@ -159102,6 +159105,7 @@ const setValue = (store, data) => {
159102
159105
  case "isMultiframe":
159103
159106
  case "isPDF":
159104
159107
  case "waveform":
159108
+ case "dsa":
159105
159109
  case "isTimeserie":
159106
159110
  case "isDSAEnabled":
159107
159111
  case "ready":
@@ -163226,6 +163230,633 @@ function revTidMask(metadataInfo, imageIds, index) {
163226
163230
  }
163227
163231
 
163228
163232
 
163233
+ /***/ }),
163234
+
163235
+ /***/ 2775:
163236
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
163237
+
163238
+ "use strict";
163239
+
163240
+ var __importDefault = (this && this.__importDefault) || function (mod) {
163241
+ return (mod && mod.__esModule) ? mod : { "default": mod };
163242
+ };
163243
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
163244
+ //external imports
163245
+ const plotly_js_dist_min_1 = __importDefault(__webpack_require__(2479));
163246
+ const cornerstone_core_1 = __importDefault(__webpack_require__(7371));
163247
+ const cornerstone_tools_1 = __importDefault(__webpack_require__(4030));
163248
+ const getToolState = cornerstone_tools_1.default.getToolState;
163249
+ const toolColors = cornerstone_tools_1.default.toolColors;
163250
+ const draw = cornerstone_tools_1.default.importInternal("drawing/draw");
163251
+ const drawLine = cornerstone_tools_1.default.importInternal("drawing/drawLine");
163252
+ const setShadow = cornerstone_tools_1.default.importInternal("drawing/setShadow");
163253
+ const getNewContext = cornerstone_tools_1.default.importInternal("drawing/getNewContext");
163254
+ const drawHandles = cornerstone_tools_1.default.importInternal("drawing/drawHandles");
163255
+ const { lengthCursor } = cornerstone_tools_1.default.importInternal("tools/cursors");
163256
+ const throttle = cornerstone_tools_1.default.importInternal("util/throttle");
163257
+ const getModule = cornerstone_tools_1.default.getModule;
163258
+ const getPixelSpacing = cornerstone_tools_1.default.importInternal("util/getPixelSpacing");
163259
+ const lineSegDistance = cornerstone_tools_1.default.importInternal("util/lineSegDistance");
163260
+ const BaseAnnotationTool = cornerstone_tools_1.default.importInternal("base/BaseAnnotationTool");
163261
+ const default_1 = __webpack_require__(6694);
163262
+ // import cornerstoneTools from "cornerstone-tools";
163263
+ class LengthPlotTool extends BaseAnnotationTool {
163264
+ constructor(props = {}) {
163265
+ const defaultProps = {
163266
+ name: "LengthPlot",
163267
+ supportedInteractionTypes: ["Mouse"],
163268
+ svgCursor: lengthCursor,
163269
+ configuration: {
163270
+ drawHandles: true,
163271
+ drawHandlesOnHover: false,
163272
+ hideHandlesIfMoving: false,
163273
+ renderDashed: false,
163274
+ digits: 2,
163275
+ offset: 15
163276
+ }
163277
+ };
163278
+ super(props, defaultProps);
163279
+ this.name = "LengthPlot";
163280
+ this.plotlydata = [];
163281
+ this.measuring = false;
163282
+ this.configuration = {
163283
+ drawHandles: true,
163284
+ drawHandlesOnHover: false,
163285
+ hideHandlesIfMoving: false,
163286
+ renderDashed: false,
163287
+ digits: 2,
163288
+ offset: 15
163289
+ };
163290
+ this.eventData;
163291
+ this.datahandles;
163292
+ this.abovehandles;
163293
+ this.belowhandles;
163294
+ this.plotlydata = [];
163295
+ this.measuring = false;
163296
+ this.handleMouseUp = this.handleMouseUp.bind(this);
163297
+ this.throttledUpdateCachedStats = throttle(this.updateCachedStats, 110);
163298
+ }
163299
+ getRandomColor() {
163300
+ const letters = "0123456789ABCDEF";
163301
+ let color = "#";
163302
+ for (let i = 0; i < 6; i++) {
163303
+ color += letters[Math.floor(Math.random() * 16)];
163304
+ }
163305
+ return color;
163306
+ }
163307
+ handleMouseUp() {
163308
+ this.measuring = false;
163309
+ const eventData = this.eventData;
163310
+ const handleData = (handles) => {
163311
+ const points = this.getPointsAlongLine(handles.start, handles.end, getPixelSpacing(eventData.image).colPixelSpacing);
163312
+ const pixelValues = this.getPixelValuesAlongLine(handles.start, points, getPixelSpacing(eventData.image).colPixelSpacing, eventData);
163313
+ let color = "green";
163314
+ return { points, pixelValues, color };
163315
+ };
163316
+ const aboveResults = handleData(this.abovehandles);
163317
+ aboveResults.color = "red";
163318
+ const belowResults = handleData(this.belowhandles);
163319
+ belowResults.color = "blue";
163320
+ const data = [handleData(this.datahandles), aboveResults, belowResults];
163321
+ this.createPlot(...data);
163322
+ }
163323
+ createNewMeasurement(eventData) {
163324
+ this.eventData = eventData;
163325
+ clearToolData(eventData.element, this.name);
163326
+ eventData.element.addEventListener("mouseup", () => this.handleMouseUp());
163327
+ this.measuring = true;
163328
+ const goodEventData = eventData && eventData.currentPoints && eventData.currentPoints.image;
163329
+ if (!goodEventData) {
163330
+ console.error(`required eventData not supplied to tool ${this.name}'s createNewMeasurement`);
163331
+ return;
163332
+ }
163333
+ let color = "green";
163334
+ const { x, y } = eventData.currentPoints.image;
163335
+ return {
163336
+ visible: true,
163337
+ active: true,
163338
+ color: color,
163339
+ invalidated: true,
163340
+ handles: {
163341
+ start: {
163342
+ x,
163343
+ y,
163344
+ highlight: true,
163345
+ active: false
163346
+ },
163347
+ end: {
163348
+ x,
163349
+ y,
163350
+ highlight: true,
163351
+ active: true
163352
+ },
163353
+ textBox: {
163354
+ active: false,
163355
+ hasMoved: false,
163356
+ movesIndependently: false,
163357
+ drawnIndependently: true,
163358
+ allowedOutsideImage: true,
163359
+ hasBoundingBox: true
163360
+ }
163361
+ }
163362
+ };
163363
+ }
163364
+ pointNearTool(element, data, coords) {
163365
+ const hasStartAndEndHandles = data && data.handles && data.handles.start && data.handles.end;
163366
+ const validParameters = hasStartAndEndHandles;
163367
+ if (!validParameters) {
163368
+ console.warn(`invalid parameters supplied to tool ${this.name}'s pointNearTool`);
163369
+ return false;
163370
+ }
163371
+ if (data.visible === false) {
163372
+ return false;
163373
+ }
163374
+ return (lineSegDistance(element, data.handles.start, data.handles.end, coords) <
163375
+ 25);
163376
+ }
163377
+ updateCachedStats(image, element, data) {
163378
+ const { rowPixelSpacing, colPixelSpacing } = getPixelSpacing(image);
163379
+ const dx = (data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1);
163380
+ const dy = (data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1);
163381
+ const length = Math.sqrt(dx * dx + dy * dy);
163382
+ data.length = length;
163383
+ data.invalidated = false;
163384
+ }
163385
+ renderToolData(evt) {
163386
+ const eventData = evt.detail;
163387
+ const { element } = eventData;
163388
+ const { handleRadius, drawHandlesOnHover, hideHandlesIfMoving, renderDashed } = this.configuration;
163389
+ const toolData = getToolState(evt.currentTarget, this.name);
163390
+ if (!toolData) {
163391
+ return;
163392
+ }
163393
+ const context = getNewContext(eventData.canvasContext.canvas);
163394
+ const lineDash = getModule("globalConfiguration").configuration
163395
+ .lineDash;
163396
+ let start;
163397
+ let end;
163398
+ for (let i = 0; i < toolData.data.length; i++) {
163399
+ const data = toolData.data[i];
163400
+ if (data.visible === false) {
163401
+ continue;
163402
+ }
163403
+ draw(context, (context) => {
163404
+ setShadow(context, this.configuration);
163405
+ const color = toolColors.getColorIfActive(data);
163406
+ const lineOptions = { color };
163407
+ if (renderDashed) {
163408
+ lineOptions.lineDash = lineDash;
163409
+ }
163410
+ start = data.handles.start;
163411
+ end = data.handles.end;
163412
+ data.handles.end.y = data.handles.start.y;
163413
+ drawLine(context, element, data.handles.start, data.handles.end, lineOptions);
163414
+ const offset = default_1.DEFAULT_TOOLS["LengthPlot"].offset === this.configuration.offset ||
163415
+ default_1.DEFAULT_TOOLS["LengthPlot"].offset === undefined
163416
+ ? this.configuration.offset
163417
+ : default_1.DEFAULT_TOOLS["LengthPlot"].offset; //offset customisable
163418
+ //const offset = this.configuration.offset;
163419
+ const aboveHandles = {
163420
+ start: { x: start.x, y: start.y - offset },
163421
+ end: { x: end.x, y: end.y - offset }
163422
+ };
163423
+ const belowHandles = {
163424
+ start: { x: start.x, y: start.y + offset },
163425
+ end: { x: end.x, y: end.y + offset }
163426
+ };
163427
+ const abovelineOptions = { color: "red" };
163428
+ const belowlineOptions = { color: "blue" };
163429
+ drawLine(context, element, aboveHandles.start, aboveHandles.end, abovelineOptions);
163430
+ drawLine(context, element, belowHandles.start, belowHandles.end, belowlineOptions);
163431
+ const handleOptions = {
163432
+ color,
163433
+ handleRadius,
163434
+ drawHandlesIfActive: drawHandlesOnHover,
163435
+ hideHandlesIfMoving
163436
+ };
163437
+ const abovehandleOptions = {
163438
+ color: abovelineOptions.color,
163439
+ handleRadius,
163440
+ drawHandlesIfActive: drawHandlesOnHover,
163441
+ hideHandlesIfMoving
163442
+ };
163443
+ const belowhandleOptions = {
163444
+ color: belowlineOptions.color,
163445
+ handleRadius,
163446
+ drawHandlesIfActive: drawHandlesOnHover,
163447
+ hideHandlesIfMoving
163448
+ };
163449
+ if (this.configuration.drawHandles) {
163450
+ drawHandles(context, eventData, data.handles, handleOptions);
163451
+ this.datahandles = data.handles;
163452
+ this.abovehandles = aboveHandles;
163453
+ this.belowhandles = belowHandles;
163454
+ drawHandles(context, eventData, aboveHandles, abovehandleOptions);
163455
+ drawHandles(context, eventData, belowHandles, belowhandleOptions);
163456
+ }
163457
+ });
163458
+ }
163459
+ }
163460
+ getPointsAlongLine(startHandle, endHandle, colPixelSpacing) {
163461
+ let points = [];
163462
+ const addPoints = (start, end, step) => {
163463
+ const startX = Math.floor(start.x) + 1;
163464
+ const numPoints = Math.floor(end.x) - startX;
163465
+ points = new Array(numPoints + 1);
163466
+ for (let i = 0; i <= numPoints; i++) {
163467
+ points[i] = (startX + i) * step;
163468
+ }
163469
+ };
163470
+ if (endHandle.x > startHandle.x) {
163471
+ addPoints(startHandle, endHandle, colPixelSpacing);
163472
+ }
163473
+ if (endHandle.x < startHandle.x) {
163474
+ addPoints(endHandle, startHandle, colPixelSpacing);
163475
+ }
163476
+ return points;
163477
+ }
163478
+ getPixelValuesAlongLine(startHandle, points, colPixelSpacing, eventData) {
163479
+ const pixelValues = new Array(points.length);
163480
+ const yPoint = Math.floor(startHandle.y);
163481
+ const addPixelValues = (xPoints, startIndex) => {
163482
+ const pixelValuesBatch = cornerstone_core_1.default.getStoredPixels(eventData.element, xPoints[0], yPoint, xPoints.length, 1);
163483
+ for (let i = 0; i < pixelValuesBatch.length; i++) {
163484
+ pixelValues[startIndex + i] = pixelValuesBatch[i];
163485
+ }
163486
+ };
163487
+ for (let i = 0; i < points.length; i++) {
163488
+ const xPoint = Math.floor(points[i] / colPixelSpacing);
163489
+ addPixelValues([xPoint], i);
163490
+ }
163491
+ return pixelValues;
163492
+ }
163493
+ createPlot(...dataSets) {
163494
+ const traces = dataSets.map(({ points, pixelValues, color }) => ({
163495
+ x: points,
163496
+ y: pixelValues,
163497
+ type: "lines",
163498
+ line: {
163499
+ color
163500
+ }
163501
+ }));
163502
+ this.plotlydata = traces;
163503
+ const allXValues = dataSets.flatMap(dataSet => dataSet.points);
163504
+ const allYValues = dataSets.flatMap(dataSet => dataSet.pixelValues);
163505
+ const layout = {
163506
+ xaxis: {
163507
+ range: [Math.min(...allXValues), Math.max(...allXValues)],
163508
+ title: "position (mm)"
163509
+ },
163510
+ yaxis: {
163511
+ range: [Math.min(...allYValues), Math.max(...allYValues)],
163512
+ title: "GreyScaleValue (HU)"
163513
+ },
163514
+ title: "GreyScaleValues vs position",
163515
+ responsive: true
163516
+ };
163517
+ const myPlotDiv = document.getElementById("myPlot");
163518
+ plotly_js_dist_min_1.default.react(myPlotDiv, traces, layout);
163519
+ }
163520
+ clearPlotlyData() {
163521
+ const myPlotDiv = document.getElementById("myPlot");
163522
+ plotly_js_dist_min_1.default.purge(myPlotDiv);
163523
+ this.plotlydata = [];
163524
+ }
163525
+ }
163526
+ exports["default"] = LengthPlotTool;
163527
+ function clearToolData(element, toolName) {
163528
+ const toolData = getToolState(element, toolName);
163529
+ if (toolData && toolData.data && toolData.data.length > 0) {
163530
+ toolData.data.forEach((data) => {
163531
+ data.visible = false;
163532
+ });
163533
+ }
163534
+ }
163535
+ //to set custom offset do this: DEFAULT_TOOLS["LengthPlot"].offset=parseInt(document.getElementById("offset").value,10)
163536
+ //create plot in viewport in layeout doable like this:
163537
+ //const currentDiv = eventData.element //viewport element
163538
+ //const newDiv = document.createElement("div");
163539
+ //newDiv.id=currentDiv.id+"-Plotly"
163540
+ //newDiv.style="width: 100%; max-width: 600px; height: 500px;"
163541
+ //currentDiv.appendChild(newDiv);
163542
+ //offsetInput=document.createElement("input");
163543
+ // Set the attributes for the input element
163544
+ //offsetInput.type = "number";
163545
+ //offsetInput.classList.add("manualInput");
163546
+ //offsetInput.id = currentDiv.id+"-offset";
163547
+ //offsetInput.placeholder = "offset";
163548
+ //newDiv.appendChild(offsetInput);
163549
+
163550
+
163551
+ /***/ }),
163552
+
163553
+ /***/ 893:
163554
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
163555
+
163556
+ "use strict";
163557
+
163558
+ var __importDefault = (this && this.__importDefault) || function (mod) {
163559
+ return (mod && mod.__esModule) ? mod : { "default": mod };
163560
+ };
163561
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
163562
+ //external imports
163563
+ const plotly_js_dist_min_1 = __importDefault(__webpack_require__(2479));
163564
+ const cornerstone_core_1 = __importDefault(__webpack_require__(7371));
163565
+ const cornerstone_tools_1 = __importDefault(__webpack_require__(4030));
163566
+ const getToolState = cornerstone_tools_1.default.getToolState; //check
163567
+ const toolColors = cornerstone_tools_1.default.toolColors;
163568
+ const draw = cornerstone_tools_1.default.importInternal("drawing/draw");
163569
+ const drawLine = cornerstone_tools_1.default.importInternal("drawing/drawLine");
163570
+ const setShadow = cornerstone_tools_1.default.importInternal("drawing/setShadow");
163571
+ const getNewContext = cornerstone_tools_1.default.importInternal("drawing/getNewContext");
163572
+ const drawHandles = cornerstone_tools_1.default.importInternal("drawing/drawHandles");
163573
+ const { lengthCursor } = cornerstone_tools_1.default.importInternal("tools/cursors");
163574
+ const throttle = cornerstone_tools_1.default.importInternal("util/throttle");
163575
+ const getModule = cornerstone_tools_1.default.getModule;
163576
+ const getPixelSpacing = cornerstone_tools_1.default.importInternal("util/getPixelSpacing");
163577
+ const lineSegDistance = cornerstone_tools_1.default.importInternal("util/lineSegDistance");
163578
+ const BaseAnnotationTool = cornerstone_tools_1.default.importInternal("base/BaseAnnotationTool");
163579
+ /**
163580
+ * @public
163581
+ * @class LengthTool
163582
+ * @memberof Tools.Annotation
163583
+ * @classdesc Tool for measuring distances.
163584
+ * @extends Tools.Base.BaseAnnotationTool
163585
+ */
163586
+ class ManualLengthPlotTool extends BaseAnnotationTool {
163587
+ constructor(props = {}) {
163588
+ const defaultProps = {
163589
+ name: "HorizontalTool",
163590
+ supportedInteractionTypes: ["Mouse"],
163591
+ svgCursor: lengthCursor,
163592
+ configuration: {
163593
+ drawHandles: true,
163594
+ drawHandlesOnHover: false,
163595
+ hideHandlesIfMoving: false,
163596
+ renderDashed: false,
163597
+ digits: 2
163598
+ }
163599
+ };
163600
+ super(props, defaultProps);
163601
+ this.name = "ManualLengthPlot";
163602
+ this.plotlydata = [];
163603
+ this.measuring = false;
163604
+ this.lineNumber = null;
163605
+ this.greenlineY = null;
163606
+ this.newMeasurement = false;
163607
+ this.configuration = {
163608
+ drawHandles: true,
163609
+ drawHandlesOnHover: false,
163610
+ hideHandlesIfMoving: false,
163611
+ renderDashed: false,
163612
+ digits: 2
163613
+ };
163614
+ this.handleMouseUp = () => {
163615
+ const eventData = this.eventData;
163616
+ const { element } = eventData;
163617
+ //const toolData: ToolData = getToolState(element, this.name);
163618
+ const points = this.getPointsAlongLine(this.datahandles.start, this.datahandles.end, getPixelSpacing(eventData.image).colPixelSpacing);
163619
+ const pixelValues = this.getPixelValuesAlongLine(this.datahandles.start, points, getPixelSpacing(eventData.image).colPixelSpacing, eventData);
163620
+ // Plot the graph using the extracted points and pixel values
163621
+ this.createPlot(points, pixelValues);
163622
+ };
163623
+ this.handleMouseUp = this.handleMouseUp.bind(this);
163624
+ // Add event listeners to start and stop measurements
163625
+ this.throttledUpdateCachedStats = throttle(this.updateCachedStats, 110);
163626
+ }
163627
+ getColor(y) {
163628
+ let color = "red";
163629
+ if (this.lineNumber === null || this.lineNumber === 3) {
163630
+ color = "green";
163631
+ this.greenlineY = y;
163632
+ this.lineNumber = 1;
163633
+ }
163634
+ else if (y > this.greenlineY) {
163635
+ color = this.color === "blue" ? "red" : "blue";
163636
+ this.lineNumber = this.lineNumber + 1;
163637
+ }
163638
+ else if (y < this.greenlineY) {
163639
+ color = this.color === "red" ? "blue" : "red";
163640
+ this.lineNumber = this.lineNumber + 1;
163641
+ }
163642
+ return color;
163643
+ }
163644
+ clearCanvasAndPlot(eventData) {
163645
+ // Clear the canvas
163646
+ const { element } = eventData;
163647
+ const toolData = getToolState(element, this.name);
163648
+ if (toolData && toolData.data && toolData.data.length > 0) {
163649
+ toolData.data.forEach((data) => {
163650
+ data.visible = false;
163651
+ });
163652
+ }
163653
+ // Clear the Plotly plot
163654
+ const myPlotDiv = document.getElementById("myPlot");
163655
+ plotly_js_dist_min_1.default.purge(myPlotDiv);
163656
+ this.plotlydata = [];
163657
+ }
163658
+ createNewMeasurement(eventData) {
163659
+ this.newMeasurement = true;
163660
+ if (this.lineNumber === 3) {
163661
+ this.clearCanvasAndPlot(eventData);
163662
+ }
163663
+ eventData.element.addEventListener("mouseup", () => this.handleMouseUp());
163664
+ this.eventData = eventData;
163665
+ const goodEventData = eventData && eventData.currentPoints && eventData.currentPoints.image;
163666
+ if (!goodEventData) {
163667
+ console.error(`required eventData not supplied to tool ${this.name}'s createNewMeasurement`);
163668
+ return;
163669
+ }
163670
+ const { x, y } = eventData.currentPoints.image;
163671
+ let color = this.getColor(y);
163672
+ this.color = color;
163673
+ return {
163674
+ visible: true,
163675
+ active: true,
163676
+ color: color,
163677
+ invalidated: true,
163678
+ handles: {
163679
+ start: {
163680
+ x,
163681
+ y,
163682
+ highlight: true,
163683
+ active: false
163684
+ },
163685
+ end: {
163686
+ x,
163687
+ y,
163688
+ highlight: true,
163689
+ active: true
163690
+ },
163691
+ textBox: {
163692
+ active: false,
163693
+ hasMoved: false,
163694
+ movesIndependently: false,
163695
+ drawnIndependently: true,
163696
+ allowedOutsideImage: true,
163697
+ hasBoundingBox: true
163698
+ }
163699
+ }
163700
+ };
163701
+ }
163702
+ /**
163703
+ *
163704
+ *
163705
+ * @param {*} element
163706
+ * @param {*} data
163707
+ * @param {*} coords
163708
+ * @returns {Boolean}
163709
+ */
163710
+ pointNearTool(element, data, coords) {
163711
+ const hasStartAndEndHandles = data && data.handles && data.handles.start && data.handles.end;
163712
+ const validParameters = hasStartAndEndHandles;
163713
+ if (!validParameters) {
163714
+ console.warn(`invalid parameters supplied to tool ${this.name}'s pointNearTool`);
163715
+ return false;
163716
+ }
163717
+ if (data.visible === false) {
163718
+ return false;
163719
+ }
163720
+ return (lineSegDistance(element, data.handles.start, data.handles.end, coords) <
163721
+ 25);
163722
+ }
163723
+ updateCachedStats(image, element, data) {
163724
+ const { rowPixelSpacing, colPixelSpacing } = getPixelSpacing(image);
163725
+ // Set rowPixelSpacing and columnPixelSpacing to 1 if they are undefined (or zero)
163726
+ const dx = (data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1);
163727
+ const dy = (data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1);
163728
+ // Calculate the length, and create the text variable with the millimeters or pixels suffix
163729
+ const length = Math.sqrt(dx * dx + dy * dy);
163730
+ // Store the length inside the tool for outside access
163731
+ data.length = length;
163732
+ data.invalidated = false;
163733
+ }
163734
+ renderToolData(evt) {
163735
+ const eventData = evt.detail;
163736
+ const { image, element } = eventData;
163737
+ const { handleRadius, drawHandlesOnHover, hideHandlesIfMoving, renderDashed } = this.configuration;
163738
+ const toolData = getToolState(evt.currentTarget, this.name);
163739
+ if (!toolData) {
163740
+ return;
163741
+ }
163742
+ // We have tool data for this element - iterate over each one and draw it
163743
+ const context = getNewContext(eventData.canvasContext.canvas);
163744
+ const lineDash = getModule("globalConfiguration").configuration
163745
+ .lineDash;
163746
+ let start;
163747
+ let end;
163748
+ for (let i = 0; i < toolData.data.length; i++) {
163749
+ const data = toolData.data[i];
163750
+ if (data.visible === false) {
163751
+ continue;
163752
+ }
163753
+ draw(context, (context) => {
163754
+ // Configurable shadow
163755
+ setShadow(context, this.configuration);
163756
+ const color = toolColors.getColorIfActive(data);
163757
+ if (data.active) {
163758
+ this.color = color;
163759
+ this.datahandles = data.handles;
163760
+ }
163761
+ const lineOptions = { color };
163762
+ if (renderDashed) {
163763
+ lineOptions.lineDash = lineDash;
163764
+ }
163765
+ start = data.handles.start;
163766
+ end = data.handles.end;
163767
+ data.handles.end.y = data.handles.start.y;
163768
+ // Draw the measurement line
163769
+ drawLine(context, element, data.handles.start, data.handles.end, lineOptions);
163770
+ // Draw the handles
163771
+ const handleOptions = {
163772
+ color,
163773
+ handleRadius,
163774
+ drawHandlesIfActive: drawHandlesOnHover,
163775
+ hideHandlesIfMoving
163776
+ };
163777
+ if (this.configuration.drawHandles) {
163778
+ drawHandles(context, eventData, data.handles, handleOptions);
163779
+ }
163780
+ this.currentuuid = data.uuid;
163781
+ // Update textbox stats
163782
+ if (data.invalidated === true) {
163783
+ if (data.length) {
163784
+ this.throttledUpdateCachedStats(image, element, data);
163785
+ }
163786
+ else {
163787
+ this.updateCachedStats(image, element, data);
163788
+ }
163789
+ }
163790
+ });
163791
+ }
163792
+ }
163793
+ getPointsAlongLine(startHandle, endHandle, colPixelSpacing) {
163794
+ const points = [];
163795
+ const numPoints = Math.floor(endHandle.x) - Math.floor(startHandle.x);
163796
+ let x = Math.floor(startHandle.x) + 1;
163797
+ points.push(x * colPixelSpacing);
163798
+ for (let i = 0; i < numPoints; i++) {
163799
+ x = x + 1;
163800
+ points.push(x * colPixelSpacing); //from pixels to mm
163801
+ }
163802
+ return points;
163803
+ }
163804
+ getPixelValuesAlongLine(startHandle, points, colPixelSpacing, eventData) {
163805
+ const pixelValues = [];
163806
+ const yPoint = Math.floor(startHandle.y); // Adjust this if needed
163807
+ for (let i = 0; i < points.length; i++) {
163808
+ const xPoint = Math.floor(points[i] / colPixelSpacing);
163809
+ const pixelValue = cornerstone_core_1.default.getStoredPixels(eventData.element, xPoint, yPoint, 1, 1)[0];
163810
+ // Use cornerstone to get pixel value at the specified location
163811
+ //const pixelValue = cornerstone.getPixelValue(image, xPoint, yPoint);
163812
+ pixelValues.push(pixelValue);
163813
+ }
163814
+ return pixelValues;
163815
+ }
163816
+ createPlot(points, pixelValues) {
163817
+ // Create a new trace for each measurement
163818
+ const trace = {
163819
+ x: points,
163820
+ y: pixelValues,
163821
+ type: "lines",
163822
+ line: {
163823
+ color: this.color
163824
+ }
163825
+ };
163826
+ // Add the trace to the existing data array
163827
+ if (this.newMeasurement) {
163828
+ this.plotlydata.push(trace);
163829
+ }
163830
+ else {
163831
+ const indexOfExistentData = this.plotlydata.findIndex(obj => obj.line.color === this.color);
163832
+ this.plotlydata[indexOfExistentData] = trace;
163833
+ }
163834
+ const data = [...this.plotlydata];
163835
+ // Combine all traces into a single data array
163836
+ // Adjust the axis range based on all data
163837
+ const allXValues = data.flatMap(trace => trace.x);
163838
+ const allYValues = data.flatMap(trace => trace.y);
163839
+ const layout = {
163840
+ xaxis: {
163841
+ range: [Math.min(...allXValues), Math.max(...allXValues)],
163842
+ title: "position (mm)"
163843
+ },
163844
+ yaxis: {
163845
+ range: [Math.min(...allYValues), Math.max(...allYValues)],
163846
+ title: "GreyScaleValue (HU)"
163847
+ },
163848
+ title: "GreyScaleValues vs position",
163849
+ responsive: true
163850
+ };
163851
+ // Display using Plotly
163852
+ const myPlotDiv = document.getElementById("myPlot");
163853
+ plotly_js_dist_min_1.default.react(myPlotDiv, data, layout);
163854
+ this.newMeasurement = false;
163855
+ }
163856
+ }
163857
+ exports["default"] = ManualLengthPlotTool;
163858
+
163859
+
163229
163860
  /***/ }),
163230
163861
 
163231
163862
  /***/ 4585:
@@ -163858,12 +164489,13 @@ exports.registerExternalTool = exports.setDefaultToolsProps = exports.getDefault
163858
164489
  */
163859
164490
  const lodash_1 = __webpack_require__(6486);
163860
164491
  const thresholdsBrushTool_1 = __importDefault(__webpack_require__(7073));
163861
- // import Slice4DScrollMouseWheelTool from "./custom/4dSliceScrollTool";
163862
164492
  const polylineScissorsTool_1 = __importDefault(__webpack_require__(8990));
163863
164493
  const rectangleRoiOverlayTool_1 = __importDefault(__webpack_require__(1828));
163864
164494
  const ellipticalRoiOverlayTool_1 = __importDefault(__webpack_require__(3211));
163865
164495
  const BorderMagnifyTool_1 = __importDefault(__webpack_require__(7819));
163866
164496
  const customMouseWheelScrollTool_1 = __importDefault(__webpack_require__(4585));
164497
+ const LengthPlotTool_1 = __importDefault(__webpack_require__(2775));
164498
+ const ManualLengthPlotTool_1 = __importDefault(__webpack_require__(893));
163867
164499
  /**
163868
164500
  * These tools are added with `addDefaultTools()`
163869
164501
  */
@@ -164069,6 +164701,42 @@ const DEFAULT_TOOLS = {
164069
164701
  cleanable: true,
164070
164702
  class: "LengthTool"
164071
164703
  },
164704
+ LengthPlot: {
164705
+ name: "LengthPlot",
164706
+ viewports: "all",
164707
+ configuration: {
164708
+ drawHandles: true,
164709
+ drawHandlesOnHover: false,
164710
+ hideHandlesIfMoving: false,
164711
+ renderDashed: false,
164712
+ digits: 2,
164713
+ offset: 15
164714
+ },
164715
+ options: {
164716
+ mouseButtonMask: 1,
164717
+ supportedInteractionTypes: ["Mouse"]
164718
+ },
164719
+ cleanable: true,
164720
+ class: "LengthPlotTool"
164721
+ },
164722
+ ManualLengthPlot: {
164723
+ name: "ManualLengthPlot",
164724
+ viewports: "all",
164725
+ configuration: {
164726
+ drawHandles: true,
164727
+ drawHandlesOnHover: false,
164728
+ hideHandlesIfMoving: false,
164729
+ renderDashed: false,
164730
+ digits: 2,
164731
+ offset: 15
164732
+ },
164733
+ options: {
164734
+ mouseButtonMask: 1,
164735
+ supportedInteractionTypes: ["Mouse"]
164736
+ },
164737
+ cleanable: true,
164738
+ class: "ManualLengthPlotTool"
164739
+ },
164072
164740
  Angle: {
164073
164741
  name: "Angle",
164074
164742
  viewports: "all",
@@ -164299,7 +164967,9 @@ const dvTools = {
164299
164967
  RectangleRoiOverlayTool: rectangleRoiOverlayTool_1.default,
164300
164968
  EllipticalRoiOverlayTool: ellipticalRoiOverlayTool_1.default,
164301
164969
  BorderMagnifyTool: BorderMagnifyTool_1.default,
164302
- CustomMouseWheelScrollTool: customMouseWheelScrollTool_1.default
164970
+ CustomMouseWheelScrollTool: customMouseWheelScrollTool_1.default,
164971
+ LengthPlotTool: LengthPlotTool_1.default,
164972
+ ManualLengthPlotTool: ManualLengthPlotTool_1.default
164303
164973
  };
164304
164974
  exports.dvTools = dvTools;
164305
164975
  /**
@@ -166848,7 +167518,7 @@ module.exports = JSON.parse('{"x00000000":{"tag":"x00000000","vr":"UL","vm":"1",
166848
167518
  /***/ ((module) => {
166849
167519
 
166850
167520
  "use strict";
166851
- module.exports = JSON.parse('{"name":"larvitar","keywords":["DICOM","imaging","medical","cornerstone"],"version":"2.1.8","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"}}');
167521
+ module.exports = JSON.parse('{"name":"larvitar","keywords":["DICOM","imaging","medical","cornerstone"],"version":"2.1.10","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"}}');
166852
167522
 
166853
167523
  /***/ })
166854
167524