Allowing lazy-loading on viewer

This commit is contained in:
Bruno Alves de Faria 2017-10-24 14:20:57 -02:00
parent ed0bde0404
commit bde625a961
15 changed files with 167 additions and 36 deletions

View File

@ -111,7 +111,7 @@ Template.viewer.onCreated(() => {
const studyMetadata = new OHIF.metadata.StudyMetadata(study, study.studyInstanceUid);
let displaySets = study.displaySets;
if(!study.displaySets) {
if (!study.displaySets) {
displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(studyMetadata);
study.displaySets = displaySets;
}

View File

@ -1,6 +1,6 @@
<template name="timepointBrowserQuickSwitch">
{{>timepointBrowserList (extend timepointBrowserData)}}
{{#if instance.hasAdditional.get}}
<div class='study-item-box additional'>Show additional timepoints</div>
<div class="study-item-box additional">Show additional timepoints</div>
{{/if}}
</template>

View File

@ -27,7 +27,17 @@ Template.timepointBrowserQuickSwitch.onCreated(() => {
instance.autorun(() => {
OHIF.viewerbase.layoutManager.observer.depend();
const viewportData = OHIF.viewerbase.layoutManager.viewportData[viewportIndex];
instance.updateSelectedTimepoint(viewportData.studyInstanceUid);
let { studyInstanceUid } = viewportData;
if (!studyInstanceUid) {
Tracker.nonreactive(() => {
const currentStudy = instance.data.currentStudy.get();
if (currentStudy) {
studyInstanceUid = currentStudy.studyInstanceUid;
}
});
}
instance.updateSelectedTimepoint(studyInstanceUid);
});
instance.autorun(() => {

View File

@ -1,6 +1,7 @@
import './item.html';
import './item.js';
import './list.html';
import './list.js';
import './list.styl';
import './quickSwitch.html';
import './quickSwitch.js';

View File

@ -4,18 +4,20 @@
{{#if isLoading}}
{{>loadingText}}
{{/if}}
<div class="study-item-box">
<div class="study-modality">
<div class="study-modality-text" style="{{modalityStyle}}">{{instance.modalities}}</div>
{{#let studyData=instance.studyData.get}}
<div class="study-item-box">
<div class="study-modality">
<div class="study-modality-text" style="{{modalityStyle studyData.modalities}}">{{studyData.modalities}}</div>
</div>
<div class="study-text">
<div class="study-date">{{formatDA studyData.studyDate 'D-MMM-YYYY'}}</div>
<div class="study-description">{{studyData.studyDescription}}</div>
</div>
</div>
<div class="study-text">
<div class="study-date">{{formatDA this.studyInformation.studyDate 'D-MMM-YYYY'}}</div>
<div class="study-description">{{this.studyInformation.studyDescription}}</div>
</div>
</div>
{{/let}}
</div>
{{#if this.studyChildTemplate}}
{{#if and (not isLoading) instance.loaded}}
{{#if and (not isLoading) instance.studyData.get instance.loaded}}
{{>Template.dynamic template=this.studyChildTemplate data=(clone this)}}
{{/if}}
{{/if}}

View File

@ -7,12 +7,42 @@ import { OHIF } from 'meteor/ohif:core';
Template.studyBrowserItem.onCreated(() => {
const instance = Template.instance();
const { studyInformation } = instance.data;
const { studyInstanceUid } = studyInformation;
instance.loaded = false;
instance.loading = new ReactiveVar(false);
const modalities = instance.data.studyInformation.modalities || 'UN';
instance.modalities = _.uniq(modalities.split(/[^A-Za-z]+/g)).join(' ');
instance.studyData = new ReactiveVar(studyInformation);
instance.studyMetadata = null;
instance.getStudyMetadata = () => {
instance.loading.dep.depend();
if (!instance.studyMetadata) {
instance.studyMetadata = OHIF.viewer.Studies.findBy({ studyInstanceUid }) || null;
}
return instance.studyMetadata;
};
instance.autorun(() => {
const instance = Template.instance();
OHIF.studies.loadedDict.get(studyInstanceUid);
const studyMetadata = instance.getStudyMetadata();
if (studyMetadata) {
const firstInstance = studyMetadata.getFirstInstance();
instance.studyData.set({
studyDate: firstInstance.getRawValue('x00080020') || '',
studyDescription: firstInstance.getRawValue('x00081030') || '',
modalities: firstInstance.getRawValue('x00080060') || '',
});
instance.loaded = true;
instance.loading.set(false);
}
});
});
Template.studyBrowserItem.events({
@ -49,10 +79,14 @@ Template.studyBrowserItem.helpers({
return Template.instance().loading.get();
},
modalityStyle() {
modalitiesText(modalities) {
const text = modalities || 'UN';
return _.uniq(text.split(/[^A-Za-z]+/g)).join(' ');
},
modalityStyle(modalities) {
// Responsively styles the Modality Acronyms for studies with more than one modality
const instance = Template.instance();
const numModalities = instance.modalities.split(/\s/g).length;
const numModalities = modalities.split(/\s/g).length;
if (numModalities === 1) {
// If we have only one modality, it should take up the whole div

View File

@ -1,6 +1,6 @@
<template name="studyBrowserList">
<div class="study-browser-list {{this.class}}">
{{#each studyInformation in studiesInformation}}
{{#each studyInformation in getStudiesInformation}}
{{>studyBrowserItem (clone this studyInformation=studyInformation)}}
{{/each}}
</div>

View File

@ -0,0 +1,11 @@
import { Template } from 'meteor/templating';
Template.studyBrowserList.helpers({
getStudiesInformation() {
const instance = Template.instance();
const { studiesInformation } = instance.data;
const result = new Map();
studiesInformation.forEach(item => result.set(item.studyInstanceUid, item));
return Array.from(result.values());
}
});

View File

@ -33,7 +33,8 @@ $spacerY = 12px
height: 100%
left: 0
opacity: 0.75
right: 16px
top: 0
width: 100%
.study-item-box
opacity: 0.2
@ -72,7 +73,7 @@ $spacerY = 12px
padding: $spacerY $spacerX ($spacerY - 1)
position: relative
transition($sidebarTransition)
z-index: 1
z-index: 0
&:hover
background-color: $boxHoverBackgroundColor

View File

@ -2,7 +2,7 @@
<div class="study-browser-series">
<div class="study-series-container">
{{#each thumbnail in instance.thumbnails.get}}
{{>thumbnailEntry (clone '' thumbnail=thumbnail)}}
{{>thumbnailEntry (clone this thumbnail=thumbnail)}}
{{/each}}
</div>
</div>

View File

@ -5,18 +5,43 @@ import { OHIF } from 'meteor/ohif:core';
Template.studyBrowserSeries.onCreated(() => {
const instance = Template.instance();
const { studyInformation } = instance.data;
const { studyInstanceUid } = studyInformation;
const { studyInformation, studyMetadata } = instance.data;
const studyInstanceUid = (studyMetadata && studyMetadata.studyInstanceUid) || (studyInformation && studyInformation.studyInstanceUid);
instance.thumbnails = new ReactiveVar([]);
// Get the study metadata and update the study thumbnails
instance.autorun(() => {
const studyMetadata = OHIF.viewer.Studies.findBy({ studyInstanceUid });
let metadata = studyMetadata;
// Check for reactivity
if (metadata instanceof ReactiveVar) {
metadata = metadata.get();
}
// Retrieve the study metadata
if (!metadata) {
metadata = OHIF.viewer.Studies.findBy({ studyInstanceUid });
}
// Stop here if there's no study metadata
if (!metadata) return;
// Get the study display sets
let displaySets = metadata.getDisplaySets();
if (!displaySets.length) {
displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(metadata);
metadata.displaySets = displaySets;
metadata.setDisplaySets(displaySets);
metadata.forEachDisplaySet(displaySet => {
OHIF.viewerbase.stackManager.makeAndAddStack(metadata, displaySet);
});
}
// Defines the resulting thumbnails list
const thumbnails = [];
studyMetadata.displaySets.forEach((stack, thumbnailIndex) => {
displaySets.forEach((stack, thumbnailIndex) => {
thumbnails.push({
thumbnailIndex,
stack

View File

@ -1,5 +1,9 @@
import { ReactiveDict } from 'meteor/reactive-dict';
import { OHIF } from 'meteor/ohif:core';
// Create a studies loaded state dictionary to enable reactivity
OHIF.studies.loadedDict = new ReactiveDict();
/**
* Load the study metadata and store its information locally
*
@ -8,6 +12,16 @@ import { OHIF } from 'meteor/ohif:core';
*/
OHIF.studies.loadStudy = studyInstanceUid => new Promise((resolve, reject) => {
OHIF.studies.retrieveStudyMetadata(studyInstanceUid).then(study => {
// Add the display sets to the study if not present
if (!study.displaySets) {
const displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(study);
study.displaySets = displaySets;
study.setDisplaySets(displaySets);
study.forEachDisplaySet(displaySet => {
OHIF.viewerbase.stackManager.makeAndAddStack(study, displaySet);
});
}
// Double check to make sure this study wasn't already inserted into OHIF.viewer.Studies
// so we don't cause duplicate entry errors
const loaded = OHIF.viewer.Studies.findBy({ studyInstanceUid: study.studyInstanceUid });
@ -15,6 +29,9 @@ OHIF.studies.loadStudy = studyInstanceUid => new Promise((resolve, reject) => {
OHIF.viewer.Studies.insert(study);
}
// Add the studyInstanceUid to the loaded state dictionary
OHIF.studies.loadedDict.set(study.studyInstanceUid, true);
resolve(study);
}).catch(reject);
});

View File

@ -463,11 +463,27 @@ const loadDisplaySetIntoViewport = (data, templateData) => {
*/
const setDisplaySet = (data, displaySetInstanceUid, templateData) => {
const study = data.study;
if (!study || !study.displaySets) {
throw new OHIFError('Study does not exist or has no display sets');
if (!study) {
throw new OHIFError('Study does not exist');
}
study.displaySets.every(displaySet => {
let displaySets = study.getDisplaySets();
if (!displaySets.length) {
displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(study);
study.displaySets = displaySets;
study.setDisplaySets(displaySets);
study.forEachDisplaySet(displaySet => {
OHIF.viewerbase.stackManager.makeAndAddStack(study, displaySet);
});
}
if (!displaySets) {
throw new OHIFError('Study has no display sets');
}
displaySets.every(displaySet => {
if (displaySet.displaySetInstanceUid === displaySetInstanceUid) {
data.displaySet = displaySet;
return false;
@ -478,7 +494,7 @@ const setDisplaySet = (data, displaySetInstanceUid, templateData) => {
// If we didn't find anything, stop here
if (!data.displaySet) {
data.displaySet = study.displaySets[0];
data.displaySet = displaySets[0];
// throw new OHIFError('Display set not found in specified study!');
}

View File

@ -9,9 +9,7 @@
{{/each}}
{{#scrollArea class='series-browser' scrollStep=201}}
<div class="clearfix thumbnails-wrapper">
{{#each thumbnail in (studyThumbnails instance.currentStudy.get)}}
{{>thumbnailEntry (clone this thumbnail=thumbnail)}}
{{/each}}
{{>studyBrowserSeries (clone this studyMetadata=instance.currentStudy)}}
</div>
{{/scrollArea}}
</div>

View File

@ -32,7 +32,9 @@ Template.seriesQuickSwitch.onCreated(() => {
instance.study = OHIF.viewer.Studies.findBy({
studyInstanceUid: viewportData.studyInstanceUid
});
} else {
}
if (!instance.study) {
instance.study = OHIF.viewer.Studies.getElementByIndex(0);
}
@ -73,9 +75,20 @@ Template.seriesQuickSwitch.helpers({
const seriesItems = [];
const items = study.displaySets.length;
let displaySets = study.getDisplaySets();
if (!displaySets.length) {
displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(study);
study.displaySets = displaySets;
study.setDisplaySets(displaySets);
study.forEachDisplaySet(displaySet => {
OHIF.viewerbase.stackManager.makeAndAddStack(study, displaySet);
});
}
const items = displaySets.length;
for (let i = 0; i < items; i++) {
const displaySet = study.displaySets[i];
const displaySet = displaySets[i];
const item = { class: '' };
seriesItems.push(item);
if (i === 8 && items !== 9) {
@ -105,7 +118,10 @@ Template.seriesQuickSwitch.events({
const $seriesBrowser = $switch.find('.series-browser');
$seriesBrowser.width(browserWidth - (browserWidth % 237));
instance.$('.series-quick-switch').addClass('series-triggered');
const $quickSwitch = instance.$('.series-quick-switch');
if ($quickSwitch.is(':hover')) {
$quickSwitch.addClass('series-triggered');
}
},
'mouseleave .series-browser'(event, instance) {