mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Geomap: Add opacity and prepare svg (#41170)
This commit is contained in:
@@ -43,7 +43,7 @@ export const GazetteerPathEditor: FC<StandardEditorProps<string, any, any, Gazet
|
||||
|
||||
const { current, options } = useMemo(() => {
|
||||
let options = settings?.options ? [...settings.options] : [...defaultPaths];
|
||||
let current = options.find((f) => f.value === gaz?.path);
|
||||
let current = options?.find((f) => f.value === gaz?.path);
|
||||
if (!current && gaz) {
|
||||
current = {
|
||||
label: gaz.path,
|
||||
@@ -52,7 +52,7 @@ export const GazetteerPathEditor: FC<StandardEditorProps<string, any, any, Gazet
|
||||
options.push(current);
|
||||
}
|
||||
return { options, current };
|
||||
}, [gaz, settings.options]);
|
||||
}, [gaz, settings?.options]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -30,6 +30,7 @@ import { getMarkerFromPath } from '../../utils/regularShapes';
|
||||
import { ReplaySubject } from 'rxjs';
|
||||
import { FeaturesStylesBuilderConfig, getFeatures } from '../../utils/getFeatures';
|
||||
import { StyleMaker, StyleMakerConfig } from '../../types';
|
||||
import { getSVGUri } from '../../utils/prepareSVG';
|
||||
|
||||
// Configuration options for Circle overlays
|
||||
export interface MarkersConfig {
|
||||
@@ -99,6 +100,11 @@ export const markersLayer: MapLayerRegistryItem<MarkersConfig> = {
|
||||
legend = <ObservablePropsWrapper watch={legendProps} initialSubProps={{}} child={MarkersLegend} />;
|
||||
}
|
||||
|
||||
const markerPath =
|
||||
getPublicOrAbsoluteUrl(config.markerSymbol?.fixed) ?? getPublicOrAbsoluteUrl('img/icons/marker/circle.svg');
|
||||
// double to match regularshapes using size as radius
|
||||
const uri = await getSVGUri(markerPath, config.size.fixed * 2);
|
||||
|
||||
return {
|
||||
init: () => vectorLayer,
|
||||
legend: legend,
|
||||
@@ -107,22 +113,30 @@ export const markersLayer: MapLayerRegistryItem<MarkersConfig> = {
|
||||
return; // ignore empty
|
||||
}
|
||||
|
||||
const markerPath =
|
||||
getPublicOrAbsoluteUrl(config.markerSymbol?.fixed) ?? getPublicOrAbsoluteUrl('img/icons/marker/circle.svg');
|
||||
|
||||
const marker = getMarkerFromPath(config.markerSymbol?.fixed);
|
||||
|
||||
const makeIconStyle = (cfg: StyleMakerConfig) => {
|
||||
return new style.Style({
|
||||
const icon = new style.Style({
|
||||
image: new style.Icon({
|
||||
src: markerPath,
|
||||
src: uri,
|
||||
color: cfg.color,
|
||||
// opacity,
|
||||
opacity: cfg.opacity,
|
||||
// scale based on field value
|
||||
scale: (DEFAULT_SIZE + cfg.size) / 100,
|
||||
}),
|
||||
});
|
||||
// transparent bounding box for featureAtPixel detection
|
||||
const boundingBox = new style.Style({
|
||||
image: new style.RegularShape({
|
||||
fill: new style.Fill({ color: 'rgba(0,0,0,0)' }),
|
||||
points: 4,
|
||||
radius: cfg.size,
|
||||
angle: Math.PI / 4,
|
||||
}),
|
||||
});
|
||||
return [icon, boundingBox]
|
||||
};
|
||||
|
||||
const marker = getMarkerFromPath(config.markerSymbol?.fixed);
|
||||
|
||||
const shape: StyleMaker = marker?.make ?? makeIconStyle;
|
||||
|
||||
const features: Feature<Point>[] = [];
|
||||
|
||||
@@ -47,6 +47,7 @@ export interface GeomapPanelOptions {
|
||||
}
|
||||
export interface FeatureStyleConfig {
|
||||
fillColor: string; //eventually be ColorDimensionConfig
|
||||
opacity?: number;
|
||||
strokeWidth?: number;
|
||||
rule?: FeatureRuleConfig;
|
||||
}
|
||||
@@ -84,6 +85,7 @@ export interface StyleMakerConfig {
|
||||
size: number;
|
||||
markerPath?: string;
|
||||
text?: string;
|
||||
opacity?: number;
|
||||
}
|
||||
|
||||
export type StyleMaker = (config: StyleMakerConfig) => Style;
|
||||
export type StyleMaker = (config: StyleMakerConfig) => Style | Style[];
|
||||
|
||||
@@ -16,6 +16,5 @@ export const getGeoMapStyle = (config: FeatureStyleConfig, property: any) => {
|
||||
width: config.strokeWidth,
|
||||
})
|
||||
: undefined,
|
||||
//handle a shape/marker too?
|
||||
});
|
||||
};
|
||||
|
||||
34
public/app/plugins/panel/geomap/utils/prepareSVG.ts
Normal file
34
public/app/plugins/panel/geomap/utils/prepareSVG.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { getPublicOrAbsoluteUrl } from 'app/features/dimensions';
|
||||
|
||||
const getUri = (url: string, size: number): Promise<string> => {
|
||||
return fetch(url, { method: 'GET' })
|
||||
.then((res) => {
|
||||
return res.text();
|
||||
})
|
||||
.then((text) => {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(text, 'image/svg+xml');
|
||||
const svg = doc.getElementsByTagName('svg')[0];
|
||||
if (!svg) {
|
||||
return '';
|
||||
}
|
||||
//set to white so ol color tint works
|
||||
svg.setAttribute('fill', '#fff');
|
||||
const svgString = new XMLSerializer().serializeToString(svg);
|
||||
const svgURI = encodeURIComponent(svgString);
|
||||
return `data:image/svg+xml,${svgURI}`;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
return '';
|
||||
});
|
||||
};
|
||||
|
||||
export const getSVGUri = async (url: string, size: number) => {
|
||||
const svgURI = await getUri(url, size);
|
||||
|
||||
if (!svgURI) {
|
||||
return getPublicOrAbsoluteUrl('img/icons/marker/circle.svg');
|
||||
}
|
||||
return svgURI;
|
||||
};
|
||||
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#fff" d="M21.75,12a1,1,0,0,0-.55-.89L15.08,8.05v-4a3.08,3.08,0,1,0-6.16,0v4L2.8,11.11a1,1,0,0,0-.55.89v3.33a1,1,0,0,0,.43.83,1,1,0,0,0,.92.11l5.32-2V18l-1.82.6a1,1,0,0,0-.68.95V22a1,1,0,0,0,.3.71,1,1,0,0,0,.7.29h9.17a1,1,0,0,0,1-1V19.5a1,1,0,0,0-.68-.95L15.08,18V14.28l5.32,2a1,1,0,0,0,.92-.11,1,1,0,0,0,.43-.83Zm-7.31-.1a1,1,0,0,0-.93.11,1,1,0,0,0-.43.82v5.84a1,1,0,0,0,.69.95l1.81.6V21H8.41v-.78l1.81-.6a1,1,0,0,0,.69-.95V12.83a1,1,0,0,0-.43-.82,1,1,0,0,0-.93-.11l-5.31,2V12.62l6.11-3.06a1,1,0,0,0,.56-.89V4.08a1.08,1.08,0,1,1,2.16,0V8.67a1,1,0,0,0,.56.89l6.11,3.06v1.27Z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21.75,12a1,1,0,0,0-.55-.89L15.08,8.05v-4a3.08,3.08,0,1,0-6.16,0v4L2.8,11.11a1,1,0,0,0-.55.89v3.33a1,1,0,0,0,.43.83,1,1,0,0,0,.92.11l5.32-2V18l-1.82.6a1,1,0,0,0-.68.95V22a1,1,0,0,0,.3.71,1,1,0,0,0,.7.29h9.17a1,1,0,0,0,1-1V19.5a1,1,0,0,0-.68-.95L15.08,18V14.28l5.32,2a1,1,0,0,0,.92-.11,1,1,0,0,0,.43-.83Zm-7.31-.1a1,1,0,0,0-.93.11,1,1,0,0,0-.43.82v5.84a1,1,0,0,0,.69.95l1.81.6V21H8.41v-.78l1.81-.6a1,1,0,0,0,.69-.95V12.83a1,1,0,0,0-.43-.82,1,1,0,0,0-.93-.11l-5.31,2V12.62l6.11-3.06a1,1,0,0,0,.56-.89V4.08a1.08,1.08,0,1,1,2.16,0V8.67a1,1,0,0,0,.56.89l6.11,3.06v1.27Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 654 B After Width: | Height: | Size: 642 B |
Reference in New Issue
Block a user