mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Geomap: initialization fixes (#44745)
This commit is contained in:
parent
d8df08ce5d
commit
ac90c8d68d
@ -62,7 +62,7 @@ export interface MapLayerOptions<TConfig = any> {
|
|||||||
// Layer opacity (0-1)
|
// Layer opacity (0-1)
|
||||||
opacity?: number;
|
opacity?: number;
|
||||||
|
|
||||||
// Check tooltip
|
// Check tooltip (defaults to true)
|
||||||
tooltip?: boolean;
|
tooltip?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ func newService(cfg *setting.Cfg) *Service {
|
|||||||
"img/icons",
|
"img/icons",
|
||||||
"img/bg",
|
"img/bg",
|
||||||
"gazetteer",
|
"gazetteer",
|
||||||
|
"maps",
|
||||||
"upload", // does not exist yet
|
"upload", // does not exist yet
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
DataSourceInstanceSettings,
|
DataSourceInstanceSettings,
|
||||||
DataSourceRef,
|
DataSourceRef,
|
||||||
isValidLiveChannelAddress,
|
isValidLiveChannelAddress,
|
||||||
|
MutableDataFrame,
|
||||||
parseLiveChannelAddress,
|
parseLiveChannelAddress,
|
||||||
toDataFrame,
|
toDataFrame,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
@ -149,7 +150,7 @@ export class GrafanaDatasource extends DataSourceWithBackend<GrafanaQuery> {
|
|||||||
],
|
],
|
||||||
} as any).pipe(
|
} as any).pipe(
|
||||||
map((v) => {
|
map((v) => {
|
||||||
const frame = v.data[0] ?? toDataFrame({});
|
const frame = v.data[0] ?? new MutableDataFrame();
|
||||||
return new DataFrameView<FileElement>(frame);
|
return new DataFrameView<FileElement>(frame);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
DataHoverClearEvent,
|
DataHoverClearEvent,
|
||||||
DataHoverEvent,
|
DataHoverEvent,
|
||||||
DataFrame,
|
DataFrame,
|
||||||
|
FrameGeometrySourceMode,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
|
|
||||||
@ -180,6 +181,7 @@ export class GeomapPanel extends Component<Props, State> {
|
|||||||
type: item.id,
|
type: item.id,
|
||||||
name: this.getNextLayerName(),
|
name: this.getNextLayerName(),
|
||||||
config: cloneDeep(item.defaultOptions),
|
config: cloneDeep(item.defaultOptions),
|
||||||
|
location: item.showLocation ? { mode: FrameGeometrySourceMode.Auto } : undefined,
|
||||||
tooltip: true,
|
tooltip: true,
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
@ -266,10 +268,7 @@ export class GeomapPanel extends Component<Props, State> {
|
|||||||
layers.push(await this.initLayer(map, options.basemap ?? DEFAULT_BASEMAP_CONFIG, true));
|
layers.push(await this.initLayer(map, options.basemap ?? DEFAULT_BASEMAP_CONFIG, true));
|
||||||
|
|
||||||
// Default layer values
|
// Default layer values
|
||||||
let layerOptions = options.layers;
|
const layerOptions = options.layers ?? [defaultMarkersConfig];
|
||||||
if (!layerOptions) {
|
|
||||||
layerOptions = [defaultMarkersConfig];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const lyr of layerOptions) {
|
for (const lyr of layerOptions) {
|
||||||
layers.push(await this.initLayer(map, lyr, false));
|
layers.push(await this.initLayer(map, lyr, false));
|
||||||
@ -278,10 +277,11 @@ export class GeomapPanel extends Component<Props, State> {
|
|||||||
console.error('error loading layers', ex);
|
console.error('error loading layers', ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.layers = layers;
|
|
||||||
for (const lyr of 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.mouseWheelZoom = new MouseWheelZoom();
|
||||||
this.map.addInteraction(this.mouseWheelZoom);
|
this.map.addInteraction(this.mouseWheelZoom);
|
||||||
|
@ -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 { DEFAULT_BASEMAP_CONFIG, geomapLayerRegistry } from '../layers/registry';
|
||||||
import { NestedPanelOptions, NestedValueAccess } from '@grafana/data/src/utils/OptionsUIBuilders';
|
import { NestedPanelOptions, NestedValueAccess } from '@grafana/data/src/utils/OptionsUIBuilders';
|
||||||
import { defaultMarkersConfig } from '../layers/data/markersLayer';
|
import { defaultMarkersConfig } from '../layers/data/markersLayer';
|
||||||
@ -31,11 +31,19 @@ export function getLayerEditor(opts: LayerEditorOptions): NestedPanelOptions<Map
|
|||||||
const layer = geomapLayerRegistry.getIfExists(value);
|
const layer = geomapLayerRegistry.getIfExists(value);
|
||||||
if (layer) {
|
if (layer) {
|
||||||
console.log('Change layer type:', value, state);
|
console.log('Change layer type:', value, state);
|
||||||
state.onChange({
|
const opts = {
|
||||||
...options, // keep current shared options
|
...options, // keep current shared options
|
||||||
type: layer.id,
|
type: layer.id,
|
||||||
config: { ...layer.defaultOptions }, // clone?
|
config: { ...layer.defaultOptions }, // clone?
|
||||||
});
|
};
|
||||||
|
if (layer.showLocation) {
|
||||||
|
if (!opts.location?.mode) {
|
||||||
|
opts.location = { mode: FrameGeometrySourceMode.Auto };
|
||||||
|
} else {
|
||||||
|
delete opts.location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.onChange(opts);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +84,7 @@ export function getLayerEditor(opts: LayerEditorOptions): NestedPanelOptions<Map
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (layer.showLocation) {
|
if (layer.showLocation) {
|
||||||
addLocationFields('Location', 'location', builder, options.location);
|
addLocationFields('Location', 'location.', builder, options.location);
|
||||||
}
|
}
|
||||||
if (handler.registerOptionsUI) {
|
if (handler.registerOptionsUI) {
|
||||||
handler.registerOptionsUI(builder);
|
handler.registerOptionsUI(builder);
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
import { MapLayerRegistryItem, MapLayerOptions, PanelData, GrafanaTheme2, PluginState } from '@grafana/data';
|
import {
|
||||||
|
MapLayerRegistryItem,
|
||||||
|
MapLayerOptions,
|
||||||
|
PanelData,
|
||||||
|
GrafanaTheme2,
|
||||||
|
PluginState,
|
||||||
|
SelectableValue,
|
||||||
|
} from '@grafana/data';
|
||||||
import Map from 'ol/Map';
|
import Map from 'ol/Map';
|
||||||
import VectorLayer from 'ol/layer/Vector';
|
import VectorLayer from 'ol/layer/Vector';
|
||||||
import VectorSource from 'ol/source/Vector';
|
import VectorSource from 'ol/source/Vector';
|
||||||
@ -16,6 +23,8 @@ import { StyleEditor } from './StyleEditor';
|
|||||||
import { ReplaySubject } from 'rxjs';
|
import { ReplaySubject } from 'rxjs';
|
||||||
import { map as rxjsmap, first } from 'rxjs/operators';
|
import { map as rxjsmap, first } from 'rxjs/operators';
|
||||||
import { getLayerPropertyInfo } from '../../utils/getFeatures';
|
import { getLayerPropertyInfo } from '../../utils/getFeatures';
|
||||||
|
import { GrafanaDatasource } from 'app/plugins/datasource/grafana/datasource';
|
||||||
|
import { getDataSourceSrv } from '@grafana/runtime';
|
||||||
|
|
||||||
export interface GeoJSONMapperConfig {
|
export interface GeoJSONMapperConfig {
|
||||||
// URL for a geojson file
|
// URL for a geojson file
|
||||||
@ -50,6 +59,8 @@ export const DEFAULT_STYLE_RULE: FeatureStyleConfig = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let publicGeoJSONFiles: Array<SelectableValue<string>> | undefined = undefined;
|
||||||
|
|
||||||
export const geojsonLayer: MapLayerRegistryItem<GeoJSONMapperConfig> = {
|
export const geojsonLayer: MapLayerRegistryItem<GeoJSONMapperConfig> = {
|
||||||
id: 'geojson',
|
id: 'geojson',
|
||||||
name: 'GeoJSON',
|
name: 'GeoJSON',
|
||||||
@ -151,16 +162,16 @@ export const geojsonLayer: MapLayerRegistryItem<GeoJSONMapperConfig> = {
|
|||||||
rxjsmap((v) => getLayerPropertyInfo(v))
|
rxjsmap((v) => getLayerPropertyInfo(v))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!publicGeoJSONFiles) {
|
||||||
|
initGeojsonFiles();
|
||||||
|
}
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.addSelect({
|
.addSelect({
|
||||||
path: 'config.src',
|
path: 'config.src',
|
||||||
name: 'GeoJSON URL',
|
name: 'GeoJSON URL',
|
||||||
settings: {
|
settings: {
|
||||||
options: [
|
options: publicGeoJSONFiles ?? [],
|
||||||
{ 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' },
|
|
||||||
],
|
|
||||||
allowCustomValue: true,
|
allowCustomValue: true,
|
||||||
},
|
},
|
||||||
defaultValue: defaultOptions.src,
|
defaultValue: defaultOptions.src,
|
||||||
@ -194,3 +205,28 @@ export const geojsonLayer: MapLayerRegistryItem<GeoJSONMapperConfig> = {
|
|||||||
},
|
},
|
||||||
defaultOptions,
|
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user