Skip to content
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
6 changes: 4 additions & 2 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="https://services.pacificclimate.org/plan2adapt/app/favicon.ico" />
<link rel="preconnect" href="https://swarm.pacificclimate.org" crossorigin />
<link rel="dns-prefetch" href="//delivery.maps.gov.bc.ca" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<link rel="preload" as="image" href="https://swarm.pacificclimate.org/tiles/bc-albers-lite/6/33/29.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vector Hydrologic Model Output</title>
Expand All @@ -14,4 +16,4 @@
<script type="module" src="/src/main.jsx"></script>
</body>

</html>
</html>
Binary file added app/public/favicon.ico
Binary file not shown.
9 changes: 1 addition & 8 deletions app/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import React from 'react';
import MapComponent from "./components/map/MapComponent.jsx";

console.log("Rendering App...");
const App = () => {
console.log("Rendering MapComponent from App...");
return <MapComponent />;
};

console.log("Rendering MapComponent...");
const App = () => <MapComponent />;

export default App;
Binary file removed app/src/assets/logo.png
Binary file not shown.
Binary file added app/src/assets/logo.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 55 additions & 15 deletions app/src/components/data/DataSelectionTable.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import { useState, useEffect, useCallback } from "react";
import PropTypes from "prop-types";
import { getAvailableOptions, downloadTimeseries } from "../../services/timeseriesApi.js";
import {
getAvailableOptions,
downloadTimeseries,
} from "../../services/timeseriesApi.js";
import "./DataSelection.css";

const HISTORICAL_SCENARIO = "historical";
const HISTORICAL_MODEL = "PNWNAmet";

const getModelLabel = (model) =>
model === HISTORICAL_MODEL ? `${model} (historical)` : model;

const getScenarioLabel = (scenario) =>
scenario === HISTORICAL_SCENARIO ? `${scenario} (PNWNAmet only)` : scenario;

