Submit
Path:
~
/
/
usr
/
share
/
grafana
/
public
/
app
/
plugins
/
panel
/
geomap
/
components
/
File Content:
MeasureOverlay.tsx
import { css } from '@emotion/css'; import Map from 'ol/Map'; import React, { useMemo, useRef, useState } from 'react'; import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { Button, IconButton, RadioButtonGroup, Select } from '@grafana/ui'; import { config } from 'app/core/config'; import { MapMeasure, MapMeasureOptions, measures } from '../utils/measure'; import { MeasureVectorLayer } from './MeasureVectorLayer'; type Props = { map: Map; menuActiveState: (value: boolean) => void; }; export const MeasureOverlay = ({ map, menuActiveState }: Props) => { const vector = useRef(new MeasureVectorLayer()); const measureStyle = getStyles(config.theme2); // Menu State Management const [firstLoad, setFirstLoad] = useState<boolean>(true); const [menuActive, setMenuActive] = useState<boolean>(false); // Options State const [options, setOptions] = useState<MapMeasureOptions>({ action: measures[0].value!, unit: measures[0].units[0].value!, }); const unit = useMemo(() => { const action = measures.find((m: MapMeasure) => m.value === options.action) ?? measures[0]; const current = action.getUnit(options.unit); vector.current.setOptions(options); return { current, options: action.units, }; }, [options]); const clearPrevious = true; const showSegments = false; function toggleMenu() { setMenuActive(!menuActive); // Lift menu state // TODO: consolidate into one state menuActiveState(!menuActive); if (menuActive) { map.removeInteraction(vector.current.draw); vector.current.setVisible(false); } else { if (firstLoad) { // Initialize on first load setFirstLoad(false); vector.current.setZIndex(1); map.addLayer(vector.current); map.addInteraction(vector.current.modify); } vector.current.setVisible(true); map.removeInteraction(vector.current.draw); // Remove last interaction const a = measures.find((v: MapMeasure) => v.value === options.action) ?? measures[0]; vector.current.addInteraction(map, a.geometry, showSegments, clearPrevious); } } return ( <div className={`${measureStyle.infoWrap} ${!menuActive ? measureStyle.infoWrapClosed : null}`}> {menuActive ? ( <div> <div className={measureStyle.rowGroup}> <RadioButtonGroup value={options.action} options={measures} size="md" fullWidth={false} onChange={(e: string) => { map.removeInteraction(vector.current.draw); const m = measures.find((v: MapMeasure) => v.value === e) ?? measures[0]; const unit = m.getUnit(options.unit); setOptions({ ...options, action: m.value!, unit: unit.value! }); vector.current.addInteraction(map, m.geometry, showSegments, clearPrevious); }} /> <Button className={measureStyle.button} icon="times" variant="secondary" size="sm" onClick={toggleMenu} /> </div> <Select className={measureStyle.unitSelect} value={unit.current} options={unit.options} isSearchable={false} onChange={(v: SelectableValue<string>) => { const a = measures.find((v: SelectableValue<string>) => v.value === options.action) ?? measures[0]; const unit = a.getUnit(v.value) ?? a.units[0]; setOptions({ ...options, unit: unit.value! }); }} /> </div> ) : ( <IconButton className={measureStyle.icon} name="ruler-combined" tooltip="show measure tools" tooltipPlacement="left" onClick={toggleMenu} /> )} </div> ); }; const getStyles = (theme: GrafanaTheme2) => ({ button: css({ marginLeft: 'auto', }), icon: css({ backgroundColor: theme.colors.secondary.main, display: 'inline-block', height: '19.25px', margin: '1px', width: '19.25px', }), infoWrap: css({ color: `${theme.colors.text}`, backgroundColor: theme.colors.background.secondary, // eslint-disable-next-line @grafana/no-border-radius-literal borderRadius: '4px', padding: '2px', }), infoWrapClosed: css({ height: '25.25px', width: '25.25px', }), rowGroup: css({ display: 'flex', justifyContent: 'flex-end', }), unitSelect: css({ minWidth: '200px', }), });
Submit
FILE
FOLDER
INFO
Name
Size
Permission
Action
DebugOverlay.tsx
1811 bytes
0644
MarkersLegend.tsx
5364 bytes
0644
MeasureOverlay.tsx
4541 bytes
0644
MeasureVectorLayer.ts
7111 bytes
0644
ObservablePropsWrapper.tsx
873 bytes
0644
N4ST4R_ID | Naxtarrr