diff --git a/lib/getImageData.js b/lib/getImageData.js index 2bb1c2b..5a29191 100644 --- a/lib/getImageData.js +++ b/lib/getImageData.js @@ -13,7 +13,7 @@ export function getImageData(displaySet) { const { metaData0, metaDataMap, imageIds, imageMetaData0 } = buildMetadata(displaySet); const {rowCosines, columnCosines} = metaData0; - const crossProduct = columnCosines.crossVectors(columnCosines, rowCosines); + const crossProduct = columnCosines.crossVectors(rowCosines, columnCosines); const orientation = determineOrientation(crossProduct); const zAxis = computeZAxis(orientation, metaDataMap); const xSpacing = metaData0.columnPixelSpacing; diff --git a/multiplanarReformatting/main.js b/multiplanarReformatting/main.js index 4dce97b..dcd3ed5 100644 --- a/multiplanarReformatting/main.js +++ b/multiplanarReformatting/main.js @@ -58,7 +58,10 @@ var MultiplanarReformattingPlugin = class MultiplanarReformattingPlugin extends let topRightParent = document.querySelector('#'+viewDirection+"TopRight"); const topRightMap = new Map(); - let studyDescription = displaySet.images[0]._study.studyDescription.replace(/\^/g, " "); + let studyDescription = ""; + if (displaySet.images[0]._study.studyDescription){ + studyDescription = displaySet.images[0]._study.studyDescription.replace(/\^/g, " "); + } let studyDate = displaySet.images[0]._study.studyDate; let seriesYear = parseInt(studyDate.substr(0,4),10); @@ -88,7 +91,7 @@ var MultiplanarReformattingPlugin = class MultiplanarReformattingPlugin extends } - setBottomRightText(viewDirection,displaySet,window,level){ + static setBottomRightText(viewDirection,displaySet,window,level){ let botRightParent = document.querySelector('#'+viewDirection+"BotRight"); const botRightMap = new Map(); let compStr = displaySet.images[0]._data.lossyImageCompression === undefined ? "Lossless / Uncompressed" : ds.images[0]._data.lossyImageCompression; @@ -104,10 +107,11 @@ var MultiplanarReformattingPlugin = class MultiplanarReformattingPlugin extends * @param eventData */ updateViewportText(eventData){ + debugger; MultiplanarReformattingPlugin.setBottomLeftText(eventData.viewDirection, eventData.displaySet,eventData.sliceIndex,eventData.sliceCount); MultiplanarReformattingPlugin.setTopLeftText(eventData.viewDirection,eventData.displaySet); MultiplanarReformattingPlugin.setTopRightText(eventData.viewDirection,eventData.displaySet); - this.setBottomRightText(eventData.viewDirection,eventData.displaySet,eventData.window,eventData.level); + MultiplanarReformattingPlugin.setBottomRightText(eventData.viewDirection,eventData.displaySet,eventData.window,eventData.level); } /** @@ -115,7 +119,7 @@ var MultiplanarReformattingPlugin = class MultiplanarReformattingPlugin extends * @param eventData */ updateWindowLevelText(eventData){ - this.setBottomRightText(eventData.viewDirection,eventData.displaySet,eventData.window,eventData.level); + MultiplanarReformattingPlugin.setBottomRightText(eventData.viewDirection,eventData.displaySet,eventData.window,eventData.level); } @@ -218,6 +222,7 @@ var MultiplanarReformattingPlugin = class MultiplanarReformattingPlugin extends * @param displaySet */ setupViewport(div, viewportData, displaySet) { + const divParentElement = div.parentElement; const { viewportIndex } = viewportData; let { viewDirection } = viewportData.pluginData; @@ -225,6 +230,10 @@ var MultiplanarReformattingPlugin = class MultiplanarReformattingPlugin extends if (!displaySet) { displaySet = OHIF.plugins.ViewportPlugin.getDisplaySet(viewportIndex); } + // Reject image sets that are less than 20 images. + if (displaySet.images.length < 20){ + throw new Error("Series has too few images for this plugin."); + } const { VTKUtils } = window; const genericRenderWindow = vtk.Rendering.Misc.vtkGenericRenderWindow.newInstance({ diff --git a/volumeRendering/main.js b/volumeRendering/main.js index e83ac13..76ef379 100644 --- a/volumeRendering/main.js +++ b/volumeRendering/main.js @@ -23,6 +23,154 @@ var VolumeRenderingPlugin = class VolumeRenderingPlugin extends OHIF.plugins.Vie volumeController.render(); } + + /** + * Set up the divs to receive the dynamic text later on, i.e. patient name, etc. + * @param divParentElement + * @param viewDirection + * @param displaySet + */ + setupViewportText(divParentElement,viewDirection,displaySet){ + // TODO , load style sheets. + divParentElement.style.position = "relative"; + divParentElement.style.color = '#91b9cd'; + + ///////// TOP LEFT + // NO TOP LEFT because of Volume Widget. + + //////////// BOT LEFT + const botLeftParent = document.createElement('div'); + botLeftParent.style.position="absolute"; + botLeftParent.style.bottom="10px"; + botLeftParent.style.left="10px"; + botLeftParent.id = viewDirection + "BottomLeft"; + const SeriesNumber = document.createElement('div'); + SeriesNumber.id = 'SeriesNumber'; + botLeftParent.appendChild(SeriesNumber); + + const SeriesDescription = document.createElement('div'); + botLeftParent.appendChild(SeriesDescription); + SeriesDescription.id = 'SeriesDescription'; + + /////////// TOP RIGHT + divParentElement.appendChild(botLeftParent); + const topRightParent = document.createElement('div'); + topRightParent.style.position="absolute"; + topRightParent.style.top="10px"; + topRightParent.style.right="10px"; + topRightParent.id = viewDirection + "TopRight"; + const PatientName = document.createElement('div'); + PatientName.id = 'PatientName'; + topRightParent.appendChild(PatientName); + const PatientId = document.createElement('div'); + divParentElement.appendChild(topRightParent); + PatientId.id = 'PatientId'; + topRightParent.appendChild(PatientId); + + const StudyDescription = document.createElement('div'); + StudyDescription.id = 'StudyDescription'; + topRightParent.appendChild(StudyDescription); + const SeriesDate = document.createElement('div'); + topRightParent.appendChild(SeriesDate); + SeriesDate.id = 'SeriesDate'; + + divParentElement.appendChild(topRightParent); + /////////// BOT RIGHT + const botRightParent = document.createElement('div'); + botRightParent.style.position="absolute"; + botRightParent.style.bottom="10px"; + botRightParent.id = viewDirection + "BotRight"; + botRightParent.style.right="10px"; + } + + static setText(parent, textMap){ + for (let [key, value] of textMap) { + parent.querySelector(key).innerHTML = value; + } + } + + static setBottomLeftText(viewDirection, displaySet){ + let botLeftParent = document.querySelector('#'+viewDirection+"BottomLeft"); + + const bottomLeftMap = new Map(); + let seriesNum = displaySet.seriesNumber; + let seriesDescription = displaySet.images[0]._series.seriesDescription.replace(/\^/g, " "); + bottomLeftMap.set("#SeriesNumber","Ser:" + " " + seriesNum); + bottomLeftMap.set("#SeriesDescription",seriesDescription); + VolumeRenderingPlugin.setText(botLeftParent,bottomLeftMap); + } + + static setTopRightText(viewDirection, displaySet){ + let topRightParent = document.querySelector('#'+viewDirection+"TopRight"); + + const topRightMap = new Map(); + let patientName = displaySet.images[0]._study.patientName.replace(/\^/g, " "); + let patientId = displaySet.images[0]._study.patientId; + + + let studyDescription = displaySet.images[0]._study.studyDescription.replace(/\^/g, " "); + let studyDate = displaySet.images[0]._study.studyDate; + + let seriesYear = parseInt(studyDate.substr(0,4),10); + let seriesMonth = parseInt(studyDate.substr(4,2),10); + let seriesDay = parseInt(studyDate.substr(6,2),10); + let studyTime = displaySet.images[0]._study.studyTime; + let splitTime = studyTime.split("."); + let leftTime = splitTime[0]; + let seriesHour = parseInt(leftTime.substr(0,2),10); + let seriesMinute = parseInt(leftTime.substr(2,2),10); + let seriesSecond = parseInt(leftTime.substr(4,2),10); + let sd = new Date(seriesYear, seriesMonth-1, seriesDay,seriesHour,seriesMinute,seriesSecond); + const options = { + year: 'numeric', + month: 'long', + day: 'numeric', + hour: "numeric", + minute: "numeric", + second: "numeric", + hour12: false, + }; + let seriesDateString = sd.toLocaleDateString("en-US",options); + topRightMap.set("#PatientName",patientName); + topRightMap.set("#PatientId",patientId); + topRightMap.set("#StudyDescription",studyDescription); + topRightMap.set("#SeriesDate",seriesDateString); + VolumeRenderingPlugin.setText(topRightParent,topRightMap); + } + + + /** + * Updates the text. The viewDirection helps us find the correct divs. + * @param viewDirection + * @param displaySet + */ + updateViewportText(viewDirection,displaySet){ + VolumeRenderingPlugin.setBottomLeftText(viewDirection,displaySet); + VolumeRenderingPlugin.setTopRightText(viewDirection,displaySet); + } + + + orientCamera(camera,orientation){ + switch (orientation){ + case 'I': + break; + case 'S': + camera.elevation(-89.99); // TODO camera signularuty at -90??????? + break; + case 'A': + break; + case 'P': + break; + case 'L': + break; + case 'R': + break; + default: + console.assert("unknown orientation"); + break; + } + } + /** * Overriden from base class. Sets up the viewport based on the viewportData and the displaySet. * @param div @@ -31,7 +179,8 @@ var VolumeRenderingPlugin = class VolumeRenderingPlugin extends OHIF.plugins.Vie */ setupViewport(div, viewportData, displaySet) { const viewportWrapper = div.parentElement; - + const self = this; + let { viewDirection } = viewportData.pluginData; // Seems like VolumeRendering in 4-up is not fast enough to use progressive // updating and have a nice user experience. Added loading spinner instead. div.innerHTML = `