diff --git a/web/src/features/fba/components/viz/FuelTypesBreakdown.tsx b/web/src/features/fba/components/viz/FuelTypesBreakdown.tsx
index 2798398d6..edbd1c414 100644
--- a/web/src/features/fba/components/viz/FuelTypesBreakdown.tsx
+++ b/web/src/features/fba/components/viz/FuelTypesBreakdown.tsx
@@ -4,6 +4,7 @@ import { Typography } from '@mui/material'
import { isUndefined } from 'lodash'
import { FireShape, FireZoneThresholdFuelTypeArea } from 'api/fbaAPI'
import { PieChart, Pie, ResponsiveContainer, Cell } from 'recharts'
+import { getColorByFuelTypeCode } from 'features/fba/components/viz/color'
const PREFIX = 'FuelTypesBreakdown'
@@ -35,50 +36,30 @@ interface FuelTypeDataForPieChart {
}
const RADIAN = Math.PI / 180
-const COLOURS = [
- '#2191FB',
- '#FCB1A6',
- '#B33951',
- '#CCF5AC',
- '#8CDEDC',
- '#9DACFF',
- '#4F7CAC',
- '#FFA62B',
- '#C09BD8',
- '#EBC3DB',
- '#D19C1D',
- '#FFC0BE',
- '#ED7D3A'
-]
const FuelTypesBreakdown = (props: Props) => {
const renderCustomizedLabel = ({
cx,
cy,
midAngle,
- innerRadius,
outerRadius,
percent,
- fuel_type_code,
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- area,
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- index
+ fuel_type_code
}: {
cx: number
cy: number
midAngle: number
- innerRadius: number
outerRadius: number
percent: number
fuel_type_code: string
- area: number
- index: number
}) => {
- const radius = innerRadius + (outerRadius - innerRadius) * 0.5
- const x = cx + radius * Math.cos(-midAngle * RADIAN)
- const y = cy + radius * Math.sin(-midAngle * RADIAN)
+ // Labels are positioned at the outer edge of the pie + the length of label lines (20px) +
+ // an arbitrary buffer/whitespace of 5px
+ const labelRadius = outerRadius + 25
+ const x = cx + labelRadius * Math.cos(-midAngle * RADIAN)
+ const y = cy + labelRadius * Math.sin(-midAngle * RADIAN)
+ // Only label pie slices that contribute >= 2%
if (percent * 100 < 2) {
return
}
@@ -90,6 +71,22 @@ const FuelTypesBreakdown = (props: Props) => {
)
}
+ const renderLabelLine = ({
+ percent,
+ points,
+ stroke
+ }: {
+ percent: number
+ points: { x: number; y: number }[]
+ stroke: string
+ }) => {
+ if (!points || points.length < 2 || percent * 100 < 2) {
+ return <>>
+ }
+
+ return
+ }
+
if (isUndefined(props.selectedFireZone) || isUndefined(props.fuelTypeInfo[props.selectedFireZone.fire_shape_id])) {
return
} else {
@@ -116,11 +113,11 @@ const FuelTypesBreakdown = (props: Props) => {
cy="50%"
outerRadius={80}
fill="#8884d8"
- labelLine={false}
+ labelLine={renderLabelLine}
label={renderCustomizedLabel}
>
- {advisories.map((entry, index) => (
- |
+ {advisories.map(entry => (
+ |
))}
@@ -135,11 +132,11 @@ const FuelTypesBreakdown = (props: Props) => {
cx="50%"
cy="50%"
outerRadius={80}
- labelLine={false}
+ labelLine={renderLabelLine}
label={renderCustomizedLabel}
>
- {warnings.map((entry, index) => (
- |
+ {warnings.map(entry => (
+ |
))}
diff --git a/web/src/features/fba/components/viz/color.test.ts b/web/src/features/fba/components/viz/color.test.ts
new file mode 100644
index 000000000..f587b70da
--- /dev/null
+++ b/web/src/features/fba/components/viz/color.test.ts
@@ -0,0 +1,28 @@
+import { getColorByFuelTypeCode } from 'features/fba/components/viz/color'
+
+const colorByFuelTypeCodeTestMap = new Map()
+colorByFuelTypeCodeTestMap.set('C-1', 'rgb(209, 255, 115)')
+colorByFuelTypeCodeTestMap.set('C-2', 'rgb(34, 102, 51)')
+colorByFuelTypeCodeTestMap.set('C-3', 'rgb(131, 199, 149)')
+colorByFuelTypeCodeTestMap.set('C-4', 'rgb(112, 168, 0)')
+colorByFuelTypeCodeTestMap.set('C-5', 'rgb(223, 184, 230)')
+colorByFuelTypeCodeTestMap.set('C-6', 'rgb(172, 102, 237)')
+colorByFuelTypeCodeTestMap.set('C-7', 'rgb(112, 12, 242)')
+colorByFuelTypeCodeTestMap.set('D-1/D-2', 'rgb(137, 112, 68)')
+colorByFuelTypeCodeTestMap.set('S-1', 'rgb(251, 190, 185)')
+colorByFuelTypeCodeTestMap.set('S-2', 'rgb(247, 104, 161)')
+colorByFuelTypeCodeTestMap.set('S-3', 'rgb(174, 1, 126)')
+colorByFuelTypeCodeTestMap.set('O-1a/O-1b', 'rgb(255, 255, 190)')
+colorByFuelTypeCodeTestMap.set('M-1/M-2', 'rgb(255, 211, 127)')
+
+describe('getColorByFuelTypeCode', () => {
+ it('should return the correct colour for each fuel type code', () => {
+ const keys = colorByFuelTypeCodeTestMap.keys()
+ for (const key of keys) {
+ expect(getColorByFuelTypeCode(key)).toBe(colorByFuelTypeCodeTestMap.get(key))
+ }
+ })
+ it('should return a default color when a matching key is not found', () => {
+ expect(getColorByFuelTypeCode('foo')).toBe('rgb(0, 255, 255)')
+ })
+})
diff --git a/web/src/features/fba/components/viz/color.ts b/web/src/features/fba/components/viz/color.ts
new file mode 100644
index 000000000..e20ffdf32
--- /dev/null
+++ b/web/src/features/fba/components/viz/color.ts
@@ -0,0 +1,22 @@
+// A Map of fuel type codes to the colour typically used in BCWS
+const colorByFuelTypeCode = new Map()
+colorByFuelTypeCode.set('C-1', 'rgb(209, 255, 115)')
+colorByFuelTypeCode.set('C-2', 'rgb(34, 102, 51)')
+colorByFuelTypeCode.set('C-3', 'rgb(131, 199, 149)')
+colorByFuelTypeCode.set('C-4', 'rgb(112, 168, 0)')
+colorByFuelTypeCode.set('C-5', 'rgb(223, 184, 230)')
+colorByFuelTypeCode.set('C-6', 'rgb(172, 102, 237)')
+colorByFuelTypeCode.set('C-7', 'rgb(112, 12, 242)')
+colorByFuelTypeCode.set('D-1/D-2', 'rgb(137, 112, 68)')
+colorByFuelTypeCode.set('S-1', 'rgb(251, 190, 185)')
+colorByFuelTypeCode.set('S-2', 'rgb(247, 104, 161)')
+colorByFuelTypeCode.set('S-3', 'rgb(174, 1, 126)')
+colorByFuelTypeCode.set('O-1a/O-1b', 'rgb(255, 255, 190)')
+colorByFuelTypeCode.set('M-1/M-2', 'rgb(255, 211, 127)')
+
+// Retrieve a color from the Map base don the fuel type code.
+// Provide a default value in case a non-standard code is encountered so we don't end up with empty pie slices.
+export const getColorByFuelTypeCode = (code: string): string => {
+ const color = colorByFuelTypeCode.get(code)
+ return color ?? 'rgb(0, 255, 255)'
+}