UI: add special rendering to show icons of other questions

This commit is contained in:
Pieter Vander Vennet 2025-08-17 02:45:26 +02:00
parent eb072ff5a6
commit 03fe86cb8f
3 changed files with 72 additions and 5 deletions

View file

@ -523,7 +523,9 @@ export default class TagRenderingConfig {
/** /**
* Gets all the render values. Will return multiple render values if 'multianswer' is enabled. * Gets all the render values. Will return multiple render values if 'multianswer' is enabled.
* The result will equal [GetRenderValue] if not 'multiAnswer' * The result will equal [GetRenderValue] if not 'multiAnswer'.
*
* If an iconsource is given, will return an icon too (but not necessarly an iconSize)
* @param tags * @param tags
* @constructor * @constructor
*/ */

View file

@ -1,4 +1,9 @@
import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationSvelte } from "../SpecialVisualization" import {
SpecialVisualisationArg,
SpecialVisualisationParams,
SpecialVisualization,
SpecialVisualizationSvelte,
} from "../SpecialVisualization"
import { HistogramViz } from "./HistogramViz" import { HistogramViz } from "./HistogramViz"
import { Store } from "../../Logic/UIEventSource" import { Store } from "../../Logic/UIEventSource"
import BaseUIElement from "../BaseUIElement" import BaseUIElement from "../BaseUIElement"
@ -22,6 +27,9 @@ import TagRenderingEditable from "./TagRendering/TagRenderingEditable.svelte"
import AllTagsPanel from "./AllTagsPanel/AllTagsPanel.svelte" import AllTagsPanel from "./AllTagsPanel/AllTagsPanel.svelte"
import CollectionTimes from "../CollectionTimes/CollectionTimes.svelte" import CollectionTimes from "../CollectionTimes/CollectionTimes.svelte"
import Tr from "../Base/Tr.svelte" import Tr from "../Base/Tr.svelte"
import Combine from "../Base/Combine"
import Marker from "../Map/Marker.svelte"
import { twJoin } from "tailwind-merge"
class DirectionIndicatorVis extends SpecialVisualizationSvelte { class DirectionIndicatorVis extends SpecialVisualizationSvelte {
funcName = "direction_indicator" funcName = "direction_indicator"
@ -209,6 +217,7 @@ class PresetDescription extends SpecialVisualizationSvelte {
docs = docs =
"Shows the extra description from the presets of the layer, if one matches. It will pick the most specific one (e.g. if preset `A` implies `B`, but `B` does not imply `A`, it'll pick B) or the first one if no ordering can be made. Might be empty" "Shows the extra description from the presets of the layer, if one matches. It will pick the most specific one (e.g. if preset `A` implies `B`, but `B` does not imply `A`, it'll pick B) or the first one if no ordering can be made. Might be empty"
args = [] args = []
group = "UI"
constr({ state, tags }: SpecialVisualisationParams): SvelteUIElement { constr({ state, tags }: SpecialVisualisationParams): SvelteUIElement {
const translation = tags.map((tags) => { const translation = tags.map((tags) => {
@ -223,6 +232,7 @@ class PresetTypeSelect extends SpecialVisualizationSvelte {
funcName = "preset_type_select" funcName = "preset_type_select"
docs = "An editable tag rendering which allows to change the type" docs = "An editable tag rendering which allows to change the type"
args = [] args = []
group = "ui"
constr({ state, tags, feature, layer }: SpecialVisualisationParams,): SvelteUIElement { constr({ state, tags, feature, layer }: SpecialVisualisationParams,): SvelteUIElement {
const t = Translations.t.preset_type const t = Translations.t.preset_type
@ -281,7 +291,7 @@ class PointsInTimeVis extends SpecialVisualization {
}, },
] ]
constr( {tags, args}: SpecialVisualisationParams): BaseUIElement { constr({ tags, args }: SpecialVisualisationParams): BaseUIElement {
const key = args[0] const key = args[0]
const points_in_time = tags.map((tags) => tags[key]) const points_in_time = tags.map((tags) => tags[key])
const times = points_in_time.map( const times = points_in_time.map(
@ -294,6 +304,60 @@ class PointsInTimeVis extends SpecialVisualization {
} }
} }
class KnownIcons extends SpecialVisualization {
docs = "Displays all icons from the specified tagRenderings (if they are known and have an icon) together, e.g. to give a summary of the dietary options"
needsUrls = []
group = "UI"
funcName = "show_icons"
args: SpecialVisualisationArg[] = [{
name: "labels",
doc: "A ';'-separated list of labels and/or ids of tagRenderings",
type: "key",
required: true,
}, {
name: "class",
doc: "CSS-classes of the container, space-separated",
type: "css",
required: false,
defaultValue: "inline-flex mx-4",
}]
private static readonly emojiHeights = {
small: "2rem",
medium: "3rem",
large: "5rem",
}
constr(options: SpecialVisualisationParams): BaseUIElement {
const labels = new Set(options.args[0].split(";").map(s => s.trim()))
const matchingTrs = options.layer.tagRenderings.filter(
tr => labels.has(tr.id) || tr.labels.some(l => labels.has(l)),
)
return new VariableUiElement(options.tags.map(tags =>
new Combine(matchingTrs.map(tr => {
const mapping = tr.GetRenderValueWithImage(tags)
if (!mapping?.icon) {
return undefined
}
return new SvelteUIElement(Marker, {
emojiHeight: KnownIcons.emojiHeights[mapping.iconClass] ?? "2rem",
clss: `mapping-icon-${mapping.iconClass ?? "small"}`,
icons: mapping.icon,
size: twJoin(
"shrink-0",
`mapping-icon-${mapping.iconClass ?? "small"}-height mapping-icon-${
mapping.iconClass ?? "small"
}-width`),
})
})
).SetClass(options.args[1] ?? "inline-flex mx-4")
))
}
}
export class DataVisualisations { export class DataVisualisations {
public static initList(): SpecialVisualization[] { public static initList(): SpecialVisualization[] {
return [ return [
@ -309,6 +373,7 @@ export class DataVisualisations {
new PresetDescription(), new PresetDescription(),
new PresetTypeSelect(), new PresetTypeSelect(),
new AllTagsVis(), new AllTagsVis(),
new KnownIcons(),
] ]
} }
} }

View file

@ -213,7 +213,7 @@ class OpenInId extends SpecialVisualizationSvelte {
funcName = "open_in_iD" funcName = "open_in_iD"
docs = "Opens the current view in the iD-editor" docs = "Opens the current view in the iD-editor"
args = [] args = []
group = "tagrendering_manipulation" group = "web_and_communication"
constr({state, feature}: SpecialVisualisationParams): SvelteUIElement { constr({state, feature}: SpecialVisualisationParams): SvelteUIElement {
return new SvelteUIElement(OpenIdEditor, { return new SvelteUIElement(OpenIdEditor, {
@ -225,7 +225,7 @@ class OpenInId extends SpecialVisualizationSvelte {
class OpenInJosm extends SpecialVisualizationSvelte { class OpenInJosm extends SpecialVisualizationSvelte {
funcName = "open_in_josm" funcName = "open_in_josm"
group = "tagrendering_manipulation" group = "web_and_communication"
docs = "Opens the current view in the JOSM-editor" docs = "Opens the current view in the JOSM-editor"
args = [] args = []
needsUrls = [ needsUrls = [