Improving overlay information display

This commit is contained in:
Bruno Alves de Faria 2018-01-30 16:46:31 -02:00
parent c8348cc084
commit 45c5766501
5 changed files with 76 additions and 5 deletions

View File

@ -2,9 +2,9 @@
<div class="imageViewerViewportOverlay noselect {{#if gt numImages 1}}controlsVisible{{/if}}">
{{#unless tagDisplaySpecified}}
<div class="topleft dicomTag">
<div>{{formatPN patientName}}</div>
<div>{{patientId}}</div>
<div class='timepointName'>{{timepointName}}</div>
<div>{{patientName}}</div>
<div>{{getGenderAndAge}}</div>
<div class="icons-section">
{{#if linked}}
<svg>
@ -15,8 +15,11 @@
</div>
</div>
<div class="topright dicomTag">
<div>{{studyDescription}}</div>
<div>{{formatDA studyDate}} {{formatTM studyTime}}</div>
<div>{{seriesDescription}}</div>
<div>{{studyInfo 'AccessionNumber'}}</div>
<div>{{formatDA (studyInfo 'AcquisitionDate')}} {{formatTM (studyInfo 'AcquisitionTime')}}</div>
<div>{{#if seriesNumber}}S: {{seriesNumber}}{{#if gt numImages 1}},{{/if}}{{/if}} {{#if gt numImages 1}}I: {{instanceNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
<div class='timepointName'>{{timepointName}}</div>
</div>
<div class="bottomright dicomTag">
<div>{{#if zoom}}Zoom: {{formatNumberPrecision zoom 0}}%{{/if}}</div>

View File

@ -1,5 +1,7 @@
import { Template } from 'meteor/templating';
import { Session } from 'meteor/session';
import { Tracker } from 'meteor/tracker';
import { ReactiveVar } from 'meteor/reactive-var';
import { OHIF } from 'meteor/ohif:core';
// Use Aldeed's meteor-template-extension package to replace the
@ -8,9 +10,47 @@ import { OHIF } from 'meteor/ohif:core';
const defaultTemplate = 'viewportOverlay';
Template.longitudinalViewportOverlay.replaces(defaultTemplate);
Template[defaultTemplate].onCreated(() => {
const instance = Template.instance();
instance.instanceMetadata = new ReactiveVar();
const { DICOMTagDescriptions } = OHIF.viewerbase;
instance.getValueByTagKeyword = tagKeyword => {
const instanceMetadata = instance.instanceMetadata.get();
const tagObject = DICOMTagDescriptions.find(tagKeyword);
if (!instanceMetadata || !tagObject) return;
return instanceMetadata.getRawValue(tagObject.tag);
};
// Run this computation every time the image is changed
Tracker.autorun(() => {
Session.get('CornerstoneNewImage' + instance.data.viewportIndex);
const { studyInstanceUid, seriesInstanceUid, currentImageIdIndex } = instance.data;
OHIF.studies.loadStudy(studyInstanceUid).then(studyMetadata => {
const seriesMetadata = studyMetadata.getSeriesByUID(seriesInstanceUid);
const instanceMetadata = seriesMetadata.getInstanceByIndex(currentImageIdIndex);
instance.instanceMetadata.set(instanceMetadata);
});
});
});
// Add the TimepointName helper to the default template. The
// HTML of this template is replaced with that of longitudinalViewportOverlay
Template[defaultTemplate].helpers({
studyInfo(tagKeyword) {
const instance = Template.instance();
instance.instanceMetadata.dep.depend();
return instance.getValueByTagKeyword(tagKeyword);
},
getGenderAndAge() {
const instance = Template.instance();
const values = [];
values.push(instance.getValueByTagKeyword('PatientSex'));
values.push(instance.getValueByTagKeyword('PatientAge'));
return values.filter(value => !!value).join(', ');
},
timepointName() {
const instance = Template.instance();
const studyInstanceUid = instance.data.studyInstanceUid;

View File

@ -1,6 +1,8 @@
import { Template } from 'meteor/templating';
import { Session } from 'meteor/session';
import { _ } from 'meteor/underscore';
import { OHIF } from 'meteor/ohif:core';
import { cornerstone } from 'meteor/ohif:cornerstone';
import { viewportOverlayUtils } from '../../../lib/viewportOverlayUtils';
import { getElementIfNotEmpty } from '../../../lib/getElementIfNotEmpty';
import { getStackDataIfNotEmpty } from '../../../lib/getStackDataIfNotEmpty';
@ -21,6 +23,7 @@ Template.viewportOverlay.helpers({
return 'W ' + viewport.voi.windowWidth.toFixed(0) + ' L ' + viewport.voi.windowCenter.toFixed(0);
},
zoom() {
Session.get('CornerstoneImageRendered' + this.viewportIndex);
@ -36,6 +39,7 @@ Template.viewportOverlay.helpers({
return (viewport.scale * 100.0);
},
imageDimensions() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
@ -46,46 +50,55 @@ Template.viewportOverlay.helpers({
return image.width + ' x ' + image.height;
},
patientName() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getPatient.call(this, 'name');
},
patientId() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getPatient.call(this, 'id');
},
patientBirthDate() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getPatient.call(this, 'birthDate');
},
patientSex() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getPatient.call(this, 'sex');
},
studyDate() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getStudy.call(this, 'studyDate');
},
studyTime() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getStudy.call(this, 'studyTime');
},
studyDescription() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getStudy.call(this, 'studyDescription');
},
seriesDescription() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getSeries.call(this, 'seriesDescription');
},
frameRate() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
@ -97,16 +110,19 @@ Template.viewportOverlay.helpers({
const frameRate = 1000 / frameTime;
return frameRate.toFixed(1);
},
seriesNumber() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getSeries.call(this, 'seriesNumber');
},
instanceNumber() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getInstance.call(this, 'instanceNumber');
},
thickness() {
// Displays Slice Thickness (0018,0050)
@ -114,6 +130,7 @@ Template.viewportOverlay.helpers({
return viewportOverlayUtils.getInstance.call(this, 'sliceThickness');
},
location() {
// Displays Slice Location (0020,1041), if present.
// - Otherwise, displays Table Position (0018,9327)
@ -132,6 +149,7 @@ Template.viewportOverlay.helpers({
return viewportOverlayUtils.getInstance.call(this, 'imagePositionPatient');
},
spacingBetweenSlices() {
// Displays Spacing Between Slices (0018,0088), if present.
@ -143,6 +161,7 @@ Template.viewportOverlay.helpers({
return viewportOverlayUtils.getInstance.call(this, 'spacingBetweenSlices');
},
compression() {
// Displays whether or not lossy compression has been applied:
//
@ -170,26 +189,31 @@ Template.viewportOverlay.helpers({
return 'Lossless / Uncompressed';
},
tagDisplayLeftOnly() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getTagDisplay.call(this, 'side') === 'L';
},
tagDisplayRightOnly() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getTagDisplay.call(this, 'side') === 'R';
},
tagDisplaySpecified() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getTagDisplay.call(this, 'side');
},
imageNumber() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
return viewportOverlayUtils.getInstance.call(this, 'number');
},
imageIndex() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
@ -200,6 +224,7 @@ Template.viewportOverlay.helpers({
return stack.currentImageIdIndex + 1;
},
numImages() {
Session.get('CornerstoneNewImage' + this.viewportIndex);
@ -210,6 +235,7 @@ Template.viewportOverlay.helpers({
return stack.imageIds.length;
},
prior() {
// This helper is updated whenever a new image is displayed in the viewport
Session.get('CornerstoneNewImage' + this.viewportIndex);

View File

@ -6,6 +6,7 @@ const formatPN = context => {
if (!context) {
return;
}
return context.replace('^', ', ');
};

View File

@ -1,3 +1,4 @@
import { cornerstone } from 'meteor/ohif:cornerstone';
import { getElementIfNotEmpty } from './getElementIfNotEmpty';
const getPatient = function(property) {
@ -22,7 +23,7 @@ const getStudy = function(property) {
if (!study) {
return '';
}
return study[property];
};