feat: Segmentations Settings UI - Phase 1 #1391 (#1392)

* Filter segs and fetch correct metadata.

* Initiate seg loading logic on series load into viewport. Need to write.

* Automatic consumption of SEG functional.

* Pull in master.

* Fix issues after pulling in master.

* Clean up old segmentation handlers.

* WIP

* WIP

* Poppulate viewport with metadata.

* Show hide/segmentation in react-vtkjs-viewport.

* feat: 🎸 View segmentations in vtkjs viewport

* Filter segs and fetch correct metadata.

* Initiate seg loading logic on series load into viewport. Need to write.

* Automatic consumption of SEG functional.

* Pull in master.

* Fix issues after pulling in master.

* Clean up old segmentation handlers.

* WIP

* WIP

* Poppulate viewport with metadata.

* Show hide/segmentation in react-vtkjs-viewport.

* feat: 🎸 View segmentations in vtkjs viewport

* Rebase on master.

* format format format

* add basic extension parts

* Updated yarn lock

* Fetch derived/referenced displaysets in sidepanel

* Add buttons, expose seriesDescription, write notes for Danny.

* Add growcut tool extention. -> Move to a seperate repo.

* Change some text fields.

* expose dialog provider

* hide draggable area

* No pointer events for now; need to revisit

* Don't filter seg from the outset for now

* fiddling about

* fix path to series data

* fix logic to determine next available labelmapindex

* Ability to swtich between labelmaps

* Return a promise so we can make sure our labelmap is loaded before pulling metadata

* Better UI to toggle labelmaps

* Fix accidental untoggle of active labelmap for ui

* Remove brush tool from cornerstone extension

* Add cstools in preInit for seg extension

* Add buttons for seg magic

* Hide the measurements panel for now

* Slightly better seg/scissor icons

* Add eraser

* ability to switch segments

* seg color / switcher

* Fix vtk labelmap cache.

* sidepanel should scroll if there's overflow

* Use a fancier range slider

* Slightly prettier buttons

* Push in progress

* A bit more reactive; handle no-meta

* Update to vtk.js 11.14.0 and react-vtkjs-viewport 0.6.0

* chore: kickstart preview

* Fix conflict issues

* Refactor panel

* Isolate increment functions

* Wip segment table

* Hide selector and add scroll to segmentation

* Increase width of segment description

* Hide not used items

* Add new select for segmentations

* Align ui

* Fix default segmentation

* Fix broken import test

* Get measurements panel back and add spacing to grouped buttons

* Hide brush and selector and refresh when switching segmentations

* Add pointer events back and fix broken tests for measurement table

* Update segment list when switching humbnails

* CR Update: Minor UI adjustments

* CR Update: Set active segment

* Move components to components folder

* Add new settings ui

* Integrate configuration

* Improve styles

* Float numbers

* Improve css

* Refresh settings menu if side panel changed

* Fix settings rendering logic and remove comments

* Extract components

* Remove not used tools

* Remove non used extension

* Use style variables and remove comments

* Remove non used dep from lock

* Remove tools

* Remove segmentation from toolbar

* Add todo and brushradius from config

* Fix packagejson growcut import

* Remove webpack config already defined in parent

* Update package json description

* Change component name to british english to us

* Improve prop types

* Rename cornerstone label map event

* Scope css

* Extract and add doc to helper

* Update jsdocs for getDerivedDatasets

* Add proptypes and cr updates

* Update tablistitem proptypes

* config is readonly, rollback destructuring

* Remove event for side panel

* Add jsdocs for util

* Extract getimageid to studymetada

* Use ohif log instead of console

* Remove specific style from side panel

* Fix default props for brush radius

* Descructure configuration props from settings component to avoid invalid props

* Update proptypes to be required (settings)

* Update readme

* Remove commandsmodule

* Get configuration module inside the component

* Set selected segment

* Rename extension and use modality to filter

* Fix for failing tests (#1423)

* hello world

* Finish rebase for Igor.

* Re-fix cornerstoneTools version that got messed up in merge.

* Fix reactivity of isDisabled, write implementation for the SEG panel.

* Nuke yarn.lock to stack CST to 4.12.0

* Remove debugger statements.

* fix: bump cornerstone-tools version to address toFixed issue

* test: force tests for MISTER^MR to navigate to study directly

* test: remove eraser tool test

* test: count is off by one

* test: don't save SR state for the time being

* test: disable more tests

Co-authored-by: James A. Petts <jamesapetts@gmail.com>
Co-authored-by: dannyrb <danny.ri.brown@gmail.com>
Co-authored-by: igoroctaviano] <igoroctaviano@users.noreply.github.com>
Co-authored-by: Mirna Silva <mirna.silva@radicalimaging.com>
This commit is contained in:
authored and GitHub committed 2020-03-13 15:45:26 -04:00
1 parent d426b78967
commit e8842cf8ae
78 files changed
+3071 -1962

