@niivue/niivue 0.24.3 → 0.26.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@niivue/niivue",
3
- "version": "0.24.3",
3
+ "version": "0.26.2",
4
4
  "description": "minimal webgl2 nifti image viewer",
5
5
  "main": "./src/niivue.js",
6
6
  "unpkg": "./dist/niivue.umd.js",
@@ -72,7 +72,7 @@ colortables.prototype.makeLut = function (Rs, Gs, Bs, As, Is) {
72
72
  }
73
73
  if (this.gamma === 1.0) return lut;
74
74
  for (var i = 0; i < 255 * 4; i++) {
75
- //lut[i] = ((lut[i] / 255) ^ (1 / this.gamma)) * 255
75
+ if (i % 4 === 3) continue; //gamma changes RGB, not Alpha
76
76
  lut[i] = Math.pow(lut[i] / 255, 1 / this.gamma) * 255;
77
77
  }
78
78
  return lut;
package/src/index.html CHANGED
@@ -87,7 +87,8 @@
87
87
  // example of using the 'location' change event with a callback function
88
88
  nv1.on('location', (data) => {
89
89
  // data is an object with properties: {mm: [N N N], vox: [N N N], frac: [N N N]}
90
- document.getElementById('location').innerHTML = 'voxel location: ' + data.vox + ' ' + data.values
90
+ //document.getElementById('location').innerHTML = 'voxel location: ' + data.vox + ' ' + data.values
91
+ document.getElementById('location').innerHTML = data.xy
91
92
  })
92
93
 
93
94
  nv1.on('imageLoaded', (image) => {
@@ -99,7 +100,7 @@
99
100
  })
100
101
 
101
102
  setTimeout(() => {
102
- //nv1.saveImage('test.nii.gz')
103
+ //nv1.saveScene('test.png') // if no filename, then will use date string
103
104
  }, 2000)
104
105
 
105
106
  </script>
@@ -51,6 +51,8 @@
51
51
  <button id="growcut">grow cut</button>
52
52
  <input type="checkbox" id="check1" name="check1" checked>
53
53
  <label for="check1">fill pen overwrites</label>
54
+ <input type="checkbox" id="check3" name="check3" unchecked>
55
+ <label for="check3">World space</label>
54
56
 
55
57
  <div class="slidecontainer">
56
58
  drawing opacity <input type="range" min="0" max="100" value="80" class="slider" id="drawOpacity">
@@ -72,8 +74,10 @@
72
74
  <!-- <script type="module" src="./index.js">
73
75
  </script> -->
74
76
  <script type="module" async>
75
-
76
-
77
+ document.getElementById("check3").addEventListener("change", doCheck3Click);
78
+ function doCheck3Click() {
79
+ nv1.setSliceMM(this.checked);
80
+ }
77
81
  document.getElementById("drawOpacity").addEventListener("change", doDrawOpacity);
78
82
  function doDrawOpacity(){
79
83
  nv1.setDrawOpacity(this.value * 0.01);
@@ -177,6 +181,7 @@
177
181
  })
178
182
  nv1.setRadiologicalConvention(false)
179
183
  nv1.attachTo('gl1')
184
+ nv1.setSliceMM(true);
180
185
  //nv1.setInterpolation(1);
181
186
  await nv1.loadVolumes(volumeList1)
182
187
  nv1.getDescriptives(0, false);
