Skip to content

Commit

Permalink
TPI layout overhaul (#4050)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgboss authored Oct 30, 2024
1 parent 06c42d9 commit ee26b71
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 105 deletions.
8 changes: 7 additions & 1 deletion web/src/features/fba/components/infoPanel/TabPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Box } from '@mui/material'
import React from 'react'
import { theme } from 'app/theme'

interface TabPanelProps {
children?: React.ReactNode
Expand All @@ -9,7 +10,12 @@ interface TabPanelProps {

const TabPanel = ({ children, index, value }: TabPanelProps) => {
return (
<div hidden={value !== index} id={`tabpanel-${index}`} data-testid={`tabpanel-${index}`}>
<div
hidden={value !== index}
id={`tabpanel-${index}`}
data-testid={`tabpanel-${index}`}
style={{ backgroundColor: theme.palette.common.white }}
>
{value === index && <Box border={'1px solid #ccc'}>{children}</Box>}
</div>
)
Expand Down
44 changes: 17 additions & 27 deletions web/src/features/fba/components/viz/ElevationFlag.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
import React from 'react'
import { Box, Grid, Typography } from '@mui/material'

const FLAG_COLOUR = '#CCCCCC'
import { Typography } from '@mui/material'
import Grid from '@mui/material/Unstable_Grid2'
import Flag from '@/features/fba/components/viz/FillableFlag'

interface ElevationFlagProps {
testId?: string
id: string
percent: number
testId?: string
}

const ElevationFlag = ({ percent, testId }: ElevationFlagProps) => {
const ElevationFlag = ({ id, percent, testId }: ElevationFlagProps) => {
return (
<Grid item sx={{ display: 'flex', alignItems: 'center', flexGrow: 1, justifyContent: 'flex-start' }} xs={12}>
<Box
<Grid sx={{ alignItems: 'center', display: 'flex', justifyContent: 'flex-end' }} xs={6}>
<Flag maskId={id} percent={percent} />
<Typography
sx={{
backgroundColor: FLAG_COLOUR,
clipPath: 'polygon(0 50%, 10% 0, 100% 0, 100% 100%, 10% 100%)',
height: '32px',
padding: '1px',
width: '65%'
fontSize: '1.25em',
fontWeight: 'bold',
position: 'absolute',
right: '60px',
textShadow: '-2px 2px 4px #FFF, 2px 2px 4px #FFF, 2px -2px 4px #FFF, -2px -2px 4px #FFF'
}}
data-testid={testId}
>
<Box
sx={{
alignItems: 'center',
backgroundImage: `linear-gradient(to right, ${FLAG_COLOUR} ${percent}%, #FFFFFFFF ${percent}%)`,
clipPath: 'polygon(0 50%, 10% 0, 100% 0, 100% 100%, 10% 100%)',
display: 'flex',
height: '30px',
justifyContent: 'center'
}}
>
<Typography sx={{ fontSize: '0.75em' }} data-testid={testId}>
{percent}%
</Typography>
</Box>
</Box>
{percent}%
</Typography>
</Grid>
)
}
Expand Down
4 changes: 2 additions & 2 deletions web/src/features/fba/components/viz/ElevationLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ interface ElevationLabelProps {

const ElevationLabel = ({ label }: ElevationLabelProps) => {
return (
<Grid item sx={{ alignItems: 'center', display: 'flex', height: '25%', justifyContent: 'flex-end' }} xs={12}>
<Typography sx={{ fontSize: '0.75em' }}>{label}</Typography>
<Grid item sx={{ alignItems: 'center', display: 'flex', justifyContent: 'flex-start' }} xs={6}>
<Typography sx={{ fontWeight: 'bold' }}>{label}</Typography>
</Grid>
)
}
Expand Down
97 changes: 55 additions & 42 deletions web/src/features/fba/components/viz/ElevationStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import Grid from '@mui/material/Unstable_Grid2'
import Typography from '@mui/material/Typography'
import ElevationFlag from 'features/fba/components/viz/ElevationFlag'
import ElevationLabel from 'features/fba/components/viz/ElevationLabel'
import TPIMountain from 'features/fba/components/viz/TPIMountain'
import { Box } from '@mui/material'
import { FireZoneTPIStats } from '@/api/fbaAPI'
import Mountain from '@/features/fba/images/mountain.svg'

enum ElevationOption {
BOTTOM = 'Valley Bottom',
MID = 'Mid Slope',
Upper = 'Upper Slope'
UPPER = 'Upper Slope'
}

interface ElevationStatusProps {
Expand All @@ -25,50 +25,63 @@ const ElevationStatus = ({ tpiStats }: ElevationStatusProps) => {
const upper_percent = tpiStats.upper_slope === 0 ? 0 : Math.round((tpiStats.upper_slope / total) * 100)
const bottom_percent = tpiStats.valley_bottom === 0 ? 0 : Math.round((tpiStats.valley_bottom / total) * 100)
return (
<Box sx={{ paddingBottom: theme.spacing(2), paddingTop: theme.spacing(2) }} data-testid="elevation-status">
<Grid container sx={{ minHeight: theme.spacing(19) }} xs={12}>
<Grid container sx={{ paddingRight: theme.spacing(2) }} xs={4}>
<Grid sx={{ alignItems: 'center', display: 'flex', height: '25%', justifyContent: 'flex-end' }} xs={12}>
<Typography
sx={{
fontSize: '0.75em',
textAlign: 'right',
fontWeight: 'bold',
maxWidth: '75%'
}}
>
Topographic Position:
</Typography>
</Grid>
<ElevationLabel label={ElevationOption.Upper} />
<ElevationLabel label={ElevationOption.MID} />
<ElevationLabel label={ElevationOption.BOTTOM} />
<Grid container xs={12} data-testid="elevation-status">
<Grid container sx={{ height: theme.spacing(6) }} xs={12}>
<Grid sx={{ paddingLeft: theme.spacing(0.5), paddingRight: theme.spacing(0.5) }} xs={6}>
<Typography
sx={{
color: '#003366',
fontWeight: 'bold',
textAlign: 'left',
width: '50%'
}}
>
Topographic Position:
</Typography>
</Grid>
<Grid container sx={{ alignItems: 'flex-end', display: 'flex' }} xs={4} data-testid="tpi-mountain">
<Grid sx={{ display: 'flex', alignItems: 'flex-end', height: '80%', justifyContent: 'center' }} xs={12}>
<TPIMountain />
</Grid>
<Grid sx={{ display: 'flex', justifyContent: 'flex-end' }} xs={6}>
<Typography
sx={{
color: '#003366',
fontWeight: 'bold',
textAlign: 'right',
width: '65%'
}}
>
Proportion of Advisory Area:
</Typography>
</Grid>
<Grid container sx={{ paddingLeft: theme.spacing(2) }} xs={4}>
<Grid sx={{ alignItems: 'center', display: 'flex', height: '25%', justifyContent: 'flex-start' }} xs={12}>
<Typography
sx={{
fontSize: '0.75em',
textAlign: 'left',
fontWeight: 'bold',
maxWidth: '75%'
}}
>
Proportion of Advisory Area:
</Typography>
</Grid>
<Grid xs={12}>
<Box
sx={{
backgroundBlendMode: 'overlay',
backgroundColor: 'rgba(255, 255, 255, 0.6)',
backgroundImage: `url(${Mountain})`,
backgroundRepeat: 'round',
display: 'flex',
width: '100%'
}}
data-testId="tpi-mountain"
>
<Grid sx={{ paddingLeft: theme.spacing(0.5), paddingRight: theme.spacing(0.5) }} container xs={12}>
<Grid container sx={{ height: theme.spacing(8) }} xs={12}>
<ElevationLabel label={ElevationOption.UPPER} />
<ElevationFlag id="upper" percent={upper_percent} testId="upper-slope" />
</Grid>
<Grid container sx={{ height: theme.spacing(8) }} xs={12}>
<ElevationLabel label={ElevationOption.MID} />
<ElevationFlag id="mid" percent={mid_percent} testId="mid-slope" />
</Grid>
<Grid container sx={{ height: theme.spacing(8) }} xs={12}>
<ElevationLabel label={ElevationOption.BOTTOM} />
<ElevationFlag id="lower" percent={bottom_percent} testId="valley-bottom" />
</Grid>
</Grid>
<ElevationFlag percent={upper_percent} testId="upper-slope" />
<ElevationFlag percent={mid_percent} testId="mid-slope" />
<ElevationFlag percent={bottom_percent} testId="valley-bottom" />
</Grid>
</Box>
</Grid>
</Box>
</Grid>
)
}

export default ElevationStatus
export default ElevationStatus
31 changes: 31 additions & 0 deletions web/src/features/fba/components/viz/FillableFlag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react'

interface FillableFlagProps {
maskId: string
percent: number
}

const FillableFlag = ({ maskId, percent }: FillableFlagProps) => {
const fillWidth = (percent / 100) * 120
return (
<svg width="120" height="43" viewBox="0 0 120 43" fill="none" xmlns="http://www.w3.org/2000/svg" role="img">
<defs>
<mask id={`mask-${maskId}`}>
<rect x="0" y="0" width={`${fillWidth}`} height="43" fill="white" />
</mask>
</defs>
<path
d="M10.7443 41.822L0.558603 21.375L10.7443 0.928009L119.5 0.928009L119.5 41.822L10.7443 41.822Z"
stroke="black"
fill="black"
mask={`url(#mask-${maskId})`}
/>
<path
d="M10.7443 41.822L0.558603 21.375L10.7443 0.928009L119.5 0.928009L119.5 41.822L10.7443 41.822Z"
stroke="black"
/>
</svg>
)
}

export default React.memo(FillableFlag)
30 changes: 0 additions & 30 deletions web/src/features/fba/components/viz/TPIMountain.tsx

This file was deleted.

4 changes: 1 addition & 3 deletions web/src/features/fba/components/viz/elevationFlag.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import ElevationFlag from 'features/fba/components/viz/ElevationFlag'

describe('ElevationFlag', () => {
it('should have width relative to parent', () => {
const { getByTestId } = render(
<ElevationFlag percent={50} testId='valley-bottom' />
)
const { getByTestId } = render(<ElevationFlag id="test" percent={50} testId="valley-bottom" />)

const element = getByTestId('valley-bottom')
expect(element).toBeInTheDocument()
Expand Down
18 changes: 18 additions & 0 deletions web/src/features/fba/components/viz/fillableFlag.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'
import { render } from '@testing-library/react'
import FillableFlag from '@/features/fba/components/viz/FillableFlag'

describe('FillableFlag', () => {
it('should render', () => {
const maskId = 'test'
const { getByRole } = render(<FillableFlag maskId={maskId} percent={50} />)
const element = getByRole('img')
expect(element).toBeInTheDocument()
})
it("should use maskId in svg mask element's id", () => {
const maskId = 'test'
const result = render(<FillableFlag maskId={maskId} percent={50} />)
const element = result.container.querySelector(`#mask-${maskId}`)
expect(element).toBeInTheDocument()
})
})
28 changes: 28 additions & 0 deletions web/src/features/fba/images/mountain.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ee26b71

Please sign in to comment.