diff --git a/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/VolumetricViewer/VolumetricViewerWrapper.js b/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/VolumetricViewer/VolumetricViewerWrapper.js index 682b9bcba2..1bec1fe440 100644 --- a/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/VolumetricViewer/VolumetricViewerWrapper.js +++ b/packages/lib-classifier/src/components/Classifier/components/SubjectViewer/components/VolumetricViewer/VolumetricViewerWrapper.js @@ -22,7 +22,6 @@ function VolumetricViewerWrapper({ } const config = { - annotations: [], loadingState, onAnnotation: onAnnotationUpdate, onError, diff --git a/packages/lib-subject-viewers/src/VolumetricViewer/README.md b/packages/lib-subject-viewers/src/VolumetricViewer/README.md index fd3064522b..62bb7ef833 100644 --- a/packages/lib-subject-viewers/src/VolumetricViewer/README.md +++ b/packages/lib-subject-viewers/src/VolumetricViewer/README.md @@ -5,4 +5,4 @@ This directory holds all the relevant code for rendering the VolumetricViewer. T - `VolumetricViewerComponent` - a React component for the VolumetricViewer - `VolumetricViewerData` - a function that returns the data with instantiated models along with the React Component -NOTE: Webpack has trouble importing from a node_module package from dependent package chains (`lib-subject-viewers` => `lib-classifier` => `app-project`), therefore we have inlined `OrbitControls.js` file so that it works without Webpack issues. When updating the `three` dependency in `package.json` make sure to copy the file from `node_modules/three/examples/jsm/controls/OrbitControls.js` to `lib-subject-viewers/src/VolumetricViewer/helpers/OrbitControls.js`. \ No newline at end of file +NOTE: OrbitControls are typically imported as `import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'` but that syntax throws an error due to FEM not being pure ESM, therefore we have inlined `OrbitControls.js` file so that it works without bundling issues. When updating the `three` dependency in `package.json` make sure to copy the file from `node_modules/three/examples/jsm/controls/OrbitControls.js` to `lib-subject-viewers/src/VolumetricViewer/helpers/OrbitControls.js`. \ No newline at end of file diff --git a/packages/lib-subject-viewers/src/VolumetricViewer/components/ComponentViewer.js b/packages/lib-subject-viewers/src/VolumetricViewer/components/ComponentViewer.js index 4b60219c73..03788d279f 100644 --- a/packages/lib-subject-viewers/src/VolumetricViewer/components/ComponentViewer.js +++ b/packages/lib-subject-viewers/src/VolumetricViewer/components/ComponentViewer.js @@ -15,37 +15,73 @@ const StyledBox = styled(Box)` ` : css` background-color: #FFFFFF; + border: 1px solid #E2E5E9; color: #000000; ` } - border: 1px solid #E2E5E9; border-bottom-left-radius: 16px; border-top-left-radius: 16px; - max-width: 975px; width: 100%; - - .planes-container { - margin: 20px; - } .volume-container { background-color: #000000; - border-top-left-radius: 16px; - border-bottom-left-radius: 16px; - height: 590px; - padding: 25px; position: relative; - .volume-controls { - margin-top: 25px; - max-height: 60px; + .volume-cube { width: 100%; } + } - .volume-cube { - max-width: 430px; - width: 100%; + @media (width > 1325px) { + max-width: 975px; + + .planes-container { + margin: 20px; + } + + .volume-container { + height: 590px; + min-width: 330px; + padding: 20px; + + .volume-cube { + max-width: 460px; + } + + .volume-controls { + margin-top: 20px; + max-height: 60px; + width: 100%; + } + } + } + + @media (width <= 1325px) { + background: none; + border: none; + flex-direction: column-reverse; + max-width: 410px; + + .planes-container { + margin: 20px 0 20px 20px; + } + + .volume-container { + border-radius: 16px; + border-top-right-radius: 0; + margin: 0 0 0 20px; + width: 390px; + + .volume-cube { + max-width: 325px; + width: 100%; + } + + .volume-controls { + margin: 20px 0; + width: 90%; + } } } ` diff --git a/packages/lib-subject-viewers/src/VolumetricViewer/components/Cube.js b/packages/lib-subject-viewers/src/VolumetricViewer/components/Cube.js index a67dea3d9a..bf21e5b081 100644 --- a/packages/lib-subject-viewers/src/VolumetricViewer/components/Cube.js +++ b/packages/lib-subject-viewers/src/VolumetricViewer/components/Cube.js @@ -158,16 +158,16 @@ export const Cube = ({ annotations, tool, viewer }) => { const half = viewer.base / 2 const points = [ - [ + [ // Y [1, 1, -1], [-1, 1, -1], [-1, 1, 1] ], - [ + [ // Z [-1, 1, 1], [-1, -1, 1], [1, -1, 1] - ], + ], // X [ [1, -1, 1], [1, -1, -1], diff --git a/packages/lib-subject-viewers/src/VolumetricViewer/components/Histogram.js b/packages/lib-subject-viewers/src/VolumetricViewer/components/Histogram.js index 4e85beae00..f572d2dd88 100644 --- a/packages/lib-subject-viewers/src/VolumetricViewer/components/Histogram.js +++ b/packages/lib-subject-viewers/src/VolumetricViewer/components/Histogram.js @@ -7,7 +7,8 @@ import { useEffect, useState } from 'react' const StyledBox = styled(Box)` max-width: 195px; ` - +const HISTOGRAM_MIN = 5 +const HISTOGRAM_MAX = 255 const MAX_HEIGHT = 30 export const Histogram = ({ viewer }) => { @@ -71,9 +72,9 @@ export const Histogram = ({ viewer }) => { viewer.setThreshold({ min, max })} - valueMax={255} + valueMax={HISTOGRAM_MAX} valueMaxCurrent={viewer.threshold.max} - valueMin={0} + valueMin={HISTOGRAM_MIN} valueMinCurrent={viewer.threshold.min} /> diff --git a/packages/lib-subject-viewers/src/VolumetricViewer/components/Plane.js b/packages/lib-subject-viewers/src/VolumetricViewer/components/Plane.js index de8657d107..47aec8f4fe 100644 --- a/packages/lib-subject-viewers/src/VolumetricViewer/components/Plane.js +++ b/packages/lib-subject-viewers/src/VolumetricViewer/components/Plane.js @@ -63,11 +63,8 @@ const StyledBox = styled(Box)` .plane-title-frame { flex: 1; - - &.collapsed { - font-size: 16px !important; - line-height: 18.7px; - } + font-size: 16px !important; + line-height: 18.7px; } .plane-title-label { @@ -104,7 +101,8 @@ export const Plane = ({ tool, viewer }) => { - const [expanded, setExpanded] = useState(false) + // Default open the X/0 frame + const [expanded, setExpanded] = useState(dimension === 0) const [currentFrameIndex, setCurrentFrameIndex] = useState(0) const canvasRef = useRef(null) const containerRef = useRef(null) @@ -219,7 +217,7 @@ export const Plane = ({ {viewer.getDimensionLabel({ dimension })} - {currentFrameIndex} + {expanded ? currentFrameIndex : ' '} {expanded ? 'Collapse' : 'Expand'} diff --git a/packages/lib-subject-viewers/src/VolumetricViewer/components/Slider.js b/packages/lib-subject-viewers/src/VolumetricViewer/components/Slider.js index aaf0138761..bdf1d848b4 100644 --- a/packages/lib-subject-viewers/src/VolumetricViewer/components/Slider.js +++ b/packages/lib-subject-viewers/src/VolumetricViewer/components/Slider.js @@ -2,7 +2,7 @@ import { Box } from 'grommet' import { ForwardTen } from 'grommet-icons' import { number, object, string } from 'prop-types' import styled, { css, useTheme } from 'styled-components' -import { useState } from 'react' +import { useEffect, useState } from 'react' /* RAW SVG FOR SLIDER | Needs to be URL encoded to view const SVGSlider = ` @@ -65,13 +65,22 @@ const StyledSlider = styled(Box)` export const Slider = ({ dimension, viewer }) => { const [active, setActive] = useState(false) + useEffect(() => { + // if the advance-10 button is held, allow us to automatically advance the frame + const interval = setInterval(() => { + if (active) advanceFrame(); + }, 500); + + return () => clearInterval(interval); + }, [active]); + const theme = useTheme() const iconColor = (theme.dark) ? (active) ? '#FFFFFF' : '#FFFFFF' : (active) ? '#FFFFFF' : '#000000' function inChange (e) { - viewer.setPlaneFrameActive({ dimension, frame: e.target.value }) + viewer.setPlaneFrameActive({ dimension, frame: +e.target.value }) } function inMouseDown () { @@ -80,7 +89,10 @@ export const Slider = ({ dimension, viewer }) => { function inMouseUp () { setActive(false) + advanceFrame(); + } + function advanceFrame() { viewer.setPlaneFrameActive({ dimension, frame: (viewer.getPlaneFrameIndex({ dimension }) + 10) % viewer.base diff --git a/packages/lib-subject-viewers/src/VolumetricViewer/models/ModelViewer.js b/packages/lib-subject-viewers/src/VolumetricViewer/models/ModelViewer.js index 9c5534d2da..93947ad618 100644 --- a/packages/lib-subject-viewers/src/VolumetricViewer/models/ModelViewer.js +++ b/packages/lib-subject-viewers/src/VolumetricViewer/models/ModelViewer.js @@ -14,7 +14,7 @@ export const ModelViewer = () => { planesAbsoluteSets: [[], [], []], planeFrameActive: [0, 0, 0], points: [], - threshold: { min: 0, max: 255 }, + threshold: { min: 5, max: 255 }, // min of 5 cuts out missing data noise // initialize initialize: ({ data }) => { pointModel.data = Buffer.from(data, 'base64') diff --git a/packages/lib-subject-viewers/src/VolumetricViewer/tests/ModelViewer.spec.js b/packages/lib-subject-viewers/src/VolumetricViewer/tests/ModelViewer.spec.js index dc3ce92327..146be5b769 100644 --- a/packages/lib-subject-viewers/src/VolumetricViewer/tests/ModelViewer.spec.js +++ b/packages/lib-subject-viewers/src/VolumetricViewer/tests/ModelViewer.spec.js @@ -17,7 +17,7 @@ describe('Component > VolumetricViewer > ModelViewer', () => { expect(model.planesAbsoluteSets).deep.to.equal([[], [], []]) expect(model.planeFrameActive).deep.to.equal([0, 0, 0]) expect(model.points).deep.to.equal([]) - expect(model.threshold).deep.to.equal({ min: 0, max: 255 }) + expect(model.threshold).deep.to.equal({ min: 5, max: 255 }) expect(model._listeners.length).to.equal(0) }) @@ -69,7 +69,7 @@ describe('Component > VolumetricViewer > ModelViewer', () => { expect(pointAnnotationIndex).to.equal(-1) } - expect(model.threshold).deep.to.equal({ min: 0, max: 255 }) + expect(model.threshold).deep.to.equal({ min: 5, max: 255 }) expect(model._listeners.length).to.equal(0) })