From c3565cd687edc5a48732378a309e7a2b98d2bf38 Mon Sep 17 00:00:00 2001 From: Erik Ziegler Date: Tue, 11 Dec 2018 12:30:21 +0100 Subject: [PATCH] Begin switching study browser use react-viewerbase --- .../flexboxLayout/flexboxLayout.html | 13 -- .../components/flexboxLayout/flexboxLayout.js | 181 +++++++++++++++++- .../client/components/viewer/viewer.html | 12 +- OHIFViewer/client/components/viewer/viewer.js | 11 ++ OHIFViewer/package-lock.json | 12 ++ OHIFViewer/package.json | 3 +- .../studyBrowser/studyBrowser.html | 11 -- .../studyBrowser/studyBrowser/studyBrowser.js | 11 -- .../studyBrowser/studyBrowser.styl | 19 -- .../thumbnailEntry/thumbnailEntry.html | 30 --- .../thumbnailEntry/thumbnailEntry.js | 105 ---------- .../thumbnailEntry/thumbnailEntry.styl | 95 --------- Packages/ohif-viewerbase/package.js | 14 +- 13 files changed, 206 insertions(+), 311 deletions(-) delete mode 100644 OHIFViewer/client/components/flexboxLayout/flexboxLayout.html delete mode 100644 Packages/ohif-viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.html delete mode 100644 Packages/ohif-viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.js delete mode 100644 Packages/ohif-viewerbase/client/components/studyBrowser/studyBrowser/studyBrowser.styl delete mode 100644 Packages/ohif-viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.html delete mode 100644 Packages/ohif-viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.js delete mode 100644 Packages/ohif-viewerbase/client/components/studyBrowser/thumbnailEntry/thumbnailEntry.styl diff --git a/OHIFViewer/client/components/flexboxLayout/flexboxLayout.html b/OHIFViewer/client/components/flexboxLayout/flexboxLayout.html deleted file mode 100644 index 2eb628817..000000000 --- a/OHIFViewer/client/components/flexboxLayout/flexboxLayout.html +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/OHIFViewer/client/components/flexboxLayout/flexboxLayout.js b/OHIFViewer/client/components/flexboxLayout/flexboxLayout.js index b66aa7a45..4967c45e3 100644 --- a/OHIFViewer/client/components/flexboxLayout/flexboxLayout.js +++ b/OHIFViewer/client/components/flexboxLayout/flexboxLayout.js @@ -1,15 +1,176 @@ +import { Component } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; + import { Viewerbase } from 'meteor/ohif:viewerbase'; +import { StudyBrowser } from 'react-viewerbase'; -Template.flexboxLayout.helpers({ - leftSidebarOpen() { - return Template.instance().data.state.get('leftSidebar'); - }, +/** + * Asynchronous wrapper around Cornerstone's renderToCanvas method. + * + * @param {HTMLElement} canvasElement An HTML element + * @param {Image} image A Cornerstone Image + * + * @return {Promise} A promise tracking the progress of the rendering. Resolves empty. + */ +function renderAsync(canvasElement, image) { + return new Promise((resolve, reject) => { + try { + cornerstone.renderToCanvas(canvasElement, image); + resolve(); + } catch(error) { + reject(error); + } + }); +} - rightSidebarOpen() { - return Template.instance().data.state.get('rightSidebar'); - }, +// Define a handler for success on image load +const loadSuccess = function(image, studyInstanceUid, displaySetInstanceUid) { + // This is an off-screen canvas. It's used to get dataURL images by using + // cornerstone.renderToCanvas function. + const canvasElement = document.createElement('canvas'); + canvasElement.width = 193; + canvasElement.height = 123; - ViewerMain() { - return Viewerbase.components.viewer.ViewerMain; + console.warn(this.state); + + // Render the image to canvas to be able to get its dataURL + renderAsync(canvasElement, image).then(() => { + const studies = this.state.studiesForBrowser; + const study = studies.find(study => study.studyInstanceUid === studyInstanceUid); + const thumbnail = study.thumbnails.find(t => t.displaySetInstanceUid === displaySetInstanceUid); + + thumbnail.imageSrc = canvasElement.toDataURL('image/jpeg', 1); + + console.warn(this.state); + + this.setState({ + studiesForBrowser: studies + }); + }); +}; + +// Define a handler for error on image load +const loadError = function(error, studyInstanceUid, displaySetInstanceUid) { + const studies = this.state.studiesForBrowser; + const study = studies.find(study => study.studyInstanceUid === studyInstanceUid); + const thumbnail = study.thumbnails.find(t => t.displaySetInstanceUid === displaySetInstanceUid); + + thumbnail.error = error; + + this.setState({ + studiesForBrowser: studies + }); +}; + +const ViewerMain = Viewerbase.components.viewer.ViewerMain; + +class FlexboxLayout extends Component { + constructor(props) { + super(props); + + this.state = { + leftSidebarOpen: true, + rightSidebarOpen: false, + studiesForBrowser: this.getStudiesForBrowser(), + }; + + this.getStudiesForBrowser = this.getStudiesForBrowser.bind(this); + this.getThumbnailsFromImageIds = this.getThumbnailsFromImageIds.bind(this); } -}); + + componentDidMount() { + this.getThumbnailsFromImageIds(); + } + + getThumbnailsFromImageIds() { + const studyThumbnails = this.state.studiesForBrowser.forEach(function (study) { + const { studyInstanceUid } = study; + + study.thumbnails.forEach(function (displaySet) { + const imageId = displaySet.imageId; + const {displaySetInstanceUid, seriesDescription, seriesNumber, instanceNumber, numImageFrames} = displaySet; + + cornerstone.loadAndCacheImage(imageId).then((image) => { + loadSuccess.call(this, image, studyInstanceUid, displaySetInstanceUid); + }, error => { + loadError.call(this, error, studyInstanceUid, displaySetInstanceUid); + }); + }, this); + }, this); + + } + + getStudiesForBrowser() { + // @TypeSafeStudies + const studies = OHIF.viewer.Studies.findAllBy({ + selected: true + }); + + + // TODO[react]: + // - Add sorting of display sets + // - Pass in which display set is active from Redux + // - Pass in errors and stack loading progress from Redux + // - Add useMiddleSeriesInstanceAsThumbnail + // - Add showStackLoadingProgressBar option + return studies.map((study) => { + const { studyInstanceUid } = study; + + const thumbnails = study.displaySets.map((displaySet) => { + const active = false; + const stackPercentComplete = 0; + const { displaySetInstanceUid, seriesDescription, seriesNumber, instanceNumber, numImageFrames } = displaySet; + const imageId = displaySet.images[0].getImageId(); + return { + imageSrc: '', + imageId, + displaySetInstanceUid, + seriesDescription, + seriesNumber, + instanceNumber, + numImageFrames, + active, + stackPercentComplete + }; + }); + + return { + studyInstanceUid, + thumbnails + }; + }); + } + + render() { + let mainContentClassName = "mainContent" + if (this.state.leftSidebarOpen) { + mainContentClassName += ' sidebar-left-open'; + } + + if (this.state.rightSidebarOpen) { + mainContentClassName += ' sidebar-right-open'; + } + + // TODO[react]: Add measurementLightTable + return ( +
+
+ +
+
+ +
+
+ {/*{{> measurementLightTable (clone this)}}*/} +
+
+ ); + } +} + +FlexboxLayout.propTypes = { + studies: PropTypes.array.isRequired +}; + +export default FlexboxLayout; diff --git a/OHIFViewer/client/components/viewer/viewer.html b/OHIFViewer/client/components/viewer/viewer.html index d2db79ea1..e413c6151 100644 --- a/OHIFViewer/client/components/viewer/viewer.html +++ b/OHIFViewer/client/components/viewer/viewer.html @@ -1,13 +1,19 @@