From 88164d082df9ead4ce6b48eb8830f7a29ea05778 Mon Sep 17 00:00:00 2001 From: Bruno Alves de Faria Date: Tue, 12 Dec 2017 11:08:20 -0200 Subject: [PATCH] Refactoring MeasurementHandlers to improve maintainability --- .../client/lib/MeasurementHandlers.js | 383 ------------------ .../MeasurementHandlers.js | 78 ++++ .../MeasurementHandlers/getImageAttributes.js | 32 ++ .../handleChildMeasurementAdded.js | 94 +++++ .../handleChildMeasurementModified.js | 40 ++ .../handleChildMeasurementRemoved.js | 40 ++ .../handleSingleMeasurementAdded.js | 53 +++ .../handleSingleMeasurementModified.js | 42 ++ .../handleSingleMeasurementRemoved.js | 37 ++ .../client/lib/MeasurementHandlers/index.js | 1 + 10 files changed, 417 insertions(+), 383 deletions(-) delete mode 100644 Packages/ohif-measurements/client/lib/MeasurementHandlers.js create mode 100644 Packages/ohif-measurements/client/lib/MeasurementHandlers/MeasurementHandlers.js create mode 100644 Packages/ohif-measurements/client/lib/MeasurementHandlers/getImageAttributes.js create mode 100644 Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementAdded.js create mode 100644 Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementModified.js create mode 100644 Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementRemoved.js create mode 100644 Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementAdded.js create mode 100644 Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementModified.js create mode 100644 Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js create mode 100644 Packages/ohif-measurements/client/lib/MeasurementHandlers/index.js diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers.js deleted file mode 100644 index 4354d4c55..000000000 --- a/Packages/ohif-measurements/client/lib/MeasurementHandlers.js +++ /dev/null @@ -1,383 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { $ } from 'meteor/jquery'; -import { _ } from 'meteor/underscore'; -import { cornerstone } from 'meteor/ohif:cornerstone'; -import { OHIF } from 'meteor/ohif:core'; - -const getImageAttributes = element => { - // Get the Cornerstone imageId - const enabledElement = cornerstone.getEnabledElement(element); - const imageId = enabledElement.image.imageId; - - // Get studyInstanceUid & patientId - const study = cornerstone.metaData.get('study', imageId); - const studyInstanceUid = study.studyInstanceUid; - const patientId = study.patientId; - - // Get seriesInstanceUid - const series = cornerstone.metaData.get('series', imageId); - const seriesInstanceUid = series.seriesInstanceUid; - - // Get sopInstanceUid - const sopInstance = cornerstone.metaData.get('instance', imageId); - const sopInstanceUid = sopInstance.sopInstanceUid; - const frameIndex = sopInstance.frame || 0; - - const imagePath = [studyInstanceUid, seriesInstanceUid, sopInstanceUid, frameIndex].join('_'); - - return { - patientId, - studyInstanceUid, - seriesInstanceUid, - sopInstanceUid, - frameIndex, - imagePath - }; -}; - -class MeasurementHandlers { - - static handleSingleMeasurementAdded({ instance, eventData, tool }) { - const { measurementApi } = instance.data; - const { measurementData, toolType } = eventData; - - const Collection = measurementApi.tools[toolType]; - - // Stop here if the tool data shall not be persisted (e.g. temp tools) - if (!Collection) return; - - // Stop here if there's no measurement data or if it was cancelled - if (!measurementData || measurementData.cancelled) return; - - OHIF.log.info('CornerstoneToolsMeasurementAdded'); - - const imageAttributes = getImageAttributes(eventData.element); - const measurement = _.extend({}, measurementData, imageAttributes, { - measurementNumber: measurementData.measurementNumber, - userId: Meteor.userId() - }); - - // Get the related timepoint by the measurement number and use its location if defined - const relatedTimepoint = Collection.findOne({ - measurementNumber: measurement.measurementNumber, - toolType: measurementData.toolType, - patientId: imageAttributes.patientId, - }); - - // Use the related timepoint location if found and defined - if (relatedTimepoint && relatedTimepoint.location) { - measurement.location = relatedTimepoint.location; - } - - // Clean the measurement according to the Schema - Collection._c2._simpleSchema.clean(measurement); - - // Insert the new measurement into the collection - measurementData._id = Collection.insert(measurement); - - // Get the updated measurement number after inserting - Meteor.defer(() => { - measurementData.measurementNumber = Collection.findOne(measurementData._id).measurementNumber; - cornerstone.updateImage(OHIF.viewerbase.viewportUtils.getActiveViewportElement()); - }); - - // Signal unsaved changes - OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); - } - - static handleChildMeasurementAdded({ instance, eventData, tool, toolGroupId, toolGroup }) { - const { measurementApi } = instance.data; - const { measurementData } = eventData; - - const Collection = measurementApi.tools[tool.parentTool]; - - // Stop here if the tool data shall not be persisted (e.g. temp tools) - if (!Collection) return; - - // Stop here if there's no measurement data or if it was cancelled - if (!measurementData || measurementData.cancelled) return; - - OHIF.log.info('CornerstoneToolsMeasurementAdded'); - - const imageAttributes = getImageAttributes(eventData.element); - const measurement = { - toolType: tool.parentTool, - measurementNumber: measurementData.measurementNumber, - userId: Meteor.userId(), - patientId: imageAttributes.patientId, - studyInstanceUid: imageAttributes.studyInstanceUid - }; - - const additionalProperties = _.extend(imageAttributes, { - userId: Meteor.userId() - }); - - const childMeasurement = _.extend({}, measurementData, additionalProperties); - - const parentMeasurement = Collection.findOne({ - toolType: tool.parentTool, - patientId: imageAttributes.patientId, - [tool.attribute]: null - }); - - // Check if a measurement to fit this child tool already exists - if (parentMeasurement) { - const key = tool.attribute; - - // Add the createdAt attribute - childMeasurement.createdAt = new Date(); - - // Add the child measurement - measurement[key] = childMeasurement; - - // Clean the measurement according to the Schema - Collection._c2._simpleSchema.clean(measurement); - - // Update the measurement in the collection - Collection.update(parentMeasurement._id, { - $set: { [key]: measurement[key] }, - $inc: { childToolsCount: 1 } - }); - - // Update the measurementData ID and measurementNumber - measurementData._id = parentMeasurement._id; - measurementData.measurementNumber = parentMeasurement.measurementNumber; - } else { - measurement[tool.attribute] = _.extend({}, measurementData, additionalProperties); - - // Get the related timepoint by the measurement number and use its location if defined - const relatedTimepoint = Collection.findOne({ - measurementNumber: measurement.measurementNumber, - toolType: tool.parentTool, - patientId: imageAttributes.patientId - }); - - // Use the related timepoint location if found and defined - if (relatedTimepoint && relatedTimepoint.location) { - measurement.location = relatedTimepoint.location; - } - - // Clean the measurement according to the Schema - Collection._c2._simpleSchema.clean(measurement); - - // Insert the new measurement into the collection - measurementData._id = Collection.insert(measurement); - - // Get the updated measurement number after inserting - Meteor.defer(() => { - measurementData.measurementNumber = Collection.findOne(measurementData._id).measurementNumber; - cornerstone.updateImage(OHIF.viewerbase.viewportUtils.getActiveViewportElement()); - }); - } - - // Signal unsaved changes - OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); - } - - static onAdded(event, instance, eventData) { - const { toolType } = eventData; - const { toolGroupId, toolGroup, tool } = OHIF.measurements.getToolConfiguration(toolType); - const params = { - instance, - eventData, - tool, - toolGroupId, - toolGroup - }; - - if (!tool) return; - - if (tool.parentTool) { - MeasurementHandlers.handleChildMeasurementAdded(params); - } else { - MeasurementHandlers.handleSingleMeasurementAdded(params); - } - } - - static handleSingleMeasurementModified({ instance, eventData, tool, toolGroupId, toolGroup }) { - const { measurementApi } = instance.data; - const { measurementData, toolType } = eventData; - - const Collection = measurementApi.tools[toolType]; - - // Stop here if the tool data shall not be persisted (e.g. temp tools) - if (!Collection) return; - - OHIF.log.info('CornerstoneToolsMeasurementModified'); - - const measurement = Collection.findOne(measurementData._id); - - // Stop here if the measurement is already deleted - if (!measurement) return; - - // Update the collection data with the cornerstone measurement data - const ignoredKeys = ['location', 'description', 'response']; - Object.keys(measurementData).forEach(key => { - if (_.contains(ignoredKeys, key)) return; - measurement[key] = measurementData[key]; - }); - - const measurementId = measurement._id; - delete measurement._id; - - // If the measurement configuration includes a value for Viewport, - // we will populate this with the Cornerstone Viewport - if (Collection._c2._simpleSchema.schema('viewport')) { - measurement.viewport = cornerstone.getViewport(eventData.element); - } - - // Update the measurement in the collection - Collection.update(measurementId, { $set: measurement }); - - // Signal unsaved changes - OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); - } - - static handleChildMeasurementModified({ instance, eventData, tool, toolGroupId, toolGroup }) { - const { measurementApi } = instance.data; - const { measurementData } = eventData; - - const Collection = measurementApi.tools[tool.parentTool]; - - // Stop here if the tool data shall not be persisted (e.g. temp tools) - if (!Collection) return; - - OHIF.log.info('CornerstoneToolsMeasurementModified'); - - const measurement = Collection.findOne(measurementData._id); - const childMeasurement = measurement && measurement[tool.attribute]; - - // Stop here if the measurement is already deleted - if (!childMeasurement) return; - - // Update the collection data with the cornerstone measurement data - const ignoredKeys = ['location', 'description', 'response']; - Object.keys(measurementData).forEach(key => { - if (_.contains(ignoredKeys, key)) return; - childMeasurement[key] = measurementData[key]; - }); - - // If the measurement configuration includes a value for Viewport, - // we will populate this with the Cornerstone Viewport - if (Collection._c2._simpleSchema.schema(`${tool.attribute}.viewport`)) { - childMeasurement.viewport = cornerstone.getViewport(eventData.element); - } - - // Update the measurement in the collection - Collection.update(measurement._id, { $set: { [tool.attribute]: childMeasurement } }); - - // Signal unsaved changes - OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); - } - - static onModified(event, instance, eventData) { - const { toolType } = eventData; - const { toolGroupId, toolGroup, tool } = OHIF.measurements.getToolConfiguration(toolType); - const params = { - instance, - eventData, - tool, - toolGroupId, - toolGroup - }; - - if (!tool) return; - - if (tool.parentTool) { - MeasurementHandlers.handleChildMeasurementModified(params); - } else { - MeasurementHandlers.handleSingleMeasurementModified(params); - } - } - - static handleSingleMeasurementRemoved({ instance, eventData, tool, toolGroupId, toolGroup }) { - OHIF.log.info('CornerstoneToolsMeasurementRemoved'); - const measurementData = eventData.measurementData; - const { measurementApi, timepointApi } = instance.data; - const Collection = measurementApi.tools[eventData.toolType]; - - // Stop here if the tool data shall not be persisted (e.g. temp tools) - if (!Collection) return; - - const measurementTypeId = measurementApi.toolsGroupsMap[measurementData.toolType]; - const measurement = Collection.findOne(measurementData._id); - - // Stop here if the measurement is already gone or never existed - if (!measurement) return; - - // Remove all the measurements with the given type and number - const { measurementNumber, timepointId } = measurement; - measurementApi.deleteMeasurements(measurementTypeId, { - measurementNumber, - timepointId - }); - - // Sync the new measurement data with cornerstone tools - const baseline = timepointApi.baseline(); - measurementApi.sortMeasurements(baseline.timepointId); - - // Repaint the images on all viewports without the removed measurements - _.each($('.imageViewerViewport'), element => cornerstone.updateImage(element)); - - // Signal unsaved changes - OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); - } - - static handleChildMeasurementRemoved({ instance, eventData, tool, toolGroupId, toolGroup }) { - OHIF.log.info('CornerstoneToolsMeasurementRemoved'); - const measurementData = eventData.measurementData; - const { measurementApi, timepointApi } = instance.data; - const Collection = measurementApi.tools[tool.parentTool]; - - // Stop here if the tool data shall not be persisted (e.g. temp tools) - if (!Collection) return; - - const measurement = Collection.findOne(measurementData._id); - - // Stop here if the measurement is already gone or never existed - if (!measurement) return; - - if (measurement.childToolsCount === 1) { - // Remove the measurement - Collection.remove(measurement._id); - - // Sync the new measurement data with cornerstone tools - const baseline = timepointApi.baseline(); - measurementApi.sortMeasurements(baseline.timepointId); - } else { - // Update the measurement in the collection - Collection.update(measurement._id, { - $set: { [tool.attribute]: null }, - $inc: { childToolsCount: -1 } - }); - } - - // Repaint the images on all viewports without the removed measurements - _.each($('.imageViewerViewport'), element => cornerstone.updateImage(element)); - - // Signal unsaved changes - OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); - } - - static onRemoved(e, instance, eventData) { - const { toolType } = eventData; - const { toolGroupId, toolGroup, tool } = OHIF.measurements.getToolConfiguration(toolType); - const params = { - instance, - eventData, - tool, - toolGroupId, - toolGroup - }; - - if (!tool) return; - - if (tool.parentTool) { - MeasurementHandlers.handleChildMeasurementRemoved(params); - } else { - MeasurementHandlers.handleSingleMeasurementRemoved(params); - } - } -} - -OHIF.measurements.MeasurementHandlers = MeasurementHandlers; diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/MeasurementHandlers.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/MeasurementHandlers.js new file mode 100644 index 000000000..8e89c6083 --- /dev/null +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/MeasurementHandlers.js @@ -0,0 +1,78 @@ +import { OHIF } from 'meteor/ohif:core'; +import handleSingleMeasurementAdded from './handleSingleMeasurementAdded'; +import handleChildMeasurementAdded from './handleChildMeasurementAdded'; +import handleSingleMeasurementModified from './handleSingleMeasurementModified'; +import handleChildMeasurementModified from './handleChildMeasurementModified'; +import handleSingleMeasurementRemoved from './handleSingleMeasurementRemoved'; +import handleChildMeasurementRemoved from './handleChildMeasurementRemoved'; + +const MeasurementHandlers = { + handleSingleMeasurementAdded, + handleChildMeasurementAdded, + handleSingleMeasurementModified, + handleChildMeasurementModified, + handleSingleMeasurementRemoved, + handleChildMeasurementRemoved, + + onAdded(event, instance, eventData) { + const { toolType } = eventData; + const { toolGroupId, toolGroup, tool } = OHIF.measurements.getToolConfiguration(toolType); + const params = { + instance, + eventData, + tool, + toolGroupId, + toolGroup + }; + + if (!tool) return; + + if (tool.parentTool) { + this.handleChildMeasurementAdded(params); + } else { + this.handleSingleMeasurementAdded(params); + } + }, + + onModified(event, instance, eventData) { + const { toolType } = eventData; + const { toolGroupId, toolGroup, tool } = OHIF.measurements.getToolConfiguration(toolType); + const params = { + instance, + eventData, + tool, + toolGroupId, + toolGroup + }; + + if (!tool) return; + + if (tool.parentTool) { + this.handleChildMeasurementModified(params); + } else { + this.handleSingleMeasurementModified(params); + } + }, + + onRemoved(e, instance, eventData) { + const { toolType } = eventData; + const { toolGroupId, toolGroup, tool } = OHIF.measurements.getToolConfiguration(toolType); + const params = { + instance, + eventData, + tool, + toolGroupId, + toolGroup + }; + + if (!tool) return; + + if (tool.parentTool) { + MeasurementHandlers.handleChildMeasurementRemoved(params); + } else { + MeasurementHandlers.handleSingleMeasurementRemoved(params); + } + } +}; + +OHIF.measurements.MeasurementHandlers = MeasurementHandlers; diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/getImageAttributes.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/getImageAttributes.js new file mode 100644 index 000000000..42a0e2fa1 --- /dev/null +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/getImageAttributes.js @@ -0,0 +1,32 @@ +import { cornerstone } from 'meteor/ohif:cornerstone'; + +export default function (element) { + // Get the Cornerstone imageId + const enabledElement = cornerstone.getEnabledElement(element); + const imageId = enabledElement.image.imageId; + + // Get studyInstanceUid & patientId + const study = cornerstone.metaData.get('study', imageId); + const studyInstanceUid = study.studyInstanceUid; + const patientId = study.patientId; + + // Get seriesInstanceUid + const series = cornerstone.metaData.get('series', imageId); + const seriesInstanceUid = series.seriesInstanceUid; + + // Get sopInstanceUid + const sopInstance = cornerstone.metaData.get('instance', imageId); + const sopInstanceUid = sopInstance.sopInstanceUid; + const frameIndex = sopInstance.frame || 0; + + const imagePath = [studyInstanceUid, seriesInstanceUid, sopInstanceUid, frameIndex].join('_'); + + return { + patientId, + studyInstanceUid, + seriesInstanceUid, + sopInstanceUid, + frameIndex, + imagePath + }; +} diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementAdded.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementAdded.js new file mode 100644 index 000000000..de0d86d98 --- /dev/null +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementAdded.js @@ -0,0 +1,94 @@ +import { Meteor } from 'meteor/meteor'; +import { _ } from 'meteor/underscore'; +import { OHIF } from 'meteor/ohif:core'; +import { cornerstone } from 'meteor/ohif:cornerstone'; +import getImageAttributes from './getImageAttributes'; + +export default function ({ instance, eventData, tool, toolGroupId, toolGroup }) { + const { measurementApi } = instance.data; + const { measurementData } = eventData; + + const Collection = measurementApi.tools[tool.parentTool]; + + // Stop here if the tool data shall not be persisted (e.g. temp tools) + if (!Collection) return; + + // Stop here if there's no measurement data or if it was cancelled + if (!measurementData || measurementData.cancelled) return; + + OHIF.log.info('CornerstoneToolsMeasurementAdded'); + + const imageAttributes = getImageAttributes(eventData.element); + const measurement = { + toolType: tool.parentTool, + measurementNumber: measurementData.measurementNumber, + userId: Meteor.userId(), + patientId: imageAttributes.patientId, + studyInstanceUid: imageAttributes.studyInstanceUid + }; + + const additionalProperties = _.extend(imageAttributes, { + userId: Meteor.userId() + }); + + const childMeasurement = _.extend({}, measurementData, additionalProperties); + + const parentMeasurement = Collection.findOne({ + toolType: tool.parentTool, + patientId: imageAttributes.patientId, + [tool.attribute]: null + }); + + // Check if a measurement to fit this child tool already exists + if (parentMeasurement) { + const key = tool.attribute; + + // Add the createdAt attribute + childMeasurement.createdAt = new Date(); + + // Add the child measurement + measurement[key] = childMeasurement; + + // Clean the measurement according to the Schema + Collection._c2._simpleSchema.clean(measurement); + + // Update the measurement in the collection + Collection.update(parentMeasurement._id, { + $set: { [key]: measurement[key] }, + $inc: { childToolsCount: 1 } + }); + + // Update the measurementData ID and measurementNumber + measurementData._id = parentMeasurement._id; + measurementData.measurementNumber = parentMeasurement.measurementNumber; + } else { + measurement[tool.attribute] = _.extend({}, measurementData, additionalProperties); + + // Get the related timepoint by the measurement number and use its location if defined + const relatedTimepoint = Collection.findOne({ + measurementNumber: measurement.measurementNumber, + toolType: tool.parentTool, + patientId: imageAttributes.patientId + }); + + // Use the related timepoint location if found and defined + if (relatedTimepoint && relatedTimepoint.location) { + measurement.location = relatedTimepoint.location; + } + + // Clean the measurement according to the Schema + Collection._c2._simpleSchema.clean(measurement); + + // Insert the new measurement into the collection + measurementData._id = Collection.insert(measurement); + + // Get the updated measurement number after inserting + Meteor.defer(() => { + measurementData.measurementNumber = Collection.findOne(measurementData._id).measurementNumber; + cornerstone.updateImage(OHIF.viewerbase.viewportUtils.getActiveViewportElement()); + }); + } + + // Signal unsaved changes + OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); +} diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementModified.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementModified.js new file mode 100644 index 000000000..cf7ab4e10 --- /dev/null +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementModified.js @@ -0,0 +1,40 @@ +import { _ } from 'meteor/underscore'; +import { OHIF } from 'meteor/ohif:core'; +import { cornerstone } from 'meteor/ohif:cornerstone'; + +export default function ({ instance, eventData, tool, toolGroupId, toolGroup }) { + const { measurementApi } = instance.data; + const { measurementData } = eventData; + + const Collection = measurementApi.tools[tool.parentTool]; + + // Stop here if the tool data shall not be persisted (e.g. temp tools) + if (!Collection) return; + + OHIF.log.info('CornerstoneToolsMeasurementModified'); + + const measurement = Collection.findOne(measurementData._id); + const childMeasurement = measurement && measurement[tool.attribute]; + + // Stop here if the measurement is already deleted + if (!childMeasurement) return; + + // Update the collection data with the cornerstone measurement data + const ignoredKeys = ['location', 'description', 'response']; + Object.keys(measurementData).forEach(key => { + if (_.contains(ignoredKeys, key)) return; + childMeasurement[key] = measurementData[key]; + }); + + // If the measurement configuration includes a value for Viewport, + // we will populate this with the Cornerstone Viewport + if (Collection._c2._simpleSchema.schema(`${tool.attribute}.viewport`)) { + childMeasurement.viewport = cornerstone.getViewport(eventData.element); + } + + // Update the measurement in the collection + Collection.update(measurement._id, { $set: { [tool.attribute]: childMeasurement } }); + + // Signal unsaved changes + OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); +} diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementRemoved.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementRemoved.js new file mode 100644 index 000000000..817b9610d --- /dev/null +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleChildMeasurementRemoved.js @@ -0,0 +1,40 @@ +import { _ } from 'meteor/underscore'; +import { $ } from 'meteor/jquery'; +import { OHIF } from 'meteor/ohif:core'; +import { cornerstone } from 'meteor/ohif:cornerstone'; + +export default function ({ instance, eventData, tool, toolGroupId, toolGroup }) { + OHIF.log.info('CornerstoneToolsMeasurementRemoved'); + const measurementData = eventData.measurementData; + const { measurementApi, timepointApi } = instance.data; + const Collection = measurementApi.tools[tool.parentTool]; + + // Stop here if the tool data shall not be persisted (e.g. temp tools) + if (!Collection) return; + + const measurement = Collection.findOne(measurementData._id); + + // Stop here if the measurement is already gone or never existed + if (!measurement) return; + + if (measurement.childToolsCount === 1) { + // Remove the measurement + Collection.remove(measurement._id); + + // Sync the new measurement data with cornerstone tools + const baseline = timepointApi.baseline(); + measurementApi.sortMeasurements(baseline.timepointId); + } else { + // Update the measurement in the collection + Collection.update(measurement._id, { + $set: { [tool.attribute]: null }, + $inc: { childToolsCount: -1 } + }); + } + + // Repaint the images on all viewports without the removed measurements + _.each($('.imageViewerViewport'), element => cornerstone.updateImage(element)); + + // Signal unsaved changes + OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); +} diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementAdded.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementAdded.js new file mode 100644 index 000000000..f5bc1ad2e --- /dev/null +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementAdded.js @@ -0,0 +1,53 @@ +import { Meteor } from 'meteor/meteor'; +import { _ } from 'meteor/underscore'; +import { OHIF } from 'meteor/ohif:core'; +import { cornerstone } from 'meteor/ohif:cornerstone'; +import getImageAttributes from './getImageAttributes'; + +export default function ({ instance, eventData, tool }) { + const { measurementApi } = instance.data; + const { measurementData, toolType } = eventData; + + const Collection = measurementApi.tools[toolType]; + + // Stop here if the tool data shall not be persisted (e.g. temp tools) + if (!Collection) return; + + // Stop here if there's no measurement data or if it was cancelled + if (!measurementData || measurementData.cancelled) return; + + OHIF.log.info('CornerstoneToolsMeasurementAdded'); + + const imageAttributes = getImageAttributes(eventData.element); + const measurement = _.extend({}, measurementData, imageAttributes, { + measurementNumber: measurementData.measurementNumber, + userId: Meteor.userId() + }); + + // Get the related timepoint by the measurement number and use its location if defined + const relatedTimepoint = Collection.findOne({ + measurementNumber: measurement.measurementNumber, + toolType: measurementData.toolType, + patientId: imageAttributes.patientId, + }); + + // Use the related timepoint location if found and defined + if (relatedTimepoint && relatedTimepoint.location) { + measurement.location = relatedTimepoint.location; + } + + // Clean the measurement according to the Schema + Collection._c2._simpleSchema.clean(measurement); + + // Insert the new measurement into the collection + measurementData._id = Collection.insert(measurement); + + // Get the updated measurement number after inserting + Meteor.defer(() => { + measurementData.measurementNumber = Collection.findOne(measurementData._id).measurementNumber; + cornerstone.updateImage(OHIF.viewerbase.viewportUtils.getActiveViewportElement()); + }); + + // Signal unsaved changes + OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); +} diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementModified.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementModified.js new file mode 100644 index 000000000..dfe9ce9e8 --- /dev/null +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementModified.js @@ -0,0 +1,42 @@ +import { _ } from 'meteor/underscore'; +import { OHIF } from 'meteor/ohif:core'; +import { cornerstone } from 'meteor/ohif:cornerstone'; + +export default function ({ instance, eventData, tool, toolGroupId, toolGroup }) { + const { measurementApi } = instance.data; + const { measurementData, toolType } = eventData; + + const Collection = measurementApi.tools[toolType]; + + // Stop here if the tool data shall not be persisted (e.g. temp tools) + if (!Collection) return; + + OHIF.log.info('CornerstoneToolsMeasurementModified'); + + const measurement = Collection.findOne(measurementData._id); + + // Stop here if the measurement is already deleted + if (!measurement) return; + + // Update the collection data with the cornerstone measurement data + const ignoredKeys = ['location', 'description', 'response']; + Object.keys(measurementData).forEach(key => { + if (_.contains(ignoredKeys, key)) return; + measurement[key] = measurementData[key]; + }); + + const measurementId = measurement._id; + delete measurement._id; + + // If the measurement configuration includes a value for Viewport, + // we will populate this with the Cornerstone Viewport + if (Collection._c2._simpleSchema.schema('viewport')) { + measurement.viewport = cornerstone.getViewport(eventData.element); + } + + // Update the measurement in the collection + Collection.update(measurementId, { $set: measurement }); + + // Signal unsaved changes + OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); +} diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js new file mode 100644 index 000000000..3084f1b21 --- /dev/null +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/handleSingleMeasurementRemoved.js @@ -0,0 +1,37 @@ +import { _ } from 'meteor/underscore'; +import { $ } from 'meteor/jquery'; +import { OHIF } from 'meteor/ohif:core'; +import { cornerstone } from 'meteor/ohif:cornerstone'; + +export default function({ instance, eventData, tool, toolGroupId, toolGroup }) { + OHIF.log.info('CornerstoneToolsMeasurementRemoved'); + const measurementData = eventData.measurementData; + const { measurementApi, timepointApi } = instance.data; + const Collection = measurementApi.tools[eventData.toolType]; + + // Stop here if the tool data shall not be persisted (e.g. temp tools) + if (!Collection) return; + + const measurementTypeId = measurementApi.toolsGroupsMap[measurementData.toolType]; + const measurement = Collection.findOne(measurementData._id); + + // Stop here if the measurement is already gone or never existed + if (!measurement) return; + + // Remove all the measurements with the given type and number + const { measurementNumber, timepointId } = measurement; + measurementApi.deleteMeasurements(measurementTypeId, { + measurementNumber, + timepointId + }); + + // Sync the new measurement data with cornerstone tools + const baseline = timepointApi.baseline(); + measurementApi.sortMeasurements(baseline.timepointId); + + // Repaint the images on all viewports without the removed measurements + _.each($('.imageViewerViewport'), element => cornerstone.updateImage(element)); + + // Signal unsaved changes + OHIF.ui.unsavedChanges.set('viewer.studyViewer.measurements.' + eventData.toolType); +} diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers/index.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers/index.js new file mode 100644 index 000000000..3d74e2933 --- /dev/null +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers/index.js @@ -0,0 +1 @@ +import './MeasurementHandlers';