Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
nomad-lab
nomad-FAIR
Commits
599f5819
Commit
599f5819
authored
Feb 11, 2021
by
Markus Scheidgen
Browse files
Merge branch 'overview-alternative' into 'v0.10.0'
Overview improvements See merge request
!260
parents
f2369025
00edbd00
Pipeline
#93273
passed with stages
in 35 minutes and 46 seconds
Changes
9
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
gui/src/components/dft/DFTEntryOverview.js
View file @
599f5819
...
...
@@ -23,6 +23,7 @@ import ElectronicStructureOverview from '../visualization/ElectronicStructureOve
import
VibrationalOverview
from
'
../visualization/VibrationalOverview
'
import
{
ApiDialog
}
from
'
../ApiDialogButton
'
import
{
Structure
}
from
'
../visualization/Structure
'
import
NoData
from
'
../visualization/NoData
'
import
Actions
from
'
../Actions
'
import
Quantity
from
'
../Quantity
'
import
{
RecoilRoot
}
from
'
recoil
'
...
...
@@ -169,32 +170,40 @@ export default function DFTEntryOverview({data}) {
const
section_run
=
archive
.
section_run
[
0
]
let
section_method
=
null
const
sccs
=
section_run
.
section_single_configuration_calculation
for
(
let
i
=
sccs
.
length
-
1
;
i
>
-
1
;
--
i
)
{
const
scc
=
sccs
[
i
]
if
(
!
e_dos
&&
scc
.
section_dos
)
{
if
(
scc
.
section_dos
[
scc
.
section_dos
.
length
-
1
].
dos_kind
!==
'
vibrational
'
)
{
e_dos
=
{
'
section_system
'
:
scc
.
single_configuration_calculation_to_system_ref
,
'
section_method
'
:
scc
.
single_configuration_calculation_to_system_ref
,
'
section_dos
'
:
scc
.
section_dos
[
scc
.
section_dos
.
length
-
1
]
if
(
sccs
)
{
for
(
let
i
=
sccs
.
length
-
1
;
i
>
-
1
;
--
i
)
{
const
scc
=
sccs
[
i
]
if
(
!
e_dos
&&
scc
.
section_dos
)
{
const
first_dos
=
scc
.
section_dos
[
scc
.
section_dos
.
length
-
1
]
if
(
!
_
.
isEmpty
(
first_dos
))
{
if
(
first_dos
.
dos_kind
!==
'
vibrational
'
)
{
e_dos
=
{
'
section_system
'
:
scc
.
single_configuration_calculation_to_system_ref
,
'
section_method
'
:
scc
.
single_configuration_calculation_to_system_ref
,
'
section_dos
'
:
scc
.
section_dos
[
scc
.
section_dos
.
length
-
1
]
}
}
}
}
}
if
(
!
e_bs
&&
scc
.
section_k_band
)
{
if
(
scc
.
section_k_band
[
scc
.
section_k_band
.
length
-
1
].
band_structure_kind
!==
'
vibrational
'
)
{
e_bs
=
{
'
section_system
'
:
scc
.
single_configuration_calculation_to_system_ref
,
'
section_method
'
:
scc
.
single_configuration_calculation_to_system_ref
,
'
section_k_band
'
:
scc
.
section_k_band
[
scc
.
section_k_band
.
length
-
1
]
if
(
!
e_bs
&&
scc
.
section_k_band
)
{
const
first_band
=
scc
.
section_k_band
[
scc
.
section_k_band
.
length
-
1
]
if
(
!
_
.
isEmpty
(
first_band
))
{
if
(
first_band
.
band_structure_kind
!==
'
vibrational
'
)
{
e_bs
=
{
'
section_system
'
:
scc
.
single_configuration_calculation_to_system_ref
,
'
section_method
'
:
scc
.
single_configuration_calculation_to_system_ref
,
'
section_k_band
'
:
scc
.
section_k_band
[
scc
.
section_k_band
.
length
-
1
]
}
}
}
}
}
if
(
section_method
!==
false
)
{
let
iMethod
=
scc
.
single_configuration_to_calculation_method_ref
if
(
section_method
=
==
null
)
{
section_method
=
iM
ethod
}
else
if
(
iMethod
!==
section_method
)
{
section_method
=
false
if
(
section_method
!==
false
)
{
let
iMethod
=
scc
.
single_configuration_to_calculation_method_ref
if
(
section_method
===
null
)
{
section_method
=
iMethod
}
else
if
(
iMethod
!==
section_m
ethod
)
{
section_method
=
false
}
}
}
}
...
...
@@ -295,9 +304,17 @@ export default function DFTEntryOverview({data}) {
}
// Get method details. Any referenced core_setttings will also be taken
// into account
// into account. If there were no SCCs from which the method could be
// selected, simply select the last available method.
if
(
section_method
)
{
section_method
=
resolveRef
(
section_method
,
archive
)
}
else
{
const
methods
=
section_run
.
section_method
if
(
methods
)
{
section_method
=
methods
[
methods
.
length
-
1
]
}
}
if
(
section_method
)
{
const
refs
=
section_method
?.
section_method_to_method_refs
if
(
refs
)
{
for
(
const
ref
of
refs
)
{
...
...
@@ -321,17 +338,19 @@ export default function DFTEntryOverview({data}) {
// Get the representative system by looping over systems
let
reprSys
=
null
const
systems
=
section_run
.
section_system
for
(
let
i
=
systems
.
length
-
1
;
i
>
-
1
;
--
i
)
{
const
sys
=
systems
[
i
]
if
(
!
reprSys
&&
sys
.
is_representative
)
{
const
reprSys
=
{
'
species
'
:
sys
.
atom_species
,
'
cell
'
:
sys
.
lattice_vectors
?
convertSI
(
sys
.
lattice_vectors
,
'
meter
'
,
{
length
:
'
angstrom
'
},
false
)
:
undefined
,
'
positions
'
:
convertSI
(
sys
.
atom_positions
,
'
meter
'
,
{
length
:
'
angstrom
'
},
false
),
'
pbc
'
:
sys
.
configuration_periodic_dimensions
if
(
systems
)
{
for
(
let
i
=
systems
.
length
-
1
;
i
>
-
1
;
--
i
)
{
const
sys
=
systems
[
i
]
if
(
!
reprSys
&&
sys
.
is_representative
)
{
const
reprSys
=
{
'
species
'
:
sys
.
atom_species
,
'
cell
'
:
sys
.
lattice_vectors
?
convertSI
(
sys
.
lattice_vectors
,
'
meter
'
,
{
length
:
'
angstrom
'
},
false
)
:
undefined
,
'
positions
'
:
convertSI
(
sys
.
atom_positions
,
'
meter
'
,
{
length
:
'
angstrom
'
},
false
),
'
pbc
'
:
sys
.
configuration_periodic_dimensions
}
structs
.
original
=
reprSys
break
}
structs
.
original
=
reprSys
break
}
}
...
...
@@ -363,13 +382,7 @@ export default function DFTEntryOverview({data}) {
// Figure out which actions are available for this entry
const
actions
=
useMemo
(()
=>
{
const
buttons
=
[
{
tooltip
:
'
Show the API access code
'
,
onClick
:
(
event
)
=>
{
setShowAPIDialog
(
!
showAPIDialog
)
},
content
:
'
API access
'
}
]
const
buttons
=
[]
if
(
encyclopediaEnabled
&&
data
?.
encyclopedia
?.
material
?.
material_id
)
{
buttons
.
push
(
{
...
...
@@ -379,6 +392,13 @@ export default function DFTEntryOverview({data}) {
}
)
}
buttons
.
push
(
{
tooltip
:
'
Show the API access code
'
,
onClick
:
(
event
)
=>
{
setShowAPIDialog
(
!
showAPIDialog
)
},
content
:
'
API access
'
}
)
return
buttons
},
[
data
,
showAPIDialog
])
...
...
@@ -489,7 +509,10 @@ export default function DFTEntryOverview({data}) {
<
/Box
>
<
/Grid
>
<
Grid
item
xs
=
{
7
}
style
=
{{
marginTop
:
'
-2rem
'
}}
>
<
Structure
systems
=
{
structures
}
aspectRatio
=
{
1.5
}
/
>
{(
loading
||
!
_
.
isEmpty
(
structures
))
?
<
Structure
systems
=
{
structures
}
materialType
=
{
data
?.
dft
?.
system
}
aspectRatio
=
{
1.5
}
/
>
:
<
NoData
aspectRatio
=
{
1.5
}
/
>
}
<
/Grid
>
<
/Grid
>
<
/PropertyCard
>
...
...
gui/src/components/visualization/BandStructure.js
View file @
599f5819
...
...
@@ -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
}
...
...
gui/src/components/visualization/DOS.js
View file @
599f5819
...
...
@@ -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
}
...
...
gui/src/components/visualization/ElectronicStructureOverview.js
View file @
599f5819
...
...
@@ -15,13 +15,15 @@
* 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
,
Typography
}
from
'
@material-ui/core
'
import
DOS
from
'
./DOS
'
import
NoData
from
'
./NoData
'
import
BandStructure
from
'
./BandStructure
'
import
BrillouinZone
from
'
./BrillouinZone
'
import
{
RecoilRoot
}
from
'
recoil
'
...
...
@@ -38,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
{
...
...
@@ -45,7 +51,7 @@ function ElectronicStructureOverview({data, range, className, classes, raiseErro
display
:
'
flex
'
,
flexDirection
:
'
row
'
,
justifyContent
:
'
flex-start
'
,
alignItems
:
'
center
'
,
alignItems
:
'
flex-start
'
,
width
:
'
100%
'
,
height
:
'
100%
'
,
flexWrap
:
'
wrap
'
...
...
@@ -66,58 +72,50 @@ 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]
'
]]
}
}
setDosLayout
(
update
)
let
update
=
{
yaxis
:
{
range
:
[
event
[
'
yaxis.range[0]
'
],
event
[
'
yaxis.range[1]
'
]]}}
bsYSubject
.
next
(
update
)
}
},
[
data
])
},
[
data
,
bsYSubject
])
const
handleDOSRelayouting
=
useCallback
((
event
)
=>
{
if
(
data
.
bs
)
{
let
update
=
{
yaxis
:
{
autorange
:
false
,
range
:
[
event
[
'
yaxis.range[0]
'
],
event
[
'
yaxis.range[1]
'
]]
}
}
setBsLayout
(
update
)
let
update
=
{
yaxis
:
{
range
:
[
event
[
'
yaxis.range[0]
'
],
event
[
'
yaxis.range[1]
'
]]}}
dosYSubject
.
next
(
update
)
}
},
[
data
])
},
[
data
,
dosYSubject
])
return
(
<
RecoilRoot
>
<
Box
className
=
{
style
.
row
}
>
{
data
.
bs
?
<
Box
className
=
{
style
.
bs
}
>
<
Typography
variant
=
"
subtitle1
"
align
=
'
center
'
>
Band
structure
<
/Typography
>
<
BandStructure
<
Box
className
=
{
style
.
bs
}
>
<
Typography
variant
=
"
subtitle1
"
align
=
'
center
'
>
Band
structure
<
/Typography
>
{
data
.
bs
?
<
BandStructure
data
=
{
data
?.
bs
?.
section_k_band
}
layout
=
{
bsLayout
}
aspectRatio
=
{
1.2
}
unitsState
=
{
unitsState
}
onRelayouting
=
{
handleBSRelayouting
}
onReset
=
{()
=>
{
setDosLayout
({
yaxis
:
{
range
:
range
}})
}}
layoutSubject
=
{
dosYSubject
}
><
/BandStructure
>
<
/Box
>
:
null
}
{
data
.
dos
?
<
Box
className
=
{
style
.
dos
}
>
<
Typography
variant
=
"
subtitle1
"
align
=
'
center
'
>
Density
of
states
<
/Typography
>
<
DOS
:
<
NoData
aspectRatio
=
{
1.2
}
/
>
}
<
/Box
>
<
Box
className
=
{
style
.
dos
}
>
<
Typography
variant
=
"
subtitle1
"
align
=
'
center
'
>
Density
of
states
<
/Typography
>
{
data
.
dos
?
<
DOS
data
=
{
data
.
dos
.
section_dos
}
layout
=
{
dosLayout
}
aspectRatio
=
{
0.6
}
onRelayouting
=
{
handleDOSRelayouting
}
onReset
=
{()
=>
{
setBsLayout
({
yaxis
:
{
range
:
range
}})
}}
unitsState
=
{
unitsState
}
layoutSubject
=
{
bsYSubject
}
><
/DOS
>
<
/Box
>
:
null
}
:
<
NoData
aspectRatio
=
{
0.6
}
/
>
}
<
/Box
>
{
data
.
bs
?
<
Box
className
=
{
style
.
bz
}
>
<
Typography
variant
=
"
subtitle1
"
align
=
'
center
'
>
Brillouin
zone
<
/Typography
>
...
...
gui/src/components/visualization/GeoOptOverview.js
View file @
599f5819
...
...
@@ -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,10 @@ 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
}}}
positions
Only
=
{
true
}
positions
Subject
=
{
positionsSubject
}
><
/Structure
>
<
/Box
>
<
/Box
>
...
...
gui/src/components/visualization/NoData.js
0 → 100644
View file @
599f5819
/*
* Copyright The NOMAD Authors.
*
* This file is part of NOMAD. See https://nomad-lab.eu for further info.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
React
from
'
react
'
import
{
Box
,
makeStyles
}
from
'
@material-ui/core
'
import
PropTypes
from
'
prop-types
'
import
clsx
from
'
clsx
'
/**
* Component that is used as a replacement for data that is not available.
* Notice that this is different from invalid data (this should display an
* ErrorCard) or from a placeholder!
*/
export
default
function
NoData
({
aspectRatio
,
className
,
classes
})
{
const
useStyles
=
makeStyles
(
theme
=>
{
return
{
root
:
{
},
outerContainer
:
{
height
:
0
,
overflow
:
'
hidden
'
,
paddingBottom
:
`
${
100
/
aspectRatio
}
%`
,
position
:
'
relative
'
},
innerContainer
:
{
position
:
'
absolute
'
,
top
:
0
,
left
:
0
,
width
:
'
100%
'
,
height
:
'
100%
'
},
box
:
{
width
:
'
100%
'
,
height
:
'
100%
'
,
boxSizing
:
'
border-box
'
,
padding
:
theme
.
spacing
(
2
)
},
background
:
{
backgroundColor
:
'
#f3f3f3
'
,
width
:
'
100%
'
,
height
:
'
100%
'
,
display
:
'
flex
'
,
alignItems
:
'
center
'
,
justifyContent
:
'
center
'
},
message
:
{
color
:
theme
.
palette
.
primary
.
main
,
opacity
:
0.5
,
userSelect
:
'
none
'
}
}
})
const
styles
=
useStyles
(
classes
)
const
content
=
<
Box
className
=
{
styles
.
box
}
>
<
Box
className
=
{
styles
.
background
}
>
<
div
className
=
{
styles
.
message
}
>
NO
DATA
<
/div
>
<
/Box
>
<
/Box
>
return
aspectRatio
?
<
div
className
=
{
clsx
(
className
,
styles
.
root
)}
>
<
div
className
=
{
styles
.
outerContainer
}
>
<
div
className
=
{
styles
.
innerContainer
}
>
{
content
}
<
/div
>
<
/div
>
<
/div
>
:
content
}
NoData
.
propTypes
=
{
aspectRatio
:
PropTypes
.
number
,
className
:
PropTypes
.
string
,
classes
:
PropTypes
.
string
}
gui/src/components/visualization/Plot.js
View file @
599f5819
...
...
@@ -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,13 @@ Plot.propTypes = {
onRedraw
:
PropTypes
.
func
,
onRelayouting
:
PropTypes
.
func
,
onHover
:
PropTypes
.
func
,
onReset
:
PropTypes
.
func
onReset
:
PropTypes
.
func
,
/**
* 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
,
...
...
gui/src/components/visualization/Structure.js
View file @
599f5819
...
...
@@ -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
,
...
...
@@ -47,7 +47,20 @@ 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
,
materialType
,
viewer
,
captureName
,
aspectRatio
,
positionsOnly
,
sizeLimit
,
positionsSubject
}
)
=>
{
// States
const
[
anchorEl
,
setAnchorEl
]
=
React
.
useState
(
null
)
const
[
fullscreen
,
setFullscreen
]
=
useState
(
false
)
...
...
@@ -87,6 +100,14 @@ export const Structure = withErrorHandler(({className, classes, system, systems,
marginBottom
:
theme
.
spacing
(
1
),
height
:
'
2rem
'
},
toggle
:
{
color
:
fade
(
theme
.
palette
.
action
.
active
,
0.87
)
},
selected
:
{
'
&$selected
'
:
{
color
:
fade
(
theme
.
palette
.
action
.
active
,
0.87
)
}
},
title
:
{
marginBottom
:
theme
.
spacing
(
1
)
},
...
...
@@ -173,8 +194,13 @@ 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
},
[])
},
[
positionsSubject
])
const
loadSystem
=
useCallback
((
system
,
refViewer
)
=>
{
// If the cell all zeroes, positions are assumed to be cartesian.
...
...
@@ -185,10 +211,9 @@ export const Structure = withErrorHandler(({className, classes, system, systems,
}