LT-303: adding frame rate value to active viewport so cornerstone tools can work properly (forward not backward). Some code improvements.
This commit is contained in:
parent
be56608208
commit
c862c3fa5c
@ -22,17 +22,17 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
|
|
||||||
// Get the current element and it's index in the list of all viewports
|
// Get the current element and it's index in the list of all viewports
|
||||||
// The viewport index is often used to store information about a viewport element
|
// The viewport index is often used to store information about a viewport element
|
||||||
var element = data.element;
|
const element = data.element;
|
||||||
var viewportIndex = $('.imageViewerViewport').index(element);
|
const viewportIndex = $('.imageViewerViewport').index(element);
|
||||||
|
|
||||||
let layoutManager = window.layoutManager;
|
const layoutManager = window.layoutManager;
|
||||||
layoutManager.viewportData = layoutManager.viewportData || {};
|
layoutManager.viewportData = layoutManager.viewportData || {};
|
||||||
layoutManager.viewportData[viewportIndex] = layoutManager.viewportData[viewportIndex] || {};
|
layoutManager.viewportData[viewportIndex] = layoutManager.viewportData[viewportIndex] || {};
|
||||||
layoutManager.viewportData[viewportIndex].viewportIndex = viewportIndex;
|
layoutManager.viewportData[viewportIndex].viewportIndex = viewportIndex;
|
||||||
|
|
||||||
// Get the contentID of the current study list tab, if the viewport is running
|
// Get the contentID of the current study list tab, if the viewport is running
|
||||||
// alongside the study list package
|
// alongside the study list package
|
||||||
var contentId = Session.get('activeContentId');
|
const contentId = Session.get('activeContentId');
|
||||||
|
|
||||||
// If the viewer is inside a tab, create an object related to the specified viewport
|
// If the viewer is inside a tab, create an object related to the specified viewport
|
||||||
// This data will be saved so that the tab can be reloaded to the same state after tabs
|
// This data will be saved so that the tab can be reloaded to the same state after tabs
|
||||||
@ -46,17 +46,17 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create an empty array to populate with image IDs
|
// Create an empty array to populate with image IDs
|
||||||
var imageIds = [];
|
const imageIds = [];
|
||||||
|
|
||||||
// Loop through the current series and add metadata to the
|
// Loop through the current series and add metadata to the
|
||||||
// Cornerstone meta data provider. This will be used to fill information
|
// Cornerstone meta data provider. This will be used to fill information
|
||||||
// into the viewport overlays, and to calculate reference lines and orientation markers
|
// into the viewport overlays, and to calculate reference lines and orientation markers
|
||||||
var displaySet = data.displaySet;
|
const displaySet = data.displaySet;
|
||||||
var numImages = displaySet.images.length;
|
const numImages = displaySet.images.length;
|
||||||
var imageId;
|
let imageId;
|
||||||
|
|
||||||
displaySet.images.forEach(function(image, imageIndex) {
|
displaySet.images.forEach((image, imageIndex) => {
|
||||||
var metaData = {
|
const metaData = {
|
||||||
instance: image,
|
instance: image,
|
||||||
series: displaySet, // TODO: Check this
|
series: displaySet, // TODO: Check this
|
||||||
study: data.study,
|
study: data.study,
|
||||||
@ -64,7 +64,7 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
imageIndex: imageIndex + 1
|
imageIndex: imageIndex + 1
|
||||||
};
|
};
|
||||||
|
|
||||||
var numFrames = image.numFrames;
|
const numFrames = image.numFrames;
|
||||||
if (numFrames > 1) {
|
if (numFrames > 1) {
|
||||||
OHIF.log.info('Multiframe image detected');
|
OHIF.log.info('Multiframe image detected');
|
||||||
for (var i = 0; i < numFrames; i++) {
|
for (var i = 0; i < numFrames; i++) {
|
||||||
@ -73,7 +73,8 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
imageIds.push(imageId);
|
imageIds.push(imageId);
|
||||||
addMetaData(imageId, metaData);
|
addMetaData(imageId, metaData);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
imageId = getImageId(image);
|
imageId = getImageId(image);
|
||||||
imageIds.push(imageId);
|
imageIds.push(imageId);
|
||||||
addMetaData(imageId, metaData);
|
addMetaData(imageId, metaData);
|
||||||
@ -81,7 +82,7 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Define the current image stack using the newly created image IDs
|
// Define the current image stack using the newly created image IDs
|
||||||
var stack = {
|
const stack = {
|
||||||
currentImageIdIndex: data.currentImageIdIndex || 0,
|
currentImageIdIndex: data.currentImageIdIndex || 0,
|
||||||
imageIds: imageIds
|
imageIds: imageIds
|
||||||
};
|
};
|
||||||
@ -101,8 +102,7 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
ViewportLoading[viewportIndex] = imageId;
|
ViewportLoading[viewportIndex] = imageId;
|
||||||
|
|
||||||
// Enable Cornerstone for the viewport element
|
// Enable Cornerstone for the viewport element
|
||||||
//
|
const options = {
|
||||||
var options = {
|
|
||||||
renderer: 'webgl'
|
renderer: 'webgl'
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -113,33 +113,39 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
|
|
||||||
// Get the handler functions that will run when loading has finished or thrown
|
// Get the handler functions that will run when loading has finished or thrown
|
||||||
// an error. These are used to show/hide loading / error text boxes on each viewport.
|
// an error. These are used to show/hide loading / error text boxes on each viewport.
|
||||||
var endLoadingHandler = cornerstoneTools.loadHandlerManager.getEndLoadHandler();
|
const endLoadingHandler = cornerstoneTools.loadHandlerManager.getEndLoadHandler();
|
||||||
var errorLoadingHandler = cornerstoneTools.loadHandlerManager.getErrorLoadingHandler();
|
const errorLoadingHandler = cornerstoneTools.loadHandlerManager.getErrorLoadingHandler();
|
||||||
|
|
||||||
// Get the current viewport settings
|
// Get the current viewport settings
|
||||||
var viewport = cornerstone.getViewport(element);
|
const viewport = cornerstone.getViewport(element);
|
||||||
|
|
||||||
|
const { studyInstanceUid, seriesInstanceUid, displaySetInstanceUid, currentImageIdIndex } = data;
|
||||||
|
|
||||||
// Store the current series data inside the Layout Manager
|
// Store the current series data inside the Layout Manager
|
||||||
layoutManager.viewportData[viewportIndex] = {
|
layoutManager.viewportData[viewportIndex] = {
|
||||||
imageId: imageId,
|
imageId,
|
||||||
studyInstanceUid: data.studyInstanceUid,
|
studyInstanceUid,
|
||||||
seriesInstanceUid: data.seriesInstanceUid,
|
seriesInstanceUid,
|
||||||
displaySetInstanceUid: data.displaySetInstanceUid,
|
displaySetInstanceUid,
|
||||||
currentImageIdIndex: data.currentImageIdIndex,
|
currentImageIdIndex,
|
||||||
viewport: viewport,
|
viewport,
|
||||||
viewportIndex: viewportIndex
|
viewportIndex
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start loading the image.
|
// Start loading the image.
|
||||||
cornerstone.loadAndCacheImage(imageId).then(function(image) {
|
cornerstone.loadAndCacheImage(imageId).then(image => {
|
||||||
var enabledElement;
|
let enabledElement;
|
||||||
try {
|
try {
|
||||||
enabledElement = cornerstone.getEnabledElement(element);
|
enabledElement = cornerstone.getEnabledElement(element);
|
||||||
} catch (error) {
|
}
|
||||||
|
catch (error) {
|
||||||
OHIF.log.warn('Viewport destroyed before loaded image could be displayed');
|
OHIF.log.warn('Viewport destroyed before loaded image could be displayed');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Caches element's jQuery object
|
||||||
|
const jQueryEl = $(element);
|
||||||
|
|
||||||
// Update the enabled element with the image and viewport data
|
// Update the enabled element with the image and viewport data
|
||||||
// This is not usually necessary, but we need them stored in case
|
// This is not usually necessary, but we need them stored in case
|
||||||
// a sopClassUid-specific viewport setting is present.
|
// a sopClassUid-specific viewport setting is present.
|
||||||
@ -154,8 +160,8 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var instance = displaySet.images[0];
|
const instance = displaySet.images[0];
|
||||||
var instanceClassViewport = getInstanceClassDefaultViewport(instance, enabledElement, image.imageId);
|
const instanceClassViewport = getInstanceClassDefaultViewport(instance, enabledElement, image.imageId);
|
||||||
|
|
||||||
// If there are sopClassUid-specific viewport settings, apply them
|
// If there are sopClassUid-specific viewport settings, apply them
|
||||||
if (instanceClassViewport) {
|
if (instanceClassViewport) {
|
||||||
@ -167,7 +173,8 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
|
|
||||||
// Resize the canvas to fit the current viewport element size.
|
// Resize the canvas to fit the current viewport element size.
|
||||||
cornerstone.resize(element, false);
|
cornerstone.resize(element, false);
|
||||||
} else if (data.viewport) {
|
}
|
||||||
|
else if (data.viewport) {
|
||||||
// If there is a saved object containing Cornerstone viewport data
|
// If there is a saved object containing Cornerstone viewport data
|
||||||
// (e.g. scale, invert, window settings) in the input data, apply it now.
|
// (e.g. scale, invert, window settings) in the input data, apply it now.
|
||||||
cornerstone.displayImage(element, image, data.viewport);
|
cornerstone.displayImage(element, image, data.viewport);
|
||||||
@ -175,7 +182,8 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
// Resize the canvas to fit the current viewport element size. Fit the displayed
|
// Resize the canvas to fit the current viewport element size. Fit the displayed
|
||||||
// image to the canvas dimensions.
|
// image to the canvas dimensions.
|
||||||
cornerstone.resize(element, true);
|
cornerstone.resize(element, true);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// If no saved viewport settings or modality-specific settings exists,
|
// If no saved viewport settings or modality-specific settings exists,
|
||||||
// display the loaded image in the viewport element with no loaded viewport
|
// display the loaded image in the viewport element with no loaded viewport
|
||||||
// settings.
|
// settings.
|
||||||
@ -199,8 +207,8 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
|
|
||||||
// Hide the viewport instructions (i.e. 'Drag a stack here') and show
|
// Hide the viewport instructions (i.e. 'Drag a stack here') and show
|
||||||
// the viewport overlay data.
|
// the viewport overlay data.
|
||||||
$(element).siblings('.viewportInstructions').hide();
|
jQueryEl.siblings('.viewportInstructions').hide();
|
||||||
$(element).siblings('.imageViewerViewportOverlay').show();
|
jQueryEl.siblings('.imageViewerViewportOverlay').show();
|
||||||
|
|
||||||
// Add stack state managers for the stack tool, CINE tool, and reference lines
|
// Add stack state managers for the stack tool, CINE tool, and reference lines
|
||||||
cornerstoneTools.addStackStateManager(element, ['stack', 'playClip', 'referenceLines']);
|
cornerstoneTools.addStackStateManager(element, ['stack', 'playClip', 'referenceLines']);
|
||||||
@ -213,16 +221,16 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
cornerstoneTools.addToolState(element, 'stack', stack);
|
cornerstoneTools.addToolState(element, 'stack', stack);
|
||||||
|
|
||||||
// Set the default CINE settings
|
// Set the default CINE settings
|
||||||
var multiframeMetadata = instance.multiframeMetadata;
|
const multiframeMetadata = instance.multiframeMetadata;
|
||||||
|
|
||||||
let fps;
|
let fps;
|
||||||
if (multiframeMetadata) {
|
if (multiframeMetadata && multiframeMetadata.averageFrameRate > 0) {
|
||||||
fps = multiframeMetadata.averageFrameRate
|
fps = multiframeMetadata.averageFrameRate;
|
||||||
} else {
|
} else {
|
||||||
fps = OHIF.viewer.cine.framesPerSecond
|
fps = OHIF.viewer.cine.framesPerSecond;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cineToolData = {
|
const cineToolData = {
|
||||||
loop: OHIF.viewer.cine.loop,
|
loop: OHIF.viewer.cine.loop,
|
||||||
framesPerSecond: fps
|
framesPerSecond: fps
|
||||||
};
|
};
|
||||||
@ -242,12 +250,12 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
|
|
||||||
// Use the tool manager to enable the currently active tool for this
|
// Use the tool manager to enable the currently active tool for this
|
||||||
// newly rendered element
|
// newly rendered element
|
||||||
var activeTool = toolManager.getActiveTool();
|
const activeTool = toolManager.getActiveTool();
|
||||||
toolManager.setActiveTool(activeTool, [element]);
|
toolManager.setActiveTool(activeTool, [element]);
|
||||||
|
|
||||||
// Define a function to run whenever the Cornerstone viewport is rendered
|
// Define a function to run whenever the Cornerstone viewport is rendered
|
||||||
// (e.g. following a change of window or zoom)
|
// (e.g. following a change of window or zoom)
|
||||||
function onImageRendered(e, eventData) {
|
const onImageRendered = () => {
|
||||||
OHIF.log.info('imageViewerViewport onImageRendered');
|
OHIF.log.info('imageViewerViewport onImageRendered');
|
||||||
|
|
||||||
if (!layoutManager.viewportData[viewportIndex]) {
|
if (!layoutManager.viewportData[viewportIndex]) {
|
||||||
@ -260,22 +268,22 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
|
|
||||||
// Save the current viewport into the ViewerData global variable, as well as the
|
// Save the current viewport into the ViewerData global variable, as well as the
|
||||||
// Meteor Session. This lets the viewport be saved/reloaded on a hot-code reload
|
// Meteor Session. This lets the viewport be saved/reloaded on a hot-code reload
|
||||||
var viewport = cornerstone.getViewport(element);
|
const viewport = cornerstone.getViewport(element);
|
||||||
layoutManager.viewportData[viewportIndex].viewport = viewport;
|
layoutManager.viewportData[viewportIndex].viewport = viewport;
|
||||||
ViewerData[contentId].loadedSeriesData[viewportIndex].viewport = viewport;
|
ViewerData[contentId].loadedSeriesData[viewportIndex].viewport = viewport;
|
||||||
Session.set('ViewerData', ViewerData);
|
Session.set('ViewerData', ViewerData);
|
||||||
}
|
};
|
||||||
|
|
||||||
// Attach the onImageRendered callback to the CornerstoneImageRendered event
|
// Attach the onImageRendered callback to the CornerstoneImageRendered event
|
||||||
$(element).off('CornerstoneImageRendered', onImageRendered);
|
jQueryEl.off('CornerstoneImageRendered', onImageRendered);
|
||||||
$(element).on('CornerstoneImageRendered', onImageRendered);
|
jQueryEl.on('CornerstoneImageRendered', onImageRendered);
|
||||||
|
|
||||||
// Set a random value for the Session variable in order to trigger an overlay update
|
// Set a random value for the Session variable in order to trigger an overlay update
|
||||||
Session.set('CornerstoneImageRendered' + viewportIndex, Random.id());
|
Session.set('CornerstoneImageRendered' + viewportIndex, Random.id());
|
||||||
|
|
||||||
// Define a function to run whenever the Cornerstone viewport changes images
|
// Define a function to run whenever the Cornerstone viewport changes images
|
||||||
// (e.g. during scrolling)
|
// (e.g. during scrolling)
|
||||||
function onNewImage(e, eventData) {
|
const onNewImage = (e, eventData) => {
|
||||||
OHIF.log.info('imageViewerViewport onNewImage');
|
OHIF.log.info('imageViewerViewport onNewImage');
|
||||||
|
|
||||||
// Update the metaData for missing fields
|
// Update the metaData for missing fields
|
||||||
@ -288,28 +296,26 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
layoutManager.viewportData[viewportIndex].imageId = eventData.enabledElement.image.imageId;
|
layoutManager.viewportData[viewportIndex].imageId = eventData.enabledElement.image.imageId;
|
||||||
|
|
||||||
// Get the element and stack data
|
// Get the element and stack data
|
||||||
var element = e.target;
|
const element = e.target;
|
||||||
var toolData = cornerstoneTools.getToolState(element, 'stack');
|
const toolData = cornerstoneTools.getToolState(element, 'stack');
|
||||||
if (!toolData || !toolData.data || !toolData.data.length) {
|
if (!toolData || !toolData.data || !toolData.data.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stack = toolData.data[0];
|
|
||||||
|
|
||||||
// If this viewport is displaying a stack of images, save the current image
|
// If this viewport is displaying a stack of images, save the current image
|
||||||
// index in the stack to the global ViewerData object, as well as the Meteor Session.
|
// index in the stack to the global ViewerData object, as well as the Meteor Session.
|
||||||
var stack = cornerstoneTools.getToolState(element, 'stack');
|
const stack = cornerstoneTools.getToolState(element, 'stack');
|
||||||
if (stack && stack.data.length && stack.data[0].imageIds.length > 1) {
|
if (stack && stack.data.length && stack.data[0].imageIds.length > 1) {
|
||||||
var imageIdIndex = stack.data[0].imageIds.indexOf(templateData.imageId);
|
const imageIdIndex = stack.data[0].imageIds.indexOf(templateData.imageId);
|
||||||
layoutManager.viewportData[viewportIndex].currentImageIdIndex = imageIdIndex;
|
layoutManager.viewportData[viewportIndex].currentImageIdIndex = imageIdIndex;
|
||||||
ViewerData[contentId].loadedSeriesData[viewportIndex].currentImageIdIndex = imageIdIndex;
|
ViewerData[contentId].loadedSeriesData[viewportIndex].currentImageIdIndex = imageIdIndex;
|
||||||
Session.set('ViewerData', ViewerData);
|
Session.set('ViewerData', ViewerData);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// Attach the onNewImage callback to the CornerstoneNewImage event
|
// Attach the onNewImage callback to the CornerstoneNewImage event
|
||||||
$(element).off('CornerstoneNewImage', onNewImage);
|
jQueryEl.off('CornerstoneNewImage', onNewImage);
|
||||||
$(element).on('CornerstoneNewImage', onNewImage);
|
jQueryEl.on('CornerstoneNewImage', onNewImage);
|
||||||
|
|
||||||
// Set a random value for the Session variable in order to trigger an overlay update
|
// Set a random value for the Session variable in order to trigger an overlay update
|
||||||
Session.set('CornerstoneNewImage' + viewportIndex, Random.id());
|
Session.set('CornerstoneNewImage' + viewportIndex, Random.id());
|
||||||
@ -317,13 +323,13 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
// Define a function to trigger an event whenever a new viewport is being used
|
// Define a function to trigger an event whenever a new viewport is being used
|
||||||
// This is used to update the value of the "active viewport", when the user interacts
|
// This is used to update the value of the "active viewport", when the user interacts
|
||||||
// with a new viewport element
|
// with a new viewport element
|
||||||
function sendActivationTrigger(e, eventData) {
|
const sendActivationTrigger = (e, eventData) => {
|
||||||
// Check if the current active viewport in the Meteor Session
|
// Check if the current active viewport in the Meteor Session
|
||||||
// Is the same as the viewport in which the activation event was fired.
|
// Is the same as the viewport in which the activation event was fired.
|
||||||
// If it was, no changes are necessary, so stop here.
|
// If it was, no changes are necessary, so stop here.
|
||||||
var element = eventData.element;
|
const element = eventData.element;
|
||||||
var activeViewportIndex = Session.get('activeViewport');
|
const activeViewportIndex = Session.get('activeViewport');
|
||||||
var viewportIndex = $('.imageViewerViewport').index(element);
|
const viewportIndex = $('.imageViewerViewport').index(element);
|
||||||
|
|
||||||
// Reset the focus, even if we don't need to re-enable reference lines or prefetching
|
// Reset the focus, even if we don't need to re-enable reference lines or prefetching
|
||||||
$(element).focus();
|
$(element).focus();
|
||||||
@ -337,21 +343,21 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
// Otherwise, trigger an 'ActivateViewport' event to be handled by the Template event
|
// Otherwise, trigger an 'ActivateViewport' event to be handled by the Template event
|
||||||
// handler
|
// handler
|
||||||
eventData.viewportIndex = viewportIndex;
|
eventData.viewportIndex = viewportIndex;
|
||||||
var customEvent = $.Event('ActivateViewport', eventData);
|
const customEvent = $.Event('ActivateViewport', eventData);
|
||||||
|
|
||||||
// Need to overwrite the type set in the original event
|
// Need to overwrite the type set in the original event
|
||||||
customEvent.type = 'ActivateViewport';
|
customEvent.type = 'ActivateViewport';
|
||||||
$(e.target).trigger(customEvent, eventData);
|
$(e.target).trigger(customEvent, eventData);
|
||||||
}
|
};
|
||||||
|
|
||||||
// Attach the sendActivationTrigger function to all of the Cornerstone interaction events
|
// Attach the sendActivationTrigger function to all of the Cornerstone interaction events
|
||||||
$(element).off(allCornerstoneEvents, sendActivationTrigger);
|
jQueryEl.off(allCornerstoneEvents, sendActivationTrigger);
|
||||||
$(element).on(allCornerstoneEvents, sendActivationTrigger);
|
jQueryEl.on(allCornerstoneEvents, sendActivationTrigger);
|
||||||
|
|
||||||
ViewerData[contentId].loadedSeriesData = layoutManager.viewportData;
|
ViewerData[contentId].loadedSeriesData = layoutManager.viewportData;
|
||||||
|
|
||||||
// Check if image plane (orientation / loction) data is present for the current image
|
// Check if image plane (orientation / loction) data is present for the current image
|
||||||
var imagePlane = cornerstoneTools.metaData.get('imagePlane', image.imageId);
|
const imagePlane = cornerstoneTools.metaData.get('imagePlane', image.imageId);
|
||||||
|
|
||||||
// If it is, and reference lines are enabled, add this element to the global synchronizer
|
// If it is, and reference lines are enabled, add this element to the global synchronizer
|
||||||
// that is used for updating reference lines, and enable reference lines for this viewport.
|
// that is used for updating reference lines, and enable reference lines for this viewport.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user