No files matched your search

@@ -1,6 +1,5 @@
.RoundedButtonGroup {
--height: 25px;
position: relative;
z-index: 0;
}
@@ -37,12 +36,7 @@
z-index: 1;
}
.roundedButtonWrapper
.roundedButton
svg
.roundedButtonWrapper
.roundedButton
span {
.roundedButtonWrapper .roundedButton svg .roundedButtonWrapper .roundedButton span {
margin: 0 2px;
}
@@ -51,6 +45,10 @@
font-size: 15px;
}
.roundedButtonWrapper .bottomLabel {
padding: 0 10px 0 10px;
}
.bottomLabel {
color: var(--text-secondary-color);
font-size: 12px;
@@ -79,14 +79,14 @@ function ImageThumbnail(props) {
return () => {
purgeCancelablePromise();
};
}, []);
}, [purgeCancelablePromise]);
useEffect(() => {
if (image.imageId) {
cornerstone.renderToCanvas(canvasRef.current, image);
setLoading(false);
}
}, [image.imageId]);
}, [canvasRef, image, image.imageId]);
useEffect(() => {
if (!image.imageId || image.imageId !== imageId) {
@@ -94,7 +94,7 @@ function ImageThumbnail(props) {
setImagePromise();
fetchImagePromise();
}
}, [imageId]);
}, [fetchImagePromise, image.imageId, imageId, purgeCancelablePromise, setImagePromise]);
return (
<div className="ImageThumbnail">
@@ -10,6 +10,8 @@ export class TableListItem extends Component {
children: PropTypes.node,
itemClass: PropTypes.string,
itemIndex: PropTypes.number,
itemMeta: PropTypes.node,
itemMetaClass: PropTypes.string,
itemKey: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
@@ -17,14 +19,20 @@ export class TableListItem extends Component {
onItemClick: PropTypes.func.isRequired,
};
static defaultProps = {
itemMeta: null,
itemMetaClass: ''
};
render() {
return (
<div
className={`tableListItem ${this.props.itemClass}`}
onClick={this.onItemClick}
>
<div className="itemIndex">
<div className={`itemIndex ${this.props.itemMetaClass}`}>
{this.props.itemIndex}
{this.props.itemMeta}
<span className="warning-icon">
<Icon name="exclamation-triangle" />
</span>
+6
View File
@@ -9,6 +9,7 @@ import arrowsAltH from './icons/arrows-alt-h.svg';
import arrowsAltV from './icons/arrows-alt-v.svg';
import bars from './icons/bars.svg';
import brain from './icons/brain.svg';
import brush from './icons/brush.svg';
import caretDown from './icons/caret-down.svg';
import caretUp from './icons/caret-up.svg';
import check from './icons/check.svg';
@@ -63,12 +64,14 @@ import reset from './icons/reset.svg';
import rotate from './icons/rotate.svg';
import rotateRight from './icons/rotate-right.svg';
import saveRegular from './icons/save-regular.svg';
import scissors from './icons/scissors.svg';
import search from './icons/search.svg';
import searchPlus from './icons/search-plus.svg';
import softTissue from './icons/soft-tissue.svg';
import sort from './icons/sort.svg';
import sortDown from './icons/sort-down.svg';
import sortUp from './icons/sort-up.svg';
import sphere from './icons/sphere.svg';
import squareO from './icons/square-o.svg';
import star from './icons/star.svg';
import stepBackward from './icons/step-backward.svg';
@@ -84,11 +87,14 @@ import user from './icons/user.svg';
import youtube from './icons/youtube.svg';
const ICONS = {
brush,
scissors,
user,
sort,
th,
star,
'sort-up': sortUp,
sphere,
'sort-down': sortDown,
info,
cube,
@@ -0,0 +1,11 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
aria-labelledby="title"
width="1em"
height="1em"
fill="currentColor"
>
<title id="title">Brush</title>
<path d="M167.02 309.34c-40.12 2.58-76.53 17.86-97.19 72.3-2.35 6.21-8 9.98-14.59 9.98-11.11 0-45.46-27.67-55.25-34.35C0 439.62 37.93 512 128 512c75.86 0 128-43.77 128-120.19 0-3.11-.65-6.08-.97-9.13l-88.01-73.34zM457.89 0c-15.16 0-29.37 6.71-40.21 16.45C213.27 199.05 192 203.34 192 257.09c0 13.7 3.25 26.76 8.73 38.7l63.82 53.18c7.21 1.8 14.64 3.03 22.39 3.03 62.11 0 98.11-45.47 211.16-256.46 7.38-14.35 13.9-29.85 13.9-45.99C512 20.64 486 0 457.89 0z"/>
</svg>

After

Width:  |  Height:  |  Size: 646 B

@@ -0,0 +1,11 @@
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"
aria-labelby="title"
width="1em"
height="1em"
fill="currentColor"
>
<title id="title">Scissors</title>
<path d="M278.06 256L444.48 89.57c4.69-4.69 4.69-12.29 0-16.97-32.8-32.8-85.99-32.8-118.79 0L210.18 188.12l-24.86-24.86c4.31-10.92 6.68-22.81 6.68-35.26 0-53.02-42.98-96-96-96S0 74.98 0 128s42.98 96 96 96c4.54 0 8.99-.32 13.36-.93L142.29 256l-32.93 32.93c-4.37-.61-8.83-.93-13.36-.93-53.02 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96c0-12.45-2.37-24.34-6.68-35.26l24.86-24.86L325.69 439.4c32.8 32.8 85.99 32.8 118.79 0 4.69-4.68 4.69-12.28 0-16.97L278.06 256zM96 160c-17.64 0-32-14.36-32-32s14.36-32 32-32 32 14.36 32 32-14.36 32-32 32zm0 256c-17.64 0-32-14.36-32-32s14.36-32 32-32 32 14.36 32 32-14.36 32-32 32z"/>
</svg>

After

Width:  |  Height:  |  Size: 807 B

@@ -0,0 +1,21 @@
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 512 512"
aria-labelby="title"
width="1em"
height="1em"
fill="currentColor"
>
<title id="title">Sphere</title>
<path d="M256,0C114.837,0,0,114.837,0,256s114.837,256,256,256s256-114.837,256-256S397.163,0,256,0z M256,21.333
c129.387,0,234.667,105.28,234.667,234.667c0,40.363-96.384,85.333-234.667,85.333c-28.629,0-55.339-2.005-79.893-5.44
c-3.435-24.555-5.44-51.264-5.44-79.893C170.667,117.717,215.637,21.333,256,21.333z M208.512,26.176
C173.184,67.435,149.333,153.707,149.333,256c0,26.688,1.621,52.309,4.651,76.309C72.683,317.205,21.333,285.419,21.333,256
C21.333,142.869,101.824,48.192,208.512,26.176z M26.176,303.488c27.072,23.168,73.429,41.429,131.136,51.2
c9.792,57.707,28.032,104.064,51.2,131.136C117.163,466.965,45.035,394.837,26.176,303.488z M256,490.667
c-29.419,0-61.205-51.349-76.309-132.651c24,3.029,49.621,4.651,76.309,4.651c102.293,0,188.565-23.851,229.824-59.179
C463.808,410.176,369.131,490.667,256,490.667z"/>
</svg>
<!-- style="enable-background:new 0 0 512 512;" xml:space="preserve" -->

After

Width:  |  Height:  |  Size: 1.1 KiB

+24 -12
View File
@@ -3,10 +3,10 @@ import './Range.css';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class Range extends React.Component {
class Range extends Component {
constructor(props) {
super(props);
this.state = { value: props.value };
this.state = { value: props.value || 0 };
}
handleChange = event => {
@@ -16,16 +16,20 @@ class Range extends React.Component {
render() {
return (
<input
type="range"
value={this.state.value}
min={this.props.min}
max={this.props.max}
step={this.props.step || 1}
onChange={this.handleChange}
id={this.props.id}
className="range"
/>
<>
<input
type="range"
value={this.state.value}
min={this.props.min}
max={this.props.max}
step={this.props.step || 1}
onChange={this.handleChange}
id={this.props.id}
className="range"
/>
{this.props.showPercentage && <span>{`${this.state.value}%`}</span>}
{this.props.showValue && <span>{this.state.value}</span>}
</>
);
}
}
@@ -34,8 +38,16 @@ Range.propTypes = {
value: PropTypes.number,
min: PropTypes.number.isRequired,
max: PropTypes.number.isRequired,
step: PropTypes.number,
id: PropTypes.string,
onChange: PropTypes.func,
showPercentage: PropTypes.bool,
showValue: PropTypes.bool,
};
Range.defaultProps = {
showPercentage: false,
showValue: false,
};
export { Range };