Commit f193e1c2 authored by Lauri Himanen's avatar Lauri Himanen
Browse files

Added more efficient trajectory updates for the geometry optimization viewer.

parent dcc7bbcd
......@@ -72,23 +72,13 @@ function ElectronicStructureOverview({data, range, className, classes, raiseErro
// Synchronize panning between BS/DOS plots
const handleBSRelayouting = useCallback((event) => {
if (data.dos) {
let update = {
yaxis: {
autorange: false,
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
}
}
let update = {yaxis: {range: [event['yaxis.range[0]'], event['yaxis.range[1]']]}}
bsYSubject.next(update)
}
}, [data, bsYSubject])
const handleDOSRelayouting = useCallback((event) => {
if (data.bs) {
let update = {
yaxis: {
autorange: false,
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
}
}
let update = {yaxis: {range: [event['yaxis.range[0]'], event['yaxis.range[1]']]}}
dosYSubject.next(update)
}
}, [data, dosYSubject])
......
......@@ -15,7 +15,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useState, useCallback, useMemo } from 'react'
import React, { useCallback, useMemo } from 'react'
import { Subject } from 'rxjs'
import PropTypes from 'prop-types'
import {
Box,
......@@ -28,7 +29,8 @@ import { Structure } from '../visualization/Structure'
import { ErrorHandler, withErrorHandler } from '../ErrorHandler'
function GeoOptOverview({data, className, classes}) {
const [step, setStep] = useState(0)
// RxJS subject for efficiently propagating changes in structure information
const positionsSubject = useMemo(() => new Subject(), [])
// Styles
const useStyles = makeStyles((theme) => {
......@@ -129,8 +131,8 @@ function GeoOptOverview({data, className, classes}) {
// Handles hover event on the plot to update the currently shown structure
const handleHover = useCallback((event) => {
setStep(event.points[0].x)
}, [])
positionsSubject.next(data.structures[event.points[0].x].positions)
}, [data, positionsSubject])
return (
<Box className={style.root}>
......@@ -150,10 +152,11 @@ function GeoOptOverview({data, className, classes}) {
<Box className={style.structure}>
<Typography variant="subtitle1" align='center'>Optimization trajectory</Typography>
<Structure
system={data.structures[step]}
system={data.structures[0]}
aspectRatio={0.75}
options={{view: {fitMargin: 0.75}}}
positionsOnly={true}
positionsSubject={positionsSubject}
></Structure>
</Box>
</Box>
......
......@@ -289,7 +289,12 @@ Plot.propTypes = {
onRelayouting: PropTypes.func,
onHover: PropTypes.func,
onReset: PropTypes.func,
layoutSubject: PropTypes.any // A RxJS Subject for listening to layout changes
/**
* A RxJS Subject for efficient, non-persistent, layout changes that bypass
* rendering of the component. Should send messages that contain the new
* layout object.
*/
layoutSubject: PropTypes.any
}
Plot.defaultProps = {
aspectRatio: 9 / 16,
......
......@@ -47,7 +47,19 @@ import clsx from 'clsx'
* Used to show atomistic systems in an interactive 3D viewer based on the
* 'materia'-library.
*/
export const Structure = withErrorHandler(({className, classes, system, systems, options, viewer, captureName, aspectRatio, positionsOnly, sizeLimit}) => {
export const Structure = withErrorHandler(({
className,
classes,
system,
systems,
options,
viewer,
captureName,
aspectRatio,
positionsOnly,
sizeLimit,
positionsSubject}
) => {
// States
const [anchorEl, setAnchorEl] = React.useState(null)
const [fullscreen, setFullscreen] = useState(false)
......@@ -181,6 +193,11 @@ export const Structure = withErrorHandler(({className, classes, system, systems,
if (refCanvas.current) {
refViewer.current.changeHostElement(refCanvas.current, false, false)
}
if (positionsSubject && refViewer.current) {
positionsSubject.subscribe((positions) => {
refViewer.current.setPositions(positions)
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
......@@ -412,7 +429,6 @@ export const Structure = withErrorHandler(({className, classes, system, systems,
</Menu>
</div>
</Box>
return <Box className={clsx(styles.root, className)} >
<Floatable float={fullscreen} onFloat={toggleFullscreen} aspectRatio={aspectRatio}>
{content}
......@@ -430,7 +446,13 @@ Structure.propTypes = {
captureName: PropTypes.string, // Name of the file that the user can download
aspectRatio: PropTypes.number, // Fixed aspect ratio for the viewer canvas
positionsOnly: PropTypes.bool, // Whether to update only positions. This is much faster than loading the entire structure.
sizeLimit: PropTypes.number // Maximum system size before a prompt is shown
sizeLimit: PropTypes.number, // Maximum system size before a prompt is shown
/**
* A RxJS Subject for efficient, non-persistent, position changes that bypass
* rendering of the component. Should send messages that contain the new
* atomic positions as a list.
*/
positionsSubject: PropTypes.any
}
Structure.defaultProps = {
aspectRatio: 4 / 3,
......
......@@ -86,23 +86,13 @@ export default function VibrationalOverview({data, className, classes, raiseErro
// Synchronize panning between BS/DOS plots
const handleBSRelayouting = useCallback((event) => {
if (data.dos) {
let update = {
yaxis: {
autorange: false,
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
}
}
let update = {yaxis: {range: [event['yaxis.range[0]'], event['yaxis.range[1]']]}}
bsYSubject.next(update)
}
}, [data, bsYSubject])
const handleDOSRelayouting = useCallback((event) => {
if (data.bs) {
let update = {
yaxis: {
autorange: false,
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
}
}
let update = {yaxis: {range: [event['yaxis.range[0]'], event['yaxis.range[1]']]}}
dosYSubject.next(update)
}
}, [data, dosYSubject])
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment