mirror of
https://github.com/grafana/grafana.git
synced 2025-09-23 12:23:00 +08:00
120 lines
3.5 KiB
TypeScript
120 lines
3.5 KiB
TypeScript
import { toLonLat } from 'ol/proj';
|
|
import React, { FC, useMemo, useCallback } from 'react';
|
|
|
|
import { StandardEditorProps, SelectableValue } from '@grafana/data';
|
|
import { Button, InlineField, InlineFieldRow, Select, VerticalGroup } from '@grafana/ui';
|
|
import { NumberInput } from 'app/core/components/OptionsUI/NumberInput';
|
|
|
|
import { GeomapPanelOptions, MapViewConfig, GeomapInstanceState } from '../types';
|
|
import { centerPointRegistry, MapCenterID } from '../view';
|
|
|
|
export const MapViewEditor: FC<
|
|
StandardEditorProps<MapViewConfig, unknown, GeomapPanelOptions, GeomapInstanceState>
|
|
> = ({ value, onChange, context }) => {
|
|
const labelWidth = 10;
|
|
|
|
const views = useMemo(() => {
|
|
const ids: string[] = [];
|
|
if (value?.id) {
|
|
ids.push(value.id);
|
|
} else {
|
|
ids.push(centerPointRegistry.list()[0].id);
|
|
}
|
|
return centerPointRegistry.selectOptions(ids);
|
|
}, [value?.id]);
|
|
|
|
const onSetCurrentView = useCallback(() => {
|
|
const map = context.instanceState?.map;
|
|
if (map) {
|
|
const view = map.getView();
|
|
const coords = view.getCenter();
|
|
if (coords) {
|
|
const center = toLonLat(coords, view.getProjection());
|
|
onChange({
|
|
...value,
|
|
id: MapCenterID.Coordinates,
|
|
lon: +center[0].toFixed(6),
|
|
lat: +center[1].toFixed(6),
|
|
zoom: +view.getZoom()!.toFixed(2),
|
|
});
|
|
}
|
|
}
|
|
}, [value, onChange, context.instanceState]);
|
|
|
|
const onSelectView = useCallback(
|
|
(selection: SelectableValue<string>) => {
|
|
const v = centerPointRegistry.getIfExists(selection.value);
|
|
if (v) {
|
|
onChange({
|
|
...value,
|
|
id: v.id,
|
|
lat: v.lat ?? value?.lat,
|
|
lon: v.lon ?? value?.lon,
|
|
zoom: v.zoom ?? value?.zoom,
|
|
});
|
|
}
|
|
},
|
|
[value, onChange]
|
|
);
|
|
|
|
return (
|
|
<>
|
|
<InlineFieldRow>
|
|
<InlineField label="View" labelWidth={labelWidth} grow={true}>
|
|
<Select options={views.options} value={views.current} onChange={onSelectView} />
|
|
</InlineField>
|
|
</InlineFieldRow>
|
|
{value?.id === MapCenterID.Coordinates && (
|
|
<>
|
|
<InlineFieldRow>
|
|
<InlineField label="Latitude" labelWidth={labelWidth} grow={true}>
|
|
<NumberInput
|
|
value={value.lat}
|
|
min={-90}
|
|
max={90}
|
|
step={0.001}
|
|
onChange={(v) => {
|
|
onChange({ ...value, lat: v });
|
|
}}
|
|
/>
|
|
</InlineField>
|
|
</InlineFieldRow>
|
|
<InlineFieldRow>
|
|
<InlineField label="Longitude" labelWidth={labelWidth} grow={true}>
|
|
<NumberInput
|
|
value={value.lon}
|
|
min={-180}
|
|
max={180}
|
|
step={0.001}
|
|
onChange={(v) => {
|
|
onChange({ ...value, lon: v });
|
|
}}
|
|
/>
|
|
</InlineField>
|
|
</InlineFieldRow>
|
|
</>
|
|
)}
|
|
|
|
<InlineFieldRow>
|
|
<InlineField label="Zoom" labelWidth={labelWidth} grow={true}>
|
|
<NumberInput
|
|
value={value?.zoom ?? 1}
|
|
min={1}
|
|
max={18}
|
|
step={0.01}
|
|
onChange={(v) => {
|
|
onChange({ ...value, zoom: v });
|
|
}}
|
|
/>
|
|
</InlineField>
|
|
</InlineFieldRow>
|
|
|
|
<VerticalGroup>
|
|
<Button variant="secondary" size="sm" fullWidth onClick={onSetCurrentView}>
|
|
<span>Use current map settings</span>
|
|
</Button>
|
|
</VerticalGroup>
|
|
</>
|
|
);
|
|
};
|