mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Geomap: Add alpha day/night layer (#50201)
Co-authored-by: drew08t <drew08@gmail.com>
This commit is contained in:
parent
a37b868da7
commit
c2aee2b6da
@ -139,6 +139,7 @@
|
||||
"@types/logfmt": "^1.2.1",
|
||||
"@types/mousetrap": "1.6.9",
|
||||
"@types/node": "16.11.36",
|
||||
"@types/ol-ext": "npm:@siedlerchr/types-ol-ext@2.0.0",
|
||||
"@types/papaparse": "5.3.2",
|
||||
"@types/pluralize": "^0.0.29",
|
||||
"@types/prismjs": "1.26.0",
|
||||
@ -337,6 +338,7 @@
|
||||
"mousetrap-global-bind": "1.1.0",
|
||||
"moveable": "0.30.0",
|
||||
"ol": "6.14.1",
|
||||
"ol-ext": "^3.2.25",
|
||||
"papaparse": "5.3.2",
|
||||
"pluralize": "^8.0.0",
|
||||
"prismjs": "1.28.0",
|
||||
|
@ -2,6 +2,7 @@ import { PluggableMap } from 'ol';
|
||||
import BaseLayer from 'ol/layer/Base';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { EventBus } from '../events';
|
||||
import { GrafanaTheme2 } from '../themes';
|
||||
import { MatcherConfig, PanelData } from '../types';
|
||||
import { PanelOptionsEditorBuilder } from '../utils';
|
||||
@ -79,6 +80,11 @@ export interface MapLayerHandler<TConfig = any> {
|
||||
* The update function should only be implemented if the layer type makes use of query data
|
||||
*/
|
||||
update?: (data: PanelData) => void;
|
||||
|
||||
/** Optional callback to cleaup before getting removed */
|
||||
dispose?: () => void;
|
||||
|
||||
/** return react node for the legend */
|
||||
legend?: ReactNode;
|
||||
|
||||
/**
|
||||
@ -112,5 +118,10 @@ export interface MapLayerRegistryItem<TConfig = MapLayerOptions> extends Registr
|
||||
* Function that configures transformation and returns a transformer
|
||||
* @param options
|
||||
*/
|
||||
create: (map: PluggableMap, options: MapLayerOptions<TConfig>, theme: GrafanaTheme2) => Promise<MapLayerHandler>;
|
||||
create: (
|
||||
map: PluggableMap,
|
||||
options: MapLayerOptions<TConfig>,
|
||||
eventBus: EventBus,
|
||||
theme: GrafanaTheme2
|
||||
) => Promise<MapLayerHandler>;
|
||||
}
|
||||
|
@ -100,6 +100,13 @@ export class GeomapPanel extends Component<Props, State> {
|
||||
this.panelContext = this.context as PanelContext;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.subs.unsubscribe();
|
||||
for (const lyr of this.layers) {
|
||||
lyr.handler.dispose?.();
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps: Props) {
|
||||
if (!this.map) {
|
||||
return true; // not yet initialized
|
||||
@ -404,7 +411,7 @@ export class GeomapPanel extends Component<Props, State> {
|
||||
{
|
||||
layerFilter: (l) => {
|
||||
const hoverLayerState = (l as any).__state as MapLayerState;
|
||||
return hoverLayerState.options.tooltip !== false;
|
||||
return hoverLayerState?.options?.tooltip !== false;
|
||||
},
|
||||
}
|
||||
);
|
||||
@ -467,6 +474,7 @@ export class GeomapPanel extends Component<Props, State> {
|
||||
const layers = this.layers.slice(0);
|
||||
try {
|
||||
const info = await this.initLayer(this.map, newOptions, current.isBasemap);
|
||||
layers[layerIndex]?.handler.dispose?.();
|
||||
layers[layerIndex] = info;
|
||||
group.setAt(layerIndex, info.layer);
|
||||
|
||||
@ -504,7 +512,7 @@ export class GeomapPanel extends Component<Props, State> {
|
||||
return Promise.reject('unknown layer: ' + options.type);
|
||||
}
|
||||
|
||||
const handler = await item.create(map, options, config.theme2);
|
||||
const handler = await item.create(map, options, this.props.eventBus, config.theme2);
|
||||
const layer = handler.init();
|
||||
if (options.opacity != null) {
|
||||
layer.setOpacity(1 - options.opacity);
|
||||
|
@ -3,6 +3,7 @@ import { css } from '@emotion/react';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
import 'ol/ol.css';
|
||||
import 'ol-ext/dist/ol-ext.css';
|
||||
|
||||
/**
|
||||
* Will be loaded *after* the css above
|
||||
|
@ -2,7 +2,7 @@ import Map from 'ol/Map';
|
||||
import TileLayer from 'ol/layer/Tile';
|
||||
import XYZ from 'ol/source/XYZ';
|
||||
|
||||
import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2 } from '@grafana/data';
|
||||
import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2, EventBus } from '@grafana/data';
|
||||
|
||||
// https://carto.com/help/building-maps/basemap-list/
|
||||
|
||||
@ -33,7 +33,7 @@ export const carto: MapLayerRegistryItem<CartoConfig> = {
|
||||
* Function that configures transformation and returns a transformer
|
||||
* @param options
|
||||
*/
|
||||
create: async (map: Map, options: MapLayerOptions<CartoConfig>, theme: GrafanaTheme2) => ({
|
||||
create: async (map: Map, options: MapLayerOptions<CartoConfig>, eventBus: EventBus, theme: GrafanaTheme2) => ({
|
||||
init: () => {
|
||||
const cfg = { ...defaultCartoConfig, ...options.config };
|
||||
let style = cfg.theme as string;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Map from 'ol/Map';
|
||||
|
||||
import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2, RegistryItem, Registry } from '@grafana/data';
|
||||
import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2, RegistryItem, Registry, EventBus } from '@grafana/data';
|
||||
|
||||
import { xyzTiles, defaultXYZConfig, XYZConfig } from './generic';
|
||||
|
||||
@ -60,7 +60,7 @@ export const esriXYZTiles: MapLayerRegistryItem<ESRIXYZConfig> = {
|
||||
description: 'Add layer from an ESRI ArcGIS MapServer',
|
||||
isBaseMap: true,
|
||||
|
||||
create: async (map: Map, options: MapLayerOptions<ESRIXYZConfig>, theme: GrafanaTheme2) => {
|
||||
create: async (map: Map, options: MapLayerOptions<ESRIXYZConfig>, eventBus: EventBus, theme: GrafanaTheme2) => {
|
||||
const cfg = { ...options.config };
|
||||
const svc = publicServiceRegistry.getIfExists(cfg.server ?? DEFAULT_SERVICE)!;
|
||||
if (svc.id !== CUSTOM_SERVICE) {
|
||||
@ -69,7 +69,7 @@ export const esriXYZTiles: MapLayerRegistryItem<ESRIXYZConfig> = {
|
||||
cfg.attribution = `Tiles © <a href="${base}${svc.slug}/MapServer">ArcGIS</a>`;
|
||||
}
|
||||
const opts = { ...options, config: cfg as XYZConfig };
|
||||
return xyzTiles.create(map, opts, theme).then((xyz) => {
|
||||
return xyzTiles.create(map, opts, eventBus, theme).then((xyz) => {
|
||||
xyz.registerOptionsUI = (builder) => {
|
||||
builder
|
||||
.addSelect({
|
||||
|
@ -2,7 +2,7 @@ import Map from 'ol/Map';
|
||||
import TileLayer from 'ol/layer/Tile';
|
||||
import XYZ from 'ol/source/XYZ';
|
||||
|
||||
import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2 } from '@grafana/data';
|
||||
import { MapLayerRegistryItem, MapLayerOptions, GrafanaTheme2, EventBus } from '@grafana/data';
|
||||
|
||||
export interface XYZConfig {
|
||||
url: string;
|
||||
@ -23,7 +23,7 @@ export const xyzTiles: MapLayerRegistryItem<XYZConfig> = {
|
||||
description: 'Add map from a generic tile layer',
|
||||
isBaseMap: true,
|
||||
|
||||
create: async (map: Map, options: MapLayerOptions<XYZConfig>, theme: GrafanaTheme2) => ({
|
||||
create: async (map: Map, options: MapLayerOptions<XYZConfig>, eventBus: EventBus, theme: GrafanaTheme2) => ({
|
||||
init: () => {
|
||||
const cfg = { ...options.config };
|
||||
if (!cfg.url) {
|
||||
|
@ -2,7 +2,7 @@ import Map from 'ol/Map';
|
||||
import TileLayer from 'ol/layer/Tile';
|
||||
import OSM from 'ol/source/OSM';
|
||||
|
||||
import { MapLayerRegistryItem, MapLayerOptions } from '@grafana/data';
|
||||
import { MapLayerRegistryItem, MapLayerOptions, EventBus } from '@grafana/data';
|
||||
|
||||
export const standard: MapLayerRegistryItem = {
|
||||
id: 'osm-standard',
|
||||
@ -14,7 +14,7 @@ export const standard: MapLayerRegistryItem = {
|
||||
* Function that configures transformation and returns a transformer
|
||||
* @param options
|
||||
*/
|
||||
create: async (map: Map, options: MapLayerOptions) => ({
|
||||
create: async (map: Map, options: MapLayerOptions, eventBus: EventBus) => ({
|
||||
init: () => {
|
||||
return new TileLayer({
|
||||
source: new OSM(),
|
||||
|
261
public/app/plugins/panel/geomap/layers/data/dayNightLayer.tsx
Normal file
261
public/app/plugins/panel/geomap/layers/data/dayNightLayer.tsx
Normal file
@ -0,0 +1,261 @@
|
||||
import {
|
||||
MapLayerRegistryItem,
|
||||
MapLayerOptions,
|
||||
PanelData,
|
||||
GrafanaTheme2,
|
||||
EventBus,
|
||||
DataHoverEvent,
|
||||
DataHoverClearEvent,
|
||||
PluginState,
|
||||
} from '@grafana/data';
|
||||
import Map from 'ol/Map';
|
||||
import VectorLayer from 'ol/layer/Vector';
|
||||
import VectorSource from 'ol/source/Vector';
|
||||
import { Fill, Stroke, Style, Circle } from 'ol/style';
|
||||
import {Group as LayerGroup} from 'ol/layer';
|
||||
import Feature from 'ol/Feature';
|
||||
import Point from 'ol/geom/Point';
|
||||
|
||||
import DayNight from 'ol-ext/source/DayNight';
|
||||
import { fromLonLat } from 'ol/proj';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { MultiLineString } from 'ol/geom';
|
||||
import { Coordinate } from 'ol/coordinate';
|
||||
|
||||
export enum ShowTime {
|
||||
From = 'from',
|
||||
To = 'to',
|
||||
}
|
||||
|
||||
// Configuration options for Circle overlays
|
||||
export interface DayNightConfig {
|
||||
show: ShowTime;
|
||||
sun: boolean;
|
||||
nightColor: string;
|
||||
}
|
||||
|
||||
const defaultConfig: DayNightConfig = {
|
||||
show: ShowTime.To,
|
||||
sun: false,
|
||||
nightColor: '#a7a6ba4D'
|
||||
};
|
||||
|
||||
export const DAY_NIGHT_LAYER_ID = 'dayNight';
|
||||
|
||||
// Used by default when nothing is configured
|
||||
export const defaultDayNightConfig: MapLayerOptions<DayNightConfig> = {
|
||||
type: DAY_NIGHT_LAYER_ID,
|
||||
name: '', // will get replaced
|
||||
config: defaultConfig,
|
||||
tooltip: true,
|
||||
};
|
||||
|
||||
/**
|
||||
* Map layer configuration for circle overlay
|
||||
*/
|
||||
export const dayNightLayer: MapLayerRegistryItem<DayNightConfig> = {
|
||||
id: DAY_NIGHT_LAYER_ID,
|
||||
name: 'Night / Day',
|
||||
description: 'Show day and night regions',
|
||||
isBaseMap: false,
|
||||
state: PluginState.alpha,
|
||||
|
||||
/**
|
||||
* Function that configures transformation and returns a transformer
|
||||
* @param map
|
||||
* @param options
|
||||
* @param theme
|
||||
*/
|
||||
create: async (map: Map, options: MapLayerOptions<DayNightConfig>, eventBus: EventBus, theme: GrafanaTheme2) => {
|
||||
// Assert default values
|
||||
const config = {
|
||||
...defaultConfig,
|
||||
...options?.config,
|
||||
};
|
||||
|
||||
// DayNight source
|
||||
const source = new DayNight({ });
|
||||
const sourceMethods = Object.getPrototypeOf(source);
|
||||
const sourceLine = new DayNight({ });
|
||||
const sourceLineMethods = Object.getPrototypeOf(sourceLine);
|
||||
|
||||
// Night polygon
|
||||
const vectorLayer = new VectorLayer({
|
||||
source,
|
||||
style: new Style({
|
||||
fill: new Fill({
|
||||
color: theme.visualization.getColorByName(config.nightColor)
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
// Night line (for crosshair sharing)
|
||||
const nightLineLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
features: [],
|
||||
}),
|
||||
style: new Style ({
|
||||
stroke: new Stroke({
|
||||
color: '#607D8B',
|
||||
width: 1.5,
|
||||
lineDash: [2, 3],
|
||||
})
|
||||
}),
|
||||
});
|
||||
|
||||
// Sun circle
|
||||
const sunFeature = new Feature({
|
||||
geometry: new Point([]),
|
||||
});
|
||||
|
||||
const sunLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
features: [sunFeature],
|
||||
}),
|
||||
style: new Style({
|
||||
image: new Circle({
|
||||
radius: 13,
|
||||
fill: new Fill({color: 'rgb(253,184,19)'}),
|
||||
})
|
||||
}),
|
||||
});
|
||||
|
||||
// Sun line (for crosshair sharing)
|
||||
const sunLineFeature = new Feature({
|
||||
geometry: new Point([]),
|
||||
});
|
||||
|
||||
const sunLineStyle = new Style({
|
||||
image: new Circle({
|
||||
radius: 13,
|
||||
stroke: new Stroke({
|
||||
color: 'rgb(253,184,19)',
|
||||
width: 1.5
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
const sunLineStyleDash = new Style({
|
||||
image: new Circle({
|
||||
radius: 15,
|
||||
stroke: new Stroke({
|
||||
color: '#607D8B',
|
||||
width: 1.5,
|
||||
lineDash: [2,3]
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
const sunLineLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
features: [sunLineFeature],
|
||||
}),
|
||||
style: [sunLineStyleDash, sunLineStyle],
|
||||
});
|
||||
|
||||
// Build group of layers
|
||||
// TODO: add blended night region to "connect" current night region to lines
|
||||
const layer = new LayerGroup({
|
||||
layers: config.sun? [vectorLayer, sunLayer, sunLineLayer, nightLineLayer] : [vectorLayer, nightLineLayer]
|
||||
});
|
||||
|
||||
// Crosshair sharing subscriptions
|
||||
const subscriptions = new Subscription();
|
||||
|
||||
if (false) {
|
||||
subscriptions.add(
|
||||
eventBus.subscribe(DataHoverEvent, (event) => {
|
||||
const time = event.payload?.point?.time as number;
|
||||
if (time) {
|
||||
const lineTime = new Date(time);
|
||||
const nightLinePoints = sourceLine.getCoordinates(lineTime.toString(), 'line');
|
||||
nightLineLayer.getSource()?.clear();
|
||||
const lineStringArray:Coordinate[][] = [];
|
||||
for (let l = 0; l < nightLinePoints.length - 1; l++){
|
||||
const x1:number = Object.values(nightLinePoints[l])[0];
|
||||
const y1:number = Object.values(nightLinePoints[l])[1];
|
||||
const x2:number = Object.values(nightLinePoints[l+1])[0];
|
||||
const y2:number = Object.values(nightLinePoints[l+1])[1];
|
||||
const lineString = [fromLonLat([x1, y1]),fromLonLat([x2, y2])];
|
||||
lineStringArray.push(lineString);
|
||||
}
|
||||
nightLineLayer.getSource()?.addFeature(new Feature({
|
||||
geometry: new MultiLineString(lineStringArray),
|
||||
}))
|
||||
|
||||
let sunLinePos: number[] = [];
|
||||
sunLinePos = sourceLineMethods.getSunPosition(lineTime);
|
||||
sunLineFeature.getGeometry()?.setCoordinates(fromLonLat(sunLinePos));
|
||||
sunLineFeature.setStyle([sunLineStyle, sunLineStyleDash]);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
subscriptions.add(
|
||||
eventBus.subscribe(DataHoverClearEvent, (event) => {
|
||||
nightLineLayer.getSource()?.clear();
|
||||
sunLineFeature.setStyle(new Style({}));
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
init: () => layer,
|
||||
dispose: () => subscriptions.unsubscribe(),
|
||||
update: (data: PanelData) => {
|
||||
const from = new Date(data.timeRange.from.valueOf());
|
||||
const to = new Date(data.timeRange.to.valueOf());
|
||||
let selectedTime: Date = new Date();
|
||||
let sunPos: number[] = [];
|
||||
// TODO: add option for "Both"
|
||||
if (config.show === ShowTime.From){
|
||||
selectedTime = from;
|
||||
} else {
|
||||
selectedTime = to;
|
||||
}
|
||||
|
||||
source.setTime(selectedTime);
|
||||
if (config.sun){
|
||||
sunPos = sourceMethods.getSunPosition(selectedTime);
|
||||
sunFeature.getGeometry()?.setCoordinates(fromLonLat(sunPos));
|
||||
}
|
||||
},
|
||||
|
||||
// Marker overlay options
|
||||
registerOptionsUI: (builder) => {
|
||||
if(!options.config?.nightColor) {
|
||||
options.config = { ...defaultConfig, ...options.config}
|
||||
}
|
||||
|
||||
builder
|
||||
.addRadio({
|
||||
path: 'config.show',
|
||||
name: 'Show',
|
||||
settings: {
|
||||
options: [
|
||||
{ label: 'From', value: ShowTime.From },
|
||||
{ label: 'To', value: ShowTime.To },
|
||||
],
|
||||
},
|
||||
defaultValue: defaultConfig.show,
|
||||
});
|
||||
builder.addColorPicker({
|
||||
path: 'config.nightColor',
|
||||
name: 'Night region color',
|
||||
description: 'Pick color of night region',
|
||||
defaultValue: defaultConfig.nightColor,
|
||||
settings: [{enableNamedColors: false}],
|
||||
});
|
||||
builder.addBooleanSwitch({
|
||||
path: 'config.sun',
|
||||
name: 'Display sun',
|
||||
description: 'Show the sun',
|
||||
defaultValue: defaultConfig.sun,
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
// fill in the default values
|
||||
defaultOptions: defaultConfig,
|
||||
};
|
@ -5,6 +5,7 @@ import {
|
||||
GrafanaTheme2,
|
||||
PluginState,
|
||||
SelectableValue,
|
||||
EventBus,
|
||||
} from '@grafana/data';
|
||||
import Map from 'ol/Map';
|
||||
import VectorLayer from 'ol/layer/Vector';
|
||||
@ -72,7 +73,7 @@ export const geojsonLayer: MapLayerRegistryItem<GeoJSONMapperConfig> = {
|
||||
* Function that configures transformation and returns a transformer
|
||||
* @param options
|
||||
*/
|
||||
create: async (map: Map, options: MapLayerOptions<GeoJSONMapperConfig>, theme: GrafanaTheme2) => {
|
||||
create: async (map: Map, options: MapLayerOptions<GeoJSONMapperConfig>, eventBus: EventBus, theme: GrafanaTheme2) => {
|
||||
const config = { ...defaultOptions, ...options.config };
|
||||
|
||||
const source = new VectorSource({
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {
|
||||
EventBus,
|
||||
FieldType,
|
||||
getFieldColorModeForField,
|
||||
GrafanaTheme2,
|
||||
@ -45,7 +46,7 @@ export const heatmapLayer: MapLayerRegistryItem<HeatmapConfig> = {
|
||||
* Function that configures transformation and returns a transformer
|
||||
* @param options
|
||||
*/
|
||||
create: async (map: Map, options: MapLayerOptions<HeatmapConfig>, theme: GrafanaTheme2) => {
|
||||
create: async (map: Map, options: MapLayerOptions<HeatmapConfig>, eventBus: EventBus, theme: GrafanaTheme2) => {
|
||||
const config = { ...defaultOptions, ...options.config };
|
||||
|
||||
const location = await getLocationMatchers(options.location);
|
||||
|
@ -2,8 +2,9 @@ import { markersLayer } from './markersLayer';
|
||||
import { geojsonLayer } from './geojsonLayer';
|
||||
import { heatmapLayer } from './heatMap';
|
||||
import { lastPointTracker } from './lastPointTracker';
|
||||
import { dayNightLayer } from './dayNightLayer';
|
||||
|
||||
/**
|
||||
* Registry for layer handlers
|
||||
*/
|
||||
export const dataLayers = [markersLayer, heatmapLayer, lastPointTracker, geojsonLayer];
|
||||
export const dataLayers = [markersLayer, heatmapLayer, lastPointTracker, geojsonLayer, dayNightLayer];
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { MapLayerRegistryItem, MapLayerOptions, PanelData, GrafanaTheme2, PluginState } from '@grafana/data';
|
||||
import { MapLayerRegistryItem, MapLayerOptions, PanelData, GrafanaTheme2, PluginState, EventBus } from '@grafana/data';
|
||||
import Map from 'ol/Map';
|
||||
import Feature from 'ol/Feature';
|
||||
import * as style from 'ol/style';
|
||||
@ -26,7 +26,7 @@ export const lastPointTracker: MapLayerRegistryItem<LastPointConfig> = {
|
||||
* Function that configures transformation and returns a transformer
|
||||
* @param options
|
||||
*/
|
||||
create: async (map: Map, options: MapLayerOptions<LastPointConfig>, theme: GrafanaTheme2) => {
|
||||
create: async (map: Map, options: MapLayerOptions<LastPointConfig>, eventBus: EventBus, theme: GrafanaTheme2) => {
|
||||
const point = new Feature({});
|
||||
const config = { ...defaultOptions, ...options.config };
|
||||
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
PanelData,
|
||||
GrafanaTheme2,
|
||||
FrameGeometrySourceMode,
|
||||
EventBus,
|
||||
} from '@grafana/data';
|
||||
import Map from 'ol/Map';
|
||||
import { FeatureLike } from 'ol/Feature';
|
||||
@ -61,7 +62,7 @@ export const markersLayer: MapLayerRegistryItem<MarkersConfig> = {
|
||||
* @param options
|
||||
* @param theme
|
||||
*/
|
||||
create: async (map: Map, options: MapLayerOptions<MarkersConfig>, theme: GrafanaTheme2) => {
|
||||
create: async (map: Map, options: MapLayerOptions<MarkersConfig>, eventBus: EventBus, theme: GrafanaTheme2) => {
|
||||
// Assert default values
|
||||
const config = {
|
||||
...defaultOptions,
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
Registry,
|
||||
MapLayerOptions,
|
||||
GrafanaTheme2,
|
||||
EventBus,
|
||||
SelectableValue,
|
||||
PluginState,
|
||||
} from '@grafana/data';
|
||||
@ -26,18 +27,18 @@ export const defaultBaseLayer: MapLayerRegistryItem = {
|
||||
name: 'Default base layer',
|
||||
isBaseMap: true,
|
||||
|
||||
create: (map: Map, options: MapLayerOptions, theme: GrafanaTheme2) => {
|
||||
create: (map: Map, options: MapLayerOptions, eventBus: EventBus, theme: GrafanaTheme2) => {
|
||||
const serverLayerType = config?.geomapDefaultBaseLayerConfig?.type;
|
||||
if (serverLayerType) {
|
||||
const layer = geomapLayerRegistry.getIfExists(serverLayerType);
|
||||
if (!layer) {
|
||||
throw new Error('Invalid basemap configuration on server');
|
||||
}
|
||||
return layer.create(map, config.geomapDefaultBaseLayerConfig!, theme);
|
||||
return layer.create(map, config.geomapDefaultBaseLayerConfig!, eventBus, theme);
|
||||
}
|
||||
|
||||
// For now use carto as our default basemap
|
||||
return carto.create(map, options, theme);
|
||||
return carto.create(map, options, eventBus, theme);
|
||||
},
|
||||
};
|
||||
|
||||
@ -57,16 +58,26 @@ interface RegistrySelectInfo {
|
||||
|
||||
function getLayersSelection(items: Array<MapLayerRegistryItem<any>>, current?: string): RegistrySelectInfo {
|
||||
const res: RegistrySelectInfo = { options: [], current: [] };
|
||||
const alpha: Array<SelectableValue<string>> = [];
|
||||
for (const layer of items) {
|
||||
if (layer.state === PluginState.alpha && !hasAlphaPanels) {
|
||||
continue;
|
||||
const opt: SelectableValue<string> = { label: layer.name, value: layer.id, description: layer.description };
|
||||
if (layer.state === PluginState.alpha) {
|
||||
if (!hasAlphaPanels) {
|
||||
continue;
|
||||
}
|
||||
opt.label = `${layer.name} (Alpha)`;
|
||||
opt.icon = 'bolt';
|
||||
alpha.push(opt);
|
||||
} else {
|
||||
res.options.push(opt);
|
||||
}
|
||||
const opt = { label: layer.name, value: layer.id, description: layer.description };
|
||||
res.options.push(opt);
|
||||
if (layer.id === current) {
|
||||
res.current.push(opt);
|
||||
}
|
||||
}
|
||||
for (const p of alpha) {
|
||||
res.options.push(p);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
165
yarn.lock
165
yarn.lock
@ -3221,7 +3221,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/runtime@npm:^7.18.3":
|
||||
"@babel/runtime@npm:^7.14.0, @babel/runtime@npm:^7.18.3":
|
||||
version: 7.18.3
|
||||
resolution: "@babel/runtime@npm:7.18.3"
|
||||
dependencies:
|
||||
@ -10734,6 +10734,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/ol-ext@npm:@siedlerchr/types-ol-ext@2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "@siedlerchr/types-ol-ext@npm:2.0.0"
|
||||
dependencies:
|
||||
jspdf: ^2.5.1
|
||||
checksum: f97642cbd3fbc6501d17bc8118931eb00c12cb8b92a89d055508fd24e62e0c37263da18144cada421d8dc342d74e8198179905184b32b8c260bf30e4f5d7e4cb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/overlayscrollbars@npm:^1.12.0":
|
||||
version: 1.12.1
|
||||
resolution: "@types/overlayscrollbars@npm:1.12.1"
|
||||
@ -10827,6 +10836,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/raf@npm:^3.4.0":
|
||||
version: 3.4.0
|
||||
resolution: "@types/raf@npm:3.4.0"
|
||||
checksum: d93e9b5244a081c64708b8918ef7e56936d6ef0144925b189e67d34127c0cb3a73fcf6866ab312db156554a66c26609dd056da5f7302f6658c049d6a37ed5f56
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/range-parser@npm:*":
|
||||
version: 1.2.4
|
||||
resolution: "@types/range-parser@npm:1.2.4"
|
||||
@ -13833,6 +13849,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"base64-arraybuffer@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "base64-arraybuffer@npm:1.0.2"
|
||||
checksum: 15e6400d2d028bf18be4ed97702b11418f8f8779fb8c743251c863b726638d52f69571d4cc1843224da7838abef0949c670bde46936663c45ad078e89fee5c62
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"base64-js@npm:^1.0.2, base64-js@npm:^1.3.1":
|
||||
version: 1.5.1
|
||||
resolution: "base64-js@npm:1.5.1"
|
||||
@ -14299,6 +14322,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"btoa@npm:^1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "btoa@npm:1.2.1"
|
||||
bin:
|
||||
btoa: bin/btoa.js
|
||||
checksum: afbf004fb1b1d530e053ffa66ef5bd3878b101c59d808ac947fcff96810b4452abba2b54be687adadea2ba9efc7af48b04228742789bf824ef93f103767e690c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"buffer-crc32@npm:~0.2.3":
|
||||
version: 0.2.13
|
||||
resolution: "buffer-crc32@npm:0.2.13"
|
||||
@ -14634,6 +14666,22 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"canvg@npm:^3.0.6":
|
||||
version: 3.0.10
|
||||
resolution: "canvg@npm:3.0.10"
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.12.5
|
||||
"@types/raf": ^3.4.0
|
||||
core-js: ^3.8.3
|
||||
raf: ^3.4.1
|
||||
regenerator-runtime: ^0.13.7
|
||||
rgbcolor: ^1.0.1
|
||||
stackblur-canvas: ^2.0.0
|
||||
svg-pathdata: ^6.0.3
|
||||
checksum: 2cfd86bcb9b56b43a97745cc672e696169b4c09e8850fb4f27bec5ebf173179d16feb594224d643a32f1ce01e47b55d44e0058419114d48d34f12c2452c65927
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"capture-exit@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "capture-exit@npm:2.0.0"
|
||||
@ -15832,6 +15880,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"core-js@npm:^3.6.0, core-js@npm:^3.8.3":
|
||||
version: 3.23.1
|
||||
resolution: "core-js@npm:3.23.1"
|
||||
checksum: 460328e0b743900d48fc744aab475f6dabdae498cc73f6d038321b0ae1488cb5e73d1670b5914abfe7dd84d0843a828b5d4dd3eba0a5b6a4450f0d7094cda2a5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"core-util-is@npm:1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "core-util-is@npm:1.0.2"
|
||||
@ -16085,6 +16140,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"css-line-break@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "css-line-break@npm:2.1.0"
|
||||
dependencies:
|
||||
utrie: ^1.0.2
|
||||
checksum: 37b1fe632b03be7a287cd394cef8b5285666343443125c510df9cfb6a4734a2c71e154ec8f7bbff72d7c339e1e5872989b1c52d86162aed27d6cc114725bb4d0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"css-loader@npm:6.7.1, css-loader@npm:^6.7.1":
|
||||
version: 6.7.1
|
||||
resolution: "css-loader@npm:6.7.1"
|
||||
@ -17644,6 +17708,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dompurify@npm:^2.2.0":
|
||||
version: 2.3.8
|
||||
resolution: "dompurify@npm:2.3.8"
|
||||
checksum: dc7b32ee57a03fe5166a850071200897cc13fa069287a709e3b2138052d73ec09a87026b9e28c8d2f254a74eaa52ef30644e98e54294c30acbca2a53f1bbc5f4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"domutils@npm:^2.5.2, domutils@npm:^2.6.0, domutils@npm:^2.7.0":
|
||||
version: 2.8.0
|
||||
resolution: "domutils@npm:2.8.0"
|
||||
@ -19384,6 +19455,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fflate@npm:^0.4.8":
|
||||
version: 0.4.8
|
||||
resolution: "fflate@npm:0.4.8"
|
||||
checksum: 29d8cbe44d5e7f53e7f5a160ac7f9cc025480c7b3bfd85c5f898cbe20dfa2dad4732daa534982664bf30b35896a90af44ea33ede5d94c5ffd1b8b0c0a0a56ca2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"figgy-pudding@npm:^3.5.1":
|
||||
version: 3.5.2
|
||||
resolution: "figgy-pudding@npm:3.5.2"
|
||||
@ -20720,6 +20798,7 @@ __metadata:
|
||||
"@types/logfmt": ^1.2.1
|
||||
"@types/mousetrap": 1.6.9
|
||||
"@types/node": 16.11.36
|
||||
"@types/ol-ext": "npm:@siedlerchr/types-ol-ext@2.0.0"
|
||||
"@types/papaparse": 5.3.2
|
||||
"@types/pluralize": ^0.0.29
|
||||
"@types/prismjs": 1.26.0
|
||||
@ -20850,6 +20929,7 @@ __metadata:
|
||||
node-notifier: 10.0.1
|
||||
nodemon: 2.0.16
|
||||
ol: 6.14.1
|
||||
ol-ext: ^3.2.25
|
||||
papaparse: 5.3.2
|
||||
pluralize: ^8.0.0
|
||||
postcss: 8.4.14
|
||||
@ -21472,6 +21552,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"html2canvas@npm:^1.0.0-rc.5":
|
||||
version: 1.4.1
|
||||
resolution: "html2canvas@npm:1.4.1"
|
||||
dependencies:
|
||||
css-line-break: ^2.1.0
|
||||
text-segmentation: ^1.0.3
|
||||
checksum: c134324af57f3262eecf982e436a4843fded3c6cf61954440ffd682527e4dd350e0c2fafd217c0b6f9a455fe345d0c67b4505689796ab160d4ca7c91c3766739
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"htmlparser2@npm:^6.1.0":
|
||||
version: 6.1.0
|
||||
resolution: "htmlparser2@npm:6.1.0"
|
||||
@ -24534,6 +24624,31 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jspdf@npm:^2.5.1":
|
||||
version: 2.5.1
|
||||
resolution: "jspdf@npm:2.5.1"
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.14.0
|
||||
atob: ^2.1.2
|
||||
btoa: ^1.2.1
|
||||
canvg: ^3.0.6
|
||||
core-js: ^3.6.0
|
||||
dompurify: ^2.2.0
|
||||
fflate: ^0.4.8
|
||||
html2canvas: ^1.0.0-rc.5
|
||||
dependenciesMeta:
|
||||
canvg:
|
||||
optional: true
|
||||
core-js:
|
||||
optional: true
|
||||
dompurify:
|
||||
optional: true
|
||||
html2canvas:
|
||||
optional: true
|
||||
checksum: 9ecdccc50678cd780f0995157618630ca0da65576835983232d48001aab0b29e51af765e078808526d5e5e2e1ebf3cee460e03eaf590f875d160f2e0cb614a1e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jsprim@npm:^1.2.2":
|
||||
version: 1.4.1
|
||||
resolution: "jsprim@npm:1.4.1"
|
||||
@ -27247,6 +27362,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ol-ext@npm:^3.2.25":
|
||||
version: 3.2.25
|
||||
resolution: "ol-ext@npm:3.2.25"
|
||||
peerDependencies:
|
||||
ol: ">= 5.3.0"
|
||||
checksum: ebdf354089975c36258c456c1bf7b65a898fddc578d8112ad17ad8c571df1405992662c3fcfe13a23c400a8f2b7d9deb5efff4545a526d9a03386f4bcef565bf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ol-mapbox-style@npm:^7.1.1":
|
||||
version: 7.1.1
|
||||
resolution: "ol-mapbox-style@npm:7.1.1"
|
||||
@ -32192,6 +32316,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rgbcolor@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "rgbcolor@npm:1.0.1"
|
||||
checksum: bd062ac007a3e979e2f83dc69feb3cc4f9bca7d8631899548394160e30c47e4f7e52b31aa3f66a69061ad56e899e812ec52f5c33686c085d72c9b3d22faed1c8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rimraf@npm:3.0.2, rimraf@npm:^3.0.0, rimraf@npm:^3.0.2":
|
||||
version: 3.0.2
|
||||
resolution: "rimraf@npm:3.0.2"
|
||||
@ -33628,6 +33759,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"stackblur-canvas@npm:^2.0.0":
|
||||
version: 2.5.0
|
||||
resolution: "stackblur-canvas@npm:2.5.0"
|
||||
checksum: 52b0dc595d3dbed94c8563d8fe34e0c8ff65b85eaf8fcfe7b0cd8893e93ae42c28b688f71d792fbaedf2a9b677dc474a2e721d8245165a3a0c0d794c0f6f8bba
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"stackframe@npm:^1.1.1":
|
||||
version: 1.2.0
|
||||
resolution: "stackframe@npm:1.2.0"
|
||||
@ -34267,6 +34405,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"svg-pathdata@npm:^6.0.3":
|
||||
version: 6.0.3
|
||||
resolution: "svg-pathdata@npm:6.0.3"
|
||||
checksum: f0e55be50c654be5d259d70945ed7e5354bf78e51c6039b4045d9f7c49d703a0c33dda36751815aec2824d046c417c35226e7491246ffff3e9164735ea428446
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"svg-tags@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "svg-tags@npm:1.0.0"
|
||||
@ -34619,6 +34764,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"text-segmentation@npm:^1.0.3":
|
||||
version: 1.0.3
|
||||
resolution: "text-segmentation@npm:1.0.3"
|
||||
dependencies:
|
||||
utrie: ^1.0.2
|
||||
checksum: 2e24632d59567c55ab49ac324815e2f7a8043e63e26b109636322ac3e30692cee8679a448fd5d0f0598a345f407afd0e34ba612e22524cf576d382d84058c013
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"text-table@npm:^0.2.0":
|
||||
version: 0.2.0
|
||||
resolution: "text-table@npm:0.2.0"
|
||||
@ -36031,6 +36185,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"utrie@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "utrie@npm:1.0.2"
|
||||
dependencies:
|
||||
base64-arraybuffer: ^1.0.2
|
||||
checksum: c96fbb7d4d8855a154327da0b18e39b7511cc70a7e4bcc3658e24f424bb884312d72b5ba777500b8858e34d365dc6b1a921dc5ca2f0d341182519c6b78e280a5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"uuid-browser@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "uuid-browser@npm:3.1.0"
|
||||
|
Loading…
Reference in New Issue
Block a user