Allow to sort thumbnails by AcquisitionDateTime or any other stack property (sorted by InstanceNumber ascending by default)
- Retrieve AcquisitionDateTime via DICOMWeb (WIP for DIMSE) - Add a global template helper to sort arrays by an array element property or deep array element propery, and sort type
This commit is contained in:
parent
05d5b4007b
commit
af639b4de2
@ -2,7 +2,7 @@
|
|||||||
<div class="studyBrowser">
|
<div class="studyBrowser">
|
||||||
<div class="scrollableStudyThumbnails">
|
<div class="scrollableStudyThumbnails">
|
||||||
{{#each study in studies}}
|
{{#each study in studies}}
|
||||||
{{#each thumbnail in (studyThumbnails study)}}
|
{{#each thumbnail in (sort (studyThumbnails study) thumbnailSortBy thumbnailSortType)}}
|
||||||
{{>thumbnailEntry thumbnail=thumbnail}}
|
{{>thumbnailEntry thumbnail=thumbnail}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|||||||
@ -49,6 +49,9 @@ createStacks = function(study) {
|
|||||||
// Include the instance number
|
// Include the instance number
|
||||||
displaySet.instanceNumber = instance.instanceNumber;
|
displaySet.instanceNumber = instance.instanceNumber;
|
||||||
|
|
||||||
|
// Include the acquisition datetime
|
||||||
|
displaySet.acquisitionDatetime = instance.acquisitionDatetime;
|
||||||
|
|
||||||
displaySets.push(displaySet);
|
displaySets.push(displaySet);
|
||||||
} else if (isSingleImageModality(instance.modality)) {
|
} else if (isSingleImageModality(instance.modality)) {
|
||||||
displaySet = makeDisplaySet(series, [ instance ]);
|
displaySet = makeDisplaySet(series, [ instance ]);
|
||||||
@ -59,6 +62,9 @@ createStacks = function(study) {
|
|||||||
// Include the instance number
|
// Include the instance number
|
||||||
displaySet.instanceNumber = instance.instanceNumber;
|
displaySet.instanceNumber = instance.instanceNumber;
|
||||||
|
|
||||||
|
// Include the acquisition datetime
|
||||||
|
displaySet.acquisitionDatetime = instance.acquisitionDatetime;
|
||||||
|
|
||||||
displaySets.push(displaySet);
|
displaySets.push(displaySet);
|
||||||
} else {
|
} else {
|
||||||
stackableInstances.push(instance);
|
stackableInstances.push(instance);
|
||||||
|
|||||||
59
Packages/viewerbase/lib/helpers/sorting.js
Normal file
59
Packages/viewerbase/lib/helpers/sorting.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { _ } from 'meteor/underscore';
|
||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global Blaze UI helper to sort array elements
|
||||||
|
* by an array element's property (property) or deep object property (property.childProperty)
|
||||||
|
* Sorts ascending as default
|
||||||
|
*/
|
||||||
|
Template.registerHelper('sort', (array, sortBy, sortType) => {
|
||||||
|
if (!sortBy) {
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(array);
|
||||||
|
|
||||||
|
// To keep the order for the same values of the field which is used to sort:
|
||||||
|
// 1. Group the array by the field
|
||||||
|
// 2. Sort the grouped array
|
||||||
|
// 3. Ungroup the sorted array
|
||||||
|
|
||||||
|
const groupedArray = _.groupBy(array, (element) => {
|
||||||
|
if (sortBy) {
|
||||||
|
var groupingElement = getKeyValue(element, sortBy);
|
||||||
|
if (groupingElement) {
|
||||||
|
return groupingElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
});
|
||||||
|
|
||||||
|
const sortedArray = _.sortBy(groupedArray, (element) => {
|
||||||
|
if (sortBy) {
|
||||||
|
var sortingElement = getKeyValue(element[0], sortBy);
|
||||||
|
if (sortingElement) {
|
||||||
|
return sortingElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (sortType === 'desc') {
|
||||||
|
return _.flatten(sortedArray.reverse(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _.flatten(sortedArray, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
function getKeyValue(object, keyPath) {
|
||||||
|
keyPath = keyPath.split('.');
|
||||||
|
for (var i = 0; i < keyPath.length; i++) {
|
||||||
|
if (object && _.has(object, keyPath[i])) {
|
||||||
|
object = object[keyPath[i]];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
@ -206,6 +206,7 @@ Package.onUse(function(api) {
|
|||||||
'lib/helpers/objectEach.js',
|
'lib/helpers/objectEach.js',
|
||||||
'lib/helpers/ifTypeIs.js',
|
'lib/helpers/ifTypeIs.js',
|
||||||
'lib/helpers/prettyPrintStringify.js',
|
'lib/helpers/prettyPrintStringify.js',
|
||||||
|
'lib/helpers/sorting.js',
|
||||||
'lib/helpers/studyThumbnails.js',
|
'lib/helpers/studyThumbnails.js',
|
||||||
'lib/helpers/formatPN.js'
|
'lib/helpers/formatPN.js'
|
||||||
], 'client');
|
], 'client');
|
||||||
|
|||||||
@ -100,6 +100,7 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) {
|
|||||||
sourceImageInstanceUid: getSourceImageInstanceUid(instance),
|
sourceImageInstanceUid: getSourceImageInstanceUid(instance),
|
||||||
laterality: instance[0x00200062],
|
laterality: instance[0x00200062],
|
||||||
viewPosition: instance[0x00185101],
|
viewPosition: instance[0x00185101],
|
||||||
|
acquisitionDatetime: instance[0x0008002A],
|
||||||
numFrames: parseFloat(instance[0x00280008]),
|
numFrames: parseFloat(instance[0x00280008]),
|
||||||
frameTime: parseFloat(instance[0x00181063]),
|
frameTime: parseFloat(instance[0x00181063]),
|
||||||
lossyImageCompression: instance[0x00282110],
|
lossyImageCompression: instance[0x00282110],
|
||||||
|
|||||||
@ -95,6 +95,7 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
|
|||||||
sourceImageInstanceUid: getSourceImageInstanceUid(instance),
|
sourceImageInstanceUid: getSourceImageInstanceUid(instance),
|
||||||
laterality: remoteGetValue(instance['0020,0062']),
|
laterality: remoteGetValue(instance['0020,0062']),
|
||||||
viewPosition: remoteGetValue(instance['0018,5101']),
|
viewPosition: remoteGetValue(instance['0018,5101']),
|
||||||
|
acquisitionDatetime: remoteGetValue(instance['0008,002A']),
|
||||||
numFrames: parseFloat(remoteGetValue(instance['0028,0008'])),
|
numFrames: parseFloat(remoteGetValue(instance['0028,0008'])),
|
||||||
frameTime: parseFloat(remoteGetValue(instance['0018,1063']))
|
frameTime: parseFloat(remoteGetValue(instance['0018,1063']))
|
||||||
};
|
};
|
||||||
|
|||||||
@ -106,6 +106,7 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
|
|||||||
sourceImageInstanceUid: getSourceImageInstanceUid(instance),
|
sourceImageInstanceUid: getSourceImageInstanceUid(instance),
|
||||||
laterality: DICOMWeb.getString(instance['00200062']),
|
laterality: DICOMWeb.getString(instance['00200062']),
|
||||||
viewPosition: DICOMWeb.getString(instance['00185101']),
|
viewPosition: DICOMWeb.getString(instance['00185101']),
|
||||||
|
acquisitionDatetime: DICOMWeb.getString(instance['0008002A']),
|
||||||
numFrames: DICOMWeb.getNumber(instance['00280008']),
|
numFrames: DICOMWeb.getNumber(instance['00280008']),
|
||||||
frameTime: DICOMWeb.getNumber(instance['00181063']),
|
frameTime: DICOMWeb.getNumber(instance['00181063']),
|
||||||
sliceThickness: DICOMWeb.getNumber(instance['00180050']),
|
sliceThickness: DICOMWeb.getNumber(instance['00180050']),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user