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

Enabled direct communication for layout changes between plots by using RxJS subjects.

parent 36e75eca
Pipeline #93097 passed with stages
in 35 minutes and 48 seconds
......@@ -27,7 +27,7 @@ import Plot from '../visualization/Plot'
import { convertSI, distance, mergeObjects } from '../../utils'
import { withErrorHandler } from '../ErrorHandler'
function BandStructure({data, layout, aspectRatio, className, classes, onRelayout, onAfterPlot, onRedraw, onRelayouting, onReset, unitsState}) {
function BandStructure({data, layout, aspectRatio, className, classes, unitsState, ...other}) {
const [finalData, setFinalData] = useState(undefined)
const [pathSegments, setPathSegments] = useState(undefined)
const units = useRecoilValue(unitsState)
......@@ -246,11 +246,7 @@ function BandStructure({data, layout, aspectRatio, className, classes, onRelayou
layout={finalLayout}
aspectRatio={aspectRatio}
floatTitle={'Band structure'}
onRelayout={onRelayout}
onAfterPlot={onAfterPlot}
onRedraw={onRedraw}
onRelayouting={onRelayouting}
onReset={onReset}
{...other}
>
</Plot>
</Box>
......@@ -263,11 +259,6 @@ BandStructure.propTypes = {
aspectRatio: PropTypes.number,
classes: PropTypes.object,
className: PropTypes.string,
onAfterPlot: PropTypes.func,
onRedraw: PropTypes.func,
onRelayout: PropTypes.func,
onRelayouting: PropTypes.func,
onReset: PropTypes.func,
unitsState: PropTypes.object // Recoil atom containing the unit configuration
}
......
......@@ -27,7 +27,7 @@ import Plot from '../visualization/Plot'
import { convertSI, convertSILabel, mergeObjects } from '../../utils'
import { withErrorHandler } from '../ErrorHandler'
function DOS({data, layout, resetLayout, aspectRatio, className, classes, onRelayout, onAfterPlot, onRedraw, onRelayouting, onReset, unitsState}) {
function DOS({data, layout, resetLayout, aspectRatio, className, classes, unitsState, ...other}) {
const [finalData, setFinalData] = useState(undefined)
const units = useRecoilValue(unitsState)
......@@ -128,11 +128,7 @@ function DOS({data, layout, resetLayout, aspectRatio, className, classes, onRela
resetLayout={resetLayout}
aspectRatio={aspectRatio}
floatTitle="Density of states"
onRelayout={onRelayout}
onAfterPlot={onAfterPlot}
onRedraw={onRedraw}
onRelayouting={onRelayouting}
onReset={onReset}
{...other}
>
</Plot>
</Box>
......@@ -146,11 +142,6 @@ DOS.propTypes = {
aspectRatio: PropTypes.number,
classes: PropTypes.object,
className: PropTypes.string,
onAfterPlot: PropTypes.func,
onRedraw: PropTypes.func,
onRelayout: PropTypes.func,
onRelayouting: PropTypes.func,
onReset: PropTypes.func,
unitsState: PropTypes.object // Recoil atom containing the unit configuration
}
......
......@@ -15,7 +15,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useState, useCallback } from 'react'
import React, { useState, useCallback, useMemo } from 'react'
import { Subject } from 'rxjs'
import PropTypes from 'prop-types'
import {
Box,
......@@ -39,6 +40,10 @@ function ElectronicStructureOverview({data, range, className, classes, raiseErro
yaxis: {range: range}
})
// RxJS subject for efficiently propagating y axis changes between DOS and BS
const bsYSubject = useMemo(() => new Subject(), [])
const dosYSubject = useMemo(() => new Subject(), [])
// Styles
const useStyles = makeStyles((theme) => {
return {
......@@ -73,9 +78,9 @@ function ElectronicStructureOverview({data, range, className, classes, raiseErro
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
}
}
setDosLayout(update)
bsYSubject.next(update)
}
}, [data])
}, [data, bsYSubject])
const handleDOSRelayouting = useCallback((event) => {
if (data.bs) {
let update = {
......@@ -84,9 +89,9 @@ function ElectronicStructureOverview({data, range, className, classes, raiseErro
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
}
}
setBsLayout(update)
dosYSubject.next(update)
}
}, [data])
}, [data, dosYSubject])
return (
<RecoilRoot>
......@@ -101,6 +106,7 @@ function ElectronicStructureOverview({data, range, className, classes, raiseErro
unitsState={unitsState}
onRelayouting={handleBSRelayouting}
onReset={() => { setDosLayout({yaxis: {range: range}}) }}
layoutSubject={dosYSubject}
></BandStructure>
: <NoData aspectRatio={1.2}/>
}
......@@ -115,6 +121,7 @@ function ElectronicStructureOverview({data, range, className, classes, raiseErro
onRelayouting={handleDOSRelayouting}
onReset={() => { setBsLayout({yaxis: {range: range}}) }}
unitsState={unitsState}
layoutSubject={bsYSubject}
></DOS>
: <NoData aspectRatio={0.6}/>
}
......
......@@ -37,7 +37,7 @@ import Plotly from 'plotly.js-cartesian-dist-min'
import clsx from 'clsx'
import { mergeObjects } from '../../utils'
export default function Plot({data, layout, config, floatTitle, capture, aspectRatio, className, classes, onRelayout, onAfterPlot, onRedraw, onRelayouting, onHover, onReset}) {
export default function Plot({data, layout, config, floatTitle, capture, aspectRatio, className, classes, onRelayout, onAfterPlot, onRedraw, onRelayouting, onHover, onReset, layoutSubject}) {
// States
const [float, setFloat] = useState(false)
const [captureSettings, setCaptureSettings] = useState()
......@@ -206,6 +206,14 @@ export default function Plot({data, layout, config, floatTitle, capture, aspectR
node.on('plotly_hover', onHover)
}
// Subscribe to the layout change publisher if one is given
if (layoutSubject) {
layoutSubject.subscribe(layout => {
let oldLayout = canvasRef.current.layout
Plotly.relayout(canvasRef.current, mergeObjects(layout, oldLayout))
})
}
// Update canvas element
canvasRef.current = node
// eslint-disable-next-line react-hooks/exhaustive-deps
......@@ -280,7 +288,8 @@ Plot.propTypes = {
onRedraw: PropTypes.func,
onRelayouting: PropTypes.func,
onHover: PropTypes.func,
onReset: PropTypes.func
onReset: PropTypes.func,
layoutSubject: PropTypes.any // A RxJS Subject for listening to layout changes
}
Plot.defaultProps = {
aspectRatio: 9 / 16,
......
......@@ -17,7 +17,7 @@
*/
import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react'
import PropTypes from 'prop-types'
import { makeStyles } from '@material-ui/core/styles'
import { makeStyles, fade } from '@material-ui/core/styles'
import {
Box,
Checkbox,
......@@ -88,7 +88,12 @@ export const Structure = withErrorHandler(({className, classes, system, systems,
height: '2rem'
},
toggle: {
color: theme.palette.action.active
color: fade(theme.palette.action.active, 0.87)
},
selected: {
'&$selected': {
color: fade(theme.palette.action.active, 0.87)
}
},
title: {
marginBottom: theme.spacing(1)
......@@ -291,7 +296,12 @@ export const Structure = withErrorHandler(({className, classes, system, systems,
if (systems) {
const toggles = []
for (let key in systems) {
toggles.push(<ToggleButton key={key} value={key} aria-label={key} classes={{root: styles.toggle}}>{key}</ToggleButton>)
toggles.push(<ToggleButton
key={key}
value={key}
aria-label={key}
classes={{root: styles.toggle, selected: styles.selected}}
>{key}</ToggleButton>)
}
return toggles
}
......
......@@ -17,6 +17,7 @@
*/
import React, { useState, useCallback, useMemo } from 'react'
import PropTypes from 'prop-types'
import { Subject } from 'rxjs'
import {
Box,
Typography,
......@@ -50,6 +51,10 @@ export default function VibrationalOverview({data, className, classes, raiseErro
const [dosLayout, setDosLayout] = useState({yaxis: {range: range}})
const [bsLayout, setBsLayout] = useState({yaxis: {range: range}})
// RxJS subject for efficiently propagating y axis changes between DOS and BS
const bsYSubject = useMemo(() => new Subject(), [])
const dosYSubject = useMemo(() => new Subject(), [])
// Styles
const useStyles = makeStyles((theme) => {
return {
......@@ -87,9 +92,9 @@ export default function VibrationalOverview({data, className, classes, raiseErro
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
}
}
setDosLayout(update)
bsYSubject.next(update)
}
}, [data])
}, [data, bsYSubject])
const handleDOSRelayouting = useCallback((event) => {
if (data.bs) {
let update = {
......@@ -98,9 +103,9 @@ export default function VibrationalOverview({data, className, classes, raiseErro
range: [event['yaxis.range[0]'], event['yaxis.range[1]']]
}
}
setBsLayout(update)
dosYSubject.next(update)
}
}, [data])
}, [data, dosYSubject])
const theme = useTheme()
const heatCapacityData = useMemo(() => {
......@@ -170,6 +175,7 @@ export default function VibrationalOverview({data, className, classes, raiseErro
unitsState={unitsState}
onRelayouting={handleBSRelayouting}
onReset={() => { setDosLayout({yaxis: {range: range}}) }}
layoutSubject={dosYSubject}
></BandStructure>
: <Placeholder className={null} aspectRatio={1.1} variant="rect"></Placeholder>
}
......@@ -187,6 +193,7 @@ export default function VibrationalOverview({data, className, classes, raiseErro
onRelayouting={handleDOSRelayouting}
onReset={() => { setBsLayout({yaxis: {range: range}}) }}
unitsState={unitsState}
layoutSubject={bsYSubject}
></DOS>
: <Placeholder className={null} aspectRatio={1.1} variant="rect"></Placeholder>
}
......
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