Skip to content
Snippets Groups Projects
Commit babeaa64 authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Added matrix visualizations.

parent 20eaba35
Branches
Tags 1.0.0
1 merge request!149V0.8.6
Pipeline #80012 failed
......@@ -44,7 +44,8 @@
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.1",
"react-swipeable-views": "^0.13.0",
"react-virtualized": "^9.21.2",
"react-virtualized-auto-sizer": "^1.0.2",
"react-window": "^1.8.5",
"recoil": "^0.0.10",
"recompose": "^0.28.2",
"remark": "^12.0.1",
......
......@@ -13,9 +13,9 @@ import { useLocation, useRouteMatch, Link } from 'react-router-dom'
export const configState = atom({
key: 'config',
default: {
'showMeta': true,
'showMeta': false,
'showCodeSpecific': false,
'showAllDefined': true
'showAllDefined': false
}
})
......
......@@ -6,6 +6,8 @@ import { Item, Content, Compartment, configState, List } from './ArchiveBrowser'
import { Typography, Box } from '@material-ui/core'
import { resolveRef, sectionDefs } from './metainfo'
import { Title, metainfoAdaptorFactory, Meta } from './metainfoAdaptors'
import { Matrix, Number } from './visualizations'
import shape from '@material-ui/core/styles/shape'
export default function archiveAdaptorFactory(data, sectionDef) {
return new SectionAdaptor(data, sectionDef || sectionDefs['EntryArchive'], {archive: data})
......@@ -95,11 +97,12 @@ function QuantityItemPreview({value, def}) {
}
}
return <Box component="span" whiteSpace="nowrap" fontStyle="italic">
<Typography component="span">{`[${dimensions.join(', ')}] ${typeLabel}`}</Typography>
<Typography component="span">{dimensions.map((v, i) => <span>{i > 0 && <span>&nbsp;&times;&nbsp;</span>}{new String(v)}</span>)}&nbsp;{typeLabel}</Typography>
</Box>
} else {
return <Box component="span" whiteSpace="nowarp">
<Typography component="span">{String(value)}</Typography>
<Number component="span" variant="body1" value={value} exp={8} />
{def.unit && <Typography component="span">&nbsp;{def.unit}</Typography>}
</Box>
}
}
......@@ -112,9 +115,9 @@ function QuantityValue({value, def}) {
return <Box
marginTop={2} marginBottom={2} textAlign="center" fontWeight="bold"
>
<Typography>
{String(value)}
</Typography>
{def.shape.length > 0 ? <Matrix values={value} shape={def.shape} invert={def.shape.length === 1} /> : <Number value={value} exp={16} variant="body2" />}
{def.shape.length > 0 && <Typography nowrap variant="caption">({def.shape.map((v, i) => <span>{i > 0 && <span>&nbsp;&times;&nbsp;</span>}{new String(v)}</span>)}&nbsp;)</Typography>}
{def.unit && <Typography nowrap>{def.unit}</Typography>}
</Box>
}
QuantityValue.propTypes = ({
......
import React, { useRef, useLayoutEffect, useState } from 'react'
import PropTypes from 'prop-types'
import { FixedSizeGrid as Grid } from 'react-window'
import { Typography, makeStyles, FormGroup, Button, FormLabel, Grid as MuiGrid, Box } from '@material-ui/core'
import AutoSizer from 'react-virtualized-auto-sizer'
export function Number({value, exp, variant, ...props}) {
variant = variant || 'body2'
exp = exp || 2
const fixed = 5
let html = '-'
if (value !== undefined && value !== null) {
if (typeof value === 'number') {
const str = value.toExponential(exp)
const [f, e] = str.split('e')
if (e <= fixed && e >= -fixed) {
html = value.toFixed(fixed).replace(/[.,]0*$/, '')
} else {
html = <span>{f.toString().replace(/0*$/, '')}&middot;10<sup>{e}</sup></span>
}
} else {
html = value.toString()
}
}
return <Typography {...props} variant={variant} >{html}</Typography>
}
Number.propTypes = ({
value: PropTypes.any
})
function MatrixPagination({length, page, onChange}) {
return <MuiGrid
spacing={2}
container
direction="row"
justify="center"
alignItems="center"
>
<MuiGrid item>
<Button disabled={page === 0} size="small" onClick={() => onChange(page - 1)}>
prev
</Button>
</MuiGrid>
<MuiGrid item>
<Typography>{page}</Typography>
</MuiGrid>
<MuiGrid item>
<Button size="small" disabled={page + 1 === length} onClick={() => onChange(page + 1)}>
next
</Button>
</MuiGrid>
</MuiGrid>
}
MatrixPagination.propTypes = ({
length: PropTypes.number.isRequired,
page: PropTypes.number.isRequired,
onChange: PropTypes.func.isRequired
})
const useMatrixStyles = makeStyles(theme => ({
root: {
display: 'flex',
flexDirection: 'row',
alignItems: 'stretch',
minWidth: 300,
justifyContent: 'center'
},
leftBracket: {
width: theme.spacing(1),
border: 'solid 2px black',
borderRight: 'none',
marginRight: -theme.spacing(1)
},
matrix: {
width: '100%'
},
rightBracket: {
width: theme.spacing(1),
border: 'solid 2px black',
borderLeft: 'none',
marginLeft: -theme.spacing(1)
}
}))
export function Matrix({values, shape, invert}) {
const rootRef = useRef()
const matrixRef = useRef()
const [pages, setPages] = useState(new Array(Math.max(0, shape.length - 2)).fill(0))
const pageLengths = []
const classes = useMatrixStyles()
let ii = 0
for (let i = shape.length; i > 2; i--) {
pageLengths.push(values.length)
values = values[pages[ii++]]
}
const columnWidth = 92
const rowHeight = 24
const rowCount = invert ? values.length : shape.length > 1 ? values[0].length : 1
const columnCount = invert ? shape.length > 1 ? values[0].length : 1 : values.length
const height = Math.min(300, rowCount * rowHeight)
useLayoutEffect(() => {
matrixRef.current.style.width = Math.min(
rootRef.current.clientWidth - 4, columnCount * columnWidth) + 'px'
})
let value = shape.length > 1 ? ({rowIndex, columnIndex}) => values[columnIndex][rowIndex] : ({columnIndex}) => values[columnIndex]
if (invert) {
value = shape.length > 1 ? ({rowIndex, columnIndex}) => values[rowIndex][columnIndex] : ({rowIndex}) => values[rowIndex]
}
return <React.Fragment>
<div ref={rootRef} className={classes.root}>
<div className={classes.leftBracket} style={{height: height}}>&nbsp;</div>
<div ref={matrixRef} className={classes.matrix}>
<AutoSizer>
{({width}) => (
<Grid
columnCount={columnCount}
columnWidth={columnWidth}
height={height}
rowCount={rowCount}
rowHeight={rowHeight}
width={width}
>
{({style, ...props}) => <Number style={style} value={value(props)} />}
</Grid>
)}
</AutoSizer>
</div>
<div className={classes.rightBracket} style={{height: height}}>&nbsp;</div>
</div>
{pages.map((page, index) => <Box margin={1} key={index}>
<MatrixPagination
length={pageLengths[index]} page={page}
onChange={(page) => setPages([...pages.slice(0, index), page, ...pages.slice(index + 1)])}
/>
</Box>)}
</React.Fragment>
}
Matrix.propTypes = ({
values: PropTypes.array.isRequired,
shape: PropTypes.arrayOf(PropTypes.any).isRequired,
invert: PropTypes.bool
})
\ No newline at end of file
......@@ -3258,11 +3258,6 @@ clone-deep@^4.0.1:
kind-of "^6.0.2"
shallow-clone "^3.0.0"
 
clsx@^1.0.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
clsx@^1.0.2, clsx@^1.0.4:
version "1.1.0"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702"
......@@ -3914,11 +3909,6 @@ csstype@^2.2.0, csstype@^2.5.2, csstype@^2.6.5, csstype@^2.6.7:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b"
integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==
 
csstype@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.2.tgz#ee5ff8f208c8cd613b389f7b222c9801ca62b3f7"
integrity sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==
cyclist@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
......@@ -4436,14 +4426,6 @@ dom-converter@^0.2:
dependencies:
utila "~0.4"
 
dom-helpers@^5.0.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b"
integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==
dependencies:
"@babel/runtime" "^7.8.7"
csstype "^3.0.2"
dom-helpers@^5.0.1:
version "5.1.4"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.4.tgz#4609680ab5c79a45f2531441f1949b79d6587f4b"
......@@ -7752,7 +7734,7 @@ longest-streak@^2.0.1:
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4"
integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==
 
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
......@@ -7901,6 +7883,11 @@ mem@^4.0.0:
mimic-fn "^2.0.0"
p-is-promise "^2.0.0"
 
"memoize-one@>=3.1.1 <6":
version "5.1.1"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0"
integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==
memory-fs@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
......@@ -10336,17 +10323,18 @@ react-transition-group@^4.3.0:
loose-envify "^1.4.0"
prop-types "^15.6.2"
 
react-virtualized@^9.21.2:
version "9.21.2"
resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.21.2.tgz#02e6df65c1e020c8dbf574ec4ce971652afca84e"
integrity sha512-oX7I7KYiUM7lVXQzmhtF4Xg/4UA5duSA+/ZcAvdWlTLFCoFYq1SbauJT5gZK9cZS/wdYR6TPGpX/dqzvTqQeBA==
react-virtualized-auto-sizer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.2.tgz#a61dd4f756458bbf63bd895a92379f9b70f803bd"
integrity sha512-MYXhTY1BZpdJFjUovvYHVBmkq79szK/k7V3MO+36gJkWGkrXKtyr4vCPtpphaTLRAdDNoYEYFZWE8LjN+PIHNg==
react-window@^1.8.5:
version "1.8.5"
resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.5.tgz#a56b39307e79979721021f5d06a67742ecca52d1"
integrity sha512-HeTwlNa37AFa8MDZFZOKcNEkuF2YflA0hpGPiTT9vR7OawEt+GZbfM6wqkBahD3D3pUjIabQYzsnY/BSJbgq6Q==
dependencies:
babel-runtime "^6.26.0"
clsx "^1.0.1"
dom-helpers "^5.0.0"
loose-envify "^1.3.0"
prop-types "^15.6.0"
react-lifecycles-compat "^3.0.4"
"@babel/runtime" "^7.0.0"
memoize-one ">=3.1.1 <6"
 
react@^16.13.1:
version "16.13.1"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment