AWV-1: Refactoring layout manager

This commit is contained in:
Bruno Alves de Faria 2016-09-02 20:07:14 -03:00
parent 0469747b5a
commit e98e686664
5 changed files with 192 additions and 104 deletions

View File

@ -97,7 +97,7 @@ Template.toolbarSection.helpers({
title: 'Previous',
classes: 'imageViewerCommand',
buttonTemplateName: 'displaySetNavigation',
isPrevious: true
isNext: false
});
buttonData.push({
@ -105,7 +105,7 @@ Template.toolbarSection.helpers({
title: 'Next',
classes: 'imageViewerCommand',
buttonTemplateName: 'displaySetNavigation',
isPrevious: false
isNext: true
});
buttonData.push({

View File

@ -2,6 +2,107 @@ import { OHIF } from 'meteor/ohif:core';
OHIF.viewer = {};
OHIF.viewer.getDisplaySetSequenceMap = () => {
// Get the viewport data list
const viewportDataList = window.layoutManager.viewportData;
// Create a map to control the display set sequence
const sequenceMap = new Map();
// Iterate over each viewport and register its details on the sequence map
viewportDataList.forEach((viewportData, viewportIndex) => {
// Get the current study
const currentStudy = _.findWhere(window.layoutManager.studies, {
studyInstanceUid: viewportData.studyInstanceUid
}) || window.layoutManager.studies[0];
// Get the display sets
const displaySets = currentStudy.displaySets;
// Get the current display set
const displaySet = _.findWhere(displaySets, {
displaySetInstanceUid: viewportData.displaySetInstanceUid
});
// Get the current instance index
let displaySetIndex = _.indexOf(displaySets, displaySet);
displaySetIndex = displaySetIndex < 0 ? 9999 : displaySetIndex;
// Try to get a map entry for current study or create it if not present
let studyViewports = sequenceMap.get(currentStudy);
if (!studyViewports) {
studyViewports = [];
sequenceMap.set(currentStudy, studyViewports);
}
// Register the viewport index and the display set index on the map
studyViewports.push({
viewportIndex,
displaySetIndex
});
});
// Return the generated sequence map
return sequenceMap;
};
OHIF.viewer.isDisplaySetsSequenced = definedSequenceMap => {
let isSequenced = true;
// Get the studies and display sets sequence map
const sequenceMap = definedSequenceMap || OHIF.viewer.getDisplaySetSequenceMap();
sequenceMap.forEach((studyViewports, study) => {
let lastDisplaySetIndex = null;
let lastViewportIndex = null;
studyViewports.forEach(({ viewportIndex, displaySetIndex }, index) => {
// Check if the sequence is wrong
if (
displaySetIndex !== 9999 &&
lastViewportIndex !== null &&
lastDisplaySetIndex !== null &&
displaySetIndex !== null &&
(viewportIndex - 1) !== lastViewportIndex &&
(displaySetIndex - 1) !== lastDisplaySetIndex
) {
// Set the sequenced flag as false;
isSequenced = false;
}
// Update the last viewport index
lastViewportIndex = viewportIndex;
// Update the last display set index
lastDisplaySetIndex = displaySetIndex;
});
});
return isSequenced;
};
OHIF.viewer.canMoveDisplaySets = isNext => {
// Get the setting that defines if the display set navigation is multiple
const isMultiple = OHIF.uiSettings.displaySetNavigationMultipleViewports;
// Get the setting that allow display set navigation looping over series
const allowLooping = OHIF.uiSettings.displaySetNavigationLoopOverSeries;
// Return false if no layout manager is not defined yet
if (!window.layoutManager) {
return false;
}
// Get the studies and display sets sequence map
const sequenceMap = OHIF.viewer.getDisplaySetSequenceMap();
// Return false for moving backward if display sets are not sequenced
if (isMultiple && !isNext && !OHIF.viewer.isDisplaySetsSequenced(sequenceMap)) {
return false;
}
return true;
};
// Move display sets forward or backward in the given viewport index
OHIF.viewer.moveSingleViewportDisplaySets = (viewportIndex, isNext) => {
// Get the setting that allow display set navigation looping over series
@ -59,47 +160,14 @@ OHIF.viewer.moveMultipleViewportDisplaySets = isNext => {
// Get the setting that allow display set navigation looping over series
const allowLooping = OHIF.uiSettings.displaySetNavigationLoopOverSeries;
// Get the viewport data list
const viewportDataList = window.layoutManager.viewportData;
// Create a map to control the display set sequence
const sequenceMap = new OHIF.viewer.getDisplaySetSequenceMap();
// Create a map to control the display set movement
const moveMap = new Map();
// Iterate over each viewport and register its details on the movement map
viewportDataList.forEach((viewportData, viewportIndex) => {
// Get the current study
const currentStudy = _.findWhere(window.layoutManager.studies, {
studyInstanceUid: viewportData.studyInstanceUid
}) || window.layoutManager.studies[0];
// Get the display sets
const displaySets = currentStudy.displaySets;
// Get the current display set
const displaySet = _.findWhere(displaySets, {
displaySetInstanceUid: viewportData.displaySetInstanceUid
});
// Get the current instance index
let displaySetIndex = _.indexOf(displaySets, displaySet);
displaySetIndex = displaySetIndex < 0 ? 9999 : displaySetIndex;
// Try to get a map entry for current study or create it if not present
let studyViewports = moveMap.get(currentStudy);
if (!studyViewports) {
studyViewports = [];
moveMap.set(currentStudy, studyViewports);
}
// Register the viewport index and the display set index on the map
studyViewports.push({
viewportIndex,
displaySetIndex
});
});
// Check if the display sets are sequenced
const isSequenced = OHIF.viewer.isDisplaySetsSequenced(sequenceMap);
// Iterate over the studies map and move its display sets
moveMap.forEach((studyViewports, study) => {
sequenceMap.forEach((studyViewports, study) => {
// Sort the viewports on the study by the display set index
studyViewports.sort((a, b) => a.displaySetIndex > b.displaySetIndex);
@ -114,13 +182,17 @@ OHIF.viewer.moveMultipleViewportDisplaySets = isNext => {
const direction = isNext ? 1 : -1;
baseIndex += amount * direction;
// Check if the base index will be outside the array bounds
if (baseIndex >= displaySets.length) {
// Check if the indexes are sequenced or will overflow the array bounds
if (!isSequenced) {
// Reset the sequence if indexes are not sequenced
baseIndex = 0;
} else if (baseIndex >= displaySets.length) {
// Stop here if looping is not allowed
if (!allowLooping) {
return;
}
// Start over the series if looping is allowed
baseIndex = 0;
} else if (baseIndex < 0) {
// Stop here if looping is not allowed
@ -128,6 +200,7 @@ OHIF.viewer.moveMultipleViewportDisplaySets = isNext => {
return;
}
// Go to the series' end if looping is allowed
baseIndex = (displaySets.length - 1) - ((displaySets.length - 1) % amount);
}

View File

@ -1,16 +1,16 @@
<template name="displaySetNavigation">
<div id="{{this.id}}"
class="toolbarSectionButton rp-x-1 {{this.classes}} {{#if isPrevious}}js-prev{{else}}js-next{{/if}}"
class="toolbarSectionButton rp-x-1 {{this.classes}} {{#if isNext}}js-next{{else}}js-prev{{/if}} {{#if (disableButton isNext)}}disabled{{/if}}"
title="{{this.title}}">
<div class="svgContainer">
{{#if isPrevious}}
<i class="fa fa-toggle-up fa-fw"></i>
{{else}}
{{#if isNext}}
<i class="fa fa-toggle-down fa-fw"></i>
{{else}}
<i class="fa fa-toggle-up fa-fw"></i>
{{/if}}
</div>
<div class="buttonLabel" disabled="{{#if (disableButton isPrevious)}}disabled{{/if}}">
{{#if isPrevious}}Previous{{else}}Next{{/if}}
<div class="buttonLabel">
{{#if isNext}}Next{{else}}Previous{{/if}}
</div>
</div>
</template>

View File

@ -3,16 +3,25 @@ import { Template } from 'meteor/templating';
Template.displaySetNavigation.events({
'click .js-next'(event, instance) {
if ($(event.currentTarget).hasClass('disabled')) {
return;
}
OHIF.viewer.moveDisplaySets(true);
},
'click .js-prev'(event, instance) {
if ($(event.currentTarget).hasClass('disabled')) {
return;
}
OHIF.viewer.moveDisplaySets(false);
}
});
Template.displaySetNavigation.helpers({
disableButton(isPrevious) {
disableButton(isNext) {
Session.get('LayoutManagerUpdated');
return !OHIF.viewer.canMoveDisplaySets(isNext);
}
});

View File

@ -25,68 +25,74 @@ LayoutManager = class LayoutManager {
}
setDefaultViewportData() {
var numViewports = this.getNumberOfViewports();
const self = this;
var viewportIndex = 0;
var self = this;
var oldViewportData = self.viewportData;
var running = true;
self.viewportData = [];
this.studies.forEach(function(study) {
study.displaySets.forEach(function(displaySet) {
if (!displaySet.images.length || !running) {
return;
}
// Get the number of vieports to be rendered
const viewportsAmount = this.getNumberOfViewports();
var currentViewportData;
var existingViewportData = oldViewportData[viewportIndex];
if (oldViewportData[viewportIndex]) {
currentViewportData = {
viewportIndex: existingViewportData.viewportIndex,
studyInstanceUid: existingViewportData.studyInstanceUid,
seriesInstanceUid: existingViewportData.seriesInstanceUid,
displaySetInstanceUid: existingViewportData.displaySetInstanceUid,
sopInstanceUid: existingViewportData.sopInstanceUid,
viewport: existingViewportData.viewport,
imageId: existingViewportData.imageId,
currentImageIdIndex: existingViewportData.currentImageIdIndex // TODO Remove this once currentImageIdIndex is removed from imageViewerViewports
};
} else {
// This tests to make sure there is actually image data in this instance
// TODO: Change this when we add PDF and MPEG support
// See https://ohiforg.atlassian.net/browse/LT-227
var firstInstance = displaySet.images[0];
// Store the old viewport data and reset the current
const oldViewportData = self.viewportData;
// All imaging modalities must have a valid value for sopClassUid or rows
if (!firstInstance || (!isImage(firstInstance.sopClassUid) && !firstInstance.rows)) {
currentViewportData = {};
} else {
currentViewportData = {
viewportIndex: viewportIndex,
studyInstanceUid: study.studyInstanceUid,
seriesInstanceUid: displaySet.seriesInstanceUid,
displaySetInstanceUid: displaySet.displaySetInstanceUid,
sopInstanceUid: firstInstance.sopInstanceUid,
currentImageIdIndex: 0 // TODO Remove this once currentImageIdIndex is removed from imageViewerViewports
};
}
}
// Get the studies and display sets sequence map
const sequenceMap = OHIF.viewer.getDisplaySetSequenceMap();
self.viewportData.push(currentViewportData);
// Check if the display sets are sequenced
const isSequenced = OHIF.viewer.isDisplaySetsSequenced(sequenceMap);
viewportIndex++;
// Define the current viewport index and the viewport data array
let currentViewportIndex = 0;
if (viewportsAmount > oldViewportData.length && isSequenced) {
// Keep the displayed display sets
self.viewportData = oldViewportData;
currentViewportIndex = oldViewportData.length - 1;
} else if (viewportsAmount <= oldViewportData.length) {
// Reduce the original displayed display sets
self.viewportData = oldViewportData.slice(0, viewportsAmount);
return;
} else {
// Reset all display sets
self.viewportData = [];
}
if (viewportIndex === numViewports) {
running = false;
return false;
}
// Get all the display sets for the viewer studies
let displaySets = [];
this.studies.forEach(study => {
study.displaySets.forEach(displaySet => {
displaySet.images.length && displaySets.push(displaySet);
});
if (viewportIndex === numViewports) {
running = false;
return false;
}
});
// Get the display sets that will be appended to the current ones
let appendix;
const currentLength = self.viewportData.length;
if (currentLength) {
// TODO: isolate displaySets array by study (maybe a map?)
const endIndex = currentViewportIndex + (viewportsAmount - currentLength) + 1;
appendix = displaySets.slice(currentViewportIndex + 1, endIndex);
} else {
// Get available display sets from the first to the grid size
appendix = displaySets.slice(0, viewportsAmount - 1);
}
// Generate the additional data based on the appendix
const additionalData = [];
appendix.forEach((displaySet, index) => {
additionalData.push({
viewportIndex: currentViewportIndex + index,
studyInstanceUid: displaySet.studyInstanceUid,
seriesInstanceUid: displaySet.seriesInstanceUid,
displaySetInstanceUid: displaySet.displaySetInstanceUid,
sopInstanceUid: displaySet.images[0].sopInstanceUid
});
});
// Append the additional data with the viewport data
self.viewportData = self.viewportData.concat(additionalData);
// Push empty objects if the amount is lesser than the grid size
while (self.viewportData.length < viewportsAmount) {
self.viewportData.push({});
}
}
updateViewports() {