Merge pull request #2260 from OHIF/IDC-2258
IDC-2258: Replace instance dropdown to slider for dicom tag browser
This commit is contained in:
commit
0ef76f8b66
@ -3,6 +3,11 @@
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.dicom-tag-browser-table-wrapper {
|
||||
height: 500px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.dicom-tag-browser-table tr {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
@ -11,6 +16,20 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dicom-tag-browser-content {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
.dicom-tag-browser-instance-range .range {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.dicom-tag-browser-instance-range {
|
||||
padding: 20px 0 20px 0;
|
||||
}
|
||||
|
||||
.dicom-tag-browser-table td.dicom-tag-browser-table-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { classes, cornerstone as OHIFCornerstone } from '@ohif/core';
|
||||
import { Range } from '@ohif/ui';
|
||||
import dcmjs from 'dcmjs';
|
||||
import DicomBrowserSelect from './DicomBrowserSelect';
|
||||
import moment from 'moment';
|
||||
@ -99,26 +100,35 @@ const DicomTagBrowser = ({ displaySets, displaySetInstanceUID }) => {
|
||||
let instanceSelectList = null;
|
||||
|
||||
if (isImageStack) {
|
||||
const selectedInstanceValue = instanceList[activeInstance];
|
||||
|
||||
instanceSelectList = (
|
||||
<DicomBrowserSelect
|
||||
value={selectedInstanceValue}
|
||||
formatOptionLabel={DicomBrowserSelectItem}
|
||||
options={instanceList}
|
||||
/>
|
||||
<div className="dicom-tag-browser-instance-range">
|
||||
<Range
|
||||
showValue
|
||||
step={1}
|
||||
min={1}
|
||||
max={instanceList.length - 1}
|
||||
value={activeInstance}
|
||||
valueRenderer={value => <p>Instance Number: {value}</p>}
|
||||
onChange={({ target }) => {
|
||||
const instanceIndex = parseInt(target.value);
|
||||
setActiveInstance(instanceIndex);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="dicom-tag-browser-content">
|
||||
<DicomBrowserSelect
|
||||
value={selectedDisplaySetValue}
|
||||
formatOptionLabel={DicomBrowserSelectItem}
|
||||
options={displaySetList}
|
||||
/>
|
||||
{instanceSelectList}
|
||||
<DicomTagTable tags={tags} meta={meta}></DicomTagTable>
|
||||
<div className="dicom-tag-browser-table-wrapper">
|
||||
<DicomTagTable tags={tags} meta={meta}></DicomTagTable>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -127,30 +137,28 @@ function DicomTagTable({ tags, meta }) {
|
||||
const rows = getFormattedRowsFromTags(tags, meta);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<table className="dicom-tag-browser-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th className="dicom-tag-browser-table-left">Tag</th>
|
||||
<th className="dicom-tag-browser-table-left">Value Representation</th>
|
||||
<th className="dicom-tag-browser-table-left">Keyword</th>
|
||||
<th className="dicom-tag-browser-table-left">Value</th>
|
||||
</tr>
|
||||
{rows.map((row, index) => {
|
||||
const className = row.className ? row.className : null;
|
||||
<table className="dicom-tag-browser-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th className="dicom-tag-browser-table-left">Tag</th>
|
||||
<th className="dicom-tag-browser-table-left">Value Representation</th>
|
||||
<th className="dicom-tag-browser-table-left">Keyword</th>
|
||||
<th className="dicom-tag-browser-table-left">Value</th>
|
||||
</tr>
|
||||
{rows.map((row, index) => {
|
||||
const className = row.className ? row.className : null;
|
||||
|
||||
return (
|
||||
<tr className={className} key={`DICOMTagRow-${index}`}>
|
||||
<td>{row[0]}</td>
|
||||
<td className="dicom-tag-browser-table-center">{row[1]}</td>
|
||||
<td>{row[2]}</td>
|
||||
<td>{row[3]}</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
return (
|
||||
<tr className={className} key={`DICOMTagRow-${index}`}>
|
||||
<td>{row[0]}</td>
|
||||
<td className="dicom-tag-browser-table-center">{row[1]}</td>
|
||||
<td>{row[2]}</td>
|
||||
<td>{row[3]}</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
|
||||
@ -183,12 +191,16 @@ function getFormattedRowsFromTags(tags, meta) {
|
||||
} else {
|
||||
if (tagInfo.vr === 'xs') {
|
||||
try {
|
||||
const dataset = metadataProvider.getStudyDataset(meta.StudyInstanceUID);
|
||||
const dataset = metadataProvider.getStudyDataset(
|
||||
meta.StudyInstanceUID
|
||||
);
|
||||
const tag = dcmjs.data.Tag.fromPString(tagInfo.tag).toCleanString();
|
||||
const originalTagInfo = dataset[tag];
|
||||
tagInfo.vr = originalTagInfo.vr;
|
||||
} catch (error) {
|
||||
console.error(`Failed to parse value representation for tag '${tagInfo.keyword}'`);
|
||||
console.error(
|
||||
`Failed to parse value representation for tag '${tagInfo.keyword}'`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ export default function getCommandsModule(servicesManager) {
|
||||
|
||||
const { UIModalService } = servicesManager.services;
|
||||
|
||||
const WrappedDicomTagBrowser = function () {
|
||||
const WrappedDicomTagBrowser = function() {
|
||||
return (
|
||||
<DicomTagBrowser
|
||||
displaySets={displaySets}
|
||||
@ -34,7 +34,7 @@ export default function getCommandsModule(servicesManager) {
|
||||
content: WrappedDicomTagBrowser,
|
||||
title: `DICOM Tag Browser`,
|
||||
fullscreen: true,
|
||||
showScrollbar: true
|
||||
noScroll: true,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@ -9,7 +9,8 @@
|
||||
* @property {boolean} [closeButton=true] Should the modal body render the close button.
|
||||
* @property {string} [title=null] Should the modal render the title independently of the body content.
|
||||
* @property {string} [customClassName=null] The custom class to style the modal.
|
||||
* @property {boolean} [showScrollbar=null] Show or hide scrollbar.
|
||||
* @property {boolean} [showScrollbar=false] Show or hide scrollbar.
|
||||
* @property {boolean} [noScroll=false] Disable or not the scrollbar.
|
||||
*/
|
||||
|
||||
const name = 'UIModalService';
|
||||
@ -29,7 +30,7 @@ const serviceImplementation = {
|
||||
/**
|
||||
* Show a new UI modal;
|
||||
*
|
||||
* @param {ModalProps} props { content, contentProps, shouldCloseOnEsc, isOpen, onClose, closeButton, title, customClassName, showScrollbar }
|
||||
* @param {ModalProps} props { content, contentProps, shouldCloseOnEsc, isOpen, onClose, closeButton, title, customClassName, showScrollbar, noScroll }
|
||||
*/
|
||||
function _show({
|
||||
content = null,
|
||||
@ -41,7 +42,8 @@ function _show({
|
||||
title = null,
|
||||
fullscreen = false,
|
||||
customClassName = null,
|
||||
showScrollbar = false
|
||||
showScrollbar = false,
|
||||
noScroll = false,
|
||||
}) {
|
||||
return serviceImplementation._show({
|
||||
content,
|
||||
@ -53,7 +55,8 @@ function _show({
|
||||
title,
|
||||
fullscreen,
|
||||
customClassName,
|
||||
showScrollbar
|
||||
showScrollbar,
|
||||
noScroll,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -32,6 +32,10 @@
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
|
||||
&.noScroll &__content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&:not(.visibleScrollbar) &__content
|
||||
overflow-x: hidden;
|
||||
scrollbar-width: none;
|
||||
|
||||
@ -82,14 +82,20 @@ const ModalProvider = ({ children, modal: Modal, service }) => {
|
||||
shouldCloseOnEsc,
|
||||
fullscreen,
|
||||
closeButton,
|
||||
showScrollbar
|
||||
showScrollbar,
|
||||
noScroll,
|
||||
} = options;
|
||||
|
||||
return (
|
||||
<Provider value={{ show, hide }}>
|
||||
{ModalContent && (
|
||||
<Modal
|
||||
className={classNames(customClassName, ModalContent.className, { 'visibleScrollbar': showScrollbar })}
|
||||
className={classNames(
|
||||
customClassName,
|
||||
ModalContent.className,
|
||||
{ visibleScrollbar: showScrollbar },
|
||||
{ noScroll }
|
||||
)}
|
||||
shouldCloseOnEsc={shouldCloseOnEsc}
|
||||
isOpen={isOpen}
|
||||
title={title}
|
||||
|
||||
@ -28,7 +28,13 @@ class Range extends Component {
|
||||
className="range"
|
||||
/>
|
||||
{this.props.showPercentage && <span>{`${this.state.value}%`}</span>}
|
||||
{this.props.showValue && <span>{this.state.value}</span>}
|
||||
{this.props.showValue && (
|
||||
<span>
|
||||
{this.props.valueRenderer
|
||||
? this.props.valueRenderer(this.state.value)
|
||||
: this.state.value}
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -40,6 +46,7 @@ Range.propTypes = {
|
||||
max: PropTypes.number.isRequired,
|
||||
step: PropTypes.number,
|
||||
id: PropTypes.string,
|
||||
valueRenderer: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
showPercentage: PropTypes.bool,
|
||||
showValue: PropTypes.bool,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user