From e1c77d8986db8fd036e86da494b13a203042c127 Mon Sep 17 00:00:00 2001 From: Matthieu Viry Date: Wed, 18 Dec 2024 14:31:10 +0100 Subject: [PATCH] Fix categorical pictogram portrayal for features with no value --- .../CategoricalPictogramLegendRenderer.tsx | 18 +++++--- .../CategoricalPictogramMapRenderer.tsx | 41 +++++++++++-------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/components/LegendRenderer/CategoricalPictogramLegendRenderer.tsx b/src/components/LegendRenderer/CategoricalPictogramLegendRenderer.tsx index 055bd995f..8f5350d6a 100644 --- a/src/components/LegendRenderer/CategoricalPictogramLegendRenderer.tsx +++ b/src/components/LegendRenderer/CategoricalPictogramLegendRenderer.tsx @@ -6,6 +6,7 @@ import { // Helpers import { useI18nContext } from '../../i18n/i18n-solid'; +import { isNonNull } from '../../helpers/common'; import { findLayerById } from '../../helpers/layers'; import { sum } from '../../helpers/math'; import { @@ -41,6 +42,10 @@ export default function legendCategoricalPictogram( legend.layerId, ) as LayerDescriptionCategoricalPictogram; + const mapping = createMemo( + () => layer.rendererParameters.mapping.filter((m) => isNonNull(m.value)), + ); + const heightTitle = () => { const titleSize = getTextSize( legend.title.text, @@ -64,7 +69,7 @@ export default function legendCategoricalPictogram( const positionNote = createMemo(() => ( heightTitleSubtitle() // The size necessary for the title and subtitle + ( // The size for all the icons and the spacing between them - sum(layer.rendererParameters.mapping.map((d) => d.iconDimension[1] + legend.spacing)) + sum(mapping().map((d) => d.iconDimension[1] + legend.spacing)) - legend.spacing ) + defaultSpacing * 2 // space between the last icon and the note @@ -109,14 +114,15 @@ export default function legendCategoricalPictogram( {makeLegendText(legend.title, [0, 0], 'title')} {makeLegendText(legend.subtitle, [0, heightTitle()], 'subtitle')} - + { (item, i) => { if (item.iconType === 'SVG') { return <> d.iconDimension[1] + legend.spacing), ))})`} // eslint-disable-next-line solid/no-innerhtml @@ -134,7 +140,7 @@ export default function legendCategoricalPictogram( dominant-baseline="middle" x={60} y={heightTitleSubtitle() + item.iconDimension[1] / 2 + (i() === 0 ? 0 : sum( - layer.rendererParameters.mapping.slice(0, i()) + mapping().slice(0, i()) .map((d: CategoricalPictogramMapping) => d.iconDimension[1] + legend.spacing), ))} >{item.categoryName} @@ -143,7 +149,7 @@ export default function legendCategoricalPictogram( return <> d.iconDimension[1] + legend.spacing), ))})`} > @@ -162,7 +168,7 @@ export default function legendCategoricalPictogram( dominant-baseline="middle" x={60} y={heightTitleSubtitle() + (i() === 0 ? 0 : sum( - layer.rendererParameters.mapping.slice(0, i()) + mapping().slice(0, i()) .map((d: CategoricalPictogramMapping) => d.iconDimension[1] + legend.spacing), ))} >{item.categoryName} diff --git a/src/components/MapRenderer/CategoricalPictogramMapRenderer.tsx b/src/components/MapRenderer/CategoricalPictogramMapRenderer.tsx index ecd3fb969..ba61aa8c1 100644 --- a/src/components/MapRenderer/CategoricalPictogramMapRenderer.tsx +++ b/src/components/MapRenderer/CategoricalPictogramMapRenderer.tsx @@ -20,21 +20,30 @@ const directives = [ // eslint-disable-line @typescript-eslint/no-unused-vars bindData, ]; +type CategoricalPictoMapK = string | number | null | undefined; +type CategoricalPictoMapV = [string, string, [number, number]] | null; + export default function categoricalPictogramRenderer( layerDescription: LayerDescriptionCategoricalPictogram, ): JSX.Element { let refElement: SVGGElement; const symbolMap = createMemo( - () => new Map( - layerDescription.rendererParameters.mapping - .map(({ - value, - iconContent, - iconType, - iconDimension, - }) => [value, [iconType, iconContent, iconDimension]]), - ), + () => { + const map = new Map( + layerDescription.rendererParameters.mapping + .map(({ + value, + iconContent, + iconType, + iconDimension, + }) => [value, [iconType, iconContent, iconDimension]]), + ); + map.set('', null); + map.set(null, null); + map.set(undefined, null); + return map; + }, ); return { const icon = createMemo(() => symbolMap() .get(feature.properties[layerDescription.rendererParameters.variable])); + if (!icon()) return <>; const projectedCoords = createMemo( () => globalStore.projection(feature.geometry.coordinates) - .map((d, i) => d - icon()[2][i] / 2), + .map((d, i) => d - icon()![2][i] / 2), ); - if (!icon()) return <>; - if (icon()[0] === 'SVG') { + if (icon()![0] === 'SVG') { return ; } return - + ; } }