forked from MapComplete/MapComplete
Merge master
This commit is contained in:
commit
890816d2dd
424 changed files with 40595 additions and 3354 deletions
|
@ -66,7 +66,7 @@
|
|||
/>
|
||||
</If>
|
||||
|
||||
{filteredLayer.layerDef.name}
|
||||
<Tr t={filteredLayer.layerDef.name}/>
|
||||
|
||||
{#if $zoomlevel < layer.minzoom}
|
||||
<span class="alert">
|
||||
|
@ -82,7 +82,7 @@
|
|||
<!-- There are three (and a half) modes of filters: a single checkbox, a radio button/dropdown or with searchable fields -->
|
||||
{#if filter.options.length === 1 && filter.options[0].fields.length === 0}
|
||||
<Checkbox selected={getBooleanStateFor(filter)}>
|
||||
{filter.options[0].question}
|
||||
<Tr t={filter.options[0].question}/>
|
||||
</Checkbox>
|
||||
{/if}
|
||||
|
||||
|
@ -94,7 +94,7 @@
|
|||
<Dropdown value={getStateFor(filter)}>
|
||||
{#each filter.options as option, i}
|
||||
<option value={i}>
|
||||
{option.question}
|
||||
<Tr t={option.question}/>
|
||||
</option>
|
||||
{/each}
|
||||
</Dropdown>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { onDestroy } from "svelte"
|
||||
import { Utils } from "../../Utils"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
|
||||
export let filteredLayer: FilteredLayer
|
||||
export let option: FilterConfigOption
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import LocationInput from "../InputElement/Helpers/LocationInput.svelte"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Tiles } from "../../Models/TileRange"
|
||||
import { Map as MlMap } from "maplibre-gl"
|
||||
import { BBox } from "../../Logic/BBox"
|
||||
import type { MapProperties } from "../../Models/MapProperties"
|
||||
|
@ -15,7 +14,6 @@
|
|||
import FeatureSourceMerger from "../../Logic/FeatureSource/Sources/FeatureSourceMerger"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import { Utils } from "../../Utils"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import Move_arrows from "../../assets/svg/Move_arrows.svelte"
|
||||
|
||||
/**
|
||||
|
@ -53,9 +51,6 @@
|
|||
lat: number
|
||||
}>(undefined)
|
||||
|
||||
const dispatch = createEventDispatcher<{ click: { lon: number; lat: number } }>()
|
||||
|
||||
const xyz = Tiles.embedded_tile(coordinate.lat, coordinate.lon, 16)
|
||||
const map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined)
|
||||
let initialMapProperties: Partial<MapProperties> & { location } = {
|
||||
zoom: new UIEventSource<number>(19),
|
||||
|
@ -73,6 +68,7 @@
|
|||
minzoom: new UIEventSource<number>(18),
|
||||
rasterLayer: UIEventSource.feedFrom(state.mapProperties.rasterLayer),
|
||||
}
|
||||
state?.showCurrentLocationOn(map)
|
||||
|
||||
if (targetLayer) {
|
||||
const featuresForLayer = state.perLayer.get(targetLayer.id)
|
||||
|
@ -120,7 +116,7 @@
|
|||
|
||||
<LocationInput
|
||||
{map}
|
||||
on:click={(data) => dispatch("click", data)}
|
||||
on:click
|
||||
mapProperties={initialMapProperties}
|
||||
value={preciseLocation}
|
||||
initialCoordinate={coordinate}
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
<script lang="ts">
|
||||
/**
|
||||
* A mapcontrol button which allows the user to select a different background.
|
||||
* Even though the component is very small, it gets it's own class as it is often reused
|
||||
* Even though the component is very small, it gets its own class as it is often reused
|
||||
*/
|
||||
import { Square3Stack3dIcon } from "@babeard/svelte-heroicons/solid"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import Translations from "../i18n/Translations"
|
||||
import MapControlButton from "../Base/MapControlButton.svelte"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import StyleLoadingIndicator from "../Map/StyleLoadingIndicator.svelte"
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Map as MlMap } from "maplibre-gl"
|
||||
import ThemeViewState from "../../Models/ThemeViewState"
|
||||
|
||||
export let state: SpecialVisualizationState
|
||||
export let state: ThemeViewState
|
||||
export let map: Store<MlMap> = undefined
|
||||
export let hideTooltip = false
|
||||
</script>
|
||||
|
||||
|
@ -17,7 +22,10 @@
|
|||
arialabel={Translations.t.general.labels.background}
|
||||
on:click={() => state.guistate.backgroundLayerSelectionIsOpened.setData(true)}
|
||||
>
|
||||
<Square3Stack3dIcon class="h-6 w-6" />
|
||||
|
||||
<StyleLoadingIndicator map={map ?? state.map} rasterLayer={state.mapProperties.rasterLayer} >
|
||||
<Square3Stack3dIcon class="h-6 w-6" />
|
||||
</StyleLoadingIndicator>
|
||||
{#if !hideTooltip}
|
||||
<Tr cls="mx-2" t={Translations.t.general.backgroundSwitch} />
|
||||
{/if}
|
||||
|
|
|
@ -13,20 +13,25 @@
|
|||
export let layer: LayerConfig
|
||||
export let selectedElement: Feature
|
||||
let tags: UIEventSource<Record<string, string>> = state.featureProperties.getStore(
|
||||
selectedElement.properties.id
|
||||
selectedElement.properties.id,
|
||||
)
|
||||
$: {
|
||||
tags = state.featureProperties.getStore(selectedElement.properties.id)
|
||||
}
|
||||
|
||||
let isTesting = state.featureSwitchIsTesting
|
||||
let isDebugging = state.featureSwitches.featureSwitchIsDebugging
|
||||
|
||||
let metatags: Store<Record<string, string>> = state.userRelatedState.preferencesAsTags
|
||||
</script>
|
||||
|
||||
{#if $tags._deleted === "yes"}
|
||||
<Tr t={Translations.t.delete.isDeleted} />
|
||||
{:else}
|
||||
<div class="low-interaction flex border-b-2 border-black px-3 drop-shadow-md">
|
||||
<div class="h-fit w-full overflow-auto sm:p-2" style="max-height: 20vh;">
|
||||
<div class="low-interaction flex border-b-2 border-black px-3 drop-shadow-md">
|
||||
<div class="h-fit w-full overflow-auto sm:p-2" style="max-height: 20vh;">
|
||||
{#if $tags._deleted === "yes"}
|
||||
<h3 class="p-4">
|
||||
<Tr t={Translations.t.delete.deletedTitle} />
|
||||
</h3>
|
||||
{:else}
|
||||
<div class="flex h-full w-full flex-grow flex-col">
|
||||
<!-- Title element and title icons-->
|
||||
<h3 class="m-0">
|
||||
|
@ -34,12 +39,11 @@
|
|||
<TagRenderingAnswer config={layer.title} {selectedElement} {state} {tags} {layer} />
|
||||
</a>
|
||||
</h3>
|
||||
|
||||
<div
|
||||
class="no-weblate title-icons links-as-button mr-2 flex flex-row flex-wrap items-center gap-x-0.5 pt-0.5 sm:pt-1"
|
||||
>
|
||||
{#each layer.titleIcons as titleIconConfig}
|
||||
{#if (titleIconConfig.condition?.matchesProperties($tags) ?? true) && (titleIconConfig.metacondition?.matchesProperties( { ...$metatags, ...$tags } ) ?? true) && titleIconConfig.IsKnown($tags)}
|
||||
{#if (titleIconConfig.condition?.matchesProperties($tags) ?? true) && (titleIconConfig.metacondition?.matchesProperties({ ...$metatags, ...$tags }) ?? true) && titleIconConfig.IsKnown($tags)}
|
||||
<div class={titleIconConfig.renderIconClass ?? "flex h-8 w-8 items-center"}>
|
||||
<TagRenderingAnswer
|
||||
config={titleIconConfig}
|
||||
|
@ -52,23 +56,27 @@
|
|||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
{#if $isTesting || $isDebugging}
|
||||
<a class="subtle" href="https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Layers/{layer.id}.md"
|
||||
target="_blank" rel="noreferrer noopener ">{layer.id}</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
on:click={() => state.selectedElement.setData(undefined)}
|
||||
use:ariaLabel={Translations.t.general.backToMap}
|
||||
class="mt-2 h-fit shrink-0 rounded-full border-none p-0"
|
||||
style="border: 0 !important; padding: 0 !important;"
|
||||
>
|
||||
<XCircleIcon aria-hidden={true} class="h-8 w-8" />
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
<button
|
||||
class="mt-2 h-fit shrink-0 rounded-full border-none p-0"
|
||||
on:click={() => state.selectedElement.setData(undefined)}
|
||||
style="border: 0 !important; padding: 0 !important;"
|
||||
use:ariaLabel={Translations.t.general.backToMap}
|
||||
>
|
||||
<XCircleIcon aria-hidden={true} class="h-8 w-8" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:global(.title-icons a) {
|
||||
display: block !important;
|
||||
}
|
||||
:global(.title-icons a) {
|
||||
display: block !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -8,17 +8,21 @@
|
|||
import Translations from "../i18n/Translations"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"
|
||||
import UserRelatedState from "../../Logic/State/UserRelatedState"
|
||||
import Delete_icon from "../../assets/svg/Delete_icon.svelte"
|
||||
import BackButton from "../Base/BackButton.svelte"
|
||||
|
||||
export let state: SpecialVisualizationState
|
||||
export let layer: LayerConfig
|
||||
export let selectedElement: Feature
|
||||
export let highlightedRendering: UIEventSource<string> = undefined
|
||||
|
||||
export let tags: UIEventSource<Record<string, string>> = state?.featureProperties?.getStore(
|
||||
selectedElement.properties.id
|
||||
)
|
||||
|
||||
|
||||
|
||||
let layer: LayerConfig = selectedElement.properties.id === "settings" ? UserRelatedState.usersettingsConfig : state.layout.getMatchingLayer(tags.data)
|
||||
|
||||
|
||||
let stillMatches = tags.map(tags => !layer?.source?.osmTags || layer.source.osmTags?.matchesProperties(tags))
|
||||
|
||||
let _metatags: Record<string, string>
|
||||
|
@ -27,7 +31,7 @@
|
|||
onDestroy(
|
||||
state.userRelatedState.preferencesAsTags.addCallbackAndRun((tags) => {
|
||||
_metatags = tags
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -36,22 +40,26 @@
|
|||
(config) =>
|
||||
(config.condition?.matchesProperties(tgs) ?? true) &&
|
||||
(config.metacondition?.matchesProperties({ ...tgs, ..._metatags }) ?? true) &&
|
||||
config.IsKnown(tgs)
|
||||
)
|
||||
config.IsKnown(tgs),
|
||||
),
|
||||
)
|
||||
</script>
|
||||
|
||||
{#if !$stillMatches}
|
||||
<div class="alert" aria-live="assertive">
|
||||
<Tr t={Translations.t.delete.isChanged}/>
|
||||
<div class="alert" aria-live="assertive">
|
||||
<Tr t={Translations.t.delete.isChanged} />
|
||||
</div>
|
||||
{:else if $tags._deleted === "yes"}
|
||||
<div aria-live="assertive">
|
||||
<Tr t={Translations.t.delete.isDeleted} />
|
||||
<div class="flex w-full flex-col p-2">
|
||||
<div aria-live="assertive" class="alert flex items-center justify-center self-stretch">
|
||||
<Delete_icon class="w-8 h-8 m-2" />
|
||||
<Tr t={Translations.t.delete.isDeleted} />
|
||||
</div>
|
||||
<BackButton clss="self-stretch mt-4" on:click={() => state.selectedElement.setData(undefined)}>
|
||||
<Tr t={Translations.t.general.returnToTheMap} />
|
||||
</BackButton>
|
||||
|
||||
</div>
|
||||
<button class="w-full" on:click={() => state.selectedElement.setData(undefined)}>
|
||||
<Tr t={Translations.t.general.returnToTheMap} />
|
||||
</button>
|
||||
{:else}
|
||||
<div
|
||||
class="selected-element-view flex h-full w-full flex-col gap-y-2 overflow-y-auto p-1 px-4"
|
||||
|
|
|
@ -11,10 +11,11 @@
|
|||
import Tr from "../Base/Tr.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import { Utils } from "../../Utils"
|
||||
import Svg from "../../Svg"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import { DocumentDuplicateIcon } from "@rgossiaux/svelte-heroicons/outline"
|
||||
import Share from "../../assets/svg/Share.svelte"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import Img from "../Base/Img"
|
||||
import Qr from "../../Utils/Qr"
|
||||
|
||||
export let state: ThemeViewState
|
||||
const tr = Translations.t.general.sharescreen
|
||||
|
@ -69,22 +70,32 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<Tr t={tr.intro} />
|
||||
<div class="flex">
|
||||
{#if typeof navigator?.share === "function"}
|
||||
<button class="h-8 w-8 shrink-0 p-1" on:click={shareCurrentLink}>
|
||||
<Share />
|
||||
</button>
|
||||
{/if}
|
||||
{#if navigator.clipboard !== undefined}
|
||||
<button class="no-image-background h-8 w-8 shrink-0 p-1" on:click={copyCurrentLink}>
|
||||
<DocumentDuplicateIcon />
|
||||
</button>
|
||||
{/if}
|
||||
<div class="literal-code" on:click={(e) => Utils.selectTextIn(e.target)}>
|
||||
{linkToShare}
|
||||
<div class="flex flex-col">
|
||||
<div class="flex justify-between items-start">
|
||||
|
||||
<div class="flex flex-col">
|
||||
|
||||
<Tr t={tr.intro} />
|
||||
<div class="flex">
|
||||
{#if typeof navigator?.share === "function"}
|
||||
<button class="h-8 w-8 shrink-0 p-1" on:click={shareCurrentLink}>
|
||||
<Share />
|
||||
</button>
|
||||
{/if}
|
||||
{#if navigator.clipboard !== undefined}
|
||||
<button class="no-image-background h-8 w-8 shrink-0 p-1" on:click={copyCurrentLink}>
|
||||
<DocumentDuplicateIcon />
|
||||
</button>
|
||||
{/if}
|
||||
<div class="literal-code" on:click={(e) => Utils.selectTextIn(e.target)}>
|
||||
{linkToShare}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ToSvelte construct={() => new Img(new Qr(linkToShare).toImageElement(125)).SetStyle(
|
||||
"width: 125px"
|
||||
)} />
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
|
@ -95,29 +106,31 @@
|
|||
|
||||
<Tr t={tr.embedIntro} />
|
||||
|
||||
<div class="link-underline my-1 flex flex-col">
|
||||
<label>
|
||||
<input bind:checked={showWelcomeMessage} type="checkbox" />
|
||||
<Tr t={tr.fsWelcomeMessage} />
|
||||
</label>
|
||||
<div class="flex flex-col interactive p-1">
|
||||
|
||||
<label>
|
||||
<input bind:checked={enableLogin} type="checkbox" />
|
||||
<Tr t={tr.fsUserbadge} />
|
||||
</label>
|
||||
</div>
|
||||
<div class="literal-code m-1">
|
||||
<span class="literal-code iframe-code-block"> <br />
|
||||
<iframe src="{linkToShare}"
|
||||
<br />
|
||||
allow="geolocation" width="100%" height="100%" style="min-width: 250px; min-height: 250px"
|
||||
<br />
|
||||
title="{state.layout.title?.txt ?? "MapComplete"} with MapComplete">
|
||||
<br />
|
||||
</iframe>
|
||||
<br />
|
||||
</span>
|
||||
</div>
|
||||
<div class="link-underline my-1 flex flex-col">
|
||||
<label>
|
||||
<input bind:checked={showWelcomeMessage} type="checkbox" id="share_show_welcome" />
|
||||
<Tr t={tr.fsWelcomeMessage} />
|
||||
</label>
|
||||
|
||||
<div class="literal-code m-1">
|
||||
<span class="literal-code iframe-code-block"> <br />
|
||||
<iframe src="${url}"
|
||||
<br />
|
||||
allow="geolocation" width="100%" height="100%" style="min-width: 250px; min-height: 250px"
|
||||
<br />
|
||||
title="${state.layout.title?.txt ?? "MapComplete"} with MapComplete">
|
||||
<br />
|
||||
</iframe>
|
||||
<br />
|
||||
</span>
|
||||
<label>
|
||||
<input bind:checked={enableLogin} type="checkbox" id="share_enable_login"/>
|
||||
<Tr t={tr.fsUserbadge} />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<Tr t={tr.documentation} cls="link-underline" />
|
||||
<Tr cls="link-underline" t={tr.documentation} />
|
||||
</div>
|
||||
|
|
|
@ -17,14 +17,17 @@ export default class StatisticsForLayerPanel extends VariableUiElement {
|
|||
return new Loading("Loading data")
|
||||
}
|
||||
if (features.length === 0) {
|
||||
return "No elements in view"
|
||||
return new Combine([
|
||||
"No elements in view for layer ",
|
||||
layer.id
|
||||
]).SetClass("block")
|
||||
}
|
||||
const els: BaseUIElement[] = []
|
||||
const featuresForLayer = features
|
||||
if (featuresForLayer.length === 0) {
|
||||
return
|
||||
}
|
||||
els.push(new Title(layer.name.Clone(), 1).SetClass("mt-8"))
|
||||
els.push(new Title(layer.name, 1).SetClass("mt-8"))
|
||||
|
||||
const layerStats = []
|
||||
for (const tagRendering of layer?.tagRenderings ?? []) {
|
||||
|
|
|
@ -8,7 +8,9 @@ import { OsmFeature } from "../../Models/OsmFeature"
|
|||
|
||||
export interface TagRenderingChartOptions {
|
||||
groupToOtherCutoff?: 3 | number
|
||||
sort?: boolean
|
||||
sort?: boolean,
|
||||
hideUnkown?: boolean,
|
||||
hideNotApplicable?: boolean
|
||||
}
|
||||
|
||||
export class StackedRenderingChart extends ChartJs {
|
||||
|
@ -19,12 +21,16 @@ export class StackedRenderingChart extends ChartJs {
|
|||
period: "day" | "month"
|
||||
groupToOtherCutoff?: 3 | number
|
||||
// If given, take the sum of these fields to get the feature weight
|
||||
sumFields?: string[]
|
||||
sumFields?: string[],
|
||||
hideUnknown?: boolean,
|
||||
hideNotApplicable?: boolean
|
||||
}
|
||||
) {
|
||||
const { labels, data } = TagRenderingChart.extractDataAndLabels(tr, features, {
|
||||
sort: true,
|
||||
groupToOtherCutoff: options?.groupToOtherCutoff,
|
||||
hideNotApplicable: options?.hideNotApplicable,
|
||||
hideUnkown: options?.hideUnknown
|
||||
})
|
||||
if (labels === undefined || data === undefined) {
|
||||
console.error(
|
||||
|
@ -36,7 +42,6 @@ export class StackedRenderingChart extends ChartJs {
|
|||
)
|
||||
throw "No labels or data given..."
|
||||
}
|
||||
// labels: ["cyclofix", "buurtnatuur", ...]; data : [ ["cyclofix-changeset", "cyclofix-changeset", ...], ["buurtnatuur-cs", "buurtnatuur-cs"], ... ]
|
||||
|
||||
for (let i = labels.length; i >= 0; i--) {
|
||||
if (data[i]?.length != 0) {
|
||||
|
@ -116,13 +121,13 @@ export class StackedRenderingChart extends ChartJs {
|
|||
datasets.push({
|
||||
data: countsPerDay,
|
||||
backgroundColor,
|
||||
label,
|
||||
label
|
||||
})
|
||||
}
|
||||
|
||||
const perDayData = {
|
||||
labels: trimmedDays,
|
||||
datasets,
|
||||
datasets
|
||||
}
|
||||
|
||||
const config = <ChartConfiguration>{
|
||||
|
@ -131,17 +136,17 @@ export class StackedRenderingChart extends ChartJs {
|
|||
options: {
|
||||
responsive: true,
|
||||
legend: {
|
||||
display: false,
|
||||
display: false
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
stacked: true,
|
||||
stacked: true
|
||||
},
|
||||
y: {
|
||||
stacked: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
stacked: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super(config)
|
||||
}
|
||||
|
@ -194,7 +199,7 @@ export default class TagRenderingChart extends Combine {
|
|||
"rgba(255, 206, 86, 0.2)",
|
||||
"rgba(75, 192, 192, 0.2)",
|
||||
"rgba(153, 102, 255, 0.2)",
|
||||
"rgba(255, 159, 64, 0.2)",
|
||||
"rgba(255, 159, 64, 0.2)"
|
||||
]
|
||||
|
||||
public static readonly borderColors = [
|
||||
|
@ -203,7 +208,7 @@ export default class TagRenderingChart extends Combine {
|
|||
"rgba(255, 206, 86, 1)",
|
||||
"rgba(75, 192, 192, 1)",
|
||||
"rgba(153, 102, 255, 1)",
|
||||
"rgba(255, 159, 64, 1)",
|
||||
"rgba(255, 159, 64, 1)"
|
||||
]
|
||||
|
||||
/**
|
||||
|
@ -239,12 +244,12 @@ export default class TagRenderingChart extends Combine {
|
|||
const borderColor = [
|
||||
TagRenderingChart.unkownBorderColor,
|
||||
TagRenderingChart.otherBorderColor,
|
||||
TagRenderingChart.notApplicableBorderColor,
|
||||
TagRenderingChart.notApplicableBorderColor
|
||||
]
|
||||
const backgroundColor = [
|
||||
TagRenderingChart.unkownColor,
|
||||
TagRenderingChart.otherColor,
|
||||
TagRenderingChart.notApplicableColor,
|
||||
TagRenderingChart.notApplicableColor
|
||||
]
|
||||
|
||||
while (borderColor.length < data.length) {
|
||||
|
@ -276,17 +281,17 @@ export default class TagRenderingChart extends Combine {
|
|||
backgroundColor,
|
||||
borderColor,
|
||||
borderWidth: 1,
|
||||
label: undefined,
|
||||
},
|
||||
],
|
||||
label: undefined
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: !barchartMode,
|
||||
},
|
||||
},
|
||||
},
|
||||
display: !barchartMode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const chart = new ChartJs(config).SetClass(options?.chartclasses ?? "w-32 h-32")
|
||||
|
@ -297,7 +302,7 @@ export default class TagRenderingChart extends Combine {
|
|||
|
||||
super([
|
||||
options?.includeTitle ? tagRendering.question.Clone() ?? tagRendering.id : undefined,
|
||||
chart,
|
||||
chart
|
||||
])
|
||||
|
||||
this.SetClass("block")
|
||||
|
@ -386,20 +391,26 @@ export default class TagRenderingChart extends Combine {
|
|||
}
|
||||
}
|
||||
|
||||
const labels = [
|
||||
"Unknown",
|
||||
"Other",
|
||||
"Not applicable",
|
||||
const labels = []
|
||||
const data: T[][] = []
|
||||
|
||||
if (!options.hideUnkown) {
|
||||
data.push(unknownCount)
|
||||
labels.push("Unknown")
|
||||
}
|
||||
data.push(otherGrouped)
|
||||
labels.push("Other")
|
||||
if (!options.hideNotApplicable) {
|
||||
data.push(notApplicable)
|
||||
labels.push(
|
||||
"Not applicable"
|
||||
)
|
||||
}
|
||||
data.push(...categoryCounts,
|
||||
...otherData)
|
||||
labels.push(
|
||||
...(mappings?.map((m) => m.then.txt) ?? []),
|
||||
...otherLabels,
|
||||
]
|
||||
const data: T[][] = [
|
||||
unknownCount,
|
||||
otherGrouped,
|
||||
notApplicable,
|
||||
...categoryCounts,
|
||||
...otherData,
|
||||
]
|
||||
...otherLabels)
|
||||
|
||||
return { labels, data }
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
import Constants from "../../Models/Constants"
|
||||
import type { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import SubtleLink from "../Base/SubtleLink.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import { LocalStorageSource } from "../../Logic/Web/LocalStorageSource"
|
||||
|
||||
|
@ -86,8 +85,10 @@
|
|||
</script>
|
||||
|
||||
{#if theme.id !== personal.id || $unlockedPersonal}
|
||||
<SubtleLink href={$href} options={{ extraClasses: "w-full" }}>
|
||||
<img slot="image" src={theme.icon} class="m-1 mr-2 block h-11 w-11 sm:m-2 sm:mr-4" alt="" />
|
||||
<a
|
||||
class={"w-full button text-ellipsis"}
|
||||
href={$href}
|
||||
> <img src={theme.icon} class="m-1 mr-2 block h-11 w-11 sm:m-2 sm:mr-4" alt="" />
|
||||
<span class="flex flex-col overflow-hidden text-ellipsis">
|
||||
<Tr t={title} />
|
||||
|
||||
|
@ -96,6 +97,5 @@
|
|||
<Tr t={Translations.t.general.morescreen.enterToOpen} />
|
||||
</span>
|
||||
{/if}
|
||||
</span>
|
||||
</SubtleLink>
|
||||
</span></a>
|
||||
{/if}
|
||||
|
|
|
@ -23,18 +23,20 @@
|
|||
import { GeoOperations } from "../../Logic/GeoOperations"
|
||||
import { BBox } from "../../Logic/BBox"
|
||||
import type { Feature, LineString, Point } from "geojson"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import SmallZoomButtons from "../Map/SmallZoomButtons.svelte"
|
||||
|
||||
const splitpoint_style = new LayerConfig(
|
||||
<LayerConfigJson>split_point,
|
||||
"(BUILTIN) SplitRoadWizard.ts",
|
||||
true
|
||||
) as const
|
||||
true,
|
||||
)
|
||||
|
||||
const splitroad_style = new LayerConfig(
|
||||
<LayerConfigJson>split_road,
|
||||
"(BUILTIN) SplitRoadWizard.ts",
|
||||
true
|
||||
) as const
|
||||
true,
|
||||
)
|
||||
|
||||
/**
|
||||
* The way to focus on
|
||||
|
@ -45,6 +47,7 @@
|
|||
* A default is given
|
||||
*/
|
||||
export let layer: LayerConfig = splitroad_style
|
||||
export let state: SpecialVisualizationState | undefined = undefined
|
||||
/**
|
||||
* Optional: use these properties to set e.g. background layer
|
||||
*/
|
||||
|
@ -58,6 +61,7 @@
|
|||
adaptor.bounds.setData(BBox.get(wayGeojson).pad(2))
|
||||
adaptor.maxbounds.setData(BBox.get(wayGeojson).pad(2))
|
||||
|
||||
state?.showCurrentLocationOn(map)
|
||||
new ShowDataLayer(map, {
|
||||
features: new StaticFeatureSource([wayGeojson]),
|
||||
drawMarkers: false,
|
||||
|
@ -101,6 +105,7 @@
|
|||
})
|
||||
</script>
|
||||
|
||||
<div class="h-full w-full">
|
||||
<MaplibreMap {map} />
|
||||
<div class="h-full w-full relative">
|
||||
<MaplibreMap {map} mapProperties={adaptor} />
|
||||
<SmallZoomButtons {adaptor} />
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue