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
18 changes: 15 additions & 3 deletions oceannavigator/frontend/src/components/AxisRange.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ function AxisRange(props) {
const [max, setMax] = useState(props.range?props.range[1]:props.variable.scale[1]);
const timerRef = useRef(null);

useEffect(() => {
setMin(props.is_imperial?props.variable.imperial_scale[0]:props.variable.scale[0])
setMax(props.is_imperial?props.variable.imperial_scale[1]:props.variable.scale[1])
}, [props.is_imperial])

useEffect(() => {
let newMin = parseFloat(min);
let newMax = parseFloat(max);
Expand Down Expand Up @@ -51,11 +56,17 @@ function AxisRange(props) {
const handleResetButton = () => {
clearTimeout(timerRef.current);

setMin(props.variable.scale[0]);
setMax(props.variable.scale[1]);
let scale = props.variable.scale

if (props.is_imperial){
scale = props.variable.imperial_scale
}

setMin(scale[0]);
setMax(scale[1]);

timerRef.current = setTimeout(
updateParent([props.variable.scale[0], props.variable.scale[1]]),
updateParent([scale[0], scale[1]]),
500,
);
};
Expand Down Expand Up @@ -110,6 +121,7 @@ AxisRange.propTypes = {
id: PropTypes.string,
title: PropTypes.string,
variable: PropTypes.object,
is_imperial: PropTypes.bool,
range: PropTypes.array,
onUpdate: PropTypes.func,
};
Expand Down
19 changes: 19 additions & 0 deletions oceannavigator/frontend/src/components/DatasetPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";

import AxisRange from "./AxisRange.jsx";
import Toggle from "./data-selectors/Toggle.jsx";
import DatasetSelector from "./data-selectors/DatasetSelector.jsx";
import VariableSelector from "./data-selectors/VariableSelector.jsx";
import TimeSelector from "./data-selectors/TimeSelector.jsx";
Expand All @@ -26,6 +27,7 @@ function DatasetPanel({
showQuiverSelector = true,
showTimeRange = false,
showDepthSelector = true,
showUnitSelector = false,
showAxisRange = false,
showVariableSelector = true,
showAllDepths = false,
Expand Down Expand Up @@ -115,6 +117,12 @@ function DatasetPanel({
axisRange: newAxisRange,
}));
break;
case "unitSelection":
setDataset((prevDataset) => ({
...prevDataset,
unitSelection: value,
}));
break;
default:
setDataset((prevDataset) => ({
...prevDataset,
Expand Down Expand Up @@ -165,6 +173,14 @@ function DatasetPanel({
/>
) : null;

let unitSelector = showUnitSelector ? (
<Toggle
id="use_imperial_units"
dataset={dataset}
onChange={updateDataset}
/>
) : null;

let axisRangeSelectors = [];
if (showAxisRange) {
let axisVariables = Array.isArray(dataset.variable)
Expand All @@ -177,6 +193,7 @@ function DatasetPanel({
id={variable.id + "_axis_range"}
title={variable.value + " Range"}
variable={variable}
is_imperial={dataset.unitSelection[variable.id]}
range={dataset.axisRange[variable.id]}
onUpdate={updateDataset}
/>
Expand Down Expand Up @@ -324,6 +341,7 @@ function DatasetPanel({
horizontalLayout={horizontalLayout}
/>
{variableSelector}
{unitSelector}
{axisRangeSelectors}
{quiverSelector}
{depthSelector}
Expand Down Expand Up @@ -359,6 +377,7 @@ DatasetPanel.propTypes = {
showQuiverSelector: PropTypes.bool,
showTimeRange: PropTypes.bool,
showDepthSelector: PropTypes.bool,
showUnitSelector: PropTypes.bool,
showAxisRange: PropTypes.bool,
showVariableSelector: PropTypes.bool,
showAllDepths: PropTypes.bool,
Expand Down
172 changes: 172 additions & 0 deletions oceannavigator/frontend/src/components/data-selectors/Toggle.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import React from "react";
import PropTypes from "prop-types";
import Form from "react-bootstrap/Form";
import { withTranslation } from "react-i18next";
import { useEffect } from "react";
import Accordion from "react-bootstrap/Accordion";

const Toggle = ({ id, dataset, onChange }) => {

const variables = Array.isArray(dataset?.variable)
? dataset.variable
: dataset?.variable
? [dataset.variable]
: [];
const unitSelection = dataset?.unitSelection || {};
const axisRange = dataset?.axisRange || {};

//For radio display, unchecking/checking all if all variables are not the same value (true or false)
const allSameBoolean = Object.keys(unitSelection).length > 0 && (Object.values(unitSelection).every((value) => value === true) || Object.values(unitSelection).every((value) => value === false));

const updateDataset = (key, value) => {
onChange(key, value);
};

// Build unit selection object
const buildUnitSelection = () => {
return {
all: false,
depth: false,
...Object.fromEntries(
variables.map((variable) => [variable.id, false])
),
};
};

// Updates axis range scale with imperial scale if checked, otherwise with metric scale
const setAxisRangeScale = (varId, checked) => {
if (
varId !== "all" &&
varId !== "depth" &&
axisRange[varId] != null
) {
if (checked) {
updateDataset("axisRange", [varId, dataset.variable.imperial_scale]);
}
else if (!checked) {
updateDataset("axisRange",[varId, dataset.variable.scale]);
}
}
}

// updates unit selection object when values are selected on UI
const updateUnitSelection = (varId, checked) => {
let currentSelection = dataset.unitSelection;

// If "all" is selected, update all variables to the same value
if (varId === "all") {
const updatedSelection = Object.fromEntries(
Object.keys(currentSelection).map((id) => [id, checked])
);

updateDataset("unitSelection", updatedSelection);

Object.keys(unitSelection).forEach((variableId) => {
setAxisRangeScale(variableId, checked);
});
} // Otherwise update single variable
else {
const updatedSelection = {
...currentSelection,
[varId]: checked,
};

// Update "all" selection based on whether all variables are selected or not
const variableIds = Object.keys(updatedSelection).filter(
(id) => id !== "all"
);
updatedSelection.all =
variableIds.length > 0 &&
variableIds.every((id) => updatedSelection[id]);

updateDataset("unitSelection", updatedSelection);

setAxisRangeScale(varId, checked);
}
};

const radioOptions = [
{
id: "all",
label: "All Variables",
},
{
id: "depth",
label: "Depth",
},
...variables.map((variable) => ({
id: variable.id,
label: variable.value,
})),
];

useEffect(() => {
// Rebuild the unit selection when the variables changes
updateDataset("unitSelection", buildUnitSelection(dataset));
}, [dataset.variable]);

return (
<div className="units-options">
<div>
<Accordion className="imperial-units-accordion">
<Accordion.Item eventKey={id}>
<Accordion.Header>{"Unit Selection"} </Accordion.Header>
<Accordion.Body>
<div className="unit-table">
<div className="unit-table-header">
<span className="unit-table-header-spacer" />
<span className="unit-table-header-col">Metric</span>
<span className="unit-table-header-col">Imperial</span>
</div>

{radioOptions.map((option) => (
<div key={option.id} className="unit-table-row">
<Form.Label className="unit-option-label mb-0">
{option.label}:
</Form.Label>

<div className="unit-radio-cell">
<Form.Check
type="radio"
aria-label="Metric"
name={`units-${option.id}`}
id={`metric-${option.id}`}
value="metric"
checked={(option.id==="all" && !allSameBoolean)?Boolean(unitSelection?.[option.id]):Boolean(!unitSelection?.[option.id])}
onChange={() =>
updateUnitSelection(option.id, false)
}
/>
</div>

<div className="unit-radio-cell">
<Form.Check
type="radio"
aria-label="Imperial"
name={`units-${option.id}`}
id={`imperial-${option.id}`}
value="imperial"
checked={Boolean(unitSelection?.[option.id])}
onChange={() =>
updateUnitSelection(option.id, true)
}
/>
</div>
</div>
))}
</div>
</Accordion.Body>
</Accordion.Item>
</Accordion>
</div>
</div>
);
};

Toggle.propTypes = {
id: PropTypes.string.isRequired,
dataset: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
};

export default withTranslation()(Toggle);
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ const PointWindow = ({
axisRange: dataset.hasOwnProperty("axisRange")
? dataset.axisRange
: { [dataset.variable.id]: null },
unitSelection: dataset.hasOwnProperty("unitSelection")
? dataset.unitSelection
: {
all: false,
depth: false,
[dataset.variable.id]: false
},
},
);
const [only2d, setOnly2d] = useState(false);
Expand Down Expand Up @@ -96,6 +103,17 @@ const PointWindow = ({
setOnly2d(dataset2D);
}, [plotDataset]);

useEffect(() => {
setPlotDataset((prev) => ({
...prev,
unitSelection: {
all: false,
depth: false,
[dataset.variable.id]: false
}
}));
}, [selected]);

const handleDatasetUpdate = (key, value) => {
setPlotDataset((prev) => ({ ...prev, ...value }));
if (value.variable && value.depth !== "all") {
Expand Down Expand Up @@ -152,6 +170,7 @@ const PointWindow = ({
].includes(selected);
const multipleVariables = selected === TabEnum.PROFILE;
const showAxisRange = [TabEnum.PROFILE, TabEnum.MOORING].includes(selected);
const showUnitSelector = (selected !== TabEnum.OBSERVATION && selected !== TabEnum.SOUND);

const plotOptions = (
<>
Expand Down Expand Up @@ -205,6 +224,7 @@ const PointWindow = ({
onUpdate={handleDatasetUpdate}
showQuiverSelector={false}
showVariableRange={false}
showUnitSelector={showUnitSelector}
showAxisRange={showAxisRange}
showTimeRange={showTimeRange}
disableTimeSelector={selected === TabEnum.OBSERVATION}
Expand Down Expand Up @@ -269,6 +289,7 @@ const PointWindow = ({
dataset: plotDataset.id,
names: names,
};

let axisRange = Array.isArray(plotDataset.variable)
? plotDataset.variable.map((v) => plotDataset.axisRange[v.id])
: plotDataset.axisRange[plotDataset.variable.id];
Expand All @@ -279,6 +300,7 @@ const PointWindow = ({
...plotQuery,
station: plotData.coordinates,
showmap: showMap,
unitSelection: plotDataset.unitSelection,
time: plotDataset.time.id,
variable: Array.isArray(plotDataset.variable)
? plotDataset.variable.map((v) => v.id)
Expand All @@ -294,6 +316,7 @@ const PointWindow = ({
...plotQuery,
station: plotData.coordinates,
showmap: showMap,
unitSelection: plotDataset.unitSelection,
time: plotDataset.time.id,
variable: `${hasTemp ? `${tempId},` : ""}${hasSal ? `${salId}` : ""}`,
};
Expand All @@ -304,6 +327,7 @@ const PointWindow = ({
...plotQuery,
station: plotData.coordinates,
showmap: showMap,
unitSelection: plotDataset.unitSelection,
time: plotDataset.time.id,
};
plotType = "ts";
Expand All @@ -313,6 +337,7 @@ const PointWindow = ({
...plotQuery,
station: plotData.coordinates,
showmap: showMap,
unitSelection: plotDataset.unitSelection,
time: plotDataset.time.id,
};
plotType = "sound";
Expand All @@ -336,6 +361,7 @@ const PointWindow = ({
: plotDataset.variable.id,
variable_range: axisRange,
showmap: showMap,
unitSelection: plotDataset.unitSelection,
station: plotData.coordinates,
depth: plotDataset.depth,
starttime: plotDataset.starttime.id,
Expand Down
Loading
Loading