Update DisplaySetService

This commit is contained in:
James A. Petts 2020-05-19 09:30:16 +01:00
parent 2b41d64e85
commit aec30e0db1
4 changed files with 226 additions and 138 deletions

View File

@ -1,7 +1,7 @@
import guid from '../../utils/guid'; import pubSubServiceInterface from '../pubSubServiceInterface';
const EVENTS = { const EVENTS = {
DISPLAY_SET_ADDED: 'event::displaySetService:displaySetAdded', DISPLAY_SETS_ADDED: 'event::displaySetService:displaySetAdded',
}; };
const displaySetCache = []; const displaySetCache = [];
@ -11,88 +11,14 @@ export default class DisplaySetService {
this.displaySets = {}; this.displaySets = {};
this.EVENTS = EVENTS; this.EVENTS = EVENTS;
this.listeners = {}; this.listeners = {};
Object.assign(this, pubSubServiceInterface);
} }
init(extensionManager, SOPClassHandlerIds) { init(extensionManager, SOPClassHandlerIds) {
this.extensionManager = extensionManager; this.extensionManager = extensionManager;
this.SOPClassHandlerIds = SOPClassHandlerIds; this.SOPClassHandlerIds = SOPClassHandlerIds;
this.activeDisplaySets = {}; this.activeDisplaySets = [];
}
/**
* Subscribe to measurement updates.
*
* @param {string} eventName The name of the event
* @param {Function} callback Events callback
* @return {Object} Observable object with actions
*/
subscribe(eventName, callback) {
if (this._isValidEvent(eventName)) {
const listenerId = guid();
const subscription = { id: listenerId, callback };
console.info(`displaySetService: Subscribing to '${eventName}'.`);
if (Array.isArray(this.listeners[eventName])) {
this.listeners[eventName].push(subscription);
} else {
this.listeners[eventName] = [subscription];
}
return {
unsubscribe: () => this._unsubscribe(eventName, listenerId),
};
} else {
throw new Error(`Event ${eventName} not supported.`);
}
}
/**
* Unsubscribe to measurement updates.
*
* @param {string} eventName The name of the event
* @param {string} listenerId The listeners id
* @return void
*/
_unsubscribe(eventName, listenerId) {
if (!this.listeners[eventName]) {
return;
}
const listeners = this.listeners[eventName];
if (Array.isArray(listeners)) {
this.listeners[eventName] = listeners.filter(
({ id }) => id !== listenerId
);
} else {
this.listeners[eventName] = undefined;
}
}
/**
* Broadcasts displaySetService changes.
*
* @param {string} eventName The event name
* @return void
*/
_broadcastChange(eventName) {
const hasListeners = Object.keys(this.listeners).length > 0;
const hasCallbacks = Array.isArray(this.listeners[eventName]);
if (hasListeners && hasCallbacks) {
this.listeners[eventName].forEach(listener => {
listener.callback(this.activeDisplaySets);
});
}
}
/**
* Check if a given displaySetService event is valid.
*
* @param {string} eventName The name of the event
* @return {boolean} Event name validation
*/
_isValidEvent(eventName) {
return Object.values(this.EVENTS).includes(eventName);
} }
_addDisplaySetsToCache(displaySets) { _addDisplaySetsToCache(displaySets) {
@ -105,19 +31,8 @@ export default class DisplaySetService {
const activeDisplaySets = this.activeDisplaySets; const activeDisplaySets = this.activeDisplaySets;
displaySets.forEach(displaySet => { displaySets.forEach(displaySet => {
const { StudyInstanceUID } = displaySet; activeDisplaySets.push(displaySet);
if (!Array.isArray(activeDisplaySets[StudyInstanceUID])) {
activeDisplaySets[StudyInstanceUID] = [];
}
activeDisplaySets[StudyInstanceUID].push(displaySet);
}); });
console.log('DISPLAY_SET_ADDED');
console.log(activeDisplaySets);
this._broadcastChange(EVENTS.DISPLAY_SET_ADDED);
} }
getActiveDisplaySets() { getActiveDisplaySets() {
@ -137,11 +52,59 @@ export default class DisplaySetService {
); );
}; };
makeDisplaySets = instances => { /**
if (!instances || !instances.length) { * Broadcasts displaySetService changes.
*
* @param {string} eventName The event name
* @return void
*/
_broadcastChange = (eventName, callbackProps) => {
const hasListeners = Object.keys(this.listeners).length > 0;
const hasCallbacks = Array.isArray(this.listeners[eventName]);
if (hasListeners && hasCallbacks) {
this.listeners[eventName].forEach(listener => {
listener.callback(callbackProps);
});
}
};
makeDisplaySets = (input, batch = false) => {
if (!input || !input.length) {
throw new Error('No instances were provided.'); throw new Error('No instances were provided.');
} }
if (batch && !input[0].length) {
throw new Error(
'Batch displaySet creation does not contain array of array of instances.'
);
}
// If array of instances => One instance.
let displaySetsAdded = [];
debugger;
if (batch) {
input.forEach(instances => {
const displaySets = this.makeDisplaySetForInstances(instances);
displaySetsAdded = [...displaySetsAdded, displaySets];
});
} else {
const displaySets = this.makeDisplaySetForInstances(input);
displaySetsAdded = displaySets;
}
// If array of array of instances
this._broadcastChange(EVENTS.DISPLAY_SETS_ADDED, displaySetsAdded);
};
makeDisplaySetForInstances(instances) {
debugger;
const instance = instances[0]; const instance = instances[0];
const existingDisplaySets = const existingDisplaySets =
@ -155,19 +118,21 @@ export default class DisplaySetService {
if (handler.sopClassUids.includes(instance.SOPClassUID)) { if (handler.sopClassUids.includes(instance.SOPClassUID)) {
// Check if displaySets are already created using this SeriesInstanceUID/SOPClassHandler pair. // Check if displaySets are already created using this SeriesInstanceUID/SOPClassHandler pair.
const cachedDisplaySets = existingDisplaySets.filter( let displaySets = existingDisplaySets.filter(
displaySet => displaySet.SOPClassHandlerId === SOPClassHandlerId displaySet => displaySet.SOPClassHandlerId === SOPClassHandlerId
); );
if (cachedDisplaySets.length) { if (displaySets.length) {
this._addActiveDisplaySets(cachedDisplaySets); this._addActiveDisplaySets(displaySets);
} else { } else {
const newDisplaySets = handler.getDisplaySetsFromSeries(instances); displaySets = handler.getDisplaySetsFromSeries(instances);
this._addDisplaySetsToCache(newDisplaySets); this._addDisplaySetsToCache(displaySets);
this._addActiveDisplaySets(newDisplaySets); this._addActiveDisplaySets(displaySets);
}
return displaySets;
} }
} }
} }
};
} }

