feat: Use QIDO + WADO to load series metadata individually rather than the entire study metadata at once (#953)
This commit is contained in:
1 parent
c5cbd77cb9
commit
9e10c2b2de
12 files changed
+675
-414
No files matched your search
@@ -1,3 +1,4 @@
|
||||
/* global cornerstone */
|
||||
import './ImageThumbnail.styl';
|
||||
|
||||
import React, { PureComponent } from 'react';
|
||||
@@ -12,25 +13,6 @@ import ViewportLoadingIndicator from '../../viewer/ViewportLoadingIndicator';
|
||||
// - Pass in the entire load and render function as a prop?
|
||||
//import cornerstone from 'cornerstone-core';
|
||||
|
||||
/**
|
||||
* Asynchronous wrapper around Cornerstone's renderToCanvas method.
|
||||
*
|
||||
* @param {HTMLElement} canvasElement An HTML <canvas> 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default class ImageThumbnail extends PureComponent {
|
||||
static propTypes = {
|
||||
imageSrc: PropTypes.string,
|
||||
@@ -52,40 +34,32 @@ export default class ImageThumbnail extends PureComponent {
|
||||
super(props);
|
||||
|
||||
this.canvas = React.createRef();
|
||||
|
||||
const renderIntoCanvas = this.props.imageId && !this.props.imageSrc;
|
||||
|
||||
this.state = {
|
||||
loading: renderIntoCanvas,
|
||||
loading: this.shouldRenderToCanvas(),
|
||||
};
|
||||
}
|
||||
|
||||
shouldRenderToCanvas() {
|
||||
return this.props.imageId && !this.props.imageSrc;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const renderIntoCanvas = this.props.imageId && !this.props.imageSrc;
|
||||
|
||||
if (renderIntoCanvas) {
|
||||
const { imageId } = this.props;
|
||||
const canvas = this.canvas.current;
|
||||
|
||||
cornerstone.loadAndCacheImage(imageId).then(
|
||||
image => {
|
||||
renderAsync(canvas, image).then(
|
||||
() => {
|
||||
this.setState({
|
||||
loading: false,
|
||||
});
|
||||
},
|
||||
error => {
|
||||
// TODO: Set state?
|
||||
throw new Error(error);
|
||||
}
|
||||
);
|
||||
},
|
||||
error => {
|
||||
// TODO: Set state?
|
||||
if (this.shouldRenderToCanvas()) {
|
||||
cornerstone
|
||||
.loadAndCacheImage(this.props.imageId)
|
||||
.then(image => {
|
||||
cornerstone.renderToCanvas(this.canvas.current, image);
|
||||
this.setState({
|
||||
loading: false,
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
this.setState({
|
||||
loading: false,
|
||||
error: true,
|
||||
});
|
||||
throw new Error(error);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,12 +74,10 @@ export default class ImageThumbnail extends PureComponent {
|
||||
const showStackLoadingProgressBar =
|
||||
this.props.stackPercentComplete !== undefined;
|
||||
|
||||
const renderIntoCanvas = this.props.imageId && !this.props.imageSrc;
|
||||
|
||||
return (
|
||||
<div className="ImageThumbnail">
|
||||
<div className="image-thumbnail-canvas">
|
||||
{renderIntoCanvas ? (
|
||||
{this.shouldRenderToCanvas() ? (
|
||||
<canvas
|
||||
ref={this.canvas}
|
||||
width={this.props.width}
|
||||
@@ -130,6 +102,9 @@ export default class ImageThumbnail extends PureComponent {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{this.state.loading && (
|
||||
<div className="image-thumbnail-loading-indicator"></div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,36 @@
|
||||
-webkit-background-clip: padding
|
||||
background-clip: padding-box
|
||||
|
||||
// Thumbnail Loading Indicator
|
||||
|
||||
.image-thumbnail-loading-indicator
|
||||
position: absolute
|
||||
left: 50%
|
||||
top: 50%
|
||||
margin: -22px 0 0 -22px
|
||||
display: block
|
||||
width: 44px
|
||||
height: 44px
|
||||
|
||||
&:after
|
||||
content: " "
|
||||
display: block
|
||||
width: 32px
|
||||
height: 32px
|
||||
margin: 1px
|
||||
border-radius: 50%
|
||||
border: 5px solid var(--ui-border-color-dark)
|
||||
border-color: var(--ui-border-color-dark) transparent var(--ui-border-color-dark) transparent
|
||||
animation: image-thumbnail-loading-indicator 1.2s linear infinite
|
||||
|
||||
@keyframes image-thumbnail-loading-indicator
|
||||
0%
|
||||
transform: rotate(0deg)
|
||||
100%
|
||||
transform: rotate(360deg)
|
||||
|
||||
// The End...
|
||||
|
||||
.image-thumbnail-canvas
|
||||
height: 100%
|
||||
overflow: hidden
|
||||
@@ -36,7 +66,6 @@
|
||||
-webkit-user-drag: none
|
||||
pointer-events: none
|
||||
|
||||
|
||||
.thumbnailLoadingIndicator
|
||||
display: none
|
||||
pointer-events: none
|
||||
|
||||
@@ -25,7 +25,7 @@ class StudyBrowser extends Component {
|
||||
if (this.props.supportsDragAndDrop) {
|
||||
return (
|
||||
<ThumbnailEntryDragSource
|
||||
key={`${studyIndex}_${thumbIndex}`}
|
||||
key={thumb.displaySetInstanceUid}
|
||||
{...study}
|
||||
{...thumb}
|
||||
id={`${studyIndex}_${thumbIndex}`}
|
||||
@@ -37,7 +37,7 @@ class StudyBrowser extends Component {
|
||||
return (
|
||||
<div className="ThumbnailEntryContainer">
|
||||
<ThumbnailEntry
|
||||
key={`${studyIndex}_${thumbIndex}`}
|
||||
key={thumb.displaySetInstanceUid}
|
||||
{...study}
|
||||
{...thumb}
|
||||
id={`${studyIndex}_${thumbIndex}`}
|
||||
|
||||
Reference in new issue
Block a user