ohif-viewer/LesionTracker/client/components/viewer/viewer.js

196 lines
6.8 KiB
JavaScript

import { Template } from 'meteor/templating';
import { Session } from 'meteor/session';
import { OHIF } from 'meteor/ohif:core';
Session.set('ViewerMainReady', false);
Session.set('TimepointsReady', false);
Session.set('MeasurementsReady', false);
Template.viewer.onCreated(() => {
ViewerData = window.ViewerData || ViewerData;
const instance = Template.instance();
ValidationErrors.remove({});
instance.data.state = new ReactiveDict();
instance.data.state.set('leftSidebar', Session.get('leftSidebar'));
instance.data.state.set('rightSidebar', Session.get('rightSidebar'));
const contentId = instance.data.contentId;
OHIF.viewer.functionList = $.extend(OHIF.viewer.functionList, {
toggleLesionTrackerTools: OHIF.lesiontracker.toggleLesionTrackerTools,
bidirectional: () => {
// Used for hotkeys
toolManager.setActiveTool('bidirectional');
},
nonTarget: () => {
// Used for hotkeys
toolManager.setActiveTool('nonTarget');
},
// Viewport functions
toggleCineDialog,
clearTools,
resetViewport,
invert,
flipV,
flipH,
rotateL,
rotateR
});
if (ViewerData[contentId].loadedSeriesData) {
OHIF.log.info('Reloading previous loadedSeriesData');
OHIF.viewer.loadedSeriesData = ViewerData[contentId].loadedSeriesData;
} else {
OHIF.log.info('Setting default ViewerData');
OHIF.viewer.loadedSeriesData = {};
ViewerData[contentId].loadedSeriesData = {};
Session.set('ViewerData', ViewerData);
}
Session.set('activeViewport', ViewerData[contentId].activeViewport || false);
// Set lesion tool buttons as disabled if pixel spacing is not available for active element
instance.autorun(OHIF.lesiontracker.pixelSpacingAutorunCheck);
// Update the ViewerStudies collection with the loaded studies
ViewerStudies.remove({});
instance.data.studies.forEach(study => {
study.selected = true;
study.displaySets = createStacks(study);
ViewerStudies.insert(study);
});
instance.data.timepointApi = new OHIF.measurements.TimepointApi(instance.data.currentTimepointId);
// TODO: Find a better way to pass this to the ViewportOverlay
OHIF.viewer.timepointApi = instance.data.timepointApi;
const patientId = instance.data.studies[0].patientId;
const filter = {
patientId
};
const timepointsPromise = instance.data.timepointApi.retrieveTimepoints(filter);
timepointsPromise.then(() => {
const timepoints = instance.data.timepointApi.all();
// Set timepointType in studies to be used in hanging protocol engine
timepoints.forEach(function(timepoint) {
timepoint.studyInstanceUids.forEach(function(studyInstanceUid) {
const study = _.find(instance.data.studies, function (element) {
return element.studyInstanceUid === studyInstanceUid;
});
if (!study) {
return;
}
study.timepointType = timepoint.timepointType;
});
});
Session.set('TimepointsReady', true);
});
instance.data.measurementApi = new OHIF.measurements.MeasurementApi(instance.data.currentTimepointId);
const measurementsPromise = instance.data.measurementApi.retrieveMeasurements(filter);
measurementsPromise.then(() => {
Session.set('MeasurementsReady', true);
instance.data.measurementApi.syncMeasurementsAndToolData();
});
// Provide the necessary data to the Measurement API and Timepoint API
const prior = instance.data.timepointApi.prior();
if (prior) {
instance.data.measurementApi.priorTimepointId = prior.timepointId;
}
if (instance.data.currentTimepointId) {
// Enable Lesion Tracker Tools if the opened study is associated
OHIF.lesiontracker.toggleLesionTrackerToolsButtons(true);
} else {
// Disable Lesion Tracker Tools if the opened study is not associated
OHIF.lesiontracker.toggleLesionTrackerToolsButtons(false);
}
instance.autorun(() => {
if (!Session.get('TimepointsReady') ||
!Session.get('MeasurementsReady') ||
!Session.get('ViewerMainReady')) {
return;
}
// Find and activate the first measurement by Lesion Number
// NOTE: This is inefficient, we should be using a hanging protocol
// to hang the first measurement's imageId immediately, rather
// than changing images after initial loading...
const config = OHIF.measurements.MeasurementApi.getConfiguration();
const measurementTypeId = config.measurementTools[0].id;
const measurementApi = instance.data.measurementApi;
const timepointApi = instance.data.timepointApi;
const collection = measurementApi[measurementTypeId];
const sorting = {
sort: {
measurementNumber: -1
}
};
const data = collection.find({}, sorting).fetch();
let timepoints = [timepointApi.current()];
const prior = timepointApi.prior();
if (prior) {
timepoints.push(prior);
}
// TODO: Clean this up, it's probably an inefficient way to get what we need
const groupObject = _.groupBy(data, m => m.measurementNumber);
// Reformat the data
const rows = Object.keys(groupObject).map(key => ({
measurementTypeId: measurementTypeId,
measurementNumber: key,
entries: groupObject[key]
}));
const rowItem = rows[0];
// Activate the first lesion
if (rowItem) {
OHIF.measurements.jumpToRowItem(rowItem, timepoints);
}
})
});
Template.viewer.helpers({
dataSourcesReady() {
// TODO: Find a better way to do this
const ready = Session.get('TimepointsReady') && Session.get('MeasurementsReady');
console.log('dataSourcesReady? : ' + ready);
return ready;
}
});
Template.viewer.events({
'CornerstoneToolsMeasurementAdded .imageViewerViewport'(event, instance, eventData) {
OHIF.measurements.MeasurementHandlers.onAdded(event, instance, eventData);
},
'CornerstoneToolsMeasurementModified .imageViewerViewport'(event, instance, eventData) {
OHIF.measurements.MeasurementHandlers.onModified(event, instance, eventData);
},
'CornerstoneToolsMeasurementRemoved .imageViewerViewport'(event, instance, eventData) {
OHIF.measurements.MeasurementHandlers.onRemoved(event, instance, eventData);
}
});
Template.viewer.onDestroyed(() => {
Session.set('ViewerMainReady', false);
Session.set('TimepointsReady', false);
Session.set('MeasurementsReady', false);
});