Skip to content

Commit

Permalink
feat(ui-map): add map zoom buttons (#1518)
Browse files Browse the repository at this point in the history
  • Loading branch information
hdinia authored May 16, 2023
1 parent c2dddaa commit 04cd3a5
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import Button from "@mui/material/Button";
import ButtonGroup from "@mui/material/ButtonGroup";
import SettingsIcon from "@mui/icons-material/Settings";
import AddIcon from "@mui/icons-material/Add";
import RemoveIcon from "@mui/icons-material/Remove";
import { Box } from "@mui/material";
import { MAX_ZOOM_LEVEL, MIN_ZOOM_LEVEL } from "./utils";

interface Props {
onZoomIn: () => void;
onZoomOut: () => void;
onOpenConfig: () => void;
zoomLevel: number;
}

function MapControlButtons({
onZoomIn,
onZoomOut,
onOpenConfig,
zoomLevel,
}: Props) {
return (
<Box
sx={{
display: "flex",
flexDirection: "column",
position: "absolute",
bottom: 15,
right: 15,
}}
>
<ButtonGroup
color="primary"
orientation="vertical"
variant="outlined"
size="small"
sx={{ mb: 2 }}
>
<Button onClick={onZoomIn} disabled={zoomLevel >= MAX_ZOOM_LEVEL}>
<AddIcon />
</Button>
<Button onClick={onZoomOut} disabled={zoomLevel <= MIN_ZOOM_LEVEL}>
<RemoveIcon />
</Button>
</ButtonGroup>
<Button
onClick={onOpenConfig}
variant="outlined"
size="small"
color="primary"
sx={{ minWidth: 40 }}
>
<SettingsIcon />
</Button>
</Box>
);
}

export default MapControlButtons;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AxiosError } from "axios";
import { DebouncedFunc } from "lodash";
import { RefObject, useEffect, useState } from "react";
import { Graph, GraphLink, GraphNode } from "react-d3-graph";
import { useTranslation } from "react-i18next";
Expand Down Expand Up @@ -27,10 +28,20 @@ interface Props {
nodes: StudyMapNode[];
graph: RefObject<Graph<StudyMapNode & GraphNode, LinkProperties & GraphLink>>;
onNodePositionChange: (id: string, x: number, y: number) => void;
zoomLevel: number;
setZoomLevel: DebouncedFunc<(zoom: number) => void>;
}

function MapGraph(props: Props) {
const { height, width, links, nodes, graph, onNodePositionChange } = props;
function MapGraph({
height,
width,
links,
nodes,
graph,
onNodePositionChange,
zoomLevel,
setZoomLevel,
}: Props) {
const [t] = useTranslation();
const dispatch = useAppDispatch();
const enqueueErrorSnackbar = useEnqueueErrorSnackbar();
Expand Down Expand Up @@ -123,6 +134,10 @@ function MapGraph(props: Props) {
);
};

const onZoomChange = (previousZoom: number, newZoom: number) => {
setZoomLevel(newZoom);
};

////////////////////////////////////////////////////////////////
// JSX
////////////////////////////////////////////////////////////////
Expand All @@ -136,6 +151,7 @@ function MapGraph(props: Props) {
links: mapNodes.length > 0 ? links : [],
}}
config={{
initialZoom: zoomLevel,
height,
width,
highlightDegree: 0,
Expand All @@ -159,6 +175,7 @@ function MapGraph(props: Props) {
onClickLink={handleOnClickLink}
onClickGraph={handleGraphClick}
onNodePositionChange={handleNodePositionChange}
onZoomChange={onZoomChange}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { useOutletContext } from "react-router-dom";
import { Fab } from "@mui/material";
import AutoSizer from "react-virtualized-auto-sizer";
import { useTranslation } from "react-i18next";
import { Graph, GraphLink, GraphNode } from "react-d3-graph";
import { AxiosError } from "axios";
import * as R from "ramda";
import * as RA from "ramda-adjunct";
import SettingsIcon from "@mui/icons-material/Settings";
import {
LinkProperties,
StudyMetadata,
Expand All @@ -18,8 +16,8 @@ import MapGraph from "./MapGraph";
import Areas from "./Areas";
import CreateAreaDialog from "./CreateAreaDialog";
import useEnqueueErrorSnackbar from "../../../../../../hooks/useEnqueueErrorSnackbar";
import { getUpdatedNode, NODE_COLOR } from "./utils";
import { MapContainer, MapFooter } from "./style";
import { getUpdatedNode, INITIAL_ZOOM, NODE_COLOR } from "./utils";
import { MapContainer } from "./style";
import useAppSelector from "../../../../../../redux/hooks/useAppSelector";
import {
getCurrentLayer,
Expand All @@ -37,6 +35,8 @@ import {
} from "../../../../../../redux/ducks/studyMaps";
import UsePromiseCond from "../../../../../common/utils/UsePromiseCond";
import MapHeader from "./MapHeader";
import MapControlButtons from "./MapControlButtons";
import useDebouncedState from "../../../../../../hooks/useDebouncedState";

function Map() {
const { study } = useOutletContext<{ study: StudyMetadata }>();
Expand All @@ -45,6 +45,7 @@ function Map() {
const enqueueErrorSnackbar = useEnqueueErrorSnackbar();
const [openDialog, setOpenDialog] = useState(false);
const [openConfig, setOpenConfig] = useState(false);
const [zoomLevel, setZoomLevel] = useDebouncedState(INITIAL_ZOOM, 250);
const previousNode = useRef<string>();
const graphRef =
useRef<Graph<GraphNode & StudyMapNode, GraphLink & LinkProperties>>(null);
Expand Down Expand Up @@ -144,6 +145,16 @@ function Map() {
}
};

const handleZoomIn = () => {
setZoomLevel(zoomLevel + 0.3);
setZoomLevel.flush();
};

const handleZoomOut = () => {
setZoomLevel(zoomLevel - 0.3);
setZoomLevel.flush();
};

const handleClose = () => {
setOpenDialog(false);
};
Expand Down Expand Up @@ -180,20 +191,17 @@ function Map() {
nodes={mapNodes}
graph={graphRef}
onNodePositionChange={handlePositionChange}
zoomLevel={zoomLevel}
setZoomLevel={setZoomLevel}
/>
)}
</AutoSizer>
<MapFooter>
<Fab
size="small"
color="default"
onClick={() => {
setOpenConfig(true);
}}
>
<SettingsIcon />
</Fab>
</MapFooter>
<MapControlButtons
onZoomIn={handleZoomIn}
onZoomOut={handleZoomOut}
onOpenConfig={() => setOpenConfig(true)}
zoomLevel={zoomLevel}
/>
</MapContainer>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ export const MapHeader = styled(Box)(() => ({
top: "10px",
}));

export const MapFooter = styled(Box)(() => ({
position: "absolute",
right: "15px",
bottom: "15px",
}));

////////////////////////////////////////////////////////////////
// Node
////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export type RGB = [number, number, number];
////////////////////////////////////////////////////////////////

export const NODE_HEIGHT = 400;
export const INITIAL_ZOOM = 1;
export const INITIAL_ZOOM = 0.8;
export const MAX_ZOOM_LEVEL = 8;
export const MIN_ZOOM_LEVEL = 0.1;
export const NODE_COLOR = "rgb(230, 108, 44)";

////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 04cd3a5

Please sign in to comment.