Skip to main content

Water Neutrality

A sustainability dashboard that measures how much water an organisation credits (augments, replenishes, offsets) against how much it debits (consumes), and expresses the balance as a single Water Neutrality %.

  • Route: /water_neutralityWaterNeutrality (libs/waterNeutrality/src/WaterNeutrality.jsx)
  • Permission: WATER_NEUTRALITY (gates the sidebar entry; the route element isn't wrapped — see Permissions)
  • Library: libs/waterNeutrality/ — standard dataSource → controller → store → components layering

The idea

Summary: The page fetches credited and debited water for a chosen date range, shows each as a treemap broken down by sub-category, and reduces the pair to a neutrality percentage (target 100%) with a plain-language status.

Formula (shown in the "See How?" popup): Water Augmented / Water Consumed x 100.


Status labels

The percentage maps to one of four statuses:

StatusMeaning
Water PositiveCrediting more than consumed (≥ 100%)
Water NeutralRoughly balanced (~90–100%)
Nearing NeutralityApproaching balance (~75–90%)
Critically LowWell below target (< 75%)

The controller caps the displayed value at 120%. When it can't be computed it shows "Unable to calculate."


What's on the page

AreaComponentWhat it showsOn click
Date headerWaterNeutralityDateHeaderA range picker (AppDatePickerSelection, up to 365 days), the current Status, and a "See How?" link"See How?" opens the concept popup
Balance figureWaterTotalValueWater Neutrality : <value> with (Target : 100%)
LegendWaterNeutralityLegendsCredited / Debited swatches + the deviation-arrow key
TreemapsWaterNeutralityTreeGraphComponent (×2)One card each for credited and debited, sub-category tiles sized by valueClicking a card's header expands it full-width (and collapses the other)
Treemap renderTreemapChartThe actual tiles (see below)
SummaryWaterNeutralitySummaryOptional bulleted insights (hidden when empty)
Concept popupWaterNeutralityPopupStatic explanation + the status-range table + formulaClose button / backdrop dismiss

Despite its name, WaterNeutralityTreeGraphComponent is not a node-link tree — it wraps a treemap. There is no React Flow / D3 here.


The treemap (chart.js)

Tiles are rendered with chart.js via react-chartjs-2 and the chartjs-chart-treemap plugin — this is the only chart.js use in the app (everything else uses Recharts):

import { Chart as ChartJS, LinearScale, Tooltip } from 'chart.js';
import { TreemapController, TreemapElement } from 'chartjs-chart-treemap';
import { Chart } from 'react-chartjs-2';

Each tile is sized by its normalizedValue; the label carries an up/down deviation arrow vs. target, the value, and the sub-category name; the tooltip lists the per-unit rows.


Data & API

Neutrality data (the only endpoint)

dataSource/neutrality.jscontroller/neutralityController.js → store init():

EndpointGET neutrality/ (Urls.getNeutralityData)
Paramsdate1, date2 (both DD/MM/YYYY) — the selected range
Triggered byinitial load and any date-range change (no polling)

The controller reshapes the response: it derives neutralityStatus from the percentage and caps waterNeutrality at 120. The response carries the credited (ID_WATER_CREDITED) and debited (ID_WATER_DEBITED) branches — each with a total, a displayTotal, and a subCategory array (the treemap tiles) — plus an optional summary array. A PAGE_VIEW analytics event fires on mount.

State (WaterNeutralityStore)

A React Context (WaterNeutralityProvider / WaterNeutralityContext) exposing neutralityData, params / setParams, and isLoading. See State Management and API Call Flow.


Edge cases & guards

CaseHandling
LoadingA centered loader while isLoading
No dataA "Data Not Found" panel with a button to Water Monitoring
Empty selected rangeWhen either credited or debited total is missing, a "Data Not Found for selected range" block replaces the treemaps
Expand / collapseSelecting one treemap hides the other; selecting again restores both
Value capThe neutrality percentage is clamped to 120 before display
Static popupThe "See How?" content (concept, ranges, formula) is hardcoded, not data-driven

Underlying libraries

PurposeLibrary
Treemapchart.js + react-chartjs-2 + chartjs-chart-treemap
UI / theming@mui/material (MUI 7)
Datesmoment

Exact versions live in package.json.


Code reference

FileRole
WaterNeutrality.jsxPage shell + provider
dataSource/neutrality.jsThe neutrality/ call
controller/neutralityController.jsStatus derivation + 120% cap
store/WaterNeutralityStore.jsContext state
helper/neutralityHelperInstance.jsDisplay config (colours, ranges, formatters)
components/BuildWaterNeutralityDetails.jsxLayout, date header, empty states
components/WaterNeutralityTreeGraphComponent.jsxPer-treemap card + expand
components/TreemapChart.jsxThe chart.js treemap
components/WaterNeutralitySummary.jsx · WaterNeutralityPopup.jsxSummary + concept popup