Mercurial > hg > orthanc-stone
comparison Applications/StoneWebViewer/WebApplication/app.js @ 2026:04148de691a7 deep-learning
integration mainline->deep-learning
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 05 Dec 2022 08:29:49 +0100 |
parents | 963f28eb40cb e0b7b2a8b914 |
children | 0cb8796c2a9b |
comparison
equal
deleted
inserted
replaced
2008:37d6805b80ee | 2026:04148de691a7 |
---|---|
32 var PATIENT_NAME = '0010,0010'; | 32 var PATIENT_NAME = '0010,0010'; |
33 var SERIES_NUMBER = '0020,0011'; | 33 var SERIES_NUMBER = '0020,0011'; |
34 var SERIES_DESCRIPTION = '0008,103e'; | 34 var SERIES_DESCRIPTION = '0008,103e'; |
35 var MODALITY = '0008,0060'; | 35 var MODALITY = '0008,0060'; |
36 var PATIENT_BIRTH_DATE = '0010,0030'; | 36 var PATIENT_BIRTH_DATE = '0010,0030'; |
37 var PATIENT_SEX = '0010,0040'; | |
37 | 38 |
38 // Registry of the PDF series for which the instance metadata is still waiting | 39 // Registry of the PDF series for which the instance metadata is still waiting |
39 var pendingSeriesPdf_ = {}; | 40 var pendingSeriesPdf_ = {}; |
40 | 41 |
41 var MOUSE_TOOL_COMBINED = 1; | 42 var MOUSE_TOOL_COMBINED = 1; |
50 var MOUSE_TOOL_CREATE_ELLIPSE_PROBE = 10; // New in 2.4 | 51 var MOUSE_TOOL_CREATE_ELLIPSE_PROBE = 10; // New in 2.4 |
51 var MOUSE_TOOL_CREATE_RECTANGLE_PROBE = 11; // New in 2.4 | 52 var MOUSE_TOOL_CREATE_RECTANGLE_PROBE = 11; // New in 2.4 |
52 var MOUSE_TOOL_CREATE_TEXT_ANNOTATION = 12; // New in 2.4 | 53 var MOUSE_TOOL_CREATE_TEXT_ANNOTATION = 12; // New in 2.4 |
53 var MOUSE_TOOL_MAGNIFYING_GLASS = 13; // New in 2.4 | 54 var MOUSE_TOOL_MAGNIFYING_GLASS = 13; // New in 2.4 |
54 | 55 |
56 var hasAuthorizationToken = false; | |
57 var axiosHeaders = {}; | |
58 | |
55 | 59 |
56 function getParameterFromUrl(key) { | 60 function getParameterFromUrl(key) { |
57 var url = window.location.search.substring(1); | 61 var url = window.location.search.substring(1); |
58 var args = url.split('&'); | 62 var args = url.split('&'); |
59 for (var i = 0; i < args.length; i++) { | 63 for (var i = 0; i < args.length; i++) { |
119 } | 123 } |
120 else { | 124 else { |
121 alert('Unsupported mouse action in the configuration file: ' + config); | 125 alert('Unsupported mouse action in the configuration file: ' + config); |
122 return stone.WebViewerAction.PAN; | 126 return stone.WebViewerAction.PAN; |
123 } | 127 } |
128 } | |
129 | |
130 | |
131 function LookupIndexOfResource(array, tag, value) { | |
132 for (var i = 0; i < array.length; i++) { | |
133 if (array[i].tags[tag] == value) { | |
134 return i; | |
135 } | |
136 } | |
137 | |
138 return -1; | |
124 } | 139 } |
125 | 140 |
126 | 141 |
127 /** | 142 /** |
128 * Enable support for tooltips in Bootstrap. This function must be | 143 * Enable support for tooltips in Bootstrap. This function must be |
136 container: 'body', | 151 container: 'body', |
137 trigger: 'hover' | 152 trigger: 'hover' |
138 }); | 153 }); |
139 } | 154 } |
140 | 155 |
156 | |
157 function TriggerDownloadFromUri(uri, filename, mime) | |
158 { | |
159 if (hasAuthorizationToken) { | |
160 axios.get(uri, { | |
161 headers: axiosHeaders, | |
162 responseType: 'arraybuffer' | |
163 }) | |
164 .then(function(response) { | |
165 const blob = new Blob([ response.data ], { type: mime }); | |
166 const url = URL.createObjectURL(blob); | |
167 | |
168 //window.open(url, '_blank'); | |
169 | |
170 // https://stackoverflow.com/a/19328891 | |
171 var a = document.createElement("a"); | |
172 document.body.appendChild(a); | |
173 a.style = "display: none"; | |
174 a.href = url; | |
175 a.download = filename; | |
176 a.click(); | |
177 window.URL.revokeObjectURL(url); | |
178 }); | |
179 | |
180 } else { | |
181 // This version was used in Stone Web viewer <= 2.4, but doesn't | |
182 // work with authorization headers | |
183 | |
184 /** | |
185 * The use of "window.open()" below might be blocked (depending on | |
186 * the browser criteria to block popup). As a consequence, we | |
187 * prefer to set "window.location". | |
188 * https://www.nngroup.com/articles/the-top-ten-web-design-mistakes-of-1999/ | |
189 **/ | |
190 // window.open(uri, '_blank'); | |
191 window.location.href = uri; | |
192 } | |
193 } | |
194 | |
195 | |
196 /** | |
197 * The "mousemove" and "mouseup" events were added in Stone Web viewer | |
198 * 2.5 to allow click/drag on the vertical scrollbar. | |
199 **/ | |
200 var activeVerticalScrollbarViewport = null; | |
201 var activeVerticalScrollbarTarget = null; | |
202 | |
203 window.addEventListener('mousemove', function(event) { | |
204 if (activeVerticalScrollbarViewport !== null) { | |
205 activeVerticalScrollbarViewport.ClickVerticalScrollbar(event, activeVerticalScrollbarTarget); | |
206 event.preventDefault(); | |
207 } | |
208 }); | |
209 | |
210 window.addEventListener('mouseup', function(event) { | |
211 activeVerticalScrollbarViewport = null; | |
212 }); | |
141 | 213 |
142 | 214 |
143 Vue.component('viewport', { | 215 Vue.component('viewport', { |
144 props: [ 'left', 'top', 'width', 'height', 'canvasId', 'active', 'content', 'viewportIndex', | 216 props: [ 'left', 'top', 'width', 'height', 'canvasId', 'active', 'content', 'viewportIndex', |
145 'showInfo', 'globalConfiguration' ], | 217 'showInfo', 'globalConfiguration' ], |
248 else if (newVal.series.type == stone.ThumbnailType.VIDEO) { | 320 else if (newVal.series.type == stone.ThumbnailType.VIDEO) { |
249 this.status = 'video'; | 321 this.status = 'video'; |
250 this.videoUri = ''; | 322 this.videoUri = ''; |
251 if (this.globalConfiguration.OrthancApiRoot) { | 323 if (this.globalConfiguration.OrthancApiRoot) { |
252 var that = this; | 324 var that = this; |
253 axios.post(that.globalConfiguration.OrthancApiRoot + '/tools/find', | 325 axios.post(that.globalConfiguration.OrthancApiRoot + '/tools/find', { |
254 { | 326 Level : 'Instance', |
255 Level : 'Instance', | 327 Query : { |
256 Query : { | 328 StudyInstanceUID: studyInstanceUid |
257 StudyInstanceUID: studyInstanceUid | 329 } |
258 } | 330 }, { |
259 }) | 331 headers: axiosHeaders |
332 }) | |
260 .then(function(response) { | 333 .then(function(response) { |
261 if (response.data.length != 1) { | 334 if (response.data.length != 1) { |
262 throw(''); | 335 throw(''); |
263 } | 336 } |
264 else { | 337 else { |
265 that.videoUri = that.globalConfiguration.OrthancApiRoot + '/instances/' + response.data[0] + '/frames/0/raw'; | 338 var uri = that.globalConfiguration.OrthancApiRoot + '/instances/' + response.data[0] + '/frames/0/raw'; |
339 | |
340 if (hasAuthorizationToken) { | |
341 axios.get(uri, { | |
342 headers: axiosHeaders, | |
343 responseType: 'arraybuffer' | |
344 }) | |
345 .then(function(response) { | |
346 const blob = new Blob([ response.data ]); | |
347 that.videoUri = URL.createObjectURL(blob); | |
348 }); | |
349 } else { | |
350 that.videoUri = uri; | |
351 } | |
266 } | 352 } |
267 }) | 353 }) |
268 .catch(function(error) { | 354 .catch(function(error) { |
269 alert('Cannot find the video in Orthanc'); | 355 alert('Cannot find the video in Orthanc'); |
270 }); | 356 }); |
329 if (args.detail.canvasId == that.canvasId) { | 415 if (args.detail.canvasId == that.canvasId) { |
330 that.windowingCenter = args.detail.windowingCenter; | 416 that.windowingCenter = args.detail.windowingCenter; |
331 that.windowingWidth = args.detail.windowingWidth; | 417 that.windowingWidth = args.detail.windowingWidth; |
332 } | 418 } |
333 }); | 419 }); |
420 | |
421 window.addEventListener('KeyCineSwitch', function(args) { | |
422 if (that.active) { | |
423 that.KeyCineSwitch(); | |
424 } | |
425 }); | |
334 }, | 426 }, |
335 methods: { | 427 methods: { |
336 DragDrop: function(event) { | 428 DragDrop: function(event) { |
337 event.preventDefault(); | 429 event.preventDefault(); |
338 | 430 |
351 IncrementFrame: function(isCircular) { | 443 IncrementFrame: function(isCircular) { |
352 return stone.IncrementFrame(this.canvasId, isCircular); | 444 return stone.IncrementFrame(this.canvasId, isCircular); |
353 }, | 445 }, |
354 CinePlay: function() { | 446 CinePlay: function() { |
355 this.cineControls = true; | 447 this.cineControls = true; |
356 this.cineIncrement = 1; | 448 this.cineIncrement = -1; |
357 this.UpdateCine(); | 449 this.UpdateCine(); |
358 }, | 450 }, |
359 CinePause: function() { | 451 CinePause: function() { |
360 if (this.cineIncrement == 0) { | 452 if (this.cineIncrement == 0) { |
361 // Two clicks on the "pause" button will hide the playback control | 453 // Two clicks on the "pause" button will hide the playback control |
365 this.UpdateCine(); | 457 this.UpdateCine(); |
366 } | 458 } |
367 }, | 459 }, |
368 CineBackward: function() { | 460 CineBackward: function() { |
369 this.cineControls = true; | 461 this.cineControls = true; |
370 this.cineIncrement = -1; | 462 this.cineIncrement = 1; |
371 this.UpdateCine(); | 463 this.UpdateCine(); |
464 }, | |
465 KeyCineSwitch: function() { | |
466 if (this.cineIncrement != 0) { | |
467 this.CinePause(); | |
468 } else { | |
469 this.CinePlay(); | |
470 } | |
372 }, | 471 }, |
373 UpdateCine: function() { | 472 UpdateCine: function() { |
374 // Cancel the previous cine loop, if any | 473 // Cancel the previous cine loop, if any |
375 if (this.cineTimeoutId !== null) { | 474 if (this.cineTimeoutId !== null) { |
376 clearTimeout(this.cineTimeoutId); | 475 clearTimeout(this.cineTimeoutId); |
409 } | 508 } |
410 | 509 |
411 if (reschedule) { | 510 if (reschedule) { |
412 this.cineTimeoutId = setTimeout(this.CineCallback, 1000.0 / this.cineFramesPerSecond); | 511 this.cineTimeoutId = setTimeout(this.CineCallback, 1000.0 / this.cineFramesPerSecond); |
413 } | 512 } |
513 }, | |
514 ClickVerticalScrollbar: function(event, target) { | |
515 if (target == undefined) { | |
516 target = event.currentTarget; | |
517 activeVerticalScrollbarViewport = this; | |
518 activeVerticalScrollbarTarget = target; | |
519 } | |
520 | |
521 var offset = target.getClientRects()[0]; | |
522 var y = event.clientY - offset.top; | |
523 var height = target.offsetHeight; | |
524 var frame = Math.min(this.numberOfFrames - 1, Math.floor(y * this.numberOfFrames / (height - 1))); | |
525 | |
526 if (frame >= 0 && | |
527 frame < this.numberOfFrames) { | |
528 this.currentFrame = frame; | |
529 } | |
414 } | 530 } |
415 } | 531 } |
416 }); | 532 }); |
417 | 533 |
418 | 534 |
424 ready: false, | 540 ready: false, |
425 leftMode: 'grid', // Can be 'small', 'grid' or 'full' | 541 leftMode: 'grid', // Can be 'small', 'grid' or 'full' |
426 leftVisible: true, | 542 leftVisible: true, |
427 viewportLayoutButtonsVisible: false, | 543 viewportLayoutButtonsVisible: false, |
428 mouseActionsVisible: false, | 544 mouseActionsVisible: false, |
545 annotationActionsVisible: false, | |
429 activeViewport: 0, | 546 activeViewport: 0, |
430 showInfo: true, | 547 showInfo: true, |
431 showReferenceLines: true, | 548 showReferenceLines: true, |
432 synchronizedBrowsing: false, | 549 synchronizedBrowsing: false, |
433 globalConfiguration: {}, | 550 globalConfiguration: {}, |
435 archiveJob: '', | 552 archiveJob: '', |
436 mouseTool: 0, | 553 mouseTool: 0, |
437 orthancSystem: {}, // Only available if "OrthancApiRoot" configuration option is set | 554 orthancSystem: {}, // Only available if "OrthancApiRoot" configuration option is set |
438 stoneWebViewerVersion: '...', | 555 stoneWebViewerVersion: '...', |
439 emscriptenVersion: '...', | 556 emscriptenVersion: '...', |
557 isFirstSeries: true, | |
440 | 558 |
441 modalWarning: false, | 559 modalWarning: false, |
442 modalNotDiagnostic: false, | 560 modalNotDiagnostic: false, |
443 modalPreferences: false, | 561 modalPreferences: false, |
444 | 562 |
539 this.$nextTick(function () { | 657 this.$nextTick(function () { |
540 stone.AllViewportsUpdateSize(true /* fit content */); | 658 stone.AllViewportsUpdateSize(true /* fit content */); |
541 }); | 659 }); |
542 } | 660 } |
543 }, | 661 }, |
662 | |
663 GetActiveViewportSeriesTags: function() { | |
664 if (this.activeViewport == 1) { | |
665 return this.viewport1Content.series.tags; | |
666 } | |
667 else if (this.activeViewport == 2) { | |
668 return this.viewport2Content.series.tags; | |
669 } | |
670 else if (this.activeViewport == 3) { | |
671 return this.viewport3Content.series.tags; | |
672 } | |
673 else if (this.activeViewport == 4) { | |
674 return this.viewport4Content.series.tags; | |
675 } | |
676 else { | |
677 return null; | |
678 } | |
679 }, | |
544 | 680 |
545 GetActiveSeries: function() { | 681 GetActiveSeriesInstanceUid: function() { |
546 var s = []; | 682 var s = []; |
547 | 683 |
548 if ('tags' in this.viewport1Content.series) | 684 if ('tags' in this.viewport1Content.series) |
549 s.push(this.viewport1Content.series.tags[SERIES_INSTANCE_UID]); | 685 s.push(this.viewport1Content.series.tags[SERIES_INSTANCE_UID]); |
550 | 686 |
687 seriesIndex: this.seriesIndex[seriesInstanceUid] | 823 seriesIndex: this.seriesIndex[seriesInstanceUid] |
688 }); | 824 }); |
689 } | 825 } |
690 }, | 826 }, |
691 | 827 |
828 SetViewportVirtualSeries: function(viewportIndex, seriesInstanceUid, virtualSeriesId) { | |
829 if (seriesInstanceUid in this.seriesIndex) { | |
830 this.SetViewportSeries(viewportIndex, { | |
831 seriesIndex: this.seriesIndex[seriesInstanceUid], | |
832 virtualSeriesId: virtualSeriesId | |
833 }); | |
834 } | |
835 }, | |
836 | |
692 SetViewportSeries: function(viewportIndex, info) { | 837 SetViewportSeries: function(viewportIndex, info) { |
693 var series = this.series[info.seriesIndex]; | 838 var series = this.series[info.seriesIndex]; |
694 | 839 |
695 if (viewportIndex == 1) { | 840 if (viewportIndex == 1) { |
696 this.viewport1Content = { | 841 this.viewport1Content = { |
714 this.viewport4Content = { | 859 this.viewport4Content = { |
715 series: series, | 860 series: series, |
716 virtualSeriesId: info.virtualSeriesId | 861 virtualSeriesId: info.virtualSeriesId |
717 }; | 862 }; |
718 } | 863 } |
864 | |
865 // Give the focus to this viewport (new in Stone Web viewer 2.5) | |
866 this.activeViewport = viewportIndex; | |
719 }, | 867 }, |
720 | 868 |
721 ClickSeries: function(seriesIndex) { | 869 ClickSeries: function(seriesIndex) { |
722 this.SetViewportSeries(this.activeViewport, { | 870 this.SetViewportSeries(this.activeViewport, { |
723 seriesIndex: seriesIndex | 871 seriesIndex: seriesIndex |
1069 { | 1217 { |
1070 if (this.creatingArchive && | 1218 if (this.creatingArchive && |
1071 this.archiveJob.length > 0) { | 1219 this.archiveJob.length > 0) { |
1072 | 1220 |
1073 var that = this; | 1221 var that = this; |
1074 axios.get(that.globalConfiguration.OrthancApiRoot + '/jobs/' + that.archiveJob) | 1222 axios.get(that.globalConfiguration.OrthancApiRoot + '/jobs/' + that.archiveJob, { |
1223 headers: axiosHeaders | |
1224 }) | |
1075 .then(function(response) { | 1225 .then(function(response) { |
1076 console.log('Progress of archive job ' + that.archiveJob + ': ' + response.data['Progress'] + '%'); | 1226 console.log('Progress of archive job ' + that.archiveJob + ': ' + response.data['Progress'] + '%'); |
1077 var state = response.data['State']; | 1227 var state = response.data['State']; |
1078 if (state == 'Success') { | 1228 if (state == 'Success') { |
1079 that.creatingArchive = false; | 1229 that.creatingArchive = false; |
1080 var uri = that.globalConfiguration.OrthancApiRoot + '/jobs/' + that.archiveJob + '/archive'; | 1230 var uri = that.globalConfiguration.OrthancApiRoot + '/jobs/' + that.archiveJob + '/archive'; |
1081 | 1231 TriggerDownloadFromUri(uri, that.archiveJob + '.zip', 'application/zip'); |
1082 /** | |
1083 * The use of "window.open()" below might be blocked | |
1084 * (depending on the browser criteria to block popup). | |
1085 * As a consequence, we prefer to set "window.location". | |
1086 * https://www.nngroup.com/articles/the-top-ten-web-design-mistakes-of-1999/ | |
1087 **/ | |
1088 // window.open(uri, '_blank'); | |
1089 window.location = uri; | |
1090 } | 1232 } |
1091 else if (state == 'Running') { | 1233 else if (state == 'Running') { |
1092 setTimeout(that.CheckIsDownloadComplete, 1000); | 1234 setTimeout(that.CheckIsDownloadComplete, 1000); |
1093 } | 1235 } |
1094 else { | 1236 else { |
1106 DownloadStudy: function(studyInstanceUid, event) | 1248 DownloadStudy: function(studyInstanceUid, event) |
1107 { | 1249 { |
1108 console.log('Creating archive for study: ' + studyInstanceUid); | 1250 console.log('Creating archive for study: ' + studyInstanceUid); |
1109 | 1251 |
1110 var that = this; | 1252 var that = this; |
1111 axios.post(this.globalConfiguration.OrthancApiRoot + '/tools/lookup', studyInstanceUid) | 1253 axios.post(this.globalConfiguration.OrthancApiRoot + '/tools/lookup', studyInstanceUid, { |
1254 headers: axiosHeaders | |
1255 }) | |
1112 .then(function(response) { | 1256 .then(function(response) { |
1113 if (response.data.length != 1) { | 1257 if (response.data.length != 1) { |
1114 throw(''); | 1258 throw(''); |
1115 } | 1259 } |
1116 else { | 1260 else { |
1125 | 1269 |
1126 if (that.orthancSystem.ApiVersion >= 13) { | 1270 if (that.orthancSystem.ApiVersion >= 13) { |
1127 // ZIP streaming is available (this is Orthanc >= | 1271 // ZIP streaming is available (this is Orthanc >= |
1128 // 1.9.4): Simply give the hand to Orthanc | 1272 // 1.9.4): Simply give the hand to Orthanc |
1129 event.preventDefault(); | 1273 event.preventDefault(); |
1130 window.location.href = uri; | 1274 TriggerDownloadFromUri(uri, orthancId + '.zip', 'application/zip'); |
1131 | |
1132 } else { | 1275 } else { |
1133 // ZIP streaming is not available: Create a job to create the archive | 1276 // ZIP streaming is not available: Create a job to create the archive |
1134 axios.post(uri, { | 1277 axios.post(uri, { |
1135 'Asynchronous' : true | 1278 'Asynchronous' : true |
1279 }, { | |
1280 headers: axiosHeaders | |
1136 }) | 1281 }) |
1137 .then(function(response) { | 1282 .then(function(response) { |
1138 that.creatingArchive = true; | 1283 that.creatingArchive = true; |
1139 that.archiveJob = response.data.ID; | 1284 that.archiveJob = response.data.ID; |
1140 setTimeout(that.CheckIsDownloadComplete, 1000); | 1285 setTimeout(that.CheckIsDownloadComplete, 1000); |
1143 } | 1288 } |
1144 }) | 1289 }) |
1145 .catch(function (error) { | 1290 .catch(function (error) { |
1146 alert('Cannot find the study in Orthanc'); | 1291 alert('Cannot find the study in Orthanc'); |
1147 }); | 1292 }); |
1148 | 1293 }, |
1149 }, | 1294 |
1150 | 1295 ApplyDeepLearning: function() { |
1151 ApplyDeepLearning: function() | |
1152 { | |
1153 stone.ApplyDeepLearningModel(this.GetActiveCanvas()); | 1296 stone.ApplyDeepLearningModel(this.GetActiveCanvas()); |
1297 }, | |
1298 | |
1299 ChangeActiveSeries: function(offset) { | |
1300 var seriesTags = this.GetActiveViewportSeriesTags(); | |
1301 if (seriesTags !== null) { | |
1302 var studyIndex = LookupIndexOfResource(this.studies, STUDY_INSTANCE_UID, seriesTags[STUDY_INSTANCE_UID]); | |
1303 if (studyIndex != -1) { | |
1304 var virtualSeriesId = this.GetActiveVirtualSeries(); | |
1305 if (virtualSeriesId.length > 0) { | |
1306 virtualSeriesId = virtualSeriesId[0]; | |
1307 } else { | |
1308 virtualSeriesId = ''; | |
1309 } | |
1310 | |
1311 var seriesInStudyIndices = this.studies[studyIndex].series; | |
1312 for (var i = 0; i < seriesInStudyIndices.length; i++) { | |
1313 var series = this.series[seriesInStudyIndices[i]]; | |
1314 if (this.series[seriesInStudyIndices[i]].tags[SERIES_INSTANCE_UID] == seriesTags[SERIES_INSTANCE_UID]) { | |
1315 if (series.virtualSeries !== null) { | |
1316 for (var j = 0; j < series.virtualSeries.length; j++) { | |
1317 if (series.virtualSeries[j].ID == virtualSeriesId) { | |
1318 var next = j + offset; | |
1319 if (next >= 0 && | |
1320 next < series.virtualSeries.length) { | |
1321 this.SetViewportVirtualSeries(this.activeViewport, seriesTags[SERIES_INSTANCE_UID], series.virtualSeries[next].ID); | |
1322 } | |
1323 return; | |
1324 } | |
1325 } | |
1326 } | |
1327 else { | |
1328 var next = i + offset; | |
1329 if (next >= 0 && | |
1330 next < seriesInStudyIndices.length) { | |
1331 this.SetViewportSeriesInstanceUid(this.activeViewport, this.series[seriesInStudyIndices[next]].tags[SERIES_INSTANCE_UID]); | |
1332 } | |
1333 return; | |
1334 } | |
1335 } | |
1336 } | |
1337 } | |
1338 } | |
1339 }, | |
1340 | |
1341 ChangeActiveStudy: function(offset) { | |
1342 var seriesTags = this.GetActiveViewportSeriesTags(); | |
1343 if (seriesTags !== null) { | |
1344 var studyIndex = LookupIndexOfResource(this.studies, STUDY_INSTANCE_UID, seriesTags[STUDY_INSTANCE_UID]); | |
1345 if (studyIndex != -1) { | |
1346 var next = studyIndex + offset; | |
1347 if (next >= 0 && | |
1348 next < this.studies.length) { | |
1349 var nextStudy = this.studies[next]; | |
1350 if (nextStudy.series.length > 0) { | |
1351 var seriesIndex = nextStudy.series[0]; | |
1352 if (this.series[seriesIndex].virtualSeries !== null) { | |
1353 this.ClickVirtualSeries(seriesIndex, this.series[seriesIndex].virtualSeries[0].ID); | |
1354 } else { | |
1355 this.ClickSeries(seriesIndex); | |
1356 } | |
1357 } | |
1358 } | |
1359 } | |
1360 } | |
1154 } | 1361 } |
1155 }, | 1362 }, |
1156 | 1363 |
1157 mounted: function() { | 1364 mounted: function() { |
1158 // Warning: In this function, the "stone" global object is not initialized yet! | 1365 // Warning: In this function, the "stone" global object is not initialized yet! |
1185 | 1392 |
1186 window.addEventListener('MetadataLoaded', function(args) { | 1393 window.addEventListener('MetadataLoaded', function(args) { |
1187 var studyInstanceUid = args.detail.studyInstanceUid; | 1394 var studyInstanceUid = args.detail.studyInstanceUid; |
1188 var seriesInstanceUid = args.detail.seriesInstanceUid; | 1395 var seriesInstanceUid = args.detail.seriesInstanceUid; |
1189 that.UpdateIsSeriesComplete(studyInstanceUid, seriesInstanceUid); | 1396 that.UpdateIsSeriesComplete(studyInstanceUid, seriesInstanceUid); |
1397 | |
1398 // Automatically open the first series to be loaded (new in Stone Web viewer 2.5) | |
1399 if (that.isFirstSeries) { | |
1400 that.SetViewportSeriesInstanceUid(1, seriesInstanceUid); | |
1401 that.isFirstSeries = false; | |
1402 } | |
1190 }); | 1403 }); |
1191 | 1404 |
1192 window.addEventListener('StoneAnnotationAdded', function() { | 1405 window.addEventListener('StoneAnnotationAdded', function() { |
1193 // Ignore | 1406 // Ignore |
1194 }); | 1407 }); |
1203 stone.AddTextAnnotation(args.detail.canvasId, label, | 1416 stone.AddTextAnnotation(args.detail.canvasId, label, |
1204 args.detail.pointedX, args.detail.pointedY, | 1417 args.detail.pointedX, args.detail.pointedY, |
1205 args.detail.labelX, args.detail.labelY); | 1418 args.detail.labelX, args.detail.labelY); |
1206 } | 1419 } |
1207 }); | 1420 }); |
1421 | |
1422 window.addEventListener('keydown', function(event) { | |
1423 var canvas = that.GetActiveCanvas(); | |
1424 if (canvas != '') { | |
1425 switch (event.key) { | |
1426 case 'Left': | |
1427 case 'ArrowLeft': | |
1428 stone.DecrementFrame(canvas, false); | |
1429 break; | |
1430 | |
1431 case 'Right': | |
1432 case 'ArrowRight': | |
1433 stone.IncrementFrame(canvas, false); | |
1434 break; | |
1435 | |
1436 case 'Up': | |
1437 case 'ArrowUp': | |
1438 that.ChangeActiveSeries(-1); | |
1439 break | |
1440 | |
1441 case 'Down': | |
1442 case 'ArrowDown': | |
1443 that.ChangeActiveSeries(1); | |
1444 break; | |
1445 | |
1446 case 'PageUp': | |
1447 that.ChangeActiveStudy(-1); | |
1448 break; | |
1449 | |
1450 case 'PageDown': | |
1451 that.ChangeActiveStudy(1); | |
1452 break; | |
1453 | |
1454 case ' ': | |
1455 case 'Space': | |
1456 dispatchEvent(new CustomEvent('KeyCineSwitch', { })); | |
1457 break; | |
1458 | |
1459 default: | |
1460 break; | |
1461 } | |
1462 } | |
1463 }); | |
1208 } | 1464 } |
1209 }); | 1465 }); |
1210 | 1466 |
1211 | 1467 |
1212 | 1468 |
1233 } | 1489 } |
1234 | 1490 |
1235 // Bearer token is new in Stone Web viewer 2.0 | 1491 // Bearer token is new in Stone Web viewer 2.0 |
1236 var token = getParameterFromUrl('token'); | 1492 var token = getParameterFromUrl('token'); |
1237 if (token !== undefined) { | 1493 if (token !== undefined) { |
1494 hasAuthorizationToken = true; | |
1238 stone.AddHttpHeader('Authorization', 'Bearer ' + token); | 1495 stone.AddHttpHeader('Authorization', 'Bearer ' + token); |
1239 } | 1496 axiosHeaders['Authorization'] = 'Bearer ' + token; |
1240 | 1497 } |
1498 | |
1499 if (app.globalConfiguration.OrthancApiRoot) { | |
1500 axios.get(app.globalConfiguration.OrthancApiRoot + '/system', { | |
1501 headers: axiosHeaders | |
1502 }) | |
1503 .then(function (response) { | |
1504 app.orthancSystem = response.data; | |
1505 }); | |
1506 } | |
1507 | |
1241 | 1508 |
1242 /** | 1509 /** |
1243 * Calls to "stone.XXX()" can be reordered after this point. | 1510 * Calls to "stone.XXX()" can be reordered after this point. |
1244 **/ | 1511 **/ |
1245 | 1512 |
1306 } | 1573 } |
1307 } | 1574 } |
1308 | 1575 |
1309 if (empty) { | 1576 if (empty) { |
1310 alert('No study, nor patient was provided in the URL!'); | 1577 alert('No study, nor patient was provided in the URL!'); |
1578 } | |
1579 } | |
1580 | |
1581 // New in Stone Web viewer 2.5 | |
1582 var menu = getParameterFromUrl('menu'); | |
1583 if (menu !== undefined) { | |
1584 if (menu == 'hidden') { | |
1585 app.leftVisible = false; | |
1586 } else if (menu == 'small' || | |
1587 menu == 'grid' || | |
1588 menu == 'full') { | |
1589 app.leftVisible = true; | |
1590 app.leftMode = menu; | |
1591 } else { | |
1592 alert('Bad value for the "menu" option in the URL (can be "hidden", "small", "grid", or "full"): ' + menu); | |
1311 } | 1593 } |
1312 } | 1594 } |
1313 }); | 1595 }); |
1314 | 1596 |
1315 | 1597 |
1391 document.body.appendChild(script); | 1673 document.body.appendChild(script); |
1392 }) | 1674 }) |
1393 .catch(function (error) { | 1675 .catch(function (error) { |
1394 alert('Cannot load the WebAssembly framework'); | 1676 alert('Cannot load the WebAssembly framework'); |
1395 }); | 1677 }); |
1396 | |
1397 if (app.globalConfiguration.OrthancApiRoot) { | |
1398 axios.get(app.globalConfiguration.OrthancApiRoot + '/system') | |
1399 .then(function (response) { | |
1400 app.orthancSystem = response.data; | |
1401 }); | |
1402 } | |
1403 }) | 1678 }) |
1404 .catch(function (error) { | 1679 .catch(function (error) { |
1405 alert('Cannot load the configuration file'); | 1680 alert('Cannot load the configuration file'); |
1406 }); | 1681 }); |
1407 }); | 1682 }); |