View File

@ -1,5 +1,6 @@
import log from '../../log'; import log from '../../log';
import guid from '../../utils/guid'; import guid from '../../utils/guid';
import pubSubServiceInterface from '../pubSubServiceInterface';
/** /**
* Measurement source schema * Measurement source schema
@ -73,6 +74,8 @@ class MeasurementService {
enumerable: true, enumerable: true,
configurable: false, configurable: false,
}); });
Object.assign(this, pubSubServiceInterface);
} }
/** /**
@ -341,26 +344,26 @@ class MeasurementService {
* @param {string} eventName The name of the event * @param {string} eventName The name of the event
* @param {Function} callback Events callback * @param {Function} callback Events callback
* @return {Object} Observable object with actions * @return {Object} Observable object with actions
*/ // */
subscribe(eventName, callback) { // subscribe(eventName, callback) {
if (this._isValidEvent(eventName)) { // if (this._isValidEvent(eventName)) {
const listenerId = guid(); // const listenerId = guid();
const subscription = { id: listenerId, callback }; // const subscription = { id: listenerId, callback };
console.info(`Subscribing to '${eventName}'.`); // console.info(`Subscribing to '${eventName}'.`);
if (Array.isArray(this.listeners[eventName])) { // if (Array.isArray(this.listeners[eventName])) {
this.listeners[eventName].push(subscription); // this.listeners[eventName].push(subscription);
} else { // } else {
this.listeners[eventName] = [subscription]; // this.listeners[eventName] = [subscription];
} // }
return { // return {
unsubscribe: () => this._unsubscribe(eventName, listenerId), // unsubscribe: () => this._unsubscribe(eventName, listenerId),
}; // };
} else { // } else {
throw new Error(`Event ${eventName} not supported.`); // throw new Error(`Event ${eventName} not supported.`);
} // }
} // }
_getMappingByMeasurementSource(measurementId, definition) { _getMappingByMeasurementSource(measurementId, definition) {
const measurement = this.getMeasurement(measurementId); const measurement = this.getMeasurement(measurementId);
@ -450,23 +453,23 @@ class MeasurementService {
* Unsubscribe to measurement updates. * Unsubscribe to measurement updates.
* *
* @param {string} eventName The name of the event * @param {string} eventName The name of the event
* @param {string} listenerId The listeners id // * @param {string} listenerId The listeners id
* @return void // * @return void
*/ // */
_unsubscribe(eventName, listenerId) { // _unsubscribe(eventName, listenerId) {
if (!this.listeners[eventName]) { // if (!this.listeners[eventName]) {
return; // return;
} // }
const listeners = this.listeners[eventName]; // const listeners = this.listeners[eventName];
if (Array.isArray(listeners)) { // if (Array.isArray(listeners)) {
this.listeners[eventName] = listeners.filter( // this.listeners[eventName] = listeners.filter(
({ id }) => id !== listenerId // ({ id }) => id !== listenerId
); // );
} else { // } else {
this.listeners[eventName] = undefined; // this.listeners[eventName] = undefined;
} // }
} // }
/** /**
* Check if a given measurement data is valid. * Check if a given measurement data is valid.
@ -490,10 +493,10 @@ class MeasurementService {
* *
* @param {string} eventName The name of the event * @param {string} eventName The name of the event
* @return {boolean} Event name validation * @return {boolean} Event name validation
*/ // */
_isValidEvent(eventName) { // _isValidEvent(eventName) {
return Object.values(this.EVENTS).includes(eventName); // return Object.values(this.EVENTS).includes(eventName);
} // }
/** /**
* Converts object of objects to array. * Converts object of objects to array.

View File

@ -0,0 +1,56 @@
import pubSubServiceInterface from '../pubSubServiceInterface';
export default class ToolBarService {
constructor() {
this.displaySets = {};
this.EVENTS = EVENTS;
this.listeners = {};
Object.assign(this, pubSubServiceInterface);
}
init(extensionManager) {
this.buttons = {};
this.extensionManager = extensionManager;
}
addButtons(buttons) {
buttons.forEach(button => {
const buttonDefinition = this.extensionManager.getModuleEntry(
button.namespace
);
const id = button.id || buttonDefinition.id;
this.buttons[id] = buttonDefinition;
});
}
setToolBarLayout(layouts) {
const toolBarLayout = [];
layouts.forEach(layout => {
const toolBarDefinitions = { tools: [], moreTools: [] };
const { tools, moreTools } = layout;
tools &&
tools.forEach(element => {
const button = this.buttons[element];
toolBarDefinitions.tools.push(button);
});
moreTools &&
moreTools.forEach(element => {
const button = this.buttons[element];
toolBarDefinitions.moreTools.push(button);
});
toolBarLayout.push(toolBarDefinitions);
});
// TODO -> Change this to a service. => emit an event to subscribers to update the toolbar layout.
}
}

View File

@ -0,0 +1,64 @@
import guid from '../../utils/guid';
export default {
subscribe,
_unsubscribe,
_isValidEvent,
};
/**
* Subscribe to measurement updates.
*
* @param {string} eventName The name of the event
* @param {Function} callback Events callback
* @return {Object} Observable object with actions
*/
function subscribe(eventName, callback) {
if (this._isValidEvent(eventName)) {
const listenerId = guid();
const subscription = { id: listenerId, callback };
console.info(`displaySetService: Subscribing to '${eventName}'.`);
if (Array.isArray(this.listeners[eventName])) {
this.listeners[eventName].push(subscription);
} else {
this.listeners[eventName] = [subscription];
}
return {
unsubscribe: () => this._unsubscribe(eventName, listenerId),
};
} else {
throw new Error(`Event ${eventName} not supported.`);
}
}
/**
* Unsubscribe to measurement updates.
*
* @param {string} eventName The name of the event
* @param {string} listenerId The listeners id
* @return void
*/
function _unsubscribe(eventName, listenerId) {
if (!this.listeners[eventName]) {
return;
}
const listeners = this.listeners[eventName];
if (Array.isArray(listeners)) {
this.listeners[eventName] = listeners.filter(({ id }) => id !== listenerId);
} else {
this.listeners[eventName] = undefined;
}
}
/**
* Check if a given displaySetService event is valid.
*
* @param {string} eventName The name of the event
* @return {boolean} Event name validation
*/
function _isValidEvent(eventName) {
return Object.values(this.EVENTS).includes(eventName);
}