const DataSelectionTable = ({ featureId, onClose }) => {
const outletId = `${featureId}`;
const [options, setOptions] = useState({
Expand All @@ -15,35 +27,46 @@ const DataSelectionTable = ({ featureId, onClose }) => {
scenario: "",
variable: "",
});
const [isFetching, setIsFetching] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const [showValidation, setShowValidation] = useState(false);
const [shake, setShake] = useState(false);

useEffect(() => {
const fetchOptions = async () => {
try {
try {
const availableOptions = await getAvailableOptions(outletId);
setOptions(availableOptions);
} catch (error) {
console.error("Failed to fetch options:", error);
alert("Failed to load available options");
} finally {
setIsFetching(false);
}
};

fetchOptions();
}, [outletId]);

const handleChange = (field, value) => {
setSelections((prev) => ({
...prev,
[field]: value,
}));
};
setSelections((prev) => {
const isNowInvalid =
field === "model" &&
prev.scenario !== "" &&
(value === HISTORICAL_MODEL) !==
(prev.scenario === HISTORICAL_SCENARIO);

const getValidationClass = (field) => {
return showValidation && !selections[field] ? "invalid" : "";
return {
...prev,
[field]: value,
...(isNowInvalid ? { scenario: "" } : {}),
};
});
};

const getValidationClass = (field) =>
showValidation && !selections[field] ? "invalid" : "";

const handleDownload = useCallback(async () => {
if (Object.values(selections).some((v) => !v)) {
setShowValidation(true);
Expand Down Expand Up @@ -77,11 +100,12 @@ const DataSelectionTable = ({ featureId, onClose }) => {
value={selections.model}
onChange={(e) => handleChange("model", e.target.value)}
className={getValidationClass("model")}
disabled={isFetching}
>
<option value="">Select Model</option>
<option value="">{isFetching ? "Loading..." : "Select Model"}</option>
{options.models.map((model) => (
<option key={model} value={model}>
{model}
{getModelLabel(model)}
</option>
))}
</select>
Expand All @@ -90,11 +114,24 @@ const DataSelectionTable = ({ featureId, onClose }) => {
value={selections.scenario}
onChange={(e) => handleChange("scenario", e.target.value)}
className={getValidationClass("scenario")}
disabled={isFetching}
>
<option value="">Select Scenario</option>
<option value="">
{isFetching ? "Loading..." : "Select Scenario"}
</option>
{options.scenarios.map((scenario) => (
<option key={scenario} value={scenario}>
{scenario}
<option
key={scenario}
value={scenario}
disabled={
(scenario === HISTORICAL_SCENARIO &&
selections.model !== "" &&
selections.model !== HISTORICAL_MODEL) ||
(scenario !== HISTORICAL_SCENARIO &&
selections.model === HISTORICAL_MODEL)
}
>
{getScenarioLabel(scenario)}
</option>
))}
</select>
Expand All @@ -103,8 +140,11 @@ const DataSelectionTable = ({ featureId, onClose }) => {
value={selections.variable}
onChange={(e) => handleChange("variable", e.target.value)}
className={getValidationClass("variable")}
disabled={isFetching}
>
<option value="">Select Variable</option>
<option value="">
{isFetching ? "Loading..." : "Select Variable"}
</option>
{options.variables.map((variable) => (
<option key={variable} value={variable}>
{variable}
Expand Down
176 changes: 164 additions & 12 deletions app/src/components/info/HelpGuide.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ import "./HelpGuide.css";

const OGL_URL =
"https://www2.gov.bc.ca/gov/content/data/policy-standards/data-policies/open-data/open-government-licence-bc";
const CNRM_ESM2_1_URL =
"https://www.wdc-climate.de/ui/cmip6?input=CMIP6.CMIP.CNRM-CERFACS.CNRM-ESM2-1";
const FGOALS_G3_URL =
"https://www.wdc-climate.de/ui/cmip6?input=CMIP6.CMIP.CAS.FGOALS-g3";
const IPSL_CM6A_LR_URL =
"https://www.wdc-climate.de/ui/cmip6?input=CMIP6.CMIP.IPSL.IPSL-CM6A-LR";
const MIROC_ES2L_URL =
"https://www.wdc-climate.de/ui/cmip6?input=CMIP6.ScenarioMIP.MIROC.MIROC-ES2L";
const MPI_ESM1_2_HR_URL =
"https://mpimet.mpg.de/en/communication/news/development-of-a-high-resolution-earth-system-model-and-its-application-in-cmip6";
const MRI_ESM2_0_URL =
"https://www.wdc-climate.de/ui/cmip6?input=CMIP6.CMIP.MRI.MRI-ESM2-0";
const NORESM2_LM_URL = "https://noresm-docs.readthedocs.io/en/noresm2/";
const TAIESM1_URL = "https://github.com/rceclccr/TaiESM-docs";
const UKESM1_0_LL_URL =
"https://ukesm.ac.uk/cmip-es-documentation/ukesm1-0-ll/";
const PNWNAMET_URL =
"https://www.uvic.ca/pcic/data-analysis-tools/data-portal/daily-gridded-meteorology/index.php";
const SSP_URL =
"https://climatedata.ca/resource/understanding-shared-socio-economic-pathways-ssps/";

const HelpGuide = () => {
const [isOpen, setIsOpen] = useState(false);
Expand Down Expand Up @@ -92,6 +112,16 @@ const HelpGuide = () => {
</ul>
</section>

<section>
<h3>Feature Name Search</h3>
<ul>
<li>Use top-left panel to search for features by name</li>
<li>Enter the lake or river name</li>
<li>Select a name from the drop-down of filtered names</li>
<li>The selected feature will be highlighted in light blue</li>
</ul>
</section>

<section>
<h3>Downloading Data</h3>
<ol>
Expand All @@ -107,40 +137,162 @@ const HelpGuide = () => {
<h3>Variables</h3>
<ul>
<li>
<strong>Simulated outflows (m³/s)</strong>
<strong>Streamflow (m³/s)</strong>
</li>
<li>
<strong>Observed outflows (m³/s)</strong>
<strong>Water Temperature or lake surface temperature (°C)</strong>
</li>
<li>
<strong>Simulated reservoir inflows (m³/s)</strong>
<strong>Saturated dissolved oxygen (mg/L)</strong>
</li>
</ul>
</section>

<section>
<h3>Models</h3>
<h3>Models (Forcing)</h3>
<p>
<strong>Downscaled Climate Projections</strong>
</p>
<ul>
<li>
<strong>CanESM2</strong>:{" "}
<strong>CNRM-ESM2-1</strong>:{" "}
<a
href={CNRM_ESM2_1_URL}
target="_blank"
rel="noopener noreferrer"
>
CNRM-CERFACS, Earth Systems Model second generation
</a>
</li>
<li>
<strong>FGOALS-g3</strong>:{" "}
<a
href={FGOALS_G3_URL}
target="_blank"
rel="noopener noreferrer"
>
Chinese Academy of Sciences, Flexible Global
Ocean-Atmosphere-Land System Model grid-point Version 3
</a>
</li>
<li>
<strong>IPSL-CM6A-LR</strong>:{" "}
<a
href="https://climate-modelling.canada.ca/climatemodeldata/cgcm4/CanESM2/index.shtml"
href={IPSL_CM6A_LR_URL}
target="_blank"
rel="noopener noreferrer"
>
Canadian Centre for Climate Modelling and Analysis ESM2
(Earth System Model ver. 2)
Institut Pierre Simon Laplace Climate Modelling Centre,
Climate Model Phase 6, low resolution
</a>
</li>
<li>
<strong>PCIC-HYDRO</strong>: An ensemble mean of the six GCM
runs ACCESS1-0_r1i1p1, CanESM2_r1i1pi, CCSM_r2i1p1,
CNRM-CM5_r1i1p1, HadGEM2-ES_r1i1p1 and MPI-ESM-LR_r3i1p1
<strong>MIROC-ES2L</strong>:{" "}
<a
href={MIROC_ES2L_URL}
target="_blank"
rel="noopener noreferrer"
>
Model for Interdisciplinary Research on Climate, Earth
System version 2 for Long-term simulations
</a>
</li>
<li>
<strong>MPI-ESM1-2-HR</strong>:{" "}
<a
href={MPI_ESM1_2_HR_URL}
target="_blank"
rel="noopener noreferrer"
>
Max Planck Institute, Earth System Model version 1.2 high
resolution
</a>
</li>
<li>
<strong>MRI-ESM2-0</strong>:{" "}
<a
href={MRI_ESM2_0_URL}
target="_blank"
rel="noopener noreferrer"
>
Meteorological Research Institute, Earth System Model
version 2.0
</a>
</li>
<li>
<strong>NorESM2-LM</strong>:{" "}
<a
href={NORESM2_LM_URL}
target="_blank"
rel="noopener noreferrer"
>
Norwegian Earth System Model second version
</a>
</li>
<li>
<strong>TaiESM1</strong>:{" "}
<a
href={TAIESM1_URL}
target="_blank"
rel="noopener noreferrer"
>
Taiwan Earth System Model version 1
</a>
</li>
<li>
<strong>UKESM1-0-LL</strong>:{" "}
<a
href={UKESM1_0_LL_URL}
target="_blank"
rel="noopener noreferrer"
>
The UK Meteorological Office, Earth System Model version
1
</a>
</li>
</ul>
<p>
<strong>Gridded Observations</strong>
</p>
<ul>
<li>
<strong>PNWNAmet</strong>:{" "}
<a
href={PNWNAMET_URL}
target="_blank"
rel="noopener noreferrer"
>
Gridded observations of temperature and precipitation for
Northwest North America.
</a>
</li>
</ul>
</section>

<section>
<h3>Scenarios</h3>
<p>
<strong>Climate Projections</strong>: Historical (1950-2014)
{" + "}
<a href={SSP_URL} target="_blank" rel="noopener noreferrer">
Socio-economic Pathways
</a>{" "}
(2015-2100)
</p>
<ul>
<li>Historical, SSP2-4.5</li>
<li>Historical, SSP5-8.5</li>
</ul>
<p>
<strong>Gridded Observations</strong>: Historical only
(1945-2012)
</p>
<ul>
<li>Historical (PNWNAmet only)</li>
</ul>
</section>
<section>
<h3>Credits & licensing</h3>
<h3>Credits & Licensing</h3>
<p>
This application uses data and services from the BC Geographic
Warehouse (DataBC).
Expand Down
Loading
Loading