diff --git a/public/app/plugins/panel/geomap/layers/data/markersLayer.tsx b/public/app/plugins/panel/geomap/layers/data/markersLayer.tsx index 6b5339755df..35c25310fb8 100644 --- a/public/app/plugins/panel/geomap/layers/data/markersLayer.tsx +++ b/public/app/plugins/panel/geomap/layers/data/markersLayer.tsx @@ -81,10 +81,13 @@ export const markersLayer: MapLayerRegistryItem = { const location = await getLocationMatchers(options.location); const source = new FrameVectorSource(location); const symbolLayer = new WebGLPointsLayer({ source, style: webGLStyle }); - const textLayer = new VectorImage({ source, declutter: true }); + const vectorLayer = new VectorImage({ source, declutter: true }); + // Initialize hasVector with just text check, will be updated when features are available + let hasVector = hasText; + const layers = new LayerGroup({ // If text and no symbol, only show text - fall back on default symbol - layers: hasText && symbol ? [symbolLayer, textLayer] : hasText && !symbol ? [textLayer] : [symbolLayer], + layers: hasVector && symbol ? [symbolLayer, vectorLayer] : hasVector && !symbol ? [vectorLayer] : [symbolLayer], }); const legendProps = new ReplaySubject(1); @@ -116,7 +119,15 @@ export const markersLayer: MapLayerRegistryItem = { } source.update(frame); + + // Track if we find any line strings during feature processing + let hasLineString = false; + source.forEachFeature((feature) => { + const isLineString = feature.getGeometry()?.getType() === 'LineString'; + if (isLineString) { + hasLineString = true; + } const idx: number = feature.get('rowIndex'); const dims = style.dims; const values = { ...style.base }; @@ -133,28 +144,51 @@ export const markersLayer: MapLayerRegistryItem = { if (dims?.rotation) { values.rotation = dims.rotation.get(idx); } - const colorString = tinycolor(theme.visualization.getColorByName(values.color)).toString(); - const colorValues = getRGBValues(colorString); - - const radius = values.size ?? DEFAULT_SIZE; - const displacement = getDisplacement(values.symbolAlign ?? defaultStyleConfig.symbolAlign, radius); - - // WebGLPointsLayer uses style expressions instead of style functions - feature.setProperties({ red: colorValues?.r ?? 255 }); - feature.setProperties({ green: colorValues?.g ?? 255 }); - feature.setProperties({ blue: colorValues?.b ?? 255 }); - feature.setProperties({ size: (values.size ?? 1) * 2 }); // TODO unify sizing across all source types - feature.setProperties({ rotation: ((values.rotation ?? 0) * Math.PI) / 180 }); - feature.setProperties({ opacity: (values.opacity ?? 1) * (colorValues?.a ?? 1) }); - feature.setProperties({ offsetX: displacement[0] }); - feature.setProperties({ offsetY: displacement[1] }); + if (!isLineString) { + const colorString = tinycolor(theme.visualization.getColorByName(values.color)).toString(); + const colorValues = getRGBValues(colorString); + + const radius = values.size ?? DEFAULT_SIZE; + const displacement = getDisplacement(values.symbolAlign ?? defaultStyleConfig.symbolAlign, radius); + + // WebGLPointsLayer uses style expressions instead of style functions + feature.setProperties({ red: colorValues?.r ?? 255 }); + feature.setProperties({ green: colorValues?.g ?? 255 }); + feature.setProperties({ blue: colorValues?.b ?? 255 }); + feature.setProperties({ size: (values.size ?? 1) * 2 }); // TODO unify sizing across all source types + feature.setProperties({ rotation: ((values.rotation ?? 0) * Math.PI) / 180 }); + feature.setProperties({ opacity: (values.opacity ?? 1) * (colorValues?.a ?? 1) }); + feature.setProperties({ offsetX: displacement[0] }); + feature.setProperties({ offsetY: displacement[1] }); + } // Set style to be used by VectorLayer (text only) if (hasText) { const textStyle = textMarker(values); feature.setStyle(textStyle); } + + // Set style to be used by LineString + if (isLineString) { + const lineStringStyle = style.maker(values); + feature.setStyle(lineStringStyle); + } }); + + // Update hasVector state after processing all features + hasVector = hasText || hasLineString; + + // Update layer visibility based on current hasVector state + const layersArray = layers.getLayers(); + layersArray.clear(); + if (hasVector && symbol) { + layersArray.extend([symbolLayer, vectorLayer]); + } else if (hasVector && !symbol) { + layersArray.extend([vectorLayer]); + } else { + layersArray.extend([symbolLayer]); + } + break; // Only the first frame for now! } },