mirror of https://github.com/grafana/grafana
Geomap: improve the view configuration (#36893)
parent
001331e2ac
commit
ee3a320540
@ -1,85 +0,0 @@ |
||||
import React, { FC, useMemo } from 'react'; |
||||
import { GrafanaTheme, StandardEditorProps } from '@grafana/data'; |
||||
import { Select, stylesFactory, useStyles } from '@grafana/ui'; |
||||
import { GeomapPanelOptions, MapCenterConfig } from '../types'; |
||||
import { centerPointRegistry, MapCenterID } from '../view'; |
||||
import { css } from '@emotion/css'; |
||||
import { NumberInput } from '../components/NumberInput'; |
||||
|
||||
export const MapCenterEditor: FC<StandardEditorProps<MapCenterConfig, any, GeomapPanelOptions>> = ({ |
||||
value, |
||||
onChange, |
||||
context, |
||||
}) => { |
||||
const style = useStyles(getStyles); |
||||
|
||||
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]); |
||||
|
||||
return ( |
||||
<div> |
||||
<Select |
||||
options={views.options} |
||||
value={views.current} |
||||
onChange={(v) => { |
||||
onChange({ |
||||
id: v.value!, |
||||
}); |
||||
}} |
||||
/> |
||||
{value?.id === MapCenterID.Coordinates && ( |
||||
<div> |
||||
<table className={style.table}> |
||||
<tbody> |
||||
<tr> |
||||
<th className={style.half}>Latitude</th> |
||||
<th className={style.half}>Longitude</th> |
||||
</tr> |
||||
<tr> |
||||
<td> |
||||
<NumberInput |
||||
value={value.lat} |
||||
min={-90} |
||||
max={90} |
||||
placeholder="0" |
||||
onChange={(v) => { |
||||
onChange({ ...value, lat: v }); |
||||
}} |
||||
/> |
||||
</td> |
||||
<td> |
||||
<NumberInput |
||||
value={value.lon} |
||||
min={-180} |
||||
max={180} |
||||
placeholder="0" |
||||
onChange={(v) => { |
||||
onChange({ ...value, lon: v }); |
||||
}} |
||||
/> |
||||
</td> |
||||
</tr> |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
)} |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme) => ({ |
||||
table: css` |
||||
width: 100%; |
||||
margin-top: 8px; |
||||
`,
|
||||
half: css` |
||||
width: 50%; |
||||
`,
|
||||
})); |
@ -0,0 +1,120 @@ |
||||
import React, { FC, useMemo, useCallback } from 'react'; |
||||
import { StandardEditorProps, SelectableValue } from '@grafana/data'; |
||||
import { Button, InlineField, InlineFieldRow, Select, VerticalGroup } from '@grafana/ui'; |
||||
import { GeomapPanelOptions, MapViewConfig } from '../types'; |
||||
import { centerPointRegistry, MapCenterID } from '../view'; |
||||
import { NumberInput } from '../components/NumberInput'; |
||||
import { lastGeomapPanelInstance } from '../GeomapPanel'; |
||||
import { toLonLat } from 'ol/proj'; |
||||
|
||||
export const MapViewEditor: FC<StandardEditorProps<MapViewConfig, any, GeomapPanelOptions>> = ({ |
||||
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 = lastGeomapPanelInstance?.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]); |
||||
|
||||
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> |
||||
</> |
||||
); |
||||
}; |
@ -1,18 +0,0 @@ |
||||
import React, { FC } from 'react'; |
||||
import { StandardEditorProps } from '@grafana/data'; |
||||
import { GeomapPanelOptions } from '../types'; |
||||
import { NumberInput } from '../components/NumberInput'; |
||||
|
||||
export const MapZoomEditor: FC<StandardEditorProps<number | undefined, any, GeomapPanelOptions>> = ({ |
||||
value, |
||||
onChange, |
||||
context, |
||||
}) => { |
||||
// TODO:
|
||||
// Somehow use context to get the current map and listen to zoom changes
|
||||
return ( |
||||
<div> |
||||
<NumberInput value={value} min={1} max={30} onChange={onChange} /> |
||||
</div> |
||||
); |
||||
}; |
Loading…
Reference in new issue