From ac90c8d68d27c7547b4d0d7fca2c23e390d39a3e Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Tue, 1 Feb 2022 22:08:07 -0800 Subject: [PATCH] Geomap: initialization fixes (#44745) --- packages/grafana-data/src/geo/layer.ts | 2 +- pkg/tsdb/grafanads/grafana.go | 1 + .../plugins/datasource/grafana/datasource.ts | 3 +- .../app/plugins/panel/geomap/GeomapPanel.tsx | 12 ++--- .../panel/geomap/editor/layerEditor.tsx | 16 +++++-- .../panel/geomap/layers/data/geojsonLayer.ts | 48 ++++++++++++++++--- 6 files changed, 64 insertions(+), 18 deletions(-) diff --git a/packages/grafana-data/src/geo/layer.ts b/packages/grafana-data/src/geo/layer.ts index c9ccce81d31..88c22cda757 100644 --- a/packages/grafana-data/src/geo/layer.ts +++ b/packages/grafana-data/src/geo/layer.ts @@ -62,7 +62,7 @@ export interface MapLayerOptions { // Layer opacity (0-1) opacity?: number; - // Check tooltip + // Check tooltip (defaults to true) tooltip?: boolean; } diff --git a/pkg/tsdb/grafanads/grafana.go b/pkg/tsdb/grafanads/grafana.go index 4c28b32e04b..aeca944a85c 100644 --- a/pkg/tsdb/grafanads/grafana.go +++ b/pkg/tsdb/grafanads/grafana.go @@ -51,6 +51,7 @@ func newService(cfg *setting.Cfg) *Service { "img/icons", "img/bg", "gazetteer", + "maps", "upload", // does not exist yet }, } diff --git a/public/app/plugins/datasource/grafana/datasource.ts b/public/app/plugins/datasource/grafana/datasource.ts index f7ba1a33289..323546944a1 100644 --- a/public/app/plugins/datasource/grafana/datasource.ts +++ b/public/app/plugins/datasource/grafana/datasource.ts @@ -15,6 +15,7 @@ import { DataSourceInstanceSettings, DataSourceRef, isValidLiveChannelAddress, + MutableDataFrame, parseLiveChannelAddress, toDataFrame, } from '@grafana/data'; @@ -149,7 +150,7 @@ export class GrafanaDatasource extends DataSourceWithBackend { ], } as any).pipe( map((v) => { - const frame = v.data[0] ?? toDataFrame({}); + const frame = v.data[0] ?? new MutableDataFrame(); return new DataFrameView(frame); }) ); diff --git a/public/app/plugins/panel/geomap/GeomapPanel.tsx b/public/app/plugins/panel/geomap/GeomapPanel.tsx index 244bfea89dd..01b5de26e03 100644 --- a/public/app/plugins/panel/geomap/GeomapPanel.tsx +++ b/public/app/plugins/panel/geomap/GeomapPanel.tsx @@ -15,6 +15,7 @@ import { DataHoverClearEvent, DataHoverEvent, DataFrame, + FrameGeometrySourceMode, } from '@grafana/data'; import { config } from '@grafana/runtime'; @@ -180,6 +181,7 @@ export class GeomapPanel extends Component { type: item.id, name: this.getNextLayerName(), config: cloneDeep(item.defaultOptions), + location: item.showLocation ? { mode: FrameGeometrySourceMode.Auto } : undefined, tooltip: true, }, false @@ -266,10 +268,7 @@ export class GeomapPanel extends Component { layers.push(await this.initLayer(map, options.basemap ?? DEFAULT_BASEMAP_CONFIG, true)); // Default layer values - let layerOptions = options.layers; - if (!layerOptions) { - layerOptions = [defaultMarkersConfig]; - } + const layerOptions = options.layers ?? [defaultMarkersConfig]; for (const lyr of layerOptions) { layers.push(await this.initLayer(map, lyr, false)); @@ -278,10 +277,11 @@ export class GeomapPanel extends Component { console.error('error loading layers', ex); } - this.layers = layers; for (const lyr of layers) { - this.map.addLayer(lyr.layer); + map.addLayer(lyr.layer); } + this.layers = layers; + this.map = map; // redundant this.mouseWheelZoom = new MouseWheelZoom(); this.map.addInteraction(this.mouseWheelZoom); diff --git a/public/app/plugins/panel/geomap/editor/layerEditor.tsx b/public/app/plugins/panel/geomap/editor/layerEditor.tsx index ba642f61814..4ae3c1cd85e 100644 --- a/public/app/plugins/panel/geomap/editor/layerEditor.tsx +++ b/public/app/plugins/panel/geomap/editor/layerEditor.tsx @@ -1,4 +1,4 @@ -import { MapLayerOptions, MapLayerRegistryItem, PluginState } from '@grafana/data'; +import { FrameGeometrySourceMode, MapLayerOptions, MapLayerRegistryItem, PluginState } from '@grafana/data'; import { DEFAULT_BASEMAP_CONFIG, geomapLayerRegistry } from '../layers/registry'; import { NestedPanelOptions, NestedValueAccess } from '@grafana/data/src/utils/OptionsUIBuilders'; import { defaultMarkersConfig } from '../layers/data/markersLayer'; @@ -31,11 +31,19 @@ export function getLayerEditor(opts: LayerEditorOptions): NestedPanelOptions> | undefined = undefined; + export const geojsonLayer: MapLayerRegistryItem = { id: 'geojson', name: 'GeoJSON', @@ -151,16 +162,16 @@ export const geojsonLayer: MapLayerRegistryItem = { rxjsmap((v) => getLayerPropertyInfo(v)) ); + if (!publicGeoJSONFiles) { + initGeojsonFiles(); + } + builder .addSelect({ path: 'config.src', name: 'GeoJSON URL', settings: { - options: [ - { label: 'public/maps/countries.geojson', value: 'public/maps/countries.geojson' }, - { label: 'public/maps/usa-states.geojson', value: 'public/maps/usa-states.geojson' }, - { label: 'public/gazetteer/airports.geojson', value: 'public/gazetteer/airports.geojson' }, - ], + options: publicGeoJSONFiles ?? [], allowCustomValue: true, }, defaultValue: defaultOptions.src, @@ -194,3 +205,28 @@ export const geojsonLayer: MapLayerRegistryItem = { }, defaultOptions, }; + +// This will find all geojson files in the maps and gazetteer folders +async function initGeojsonFiles() { + if (publicGeoJSONFiles) { + return; + } + publicGeoJSONFiles = []; + + const ds = (await getDataSourceSrv().get('-- Grafana --')) as GrafanaDatasource; + for (let folder of ['maps', 'gazetteer']) { + ds.listFiles(folder).subscribe({ + next: (frame) => { + frame.forEach((item) => { + if (item.name.endsWith('.geojson')) { + const value = `public/${folder}/${item.name}`; + publicGeoJSONFiles!.push({ + value, + label: value, + }); + } + }); + }, + }); + } +}