Skip to content

Commit

Permalink
VV: UI + Design
Browse files Browse the repository at this point in the history
- Add 4, 8, 16, 32, and 64 example to Storybook
- Add Histogram range slider
- Add params to overall Viewer
- Fix scroll bug
- Inline OrbitControls import
- Incorporate Figma Styles
  • Loading branch information
kieftrav committed Dec 19, 2024
1 parent c9ecdc9 commit 69b6604
Show file tree
Hide file tree
Showing 23 changed files with 1,972 additions and 596 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@ function VolumetricViewerWrapper({
addAnnotation(activeStepTasks[0], annotations)
}

const config = {
annotations: [],
loadingState,
onAnnotation: onAnnotationUpdate,
onError,
onReady,
subject,
}

return <Suspense fallback={<p>Suspense boundary</p>}>
<VolumetricViewer
loadingState={loadingState}
onAnnotation={onAnnotationUpdate}
onError={onError}
onReady={onReady}
subject={subject}
/>
<VolumetricViewer {...config} />
</Suspense>
}

Expand Down
2 changes: 2 additions & 0 deletions packages/lib-subject-viewers/src/VolumetricViewer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ 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`.
Original file line number Diff line number Diff line change
Expand Up @@ -10,44 +10,51 @@ import asyncStates from '@zooniverse/async-states'
const DEFAULT_HANDLER = () => {}

export default function VolumetricViewer ({
// algorithm = 'a-star',
// annotations = [],
loadingState = asyncStates.initialized,
onAnnotation = DEFAULT_HANDLER,
onError = DEFAULT_HANDLER,
onReady = DEFAULT_HANDLER,
// showHistogram = true,
// showOrientation = true,
// showPlanes = true,
// showCube = true,
subject
// threshold = 15
}) {
const { data, loading, error } = useVolumetricSubject({ onError, onReady, subject })

const [modelState] = useState({
annotations: ModelAnnotations({ onAnnotation }),
tool: ModelTool(),
viewer: ModelViewer()
})
const isLoading = loadingState === asyncStates.initialized
|| loadingState === asyncStates.loading
|| loading;
const isError = loadingState === asyncStates.error
|| error
|| data === null;

const isLoading = loadingState === asyncStates.initialized ||
loadingState === asyncStates.loading ||
loading
const isError = loadingState === asyncStates.error ||
error ||
data === null

// Specs should skip rendering the VolumetricViewer component
// WebGL/Canvas throws exceptions when running specs due to non-browser environment
return (data === 'mock-subject-json')
? <div data-testid="subject-viewer-volumetric"></div>
? <div data-testid='subject-viewer-volumetric' />
: (isLoading)
? <p>Loading...</p>
: (isError)
? <p>Error</p>
: <ComponentViewer
data-testid="subject-viewer-volumetric"
config={{}}
data={data}
models={modelState}
/>
? <p>Loading...</p>
: (isError)
? <p>Error</p>
: <ComponentViewer
data-testid='subject-viewer-volumetric'
config={{}}
data={data}
models={modelState}
/>
}

export const VolumetricViewerData = ({
export const VolumetricViewerData = ({
onAnnotation = DEFAULT_HANDLER,
subjectData = '',
subjectUrl = ''
Expand All @@ -69,6 +76,7 @@ export const VolumetricViewerData = ({

VolumetricViewer.propTypes = {
loadingState: string,
onAnnotation: func,
onError: func,
onReady: func,
subject: object
Expand Down
Original file line number Diff line number Diff line change
@@ -1,60 +1,112 @@
import { object, string } from 'prop-types'
import styled, { css } from 'styled-components'
import { AlgorithmAStar } from './../helpers/AlgorithmAStar.js'
import { Box } from 'grommet'
import { Cube } from './Cube.js'
import { Histogram } from './Histogram.js'
import { Orientation } from './Orientation.js'
import { Plane } from './Plane.js'
import { Box } from 'grommet'

const StyledBox = styled(Box)`
${props => props.theme.dark
? css`
background-color: none;
color: #FFFFFF;
`
: css`
background-color: #FFFFFF;
color: #000000;
`
}
border: 1px solid #E2E5E9;
border-top-left-radius: 16px;
border-bottom-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-cube {
width: 100%;
max-width: 430px;
}
.volume-controls {
margin-top: 25px;
max-height: 60px;
width: 100%;
}
}
`

export const ComponentViewer = ({
data,
models
}) => {
// Initialize Annotations
if (models.annotations) {
models.annotations.initialize({
algorithm: AlgorithmAStar,
data: [], // will come from Caesar if they exist
viewer: models.viewer
})
}
models.annotations.initialize({
algorithm: AlgorithmAStar,
data: [], // will come from Caesar if they exist
viewer: models.viewer
})

// Initialize Tool
if (models.tool) {
models.tool.initialize({
annotations: models.annotations
})
}
models.tool.initialize({
annotations: models.annotations
})

// Initialize Viewer
if (models.viewer) {
models.viewer.initialize({
annotations: models.annotations,
data,
tool: models.tool
})
}
models.viewer.initialize({
annotations: models.annotations,
data,
tool: models.tool
})

return (
<Box direction='row' style={{ maxWidth: '800px', padding: '20px' }}>
<Box flex>
{models.viewer.dimensions.map((dimensionName, dimension) => {
return (
<Plane
<Box flex align="end">
<StyledBox direction='row'>
<Box className='planes-container'>
{models.viewer.dimensions.map((dimensionName, dimension) => {
return (
<Plane
annotations={models.annotations}
dimension={dimension}
key={`dimension-${dimensionName}`}
tool={models.tool}
viewer={models.viewer}
/>
)
})}
</Box>
<Box className='volume-container' flex align='center' justify='between'>
<Box className='volume-cube'>
<Cube
annotations={models.annotations}
tool={models.tool}
viewer={models.viewer}
/>
</Box>
<Box className='volume-controls' flex direction='row' justify='between'>
<Orientation />
<Histogram
annotations={models.annotations}
dimension={dimension}
key={`dimension-${dimensionName}`}
tool={models.tool}
viewer={models.viewer}
/>
)
})}
</Box>
<Box flex>
<Cube
annotations={models.annotations}
tool={models.tool}
viewer={models.viewer}
/>
</Box>
</Box>
</Box>
</StyledBox>
</Box>
)
}
Expand Down
Loading

0 comments on commit 69b6604

Please sign in to comment.