Adding metadata support for rule entry dialog

This commit is contained in:
Eloízio Salgado 2017-02-22 17:29:03 -03:00
parent bec8f21c0a
commit 2333276e96
5 changed files with 163 additions and 54 deletions

View File

@ -80,20 +80,21 @@ openRuleEntryDialog = function(attributes, level, rule) {
// Set the current value input based on the rule constraint // Set the current value input based on the rule constraint
var currentValue = rule.constraint[validator][validatorOption]; var currentValue = rule.constraint[validator][validatorOption];
currentValueInput.val(currentValue); currentValueInput.val(currentValue);
// If a Comparator was found, set the default value of the Comparators select2 box
// to the comparatorId in the input rule
if (comparator) {
// Trigger('change') is used to update the Select2 choice in the UI
dialog.find('.comparators').val(comparator.id).trigger('change');
}
} }
// If a Comparator was found, set the default value of the Comparators select2 box
// to the comparatorId in the input rule
if (comparator) {
// Trigger('change') is used to update the Select2 choice in the UI
dialog.find('.comparators').val(comparator.id).trigger('change');
}
// Update the dialog's CSS so that it is visible on the page // Update the dialog's CSS so that it is visible on the page
dialog.css('display', 'block'); dialog.css('display', 'block');
// Show the backdrop // Show the backdrop
UI.render(Template.removableBackdrop, document.body); Blaze.render(Template.removableBackdrop, document.body);
// Make sure the context menu is closed when the user clicks away // Make sure the context menu is closed when the user clicks away
$('.removableBackdrop').one('mousedown touchstart', function() { $('.removableBackdrop').one('mousedown touchstart', function() {
@ -105,31 +106,12 @@ openRuleEntryDialog = function(attributes, level, rule) {
* Retrieves the current active element's imageId using Cornerstone * Retrieves the current active element's imageId using Cornerstone
*/ */
function getActiveViewportImageId() { function getActiveViewportImageId() {
// Retrieve the active viewport index from the Session const enabledElement = Viewerbase.viewportUtils.getEnabledElementForActiveElement();
var activeViewport = Session.get('activeViewport');
if (activeViewport === undefined) { if (!enabledElement) {
return; return;
} }
// Obtain the list of all Viewports on the page
var viewports = $('.imageViewerViewport');
// Retrieve the active viewport element
var element = viewports.get(activeViewport);
if (!element) {
return;
}
// Obtain the enabled element from Cornerstone
try {
var enabledElement = cornerstone.getEnabledElement(element);
if (!enabledElement) {
return;
}
} catch(error) {
OHIF.log.warn(error);
return;
}
// Return the enabled element's imageId // Return the enabled element's imageId
return enabledElement.image.imageId; return enabledElement.image.imageId;
} }
@ -179,36 +161,50 @@ function getAbstractPriorValue(imageId) {
} }
/** /**
* Retrieve the current value of an attribute * Retrieve the current value of a metadata tag or property. It searches the value in different levels (study, series or instance)
* @returns {*} * @param {String} tagOrProperty DICOM Tag or Property name (Ex: 'x00100020', 'patientId')
* @return {Any} The value of the DICOM tag or property name
*/ */
function getCurrentAttributeValue(attribute, level) { const getCurrentTagOrPropertyValue = tagOrProperty => {
// Retrieve the active viewport's imageId. If none exists, stop here // Retrieve the active viewport's imageId. If none exists, stop here
var imageId = getActiveViewportImageId(); const imageId = getActiveViewportImageId();
if (!imageId) { if (!imageId) {
return; return;
} }
// If the dialog level is specified as 'protocol', change it to if (tagOrProperty === 'abstractPriorValue') {
// 'study' for metaData retrieval
if (level === 'protocol') {
level = 'study';
}
if (attribute === 'abstractPriorValue') {
return getAbstractPriorValue(imageId); return getAbstractPriorValue(imageId);
} }
// Retrieve the metadata values for the specified level from // Create the object for the instance metadata
// the Cornerstone Tools metaData provider let instance;
var metadata = cornerstoneTools.metaData.get(level, imageId);
if (metadata[attribute] === undefined) { OHIF.viewer.StudyMetadataList.find(studyMetadata => {
return HP.attributeDefaults[attribute]; // Search for the instance that has the current imageId
instance = studyMetadata.findInstance(instance => {
return instance.getImageId() === imageId;
});
// If instance if found stop the search
return !!instance;
});
// No instance found
if (!instance) {
return;
} }
return metadata[attribute]; // Get the value for the given tag
} // It searches the value in different levels (study, series or instance)
const tagOrPropertyValue = instance.getTagValue(tagOrProperty);
// If not found, is a custom Hanging Protocol attribute
if (tagOrPropertyValue === void 0) {
return HP.attributeDefaults[tagOrProperty];
}
return tagOrPropertyValue;
};
Template.ruleEntryDialog.onCreated(function() { Template.ruleEntryDialog.onCreated(function() {
// Define the ReactiveVars that will be used to link aspects of the UI // Define the ReactiveVars that will be used to link aspects of the UI
@ -362,11 +358,11 @@ Template.ruleEntryDialog.events({
// Store this attribute in the template data context // Store this attribute in the template data context
Template.ruleEntryDialog.selectedAttribute = attribute; Template.ruleEntryDialog.selectedAttribute = attribute;
// Get the level of this dialog // // Get the level of this dialog
var level = Template.ruleEntryDialog.level; // var level = Template.ruleEntryDialog.level;
// Retrieve the current value of the attribute for the active viewport model // Retrieve the current value of the attribute for the active viewport model
var value = getCurrentAttributeValue(attribute, level); var value = getCurrentTagOrPropertyValue(attribute);
// Update the ReactiveVar with the user-specified value // Update the ReactiveVar with the user-specified value
template.currentValue.set(value); template.currentValue.set(value);

View File

@ -14,7 +14,7 @@ export class OHIFStudyMetadata extends Viewerbase.metadata.StudyMetadata {
init() { init() {
const study = this.getData(); const study = this.getData();
// define "_studyInstanceUID" protected property... // define "_studyInstanceUID" protected property
Object.defineProperty(this, '_studyInstanceUID', { Object.defineProperty(this, '_studyInstanceUID', {
configurable: false, configurable: false,
enumerable: false, enumerable: false,
@ -22,7 +22,7 @@ export class OHIFStudyMetadata extends Viewerbase.metadata.StudyMetadata {
value: study.studyInstanceUid value: study.studyInstanceUid
}); });
// populate internal list of series... // populate internal list of series
study.seriesList.forEach(series => { study.seriesList.forEach(series => {
this.addSeries(new OHIFSeriesMetadata(series, study)); this.addSeries(new OHIFSeriesMetadata(series, study));
}); });

View File

@ -160,6 +160,22 @@ export class SeriesMetadata extends Metadata {
return this._instances.indexOf(instance); return this._instances.indexOf(instance);
} }
/**
* Search the associated instances using the supplied callback as criteria. The callback is passed
* two arguments: instance (a InstanceMetadata instance) and index (the integer
* index of the instance within its series)
* @param {function} callback The callback function which will be invoked for each instance.
* @returns {InstanceMetadata|undefined} If an instance is found based on callback criteria it
* returns a InstanceMetadata. "undefined" is returned otherwise
*/
findInstance(callback) {
if (Metadata.isValidCallback(callback)) {
return this._instances.find((instance, index) => {
return callback.call(null, instance, index);
});
}
}
/** /**
* Compares the current series with another one. * Compares the current series with another one.
* @param {SeriesMetadata} series An instance of the SeriesMetadata class. * @param {SeriesMetadata} series An instance of the SeriesMetadata class.

View File

@ -338,4 +338,65 @@ export class StudyMetadata extends Metadata {
return instance; return instance;
} }
/**
* Search the associated series to find an specific instance using the supplied callback as criteria.
* The callback is passed two arguments: instance (a InstanceMetadata instance) and index (the integer
* index of the instance within the current series)
* @param {function} callback The callback function which will be invoked for each instance instance.
* @returns {Object} Result object containing series (SeriesMetadata) and instance (InstanceMetadata)
* objects or an empty object if not found.
*/
findSeriesAndInstanceByInstance(callback) {
let result;
if (Metadata.isValidCallback(callback)) {
let instance;
const series = this._series.find(series => {
instance = series.findInstance(callback);
return instance instanceof InstanceMetadata;
});
// No series found
if (series instanceof SeriesMetadata) {
result = {
series,
instance
};
}
}
return result || {};
}
/**
* Find series by instance using the supplied callback as criteria. The callback is passed
* two arguments: instance (a InstanceMetadata instance) and index (the integer index of
* the instance within its series)
* @param {function} callback The callback function which will be invoked for each instance.
* @returns {SeriesMetadata|undefined} If a series is found based on callback criteria it
* returns a SeriesMetadata. "undefined" is returned otherwise
*/
findSeriesByInstance(callback) {
const result = this.findSeriesAndInstanceByInstance(callback);
return result.series;
}
/**
* Find an instance using the supplied callback as criteria. The callback is passed
* two arguments: instance (a InstanceMetadata instance) and index (the integer index of
* the instance within its series)
* @param {function} callback The callback function which will be invoked for each instance.
* @returns {InstanceMetadata|undefined} If an instance is found based on callback criteria it
* returns a InstanceMetadata. "undefined" is returned otherwise
*/
findInstance(callback) {
const result = this.findSeriesAndInstanceByInstance(callback);
return result.instance;
}
} }

View File

@ -7,11 +7,46 @@ import { OHIF } from 'meteor/ohif:core';
import { updateOrientationMarkers } from './updateOrientationMarkers'; import { updateOrientationMarkers } from './updateOrientationMarkers';
import { getInstanceClassDefaultViewport } from './instanceClassSpecificViewport'; import { getInstanceClassDefaultViewport } from './instanceClassSpecificViewport';
/**
* Get a cornerstone enabledElement for a DOM Element
* @param {DOMElement} element Element to get the enabledElement from Cornerstone
* @return {Object} Cornerstone's enabledElement object for the given
* element or undefined if the element is not enabled
*/
const getEnabledElement = element => {
let enabledElement;
try {
enabledElement = cornerstone.getEnabledElement(element);
} catch(error) {
OHIF.log.warn(error);
}
return enabledElement;
};
/**
* Get the active viewport element. It uses activeViewport Session Variable
* @return {DOMElement} DOMElement of the current active viewport
*/
const getActiveViewportElement = () => { const getActiveViewportElement = () => {
const viewportIndex = Session.get('activeViewport') || 0; const viewportIndex = Session.get('activeViewport') || 0;
return $('.imageViewerViewport').get(viewportIndex); return $('.imageViewerViewport').get(viewportIndex);
}; };
/**
* Get a cornerstone enabledElement for the Active Viewport Element
* @return {Object} Cornerstone's enabledElement object for the active
* viewport element or undefined if the element
* is not enabled
*/
const getEnabledElementForActiveElement = () => {
const activeViewportElement = getActiveViewportElement();
const enabledElement = getEnabledElement(activeViewportElement);
return enabledElement;
};
const zoomIn = () => { const zoomIn = () => {
const element = getActiveViewportElement(); const element = getActiveViewportElement();
if (!element) { if (!element) {
@ -99,8 +134,7 @@ const flipH = () => {
}; };
const resetViewport = () => { const resetViewport = () => {
const element = getActiveViewportElement(); const enabledElement = getEnabledElementForActiveElement();
const enabledElement = cornerstone.getEnabledElement(element);
if (enabledElement.fitToWindow === false) { if (enabledElement.fitToWindow === false) {
const imageId = enabledElement.image.imageId; const imageId = enabledElement.image.imageId;
const instance = cornerstoneTools.metaData.get('instance', imageId); const instance = cornerstoneTools.metaData.get('instance', imageId);
@ -272,6 +306,8 @@ $(window).on('CornerstoneToolsClipStopped', () => Session.set('UpdateCINE', Rand
*/ */
const viewportUtils = { const viewportUtils = {
getEnabledElementForActiveElement,
getEnabledElement,
getActiveViewportElement, getActiveViewportElement,
zoomIn, zoomIn,
zoomOut, zoomOut,