@@ -0,0 +1,229 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+ <meta name="viewport" content="width=device-width,initial-scale=1.0">
8
+ <title>NiiVue</title>
9
+ <style>
10
+ section {
11
+ margin: 20px;
12
+ }
13
+ </style>
14
+ </head>
15
+
16
+ <body style="font-family: sans-serif;">
17
+ <div id="app">
18
+ <noscript>
19
+ <strong>niivue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
20
+ </noscript>
21
+
22
+ <section>
23
+ <h1>
24
+ hot reloadable development preview
25
+ </h1>
26
+ <div class="slidecontainer">
27
+ X Pan <input type="range" min="-30" max="30" value="0" class="slider" id="xSlider">
28
+ </div>
29
+ <div class="slidecontainer">
30
+ Y Pan <input type="range" min="-30" max="30" value="0" class="slider" id="ySlider">
31
+ </div>
32
+ <div class="slidecontainer">
33
+ Z Pan <input type="range" min="-30" max="30" value="0" class="slider" id="zSlider">
34
+ </div>
35
+ <div class="slidecontainer">
36
+ Zoom <input type="range" min="1" max="40" value="10" class="slider" id="zoomSlider">
37
+ </div>
38
+ <div class="slidecontainer">
39
+ Mesh Visibility <input type="range" min="0" max="11" value="11" class="slider" id="dxSlider">
40
+ </div>
41
+ <div class="slidecontainer">
42
+ gamma <input type="range" min="1" max="20" value="10" class="slider" id="gamma">
43
+ </div>
44
+ <input type="checkbox" id="check1" name="check1" unchecked>
45
+ <label for="check1">Radiological</label>
46
+ <input type="checkbox" id="check2" name="check2" unchecked>
47
+ <label for="check2">Corner text</label>
48
+ <input type="checkbox" id="check3" name="check3" checked>
49
+ <label for="check3">World space</label>
50
+ <input type="checkbox" id="check4" name="check4" unchecked>
51
+ <label for="check4">Drag measurement</label>
52
+ <input type="checkbox" id="check5" name="check5" unchecked>
53
+ <label for="check5">Ruler</label>
54
+ <input type="checkbox" id="check6" name="check6" unchecked>
55
+ <label for="check6">Nose left</label>
56
+ <input type="checkbox" id="check7" name="check7" checked>
57
+ <label for="check7">Colorbar</label>
58
+ <input type="checkbox" id="check8" name="check8" checked>
59
+ <label for="check8">Negative colors</label>
60
+ </section>
61
+ <!-- demo 1 -->
62
+ <section>
63
+ <div id="demo1" style="width:98%; height:480px;">
64
+ <canvas id="gl1" height=480 width=480>
65
+ </canvas>
66
+ </div>
67
+ </section>
68
+
69
+ <section>
70
+ <p id="location"></p>
71
+ </section>
72
+
73
+ <!-- <script type="module" src="./index.js">
74
+ </script> -->
75
+ <script type="module" async>
76
+ var slider = document.getElementById("gamma");
77
+ slider.oninput = function() {
78
+ nv1.setGamma(0.1 * this.value)
79
+ }
80
+ function doSlider() {
81
+ var sx = document.getElementById("xSlider");
82
+ var sy = document.getElementById("ySlider");
83
+ var sz =document.getElementById("zSlider");
84
+ var szoom =document.getElementById("zoomSlider");
85
+
86
+ nv1.setPan2Dxyzmm([parseInt(sx.value),parseInt(sy.value), parseInt(sz.value), 0.1 * parseInt(szoom.value)])
87
+ }
88
+ var xslider = document.getElementById("xSlider");
89
+ xslider.oninput = function() {
90
+ doSlider()
91
+ }
92
+ var yslider = document.getElementById("ySlider");
93
+ yslider.oninput = function() {
94
+ doSlider()
95
+ }
96
+ var zslider = document.getElementById("zSlider");
97
+ zslider.oninput = function() {
98
+ doSlider()
99
+ }
100
+ var zoomslider = document.getElementById("zoomSlider");
101
+ zoomslider.oninput = function() {
102
+ doSlider()
103
+ }
104
+ var dxslider = document.getElementById("dxSlider");
105
+ dxslider.oninput = function() {
106
+ let dx = parseFloat(this.value);
107
+ if (dx > 10)
108
+ dx = Infinity;
109
+ nv1.setMeshThicknessOn2D(dx);
110
+ }
111
+ document.getElementById("check1").addEventListener("change", doCheckClick);
112
+ function doCheckClick() {
113
+ nv1.setRadiologicalConvention(this.checked);
114
+ }
115
+ document.getElementById("check2").addEventListener("change", doCheck2Click);
116
+ function doCheck2Click() {
117
+ nv1.setCornerOrientationText(this.checked);
118
+ }
119
+ document.getElementById("check3").addEventListener("change", doCheck3Click);
120
+ function doCheck3Click() {
121
+ nv1.setSliceMM(this.checked);
122
+ }
123
+ document.getElementById("check4").addEventListener("change", doCheck4Click);
124
+ function doCheck4Click() {
125
+ nv1.opts.isDragShowsMeasurementTool = this.checked;
126
+ }
127
+ document.getElementById("check5").addEventListener("change", doCheck5Click);
128
+ function doCheck5Click() {
129
+ nv1.opts.isRuler = this.checked;
130
+ nv1.drawScene();
131
+ }
132
+ document.getElementById("check6").addEventListener("change", doCheck6Click);
133
+ function doCheck6Click() {
134
+ nv1.opts.sagittalNoseLeft = this.checked;
135
+ nv1.drawScene();
136
+ }
137
+ document.getElementById("check7").addEventListener("change", doCheck7Click);
138
+ function doCheck7Click() {
139
+ nv1.opts.isColorbar = this.checked;
140
+ nv1.drawScene();
141
+ }
142
+ document.getElementById("check8").addEventListener("change", doCheck8Click);
143
+ function doCheck8Click() {
144
+ if (this.checked)
145
+ nv1.setColorMapNegative(nv1.volumes[1].id,"winter");
146
+ else
147
+ nv1.setColorMapNegative(nv1.volumes[1].id,"");
148
+ nv1.drawScene();
149
+ }
150
+ import { Niivue } from './niivue.js'
151
+ import {NVImage} from './nvimage.js'
152
+ import {NVMesh} from './nvmesh.js'
153
+ let query = window.location.search
154
+ const params = new URLSearchParams(query);
155
+ let url = params.get('url')
156
+ var volumeList1 = [
157
+ // first item is brackground image
158
+ {
159
+ //url: url ? url : "../demos/images/FLAIR.nii.gz",//"./AIL.nii.gz",//"./images/RAS.nii.gz", "./images/spm152.nii.gz",
160
+ url: url ? url : "../demos/images/fslmean.nii.gz",//"./AIL.nii.gz",//"./images/RAS.nii.gz", "./images/spm152.nii.gz",
161
+ //url: "./mni152.nii.gz",
162
+ colorMap: "gray",
163
+ //urlImgData : "../demos/images/example4d+orig.BRIK.gz",
164
+ opacity: 1,
165
+ visible: true,
166
+ },
167
+ {
168
+ url: url ? url : "../demos/images/fslt.nii.gz",//"./AIL.nii.gz",//"./images/RAS.nii.gz", "./images/spm152.nii.gz",
169
+ colorMap: "warm",
170
+ colorMapNegative: "winter",
171
+ opacity: 1,
172
+ cal_min: 1,
173
+ cal_max: 6,
174
+ visible: true,
175
+ },
176
+ ]
177
+ var nv1 = new Niivue({
178
+ logging: false,
179
+ show3Dcrosshair: true,
180
+ loadingText: 'there are no images',
181
+ dragAndDropEnabled: true,
182
+ backColor: [0, 0.2, 0.3, 1],
183
+ //thumbnail: "../demos/images/DoG.png"
184
+ })
185
+ nv1.setRadiologicalConvention(false)
186
+ nv1.setSliceMM(true)
187
+ nv1.attachTo('gl1')
188
+ //nv1.setSliceType(nv1.sliceTypeRender)
189
+ nv1.setClipPlane([-0.1, 270, 0])
190
+ nv1.setRenderAzimuthElevation(90,10)
191
+ await nv1.loadVolumes(volumeList1)
192
+
193
+ var meshLayersList1 = [
194
+ //{url: "../demos/images/PJM-stc-lh.stc", colorMap: "rocket", opacity: 0.7},
195
+ //{url: "../demos/images/boggle.lh.annot", colorMap: "rocket", opacity: 0.9},
196
+ ]
197
+ /*nv1.opts.isDragShowsMeasurementTool = this.checked;
198
+ await nv1.loadMeshes([
199
+ {url: "../demos/images/BrainMesh_ICBM152.lh.mz3", rgba255 : [200, 162, 255, 255], layers : meshLayersList1},
200
+ {url: "../demos/images/dpsv.trx", rgba255 : [255, 255, 255, 255], layers : meshLayersList1},
201
+ //{url: "../demos/images/mni152_2009AO.mz3", rgba255 : [255, 255, 255, 255]},
202
+ //{url: "../demos/images/BrainMesh_ICBM152.lh.mz3", rgba255 : [255, 255, 255, 255], layers : meshLayersList1},
203
+ //{url: "../demos/images/PJM-example-lh.gii", rgba255 : [255, 255, 255, 255], layers : meshLayersList1},
204
+ ])*/
205
+ //nv1.setSliceMosaicString('C -50 -76 L- A -50 16 32 S -36 -30 S X -30');
206
+ //nv1.opts.isDragShowsMeasurementTool = true;
207
+ // example of using the 'location' change event with a callback function
208
+ nv1.on('location', (data) => {
209
+ // data is an object with properties: {mm: [N N N], vox: [N N N], frac: [N N N]}
210
+ document.getElementById('location').innerHTML = 'voxel location: ' + data.vox + ' ' + data.values
211
+ })
212
+
213
+ nv1.on('imageLoaded', (image) => {
214
+ console.log('imageLoaded', image.name)
215
+ })
216
+
217
+ nv1.on('intensityRange', (image) => {
218
+ console.log(image.cal_min, image.cal_max)
219
+ })
220
+
221
+ setTimeout(() => {
222
+ //nv1.saveImage('test.nii.gz')
223
+ }, 2000)
224
+
225
+ </script>
226
+ </div>
227
+ </body>
228
+
229
+ </html>
@@ -0,0 +1,223 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+ <meta name="viewport" content="width=device-width,initial-scale=1.0">
8
+ <title>NiiVue</title>
9
+ <style>
10
+ section {
11
+ margin: 20px;
12
+ }
13
+ </style>
14
+ </head>
15
+
16
+ <body style="font-family: sans-serif;">
17
+ <div id="app">
18
+ <noscript>
19
+ <strong>niivue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
20
+ </noscript>
21
+
22
+ <section>
23
+ <h1>
24
+ hot reloadable development preview
25
+ </h1>
26
+ <div class="slidecontainer">
27
+ X Pan <input type="range" min="-30" max="30" value="0" class="slider" id="xSlider">
28
+ </div>
29
+ <div class="slidecontainer">
30
+ Y Pan <input type="range" min="-30" max="30" value="0" class="slider" id="ySlider">
31
+ </div>
32
+ <div class="slidecontainer">
33
+ Z Pan <input type="range" min="-30" max="30" value="0" class="slider" id="zSlider">
34
+ </div>
35
+ <div class="slidecontainer">
36
+ Zoom <input type="range" min="1" max="40" value="10" class="slider" id="zoomSlider">
37
+ </div>
38
+ <div class="slidecontainer">
39
+ Mesh Visibility <input type="range" min="0" max="11" value="11" class="slider" id="dxSlider">
40
+ </div>
41
+ <div class="slidecontainer">
42
+ gamma <input type="range" min="1" max="20" value="10" class="slider" id="gamma">
43
+ </div>
44
+ <input type="checkbox" id="check1" name="check1" unchecked>
45
+ <label for="check1">Radiological</label>
46
+ <input type="checkbox" id="check2" name="check2" unchecked>
47
+ <label for="check2">Corner text</label>
48
+ <input type="checkbox" id="check3" name="check3" checked>
49
+ <label for="check3">World space</label>
50
+ <input type="checkbox" id="check4" name="check4" unchecked>
51
+ <label for="check4">Drag measurement</label>
52
+ <input type="checkbox" id="check5" name="check5" unchecked>
53
+ <label for="check5">Ruler</label>
54
+ <input type="checkbox" id="check6" name="check6" unchecked>
55
+ <label for="check6">Nose left</label>
56
+ <input type="checkbox" id="check7" name="check7" checked>
57
+ <label for="check7">Colorbar</label>
58
+ <input type="checkbox" id="check8" name="check8" checked>
59
+ <label for="check8">Negative colors</label>
60
+
61
+ <label for="mode">Display:</label>
62
+ <select name="mode" id="mode">
63
+ <option value="FA">FA</option>
64
+ <option value="V1">V1</option>
65
+ <option value="MV1">V1 modulated by FA</option>
66
+ </select>
67
+
68
+ </section>
69
+ <!-- demo 1 -->
70
+ <section>
71
+ <div id="demo1" style="width:98%; height:480px;">
72
+ <canvas id="gl1" height=480 width=480>
73
+ </canvas>
74
+ </div>
75
+ </section>
76
+
77
+ <section>
78
+ <p id="location"></p>
79
+ </section>
80
+
81
+ <!-- <script type="module" src="./index.js">
82
+ </script> -->
83
+ <script type="module" async>
84
+ var slider = document.getElementById("gamma");
85
+ slider.oninput = function() {
86
+ nv1.setGamma(0.1 * this.value)
87
+ }
88
+ function doSlider() {
89
+ var sx = document.getElementById("xSlider");
90
+ var sy = document.getElementById("ySlider");
91
+ var sz =document.getElementById("zSlider");
92
+ var szoom =document.getElementById("zoomSlider");
93
+
94
+ nv1.setPan2Dxyzmm([parseInt(sx.value),parseInt(sy.value), parseInt(sz.value), 0.1 * parseInt(szoom.value)])
95
+ }
96
+ var xslider = document.getElementById("xSlider");
97
+ xslider.oninput = function() {
98
+ doSlider()
99
+ }
100
+ var yslider = document.getElementById("ySlider");
101
+ yslider.oninput = function() {
102
+ doSlider()
103
+ }
104
+ var zslider = document.getElementById("zSlider");
105
+ zslider.oninput = function() {
106
+ doSlider()
107
+ }
108
+ var zoomslider = document.getElementById("zoomSlider");
109
+ zoomslider.oninput = function() {
110
+ doSlider()
111
+ }
112
+ var dxslider = document.getElementById("dxSlider");
113
+ dxslider.oninput = function() {
114
+ let dx = parseFloat(this.value);
115
+ if (dx > 10)
116
+ dx = Infinity;
117
+ nv1.setMeshThicknessOn2D(dx);
118
+ }
119
+ document.getElementById("check1").addEventListener("change", doCheckClick);
120
+ function doCheckClick() {
121
+ nv1.setRadiologicalConvention(this.checked);
122
+ }
123
+ document.getElementById("check2").addEventListener("change", doCheck2Click);
124
+ function doCheck2Click() {
125
+ nv1.setCornerOrientationText(this.checked);
126
+ }
127
+ document.getElementById("check3").addEventListener("change", doCheck3Click);
128
+ function doCheck3Click() {
129
+ nv1.setSliceMM(this.checked);
130
+ }
131
+ document.getElementById("check4").addEventListener("change", doCheck4Click);
132
+ function doCheck4Click() {
133
+ nv1.opts.isDragShowsMeasurementTool = this.checked;
134
+ }
135
+ document.getElementById("check5").addEventListener("change", doCheck5Click);
136
+ function doCheck5Click() {
137
+ nv1.opts.isRuler = this.checked;
138
+ nv1.drawScene();
139
+ }
140
+ document.getElementById("check6").addEventListener("change", doCheck6Click);
141
+ function doCheck6Click() {
142
+ nv1.opts.sagittalNoseLeft = this.checked;
143
+ nv1.drawScene();
144
+ }
145
+ document.getElementById("check7").addEventListener("change", doCheck7Click);
146
+ function doCheck7Click() {
147
+ nv1.opts.isColorbar = this.checked;
148
+ nv1.drawScene();
149
+ }
150
+ document.getElementById("check8").addEventListener("change", doCheck8Click);
151
+ function doCheck8Click() {
152
+ if (this.checked)
153
+ nv1.setColorMapNegative(nv1.volumes[1].id,"winter");
154
+ else
155
+ nv1.setColorMapNegative(nv1.volumes[1].id,"");
156
+ nv1.drawScene();
157
+ }
158
+ var drop = document.getElementById("mode");
159
+ drop.onchange = function() {
160
+ let mode = document.getElementById("mode").selectedIndex;
161
+ if (mode === 0)
162
+ nv1.setOpacity(1, 1.0);
163
+ else
164
+ nv1.setOpacity(1, 0.0)
165
+
166
+ if (mode === 2)
167
+ nv1.setModulationImage(nv1.volumes[0].id, nv1.volumes[1].id);
168
+ else
169
+ nv1.setModulationImage(nv1.volumes[0].id, null);
170
+ }
171
+ import { Niivue } from './niivue.js'
172
+ import {NVImage} from './nvimage.js'
173
+ import {NVMesh} from './nvmesh.js'
174
+ let query = window.location.search
175
+ const params = new URLSearchParams(query);
176
+ let url = params.get('url')
177
+ var volumeList1 = [
178
+ {
179
+ url: url ? url : "../demos/images/V1.nii.gz",//"./AIL.nii.gz",//"./images/RAS.nii.gz", "./images/spm152.nii.gz",
180
+ opacity: 1,
181
+ visible: false,
182
+ },
183
+ {
184
+ url: url ? url : "../demos/images/FA.nii.gz",//"./AIL.nii.gz",//"./images/RAS.nii.gz", "./images/spm152.nii.gz",
185
+ colorMap: "gray",
186
+ opacity: 1.0,
187
+ visible: false,
188
+ },
189
+ ]
190
+ var nv1 = new Niivue({
191
+ logging: false,
192
+ show3Dcrosshair: true,
193
+ loadingText: 'there are no images',
194
+ dragAndDropEnabled: true,
195
+ backColor: [0, 0.2, 0.3, 1],
196
+ //thumbnail: "../demos/images/DoG.png"
197
+ })
198
+ nv1.setRadiologicalConvention(false)
199
+ nv1.setSliceMM(true)
200
+ nv1.attachTo('gl1')
201
+ //nv1.setSliceType(nv1.sliceTypeRender)
202
+ nv1.setClipPlane([-0.1, 270, 0])
203
+ nv1.setRenderAzimuthElevation(90,10)
204
+ await nv1.loadVolumes(volumeList1);
205
+ nv1.setModulationImage(nv1.volumes[0].id, nv1.volumes[1].id);
206
+
207
+ nv1.on('location', (data) => {
208
+ // data is an object with properties: {mm: [N N N], vox: [N N N], frac: [N N N]}
209
+ document.getElementById('location').innerHTML = 'voxel location: ' + data.vox + ' ' + data.values
210
+ })
211
+ nv1.on('intensityRange', (image) => {
212
+ console.log(image.cal_min, image.cal_max)
213
+ })
214
+
215
+ setTimeout(() => {
216
+ //nv1.saveImage('test.nii.gz')
217
+ }, 2000)
218
+
219
+ </script>
220
+ </div>
221
+ </body>
222
+
223
+ </html>