Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fuel type distribution #3792

Merged
merged 9 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"maxx",
"maxy",
"miny",
"luxon",
"ndarray",
"numba",
"osgeo",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { Grid } from '@mui/material'
import { isUndefined } from 'lodash'
import { ElevationInfoByThreshold, FireShape, FireShapeArea, FireZoneThresholdFuelTypeArea } from 'api/fbaAPI'
import ElevationInfoViz from 'features/fba/components/viz/ElevationInfoViz'
import FuelTypesBreakdown from 'features/fba/components/viz/FuelTypesBreakdown'
import InfoAccordion from 'features/fba/components/infoPanel/InfoAccordion'
import { useTheme } from '@mui/material/styles'
import FuelSummary from 'features/fba/components/viz/FuelSummary'

interface FireZoneUnitSummaryProps {
selectedFireZoneUnit: FireShape | undefined
Expand Down Expand Up @@ -40,8 +40,8 @@ const FireZoneUnitSummary = ({
fireZoneAreas={fireShapeAreas.filter(area => area.fire_shape_id == selectedFireZoneUnit?.fire_shape_id)}
/>
</Grid>
<Grid item>
<FuelTypesBreakdown selectedFireZone={selectedFireZoneUnit} fuelTypeInfo={fuelTypeInfo} />
<Grid item sx={{ width: '95%' }}>
<FuelSummary selectedFireZoneUnit={selectedFireZoneUnit} fuelTypeInfo={fuelTypeInfo} />
</Grid>
<Grid item>
<ElevationInfoViz selectedFireZone={selectedFireZoneUnit} hfiElevationInfo={hfiElevationInfo} />
Expand Down
7 changes: 4 additions & 3 deletions web/src/features/fba/components/viz/CombustibleAreaViz.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ const PREFIX = 'CombustibleAreaViz'
const StyledTypography = styled(Typography, {
name: `${PREFIX}-Typography`
})({
fontSize: '1.3rem',
textAlign: 'center',
variant: 'h3'
fontSize: '1rem',
fontWeight: 'bold',
paddingBottom: '0.5rem',
textAlign: 'left'
})

export interface AdvisoryMetadataProps {
Expand Down
17 changes: 4 additions & 13 deletions web/src/features/fba/components/viz/ElevationInfoViz.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,6 @@ const classes = {
wrapper: `${PREFIX}-wrapper`
}

const Root = styled('div')({
[`& .${classes.header}`]: {
fontSize: '1.3rem',
textAlign: 'center',
variant: 'h3'
},
[`& .${classes.wrapper}`]: {
padding: '20px 10px'
}
})

interface Props {
className?: string
selectedFireZone: FireShape | undefined
Expand All @@ -36,7 +25,7 @@ interface Props {

const ElevationInfoViz = (props: Props) => {
if (isUndefined(props.hfiElevationInfo) || props.hfiElevationInfo.length === 0) {
return <Root></Root>
return
}
const advisoryElevationInfoByThreshold = props.hfiElevationInfo.filter(info => info.threshold === 1)
const warnElevationInfoByThreshold = props.hfiElevationInfo.filter(info => info.threshold === 2)
Expand All @@ -62,7 +51,9 @@ const ElevationInfoViz = (props: Props) => {
return (
<div className={props.className}>
<Paper className={classes.wrapper}>
<Typography className={classes.header}>HFI By Elevation</Typography>
<Typography sx={{ fontSize: '1rem', fontWeight: 'bold', paddingBottom: '0.5rem', textAlign: 'center' }}>
HFI By Elevation
</Typography>
<TableContainer component={Paper}>
<Table>
<TableHead>
Expand Down
20 changes: 20 additions & 0 deletions web/src/features/fba/components/viz/FuelDistribution.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Box } from '@mui/material'
import React from 'react'
import { getColorByFuelTypeCode } from 'features/fba/components/viz/color'

interface FuelDistributionProps {
code: string
percent: number
}

// Represents the percent contribution of the given fuel type to the overall high HFI area.
const FuelDistribution = ({ code, percent }: FuelDistributionProps) => {
return (
<Box
data-testid="fuel-distribution-box"
sx={{ height: '75%', width: `${percent}%`, background: getColorByFuelTypeCode(code) }}
/>
)
}

export default React.memo(FuelDistribution)
134 changes: 134 additions & 0 deletions web/src/features/fba/components/viz/FuelSummary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import React, { useEffect, useState } from 'react'
import { FireShape, FireZoneThresholdFuelTypeArea } from 'api/fbaAPI'
import { Box, Tooltip, Typography } from '@mui/material'
import { groupBy, isUndefined } from 'lodash'
import { DateTime } from 'luxon'
import FuelDistribution from 'features/fba/components/viz/FuelDistribution'
import { DataGridPro, GridColDef, GridRenderCellParams } from '@mui/x-data-grid-pro'
import { useTheme } from '@mui/material/styles'

export interface FuelTypeInfoSummary {
area: number
criticalHoursStart?: DateTime
criticalHoursEnd?: DateTime
id: number
code: string
description: string
percent?: number
selected: boolean
}

interface FuelSummaryProps {
fuelTypeInfo: Record<number, FireZoneThresholdFuelTypeArea[]>
selectedFireZoneUnit: FireShape | undefined
}

// Column definitions for fire zone unit fuel summary table
const columns: GridColDef[] = [
{
field: 'code',
headerClassName: 'fuel-summary-header',
headerName: 'Fuel Type',
sortable: false,
width: 75,
renderCell: (params: GridRenderCellParams) => (
<Tooltip placement="right" title={params.row['description']}>
<Typography sx={{ fontSize: '0.75rem' }}>{params.row[params.field]}</Typography>
</Tooltip>
)
},
{
field: 'area',
flex: 3,
headerClassName: 'fuel-summary-header',
headerName: 'Distribution > 4k kW/m',
minWidth: 200,
sortable: false,
renderCell: (params: GridRenderCellParams) => {
return <FuelDistribution code={params.row['code']} percent={params.row['percent']} />
}
}
]

const FuelSummary = ({ fuelTypeInfo, selectedFireZoneUnit }: FuelSummaryProps) => {
const theme = useTheme()
const [fuelTypeInfoRollup, setFuelTypeInfoRollup] = useState<FuelTypeInfoSummary[]>([])

useEffect(() => {
if (isUndefined(fuelTypeInfo) || isUndefined(selectedFireZoneUnit)) {
setFuelTypeInfoRollup([])
return
}
const shapeId = selectedFireZoneUnit.fire_shape_id
const fuelDetails = fuelTypeInfo[shapeId]
if (isUndefined(fuelDetails)) {
setFuelTypeInfoRollup([])
return
}
// Sum the total area with HFI > 4000 for all fuel types
const totalHFIArea4K = fuelDetails.reduce((acc, { area }) => acc + area, 0)
const rollUp: FuelTypeInfoSummary[] = []
// We receive HFI area per fuel type per HFI threshold (4-10K and >10K), so group fuel type.
// Iterate through the groups adding the area for both HFI thresholds' we're interested in all
// HFI > 4,000.
const groupedFuelDetails = groupBy(fuelDetails, 'fuel_type.fuel_type_id')
for (const key in groupedFuelDetails) {
const groupedFuelDetail = groupedFuelDetails[key]
if (groupedFuelDetail.length) {
const area = groupedFuelDetail.reduce((acc, { area }) => acc + area, 0)
const fuelType = groupedFuelDetail[0].fuel_type
const fuelInfo: FuelTypeInfoSummary = {
area,
code: fuelType.fuel_type_code,
description: fuelType.description,
id: fuelType.fuel_type_id,
percent: totalHFIArea4K ? (area / totalHFIArea4K) * 100 : 0,
selected: false
}
rollUp.push(fuelInfo)
}
}
setFuelTypeInfoRollup(rollUp)
}, [fuelTypeInfo]) // eslint-disable-line react-hooks/exhaustive-deps

return (
<Box sx={{ paddingBottom: theme.spacing(2), paddingTop: theme.spacing(2) }}>
<Typography sx={{ fontWeight: 'bold', paddingBottom: theme.spacing(1), textAlign: 'center' }}>
HFI Distribution by Fuel Type
</Typography>
{fuelTypeInfoRollup.length === 0 ? (
<Typography>No fuel type information available.</Typography>
) : (
<DataGridPro
columns={columns}
density="compact"
disableColumnMenu
disableChildrenSorting
disableRowSelectionOnClick
hideFooter={true}
initialState={{
sorting: {
sortModel: [{ field: 'area', sort: 'desc' }]
}
}}
rows={fuelTypeInfoRollup}
showCellVerticalBorder
showColumnVerticalBorder
sx={{
maxHeight: '147px',
minHeight: '100px',
overflow: 'hidden',
'& .MuiDataGrid-columnHeaderTitle': {
fontWeight: 'bold'
},
'& .fuel-summary-header': {
background: '#F1F1F1'
}
}}
></DataGridPro>
)}
</Box>
)
}

export default FuelSummary
149 changes: 0 additions & 149 deletions web/src/features/fba/components/viz/FuelTypesBreakdown.tsx

This file was deleted.

Loading
Loading