Compare commits
4 Commits
ash/react-
...
cherry-pic
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e107d7b889 | ||
|
|
e9227885ae | ||
|
|
e4b59d96df | ||
|
|
5c30bcccc7 |
@@ -177,6 +177,16 @@ Default Views are also available including:
|
||||
| South Asia | South-East Asia | East Asia | Australia | Oceania |
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
#### Enable dashboard variable (Experimental)
|
||||
|
||||
When toggled, the Geomap panel updates the dashboard variable named `mapViewData` (if it exists) with the bounding box data of the current view.
|
||||
|
||||
The variable should be of the type `Custom` and can be hidden on the dashboard by setting its visibility to “Nothing” (Show on dashboard: Nothing).
|
||||
|
||||
You can use then the variable inside your query to receive on the server side a string like this:
|
||||
|
||||
4.102646520428928,44.489253792751214,12.793524298588558,46.4346026776777
|
||||
|
||||
#### Share view
|
||||
|
||||
The **Share view** option allows you to link the movement and zoom actions of multiple map visualizations within the same dashboard. The map visualizations that have this option enabled act in tandem when one of them is moved or zoomed, leaving the other ones independent.
|
||||
|
||||
@@ -26,6 +26,7 @@ export const defaultOptions: Partial<Options> = {
|
||||
|
||||
export interface MapViewConfig {
|
||||
allLayers?: boolean;
|
||||
dashboardVariable?: boolean;
|
||||
id: string;
|
||||
lastOnly?: boolean;
|
||||
lat?: number;
|
||||
|
||||
@@ -7,6 +7,7 @@ import Attribution from 'ol/control/Attribution';
|
||||
import ScaleLine from 'ol/control/ScaleLine';
|
||||
import Zoom from 'ol/control/Zoom';
|
||||
import { Coordinate } from 'ol/coordinate';
|
||||
import { EventsKey } from 'ol/events';
|
||||
import { isEmpty } from 'ol/extent';
|
||||
import MouseWheelZoom from 'ol/interaction/MouseWheelZoom';
|
||||
import { fromLonLat, transformExtent } from 'ol/proj';
|
||||
@@ -16,7 +17,7 @@ import { Subscription } from 'rxjs';
|
||||
|
||||
import { DataHoverEvent, PanelData, PanelProps } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { config, locationService } from '@grafana/runtime';
|
||||
import { PanelContext, PanelContextRoot } from '@grafana/ui';
|
||||
import { appEvents } from 'app/core/app_events';
|
||||
import { VariablesChanged } from 'app/features/variables/types';
|
||||
@@ -73,6 +74,8 @@ export class GeomapPanel extends Component<Props, State> {
|
||||
layers: MapLayerState[] = [];
|
||||
readonly byName = new Map<string, MapLayerState>();
|
||||
|
||||
mapViewData?: string;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = { ttipOpen: false, legends: [] };
|
||||
@@ -125,6 +128,12 @@ export class GeomapPanel extends Component<Props, State> {
|
||||
// Check for resize
|
||||
if (this.props.height !== nextProps.height || this.props.width !== nextProps.width) {
|
||||
this.map.updateSize();
|
||||
// update dashboard variable if enabled
|
||||
const options = this.props.options;
|
||||
if (options.view.dashboardVariable) {
|
||||
const view = this.map.getView();
|
||||
this.updateGeoVariables(view, options);
|
||||
}
|
||||
}
|
||||
|
||||
// External data changed
|
||||
@@ -227,6 +236,28 @@ export class GeomapPanel extends Component<Props, State> {
|
||||
this.setState({ legends: this.getLegends() });
|
||||
}
|
||||
|
||||
// view listerner handler, used to unregister when view changes
|
||||
private viewListernerKey: EventsKey | null = null;
|
||||
|
||||
// updateGeoVariables debounce timeout
|
||||
private timeoutId: NodeJS.Timeout | null = null; // for debounce
|
||||
|
||||
// Updates the dashboard variable `mapViewData` with the view extent value.
|
||||
// Use a debounce strategy to wait the user stop dragging or zooming the map.
|
||||
updateGeoVariables = (view: View, options: Options) => {
|
||||
const bounds = view.calculateExtent();
|
||||
const bounds4326 = transformExtent(bounds, 'EPSG:3857', 'EPSG:4326');
|
||||
if (this.timeoutId) {
|
||||
clearTimeout(this.timeoutId);
|
||||
}
|
||||
this.timeoutId = setTimeout(() => {
|
||||
if (options.controls.showDebug) {
|
||||
console.log('GeomapPanel.updateGeoVariables', bounds4326);
|
||||
}
|
||||
locationService.partial({ 'var-mapViewData': `${bounds4326}` }, true);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
initMapAsync = async (div: HTMLDivElement | null) => {
|
||||
if (!div) {
|
||||
// Do not initialize new map or dispose old map
|
||||
@@ -268,7 +299,9 @@ export class GeomapPanel extends Component<Props, State> {
|
||||
}
|
||||
this.layers = layers;
|
||||
this.map = map; // redundant
|
||||
this.initViewExtent(map.getView(), options.view);
|
||||
const view = map.getView();
|
||||
const viewConfig = options.view;
|
||||
this.initViewExtent(view, viewConfig);
|
||||
|
||||
this.mouseWheelZoom = new MouseWheelZoom();
|
||||
this.map?.addInteraction(this.mouseWheelZoom);
|
||||
@@ -278,6 +311,20 @@ export class GeomapPanel extends Component<Props, State> {
|
||||
notifyPanelEditor(this, layers, layers.length - 1);
|
||||
|
||||
this.setState({ legends: this.getLegends() });
|
||||
|
||||
// register view listener to update dashboard variable if enabled
|
||||
if (viewConfig.dashboardVariable) {
|
||||
if (options.controls.showDebug) {
|
||||
console.log('Geomap.initMapAsync: register view listener', view);
|
||||
}
|
||||
if (this.viewListernerKey != null) {
|
||||
view.un('change', this.viewListernerKey.listener);
|
||||
}
|
||||
this.viewListernerKey = view.on('change', () => {
|
||||
this.updateGeoVariables(view, options);
|
||||
});
|
||||
this.updateGeoVariables(view, options);
|
||||
}
|
||||
};
|
||||
|
||||
clearTooltip = () => {
|
||||
|
||||
@@ -32,6 +32,14 @@ export const plugin = new PanelPlugin<Options>(GeomapPanel)
|
||||
defaultValue: defaultMapViewConfig,
|
||||
});
|
||||
|
||||
builder.addBooleanSwitch({
|
||||
category,
|
||||
path: 'view.dashboardVariable',
|
||||
description: 'Store view bounds into the "mapViewData" dashboard variable.',
|
||||
name: 'Enable dashboard variable (Experimental)',
|
||||
defaultValue: false,
|
||||
});
|
||||
|
||||
builder.addBooleanSwitch({
|
||||
category,
|
||||
path: 'view.shared',
|
||||
|
||||
@@ -34,18 +34,19 @@ composableKinds: PanelCfg: {
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
MapViewConfig: {
|
||||
id: string | *"zero"
|
||||
lat?: int64 | *0
|
||||
lon?: int64 | *0
|
||||
zoom?: int64 | *1
|
||||
minZoom?: int64
|
||||
maxZoom?: int64
|
||||
padding?: int64
|
||||
allLayers?: bool | *true
|
||||
lastOnly?: bool
|
||||
layer?: string
|
||||
shared?: bool
|
||||
noRepeat?: bool | *false
|
||||
id: string | *"zero"
|
||||
lat?: int64 | *0
|
||||
lon?: int64 | *0
|
||||
zoom?: int64 | *1
|
||||
minZoom?: int64
|
||||
maxZoom?: int64
|
||||
padding?: int64
|
||||
allLayers?: bool | *true
|
||||
lastOnly?: bool
|
||||
layer?: string
|
||||
shared?: bool
|
||||
noRepeat?: bool | *false
|
||||
dashboardVariable?: bool
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
ControlsOptions: {
|
||||
|
||||
1
public/app/plugins/panel/geomap/panelcfg.gen.ts
generated
1
public/app/plugins/panel/geomap/panelcfg.gen.ts
generated
@@ -24,6 +24,7 @@ export const defaultOptions: Partial<Options> = {
|
||||
|
||||
export interface MapViewConfig {
|
||||
allLayers?: boolean;
|
||||
dashboardVariable?: boolean;
|
||||
id: string;
|
||||
lastOnly?: boolean;
|
||||
lat?: number;
|
||||
|
||||
Reference in New Issue
Block a user