@niivue/niivue 0.43.5 → 0.43.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/build/index.d.ts +18 -1
- package/build/index.js +92 -24
- package/build/index.js.map +1 -1
- package/build/index.min.js +1 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +92 -24
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/niivue.umd.js +14 -14
- package/package.json +1 -1
- package/src/index.html +38 -24
- package/src/niivue/index.ts +85 -22
- package/src/nvdocument.ts +18 -4
package/build/index.d.ts
CHANGED
|
@@ -645,6 +645,11 @@ type NVConfigOptions = {
|
|
|
645
645
|
multiplanarLayout: MULTIPLANAR_TYPE;
|
|
646
646
|
renderOverlayBlend: number;
|
|
647
647
|
sliceMosaicString: string;
|
|
648
|
+
centerMosaic: boolean;
|
|
649
|
+
clickToSegment: boolean;
|
|
650
|
+
clickToSegmentRadius: number;
|
|
651
|
+
clickToSegmentSteps: number;
|
|
652
|
+
clickToSegmentBright: boolean;
|
|
648
653
|
};
|
|
649
654
|
declare const DEFAULT_OPTIONS: NVConfigOptions;
|
|
650
655
|
type SceneData = {
|
|
@@ -1687,7 +1692,6 @@ declare class Niivue {
|
|
|
1687
1692
|
private resizeObserver;
|
|
1688
1693
|
syncOpts: Record<string, unknown>;
|
|
1689
1694
|
readyForSync: boolean;
|
|
1690
|
-
centerMosaic: boolean;
|
|
1691
1695
|
uiData: UIData;
|
|
1692
1696
|
back: NVImage | null;
|
|
1693
1697
|
overlays: NVImage[];
|
|
@@ -1773,6 +1777,19 @@ declare class Niivue {
|
|
|
1773
1777
|
* }
|
|
1774
1778
|
*/
|
|
1775
1779
|
onIntensityChange: (volume: NVImage) => void;
|
|
1780
|
+
/**
|
|
1781
|
+
* callback function when clickToSegment is enabled and the user clicks on the image. data contains the volume of the segmented region in mm3 and mL
|
|
1782
|
+
* @example
|
|
1783
|
+
* niivue.onClickToSegment = (data) => {
|
|
1784
|
+
* console.log('clicked to segment')
|
|
1785
|
+
* console.log('volume mm3: ', data.mm3)
|
|
1786
|
+
* console.log('volume mL: ', data.mL)
|
|
1787
|
+
* }
|
|
1788
|
+
*/
|
|
1789
|
+
onClickToSegment: (data: {
|
|
1790
|
+
mm3: number;
|
|
1791
|
+
mL: number;
|
|
1792
|
+
}) => void;
|
|
1776
1793
|
/**
|
|
1777
1794
|
* callback function to run when a new volume is loaded
|
|
1778
1795
|
* @example
|
package/build/index.js
CHANGED
|
@@ -13,7 +13,7 @@ var __publicField = (obj, key, value) => {
|
|
|
13
13
|
import { mat4 as mat46, vec2, vec3 as vec311, vec4 as vec48 } from "gl-matrix";
|
|
14
14
|
|
|
15
15
|
// package.json
|
|
16
|
-
var version = "0.43.
|
|
16
|
+
var version = "0.43.7";
|
|
17
17
|
|
|
18
18
|
// src/logger.ts
|
|
19
19
|
var _Log = class _Log {
|
|
@@ -22006,16 +22006,21 @@ var DEFAULT_OPTIONS = {
|
|
|
22006
22006
|
legendTextColor: [1, 1, 1, 1],
|
|
22007
22007
|
multiplanarLayout: 0 /* AUTO */,
|
|
22008
22008
|
renderOverlayBlend: 1,
|
|
22009
|
-
sliceMosaicString: ""
|
|
22009
|
+
sliceMosaicString: "",
|
|
22010
|
+
centerMosaic: false,
|
|
22011
|
+
clickToSegment: false,
|
|
22012
|
+
clickToSegmentRadius: 2,
|
|
22013
|
+
clickToSegmentSteps: 10,
|
|
22014
|
+
clickToSegmentBright: true
|
|
22010
22015
|
};
|
|
22011
22016
|
var INITIAL_SCENE_DATA = {
|
|
22012
22017
|
azimuth: 110,
|
|
22013
22018
|
elevation: 10,
|
|
22014
|
-
crosshairPos: vec38.
|
|
22019
|
+
crosshairPos: vec38.create(),
|
|
22015
22020
|
clipPlane: [0, 0, 0, 0],
|
|
22016
22021
|
clipPlaneDepthAziElev: [2, 0, 0],
|
|
22017
22022
|
volScaleMultiplier: 1,
|
|
22018
|
-
pan2Dxyzmm: vec46.
|
|
22023
|
+
pan2Dxyzmm: vec46.create(),
|
|
22019
22024
|
clipThick: 2,
|
|
22020
22025
|
clipVolumeLow: [0, 0, 0],
|
|
22021
22026
|
clipVolumeHigh: [1, 1, 1]
|
|
@@ -22044,7 +22049,11 @@ var NVDocument = class _NVDocument {
|
|
|
22044
22049
|
},
|
|
22045
22050
|
onZoom3DChange: () => {
|
|
22046
22051
|
},
|
|
22047
|
-
sceneData: {
|
|
22052
|
+
sceneData: {
|
|
22053
|
+
...INITIAL_SCENE_DATA,
|
|
22054
|
+
pan2Dxyzmm: vec46.fromValues(0, 0, 0, 1),
|
|
22055
|
+
crosshairPos: vec38.fromValues(0.5, 0.5, 0.5)
|
|
22056
|
+
},
|
|
22048
22057
|
get renderAzimuth() {
|
|
22049
22058
|
return this.sceneData.azimuth;
|
|
22050
22059
|
},
|
|
@@ -23779,7 +23788,6 @@ var Niivue = class _Niivue {
|
|
|
23779
23788
|
__publicField(this, "resizeObserver", null);
|
|
23780
23789
|
__publicField(this, "syncOpts", {});
|
|
23781
23790
|
__publicField(this, "readyForSync", false);
|
|
23782
|
-
__publicField(this, "centerMosaic", false);
|
|
23783
23791
|
// UI Data
|
|
23784
23792
|
__publicField(this, "uiData", {
|
|
23785
23793
|
mousedown: false,
|
|
@@ -23943,6 +23951,17 @@ var Niivue = class _Niivue {
|
|
|
23943
23951
|
*/
|
|
23944
23952
|
__publicField(this, "onIntensityChange", () => {
|
|
23945
23953
|
});
|
|
23954
|
+
/**
|
|
23955
|
+
* callback function when clickToSegment is enabled and the user clicks on the image. data contains the volume of the segmented region in mm3 and mL
|
|
23956
|
+
* @example
|
|
23957
|
+
* niivue.onClickToSegment = (data) => {
|
|
23958
|
+
* console.log('clicked to segment')
|
|
23959
|
+
* console.log('volume mm3: ', data.mm3)
|
|
23960
|
+
* console.log('volume mL: ', data.mL)
|
|
23961
|
+
* }
|
|
23962
|
+
*/
|
|
23963
|
+
__publicField(this, "onClickToSegment", () => {
|
|
23964
|
+
});
|
|
23946
23965
|
/**
|
|
23947
23966
|
* callback function to run when a new volume is loaded
|
|
23948
23967
|
* @example
|
|
@@ -24243,7 +24262,7 @@ var Niivue = class _Niivue {
|
|
|
24243
24262
|
*/
|
|
24244
24263
|
syncWith(otherNV, syncOpts = { "2d": true, "3d": true }) {
|
|
24245
24264
|
this.otherNV = otherNV;
|
|
24246
|
-
this.syncOpts = syncOpts;
|
|
24265
|
+
this.syncOpts = { ...syncOpts };
|
|
24247
24266
|
}
|
|
24248
24267
|
/**
|
|
24249
24268
|
* Sync the scene controls (orientation, crosshair location, etc.) from one Niivue instance to others. useful for using one canvas to drive another.
|
|
@@ -24280,10 +24299,12 @@ var Niivue = class _Niivue {
|
|
|
24280
24299
|
if (this.otherNV instanceof _Niivue) {
|
|
24281
24300
|
if (this.syncOpts["2d"]) {
|
|
24282
24301
|
this.otherNV.scene.crosshairPos = this.otherNV.mm2frac(thisMM);
|
|
24302
|
+
this.otherNV.scene.pan2Dxyzmm = vec48.clone(this.scene.pan2Dxyzmm);
|
|
24283
24303
|
}
|
|
24284
24304
|
if (this.syncOpts["3d"]) {
|
|
24285
24305
|
this.otherNV.scene.renderAzimuth = this.scene.renderAzimuth;
|
|
24286
24306
|
this.otherNV.scene.renderElevation = this.scene.renderElevation;
|
|
24307
|
+
this.otherNV.scene.volScaleMultiplier = this.scene.volScaleMultiplier;
|
|
24287
24308
|
}
|
|
24288
24309
|
this.otherNV.drawScene();
|
|
24289
24310
|
this.otherNV.createOnLocationChange();
|
|
@@ -24294,10 +24315,12 @@ var Niivue = class _Niivue {
|
|
|
24294
24315
|
}
|
|
24295
24316
|
if (this.syncOpts["2d"]) {
|
|
24296
24317
|
this.otherNV[i].scene.crosshairPos = this.otherNV[i].mm2frac(thisMM);
|
|
24318
|
+
this.otherNV[i].scene.pan2Dxyzmm = vec48.clone(this.scene.pan2Dxyzmm);
|
|
24297
24319
|
}
|
|
24298
24320
|
if (this.syncOpts["3d"]) {
|
|
24299
24321
|
this.otherNV[i].scene.renderAzimuth = this.scene.renderAzimuth;
|
|
24300
24322
|
this.otherNV[i].scene.renderElevation = this.scene.renderElevation;
|
|
24323
|
+
this.otherNV[i].scene.volScaleMultiplier = this.scene.volScaleMultiplier;
|
|
24301
24324
|
}
|
|
24302
24325
|
this.otherNV[i].drawScene();
|
|
24303
24326
|
this.otherNV[i].createOnLocationChange();
|
|
@@ -25021,7 +25044,10 @@ var Niivue = class _Niivue {
|
|
|
25021
25044
|
// nothing
|
|
25022
25045
|
imageType: NVIMAGE_TYPE.DCM_FOLDER
|
|
25023
25046
|
// signify that this is a dicom directory
|
|
25024
|
-
}).then((volume) =>
|
|
25047
|
+
}).then((volume) => {
|
|
25048
|
+
this.addVolume(volume);
|
|
25049
|
+
this.setDrawingEnabled(true);
|
|
25050
|
+
}).catch((e) => {
|
|
25025
25051
|
throw e;
|
|
25026
25052
|
});
|
|
25027
25053
|
}).catch((e) => {
|
|
@@ -25207,6 +25233,7 @@ var Niivue = class _Niivue {
|
|
|
25207
25233
|
this.loadDrawing(volume);
|
|
25208
25234
|
} else {
|
|
25209
25235
|
this.addVolume(volume);
|
|
25236
|
+
this.setDrawingEnabled(true);
|
|
25210
25237
|
}
|
|
25211
25238
|
}).catch((e2) => {
|
|
25212
25239
|
throw e2;
|
|
@@ -25755,7 +25782,10 @@ var Niivue = class _Niivue {
|
|
|
25755
25782
|
* @see {@link https://niivue.github.io/niivue/features/draw.ui.html | live demo usage}
|
|
25756
25783
|
*/
|
|
25757
25784
|
saveImage(options = defaultSaveImageOptions) {
|
|
25758
|
-
const saveOptions = {
|
|
25785
|
+
const saveOptions = {
|
|
25786
|
+
...defaultSaveImageOptions,
|
|
25787
|
+
...options
|
|
25788
|
+
};
|
|
25759
25789
|
const { filename, isSaveDrawing, volumeByIndex } = saveOptions;
|
|
25760
25790
|
log.debug("saveImage", filename, isSaveDrawing, volumeByIndex);
|
|
25761
25791
|
if (this.back?.dims === void 0) {
|
|
@@ -26572,7 +26602,7 @@ var Niivue = class _Niivue {
|
|
|
26572
26602
|
* @param esm - bundled version of NiiVue
|
|
26573
26603
|
* @example
|
|
26574
26604
|
* const javascript = this.generateLoadDocumentJavaScript("gl1");
|
|
26575
|
-
* const html = `<html><body><canvas id="gl1"></canvas><script type="module" async>
|
|
26605
|
+
* const html = `<html><body><canvas id="gl1"></canvas><script type="module" async>
|
|
26576
26606
|
${javascript}</script></body></html>`;
|
|
26577
26607
|
*/
|
|
26578
26608
|
async generateLoadDocumentJavaScript(canvasId, esm) {
|
|
@@ -26580,26 +26610,26 @@ var Niivue = class _Niivue {
|
|
|
26580
26610
|
const base64 = await NVUtilities.compressToBase64String(JSON.stringify(json));
|
|
26581
26611
|
const javascript = `
|
|
26582
26612
|
${esm}
|
|
26583
|
-
|
|
26584
|
-
async function saveNiivueAsHtml(pageName) {
|
|
26613
|
+
|
|
26614
|
+
async function saveNiivueAsHtml(pageName) {
|
|
26585
26615
|
//get new docstring
|
|
26586
26616
|
const docString = nv1.json();
|
|
26587
|
-
const html =
|
|
26617
|
+
const html =
|
|
26588
26618
|
document.getElementsByTagName("html")[0]
|
|
26589
26619
|
.innerHTML.replace(base64, await NVUtilities.compressToBase64String(JSON.stringify(docString)));
|
|
26590
26620
|
NVUtilities.download(html, pageName, "application/html");
|
|
26591
26621
|
}
|
|
26592
|
-
|
|
26622
|
+
|
|
26593
26623
|
var nv1 = new Niivue();
|
|
26594
|
-
nv1.attachTo("${canvasId}");
|
|
26624
|
+
nv1.attachTo("${canvasId}");
|
|
26595
26625
|
var base64 = "${base64}";
|
|
26596
26626
|
NVUtilities.decompressBase64String(base64).then((jsonText) => {
|
|
26597
26627
|
var json = JSON.parse(jsonText); // string -> JSON
|
|
26598
|
-
var doc = NVDocument.loadFromJSON(json);
|
|
26628
|
+
var doc = NVDocument.loadFromJSON(json);
|
|
26599
26629
|
nv1.loadDocument(doc);
|
|
26600
26630
|
nv1.updateGLVolume();
|
|
26601
26631
|
});
|
|
26602
|
-
|
|
26632
|
+
|
|
26603
26633
|
`;
|
|
26604
26634
|
return javascript;
|
|
26605
26635
|
}
|
|
@@ -26673,14 +26703,14 @@ var Niivue = class _Niivue {
|
|
|
26673
26703
|
<main>
|
|
26674
26704
|
<canvas id="gl1"></canvas>
|
|
26675
26705
|
</main>
|
|
26676
|
-
<script type="module" async>
|
|
26706
|
+
<script type="module" async>
|
|
26677
26707
|
${javascript}
|
|
26678
26708
|
function saveAsHtml() {
|
|
26679
26709
|
saveNiivueAsHtml("page.html");
|
|
26680
|
-
}
|
|
26710
|
+
}
|
|
26681
26711
|
// assign our event handler
|
|
26682
26712
|
var button = document.getElementById("save");
|
|
26683
|
-
button.onclick = saveAsHtml;
|
|
26713
|
+
button.onclick = saveAsHtml;
|
|
26684
26714
|
</script>
|
|
26685
26715
|
</body>
|
|
26686
26716
|
</html>`;
|
|
@@ -29739,11 +29769,43 @@ var Niivue = class _Niivue {
|
|
|
29739
29769
|
}
|
|
29740
29770
|
if (this.opts.drawingEnabled) {
|
|
29741
29771
|
const pt = this.frac2vox(this.scene.crosshairPos);
|
|
29772
|
+
if (this.opts.clickToSegment) {
|
|
29773
|
+
const radius = this.opts.clickToSegmentRadius;
|
|
29774
|
+
const steps = this.opts.clickToSegmentSteps;
|
|
29775
|
+
const brightOrDark = this.opts.clickToSegmentBright ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
|
|
29776
|
+
this.drawPenFillPts = [];
|
|
29777
|
+
this.drawPenAxCorSag = axCorSag;
|
|
29778
|
+
for (let i2 = 1; i2 <= steps; i2++) {
|
|
29779
|
+
const angle = i2 / steps * 2 * Math.PI;
|
|
29780
|
+
let xVox = pt[0] + radius * Math.cos(angle);
|
|
29781
|
+
let yVox = pt[1] + radius * Math.sin(angle);
|
|
29782
|
+
const zVox = pt[2];
|
|
29783
|
+
xVox = Math.round(xVox);
|
|
29784
|
+
yVox = Math.round(yVox);
|
|
29785
|
+
this.drawPt(xVox, yVox, zVox, this.opts.penValue);
|
|
29786
|
+
this.drawPenFillPts.push([xVox, yVox, pt[2]]);
|
|
29787
|
+
if (i2 === steps) {
|
|
29788
|
+
this.drawFloodFill([xVox, yVox, pt[2]], 0, brightOrDark, NaN, NaN, this.opts.floodFillNeighbors);
|
|
29789
|
+
}
|
|
29790
|
+
}
|
|
29791
|
+
this.drawScene();
|
|
29792
|
+
this.createOnLocationChange(axCorSag);
|
|
29793
|
+
const info = this.getDescriptives(0, [], true);
|
|
29794
|
+
this.onClickToSegment({ mL: info.volumeML, mm3: info.volumeMM3 });
|
|
29795
|
+
return;
|
|
29796
|
+
}
|
|
29742
29797
|
if (!isFinite(this.opts.penValue) || this.opts.penValue < 0 || Object.is(this.opts.penValue, -0)) {
|
|
29743
29798
|
if (!isFinite(this.opts.penValue)) {
|
|
29744
|
-
this.drawFloodFill(pt, 0, this.opts.penValue, this.opts.floodFillNeighbors);
|
|
29799
|
+
this.drawFloodFill(pt, 0, this.opts.penValue, NaN, NaN, this.opts.floodFillNeighbors);
|
|
29745
29800
|
} else {
|
|
29746
|
-
this.drawFloodFill(
|
|
29801
|
+
this.drawFloodFill(
|
|
29802
|
+
pt,
|
|
29803
|
+
Math.abs(this.opts.penValue),
|
|
29804
|
+
this.opts.penValue,
|
|
29805
|
+
NaN,
|
|
29806
|
+
NaN,
|
|
29807
|
+
this.opts.floodFillNeighbors
|
|
29808
|
+
);
|
|
29747
29809
|
}
|
|
29748
29810
|
return;
|
|
29749
29811
|
}
|
|
@@ -31311,7 +31373,13 @@ var Niivue = class _Niivue {
|
|
|
31311
31373
|
const mm2 = this.frac2mm(this.scene.crosshairPos, 0, true);
|
|
31312
31374
|
const vox = v.mm2vox(mm2);
|
|
31313
31375
|
const val = v.getValue(vox[0], vox[1], vox[2], v.frame4D);
|
|
31314
|
-
return {
|
|
31376
|
+
return {
|
|
31377
|
+
name: v.name,
|
|
31378
|
+
value: val,
|
|
31379
|
+
id: v.id,
|
|
31380
|
+
mm: mm2,
|
|
31381
|
+
vox
|
|
31382
|
+
};
|
|
31315
31383
|
}),
|
|
31316
31384
|
string: str
|
|
31317
31385
|
};
|
|
@@ -32246,7 +32314,7 @@ var Niivue = class _Niivue {
|
|
|
32246
32314
|
const scaleW = this.gl.canvas.width / mxRowWid;
|
|
32247
32315
|
const scaleH = this.effectiveCanvasHeight() / top;
|
|
32248
32316
|
scale = Math.min(scaleW, scaleH);
|
|
32249
|
-
if (this.centerMosaic) {
|
|
32317
|
+
if (this.opts.centerMosaic) {
|
|
32250
32318
|
marginLeft = Math.floor(0.5 * (this.gl.canvas.width - mxRowWid * scale));
|
|
32251
32319
|
marginTop = Math.floor(0.5 * (this.effectiveCanvasHeight() - top * scale));
|
|
32252
32320
|
}
|